Updated coding standards in mpsl.l.
[mpsl.git] / doc / mpsl_internals.txt
blobd16f2f8f1e2dbc5ae76a78518d12ae5d32bcc09b
1 MPSL internals
2 ==============
4  Angel Ortega <angel@triptico.com>
6 This document describes some internal details of this MPSL implementation.
8 The symbol table
9 ----------------
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.
34 The bytecode
35 ------------
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
43 that call each other.
45 A description of each opcode follows:
47 MULTI
48 ~~~~~
50  MULTI <ins1> <ins2>
52 A MULTI instruction executes `ins1', then `ins2', and returns the exit
53 value of the latter.
55 LITERAL
56 ~~~~~~~
58  LITERAL <value>
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.
64 SYMVAL
65 ~~~~~~
67  SYMVAL <ins1>
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
71 (if any) returned.
73 ASSIGN
74 ~~~~~~
76  ASSIGN <ins1> <ins2>
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.
82 EXECSYM
83 ~~~~~~~
85  EXECSYM <ins1>
86  EXECSYM <ins1> <ins2>
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.
96  IF <ins1> <ins2>
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.
103 WHILE
104 ~~~~~
106  WHILE <ins1> <ins2>
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.
112 LOCAL
113 ~~~~~
115  LOCAL <ins1>
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
119 NULL.
121 UMINUS
122 ~~~~~~
124  UMINUS <ins1>
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).
129 Math operations
130 ~~~~~~~~~~~~~~~
132  ADD <ins1> <ins2>
133  SUB <ins1> <ins2>
134  MUL <ins1> <ins2>
135  DIV <ins1> <ins2>
136  MOD <ins1> <ins2>
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.
146  NOT <ins1>
148 A NOT instruction executes `ins1', takes its return value as a boolean
149 one, and returns its negation.
154  AND <ins1> <ins2>
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'
159 is never executed.
164  OR <ins1> <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
169 executed.
171 Numeric comparisons
172 ~~~~~~~~~~~~~~~~~~~
174  NUMEQ <ins1> <ins2>
175  NUMLT <ins1> <ins2>
176  NUMLE <ins1> <ins2>
177  NUMGT <ins1> <ins2>
178  NUMGE <ins1> <ins2>
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.
184 Bitwise operators
185 ~~~~~~~~~~~~~~~~~
187  BITAND <ins1> <ins2>
188  BITOR <ins1> <ins2>
189  BITXOR <ins1> <ins2>
191 Returns the bitwise operation between the exit values of `ins1' and `ins2'.
193 STRCAT
194 ~~~~~~
196  STRCAT <ins1> <ins2>
198 A STRCAT instruction executes both `ins1' and `ins2', and concatenates the
199 two (accepted as strings) exit values.
201 STREQ
202 ~~~~~
204  STREQ <ins1> <ins2>
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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
212  PINC <ins1>
213  PDEC <ins1>
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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
222  SINC <ins1>
223  SDEC <ins1>
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 ~~~~~~~~~~~~~~~~~~~~~~~~~
232  IADD <ins1> <ins2>
233  ISUB <ins1> <ins2>
234  IMUL <ins1> <ins2>
235  IDIV <ins1> <ins2>
236  IMOD <ins1> <ins2>
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.
243 BREAK
244 ~~~~~
246  BREAK
248 A BREAK instruction forces the exit of a loop as WHILE or FOREACH. Returns
249 NULL.
251 RETURN
252 ~~~~~~
254  RETURN
255  RETURN <ins1>
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.
260 FOREACH
261 ~~~~~~~
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.
270 RANGE
271 ~~~~~
273  RANGE <ins1> <ins2>
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).
279 LIST
280 ~~~~
282  LIST <ins>
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,
287 which is returned.
289 HASH
290 ~~~~
292  HASH <ins1> <ins2>
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.
299 SUBFRAME
300 ~~~~~~~~
302  SUBFRAME <ins1>
304 A SUBFRAME instruction creates a subroutine frame, executes `ins1',
305 destroys the subroutine frame and returns `ins1' exit value.
307 BLKFRAME
308 ~~~~~~~~
310  BLKFRAME <ins1>
312 A BLKFRAME instruction creates a block frame, executes `ins1',
313 destroys the block frame and returns `ins1' exit value.
315 ----
316 Angel Ortega <angel@triptico.com>