4 Angel Ortega <angel@triptico.com>
6 This document describes some internal details of this MPSL implementation.
11 There are three different scopes for a symbol in MPSL: global (accesible
12 from everywhere), local to subroutine (accesible from the subroutine where
13 it's defined) or local to block (accesible from the block where it's
14 defined). The priority for symbols with the same name is, obviously,
15 inverse: a local to block symbol obscures a local to subroutine one, and
16 both a global one. Also, as blocks can be nested, local values defined in
17 the inner blocks obscure the ones defined outside.
19 The global symbol table
20 ~~~~~~~~~~~~~~~~~~~~~~~
22 The global symbol table is the simpler one: all global symbols are keys of
23 the root hash (as returned from mpdm's function mpdm_root()). Once a
24 global symbol is defined, it's stored there until explicit deletion or
25 host program termination. MPSL library functions are also global symbols,
26 and share the same namespace.
28 The local symbol table
29 ~~~~~~~~~~~~~~~~~~~~~~
31 The local symbol table is an array of hashes. The array is used as a stack,
32 and symbols are searched in the stacked hashes from top to bottom.
37 When the compiler parses a MPSL source code file, it generates a bunch of
38 MPSL instructions, each one stored in a mpdm array. This (usually small)
39 array contains in the first element a scalar value, the _opcode_, and
40 optionally other values, that are also MPSL instructions (unless in a very
41 special case) and act as the opcode's arguments. All instructions return a
42 value after execution. A MPSL compiled program is a chain of instructions
45 A description of each opcode follows:
52 A MULTI instruction executes `ins1', then `ins2', and returns the exit
60 A LITERAL instruction clones (using mpdm_clone()) and returns the stored
61 value. This is the special case described in the introduction paragraph;
62 the arguments for all other instructions are themselves instructions.
69 A SYMVAL instruction executes `ins1' and accepts its return value as a
70 symbol name, that is looked up in the symbol table and its assigned value
78 An ASSIGN instruction executes `ins1' and accepts its return value as a
79 symbol name; then `ins2' is executed and its return value assigned to that
80 symbol. The new value is returned.
88 An EXECSYM instruction takes the value of the symbol returned by `ins1' and
89 accepts its return value as an executable one; if exists, executes `ins2'
90 and accepts its return value as a list of arguments for the executable
91 value; then it's executed and its exit value returned.
97 IF <ins1> <ins2> <ins3>
99 An IF instruction executes `ins1' and, if it returns a true value,
100 executes `ins2' and returns its value. If it's not true, returns NULL or,
101 if `ins3' is defined, executes it and returns its value.
108 A WHILE instruction executes `ins1' and, if it's a true value, executes
109 `ins2'. This operation is repeated until `ins1' returns a non-true value.
110 It always returns NULL.
117 A LOCAL instruction executes `ins1' and takes its return value as an array
118 of symbol names to be created in the local symbol table. It always returns
126 An UMINUS instruction executes `ins1', gets its value as a real number and
127 returns the unary minus operation on it (effectively multiplying it by -1).
138 These instructions execute the addition, substraction, multiply, divide and
139 modulo math operations from the exit values of the two instructions, and
140 return the result. Values are treated as real numbers except in MOD, where
141 they are treated as integers.
148 A NOT instruction executes `ins1', takes its return value as a boolean
149 one, and returns its negation.
156 An AND instruction executes `ins1'. If its return value is accepted as a
157 non-true value, returns it; otherwise, executes `ins2' and returns its
158 value. This is a short-circuiting operation; if `ins1' is non-true, `ins2'
166 An OR instruction executes `ins1'. If its return value is accepted as a
167 true value, returns it; otherwise, executes `ins2' and returns its value.
168 This is a short-circuiting operation; if `ins1' is true, `ins2' is never
180 These instructions execute the equality, less-than, less-or-equal-than,
181 greater-than and greater-or-equal-than numeric comparisons on the exit
182 values of `ins1' and `ins2', and return a boolean value.
191 Returns the bitwise operation between the exit values of `ins1' and `ins2'.
198 A STRCAT instruction executes both `ins1' and `ins2', and concatenates the
199 two (accepted as strings) exit values.
206 A STREQ instruction executes both `ins1' and `ins2', tests for string equality
207 of both values, and returns a boolean value.
209 Postfix immediate unary operations
210 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
215 These instructions execute `ins1' and accept its return value as a symbol
216 name. Its value is incremented or decremented, and then reassigned to it.
217 The new value for the symbol is returned.
219 Suffix immediate unary operations
220 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
225 These instructions execute `ins1' and accept its return value as a symbol
226 value. Its value is incremented or decremented, and then reassigned to it.
227 The old value for the symbol is returned.
229 Immediate math operations
230 ~~~~~~~~~~~~~~~~~~~~~~~~~
238 These instructions execute `ins1' and accept its return value as a symbol
239 name. Then `ins2' is executed, and its return value added, substracted,
240 multiplied, divided or modulo'ed by the value of the symbol, and then
241 reassigned to it. The new value is returned.
248 A BREAK instruction forces the exit of a loop as WHILE or FOREACH. Returns
257 A RETURN instruction forces the exit of the current subroutine. If `ins1'
258 is defined, it's executed and its value returned, or NULL otherwise.
263 FOREACH <ins1> <ins2> <ins3>
265 A FOREACH instruction executes `ins1' and accepts its return value as a
266 symbol name, and executes `ins2' and accepts its return value as an array
267 to be iterated onto. Then, in a loop, each element in `ins2' is assigned
268 to `ins1' and `ins3' executed. NULL is always returned.
275 A RANGE instruction executes both `ins1' and `ins2' and, taken their
276 return values as real numbers, returns an array containing a sequence of
277 all the values in between (including them).
283 LIST <ins> <array_value>
285 A LIST instruction returns an array. If `array_value' does not exist, a
286 new one is created. The return value of `ins' is pushed into the array,
293 HASH <ins1> <ins2> <hash_value>
295 A HASH instruction returns a hash. If `hash_value' does not exist, a
296 new one is created. The return values of `ins1' and `ins2' are used as
297 a key, value pair that is inserted into the hash, which is returned.
304 A SUBFRAME instruction creates a subroutine frame, executes `ins1',
305 destroys the subroutine frame and returns `ins1' exit value.
312 A BLKFRAME instruction creates a block frame, executes `ins1',
313 destroys the block frame and returns `ins1' exit value.
316 Angel Ortega <angel@triptico.com>