Lingo bytecode
This is a partial, work-in-progress examination of the bytecode created when Lingo code is compiled in Macromedia Director 4.0. This is also sometimes known as IML, or Idealized Machine Language. It describes instructions for a stack-based virtual machine.
Each instruction is one, two or three bytes.
- If the first byte is in the range 0x00-0x3F, then the full instruction is one byte.
- If the first byte is in the range 0x40-0x7F, then the full instruction is two bytes.
- If the first byte is in the range 0x80-0xFF, then the full instruction is three bytes.
Constant blobs like string literals are stored after the bytecode, and referred to by records that are six bytes long regardless of the actual length of the data. This means you will first the first constant will be referred to as 0x00, the second constant as 0x06, the third as 0x0C, and so on.
03 | +1 |
Push a placeholder value for internal functions with a fixed number of arguments. This is used for example in text operations like | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
04 | a * b
|
-2 | +1 | Pop two values from the stack, multiply them together and push the result. | ||||||||||||||||||
05 | a + b
|
-2 | +1 | Pop two values from the stack, add them together and push the result. | ||||||||||||||||||
06 | a - b
|
-2 | +1 | Pop two values from the stack, subtract the second from the first and push the result. | ||||||||||||||||||
07 | a / b
|
-2 | +1 | Pop two values from the stack, divide the first by the second and push the result. | ||||||||||||||||||
08 | ||||||||||||||||||||||
09 | -a
|
-1 | +1 | Pop one value from the stack, negate it and push the result. | ||||||||||||||||||
0A | a & b
|
-2 | +1 | Pop two values from the stack, concatenate them and push the resulting string. | ||||||||||||||||||
0B | a && b
|
-2 | +1 | Pop two values from the stack, concatenate them with one space character added in between, and push the resulting string. | ||||||||||||||||||
0C | a < b
|
-2 | +1 | Pop two values from the stack, push 1 if the first is less than the second and 0 if not. | ||||||||||||||||||
0D | a <= b
|
-2 | +1 | Pop two values from the stack, push 1 if the first is less than or equal to the second and 0 if not. | ||||||||||||||||||
0E | a <> b
|
-2 | +1 | Pop two values from the stack, push 0 if the two values are the same and 1 if they are not. | ||||||||||||||||||
0F | a = b
|
-2 | +1 | Pop two values from the stack, push 1 if the two values are the same and 0 if they are not. | ||||||||||||||||||
10 | a > b
|
-2 | +1 | Pop two values from the stack, push 1 if the first is greater than the second and 0 if not. | ||||||||||||||||||
11 | a >= b
|
-2 | +1 | Pop two values from the stack, push 1 if the first is greater than or equal to the sceond and 0 if not. | ||||||||||||||||||
12 | a and b
|
-2 | +1 | Pop two values from the stack, push 1 if both are logically true and 0 if not. | ||||||||||||||||||
13 | a or b
|
-2 | +1 | Pop two values from the stack, push 1 if either are logically true and 0 if not. | ||||||||||||||||||
14 | !a
|
-1 | +1 | Pop one value from the stack, push 0 if it is logically true and 1 if not. | ||||||||||||||||||
15 | a contains b
|
-2 | +1 | Pop two values from the stack, push 1 if the first is a string that contains the second and 0 if not. | ||||||||||||||||||
16 | ||||||||||||||||||||||
17 | char a of c
|
-9 | +1 | String slice. The nine arguments it takes from the stack are:
| ||||||||||||||||||
18 | ||||||||||||||||||||||
19 | ||||||||||||||||||||||
1A | ||||||||||||||||||||||
1B | ||||||||||||||||||||||
1C | ||||||||||||||||||||||
1D | ||||||||||||||||||||||
1E | -1 | +1 | Some kind of list transformation, seen used when setting the actorList to []. | |||||||||||||||||||
1F | -1 | +1 | Transform [#symbol1, val1, #symbol2, val2 ...] to [#symbol1: val1, #symbol2: val2 ...] |