LoLa Intermedia Language

This document describes all available instructions of the Lola intermediate language as well as it's encoding in a binary stream.

Instructions

The following list contains each instruction and describes it's effects on the virtual machine state.

  • nop No operation
  • store_global_name stores global variable by name [ var:str ]
    • pops a value and stores it in the environment-global str
  • load_global_name loads global variable by name [ var:str ]
    • pushes a value stored in the environment-global str
  • push_str pushes string literal [ val:str ]
    • pushes the string str
  • push_num pushes number literal [ val:f64 ]
    • pushes the number val
  • array_pack packs num elements into an array [ num:u16 ]
    • pops num elements front-to-back and packs them into an array front to back
    • stack top will be the first element
  • call_fn calls a function [ fun:str ] [argc:u8 ]
    • pops argc elements front-to-back into the argument list, then calls function fun
    • stack top will be the first argument
  • call_obj calls an object method [ fun:str ] [argc:u8 ]
    • pops the object to call,
    • then pops argc elements front-to-back into the argument list,
    • then calls function fun
    • stack top will be the first argument
  • pop destroys stack top
    • pops a value and discards it
  • add adds rhs and lhs together
    • first pops the right hand side,
    • then the left hand side,
    • then adds right to left, pushes the result
  • sub subtracts rhs and lhs together
    • first pops the right hand side,
    • then the left hand side,
    • then subtracts right from left, pushes the result
  • mul multiplies rhs and lhs together
    • first pops the left hand side,
    • then the right hand side,
    • then multiplies left and right, pushes the result
  • div divides rhs and lhs together
    • first pops the left hand side,
    • then the right hand side,
    • then divides left by right, pushing the divisor
  • mod modulo division of rhs and lhs
    • first pops the left hand side,
    • then the right hand side,
    • then divides left by right, pushing the module
    • (-5 % 2) == 1
  • bool_and conjunct rhs and lhs
    • first pops the left hand side,
    • then the right hand side,
    • then pushes true when both left and right hand side are true
  • bool_or disjuncts rhs and lhs
    • first pops the left hand side,
    • then the right hand side,
    • then pushes true when either of left or right hand side is true
  • bool_not logically inverts stack top
    • pops a value from the stack
    • pushs true if the value was false, otherwise true
  • negate arithmetically inverts stack top
    • pops a value from the stack
    • then pushes the negative value
  • eq
    • pops two values from the stack and compares if they are equal
    • pushes a boolean containing the result of the comparison
  • neq
    • pops two values from the stack and compares if they are not equal
    • pushes a boolean containing the result of the comparison
  • less_eq
    • first pops the right hand side,
    • then the left hand side,
    • then pushes true when left hand side is less or equal to the right hand side.
  • greater_eq
    • first pops the right hand side,
    • then the left hand side,
    • then pushes true when left hand side is greater or equal to the right hand side.
  • less
    • first pops the right hand side,
    • then the left hand side,
    • then pushes true when left hand side is less to the right hand side.
  • greater
    • first pops the right hand side,
    • then the left hand side,
    • then pushes true when left hand side is greater to the right hand side.
  • jmp jumps unconditionally [target:u32 ]
    • Sets the instruction pointer to target
  • jnf jump when not false [target:u32 ]
    • Pops a value from the stack
    • If that value is true
      • Sets the instruction pointer to target
  • iter_make
    • Pops an array from the stack
    • Creates an iterator over that array.
    • Pushes the created iterator.
  • iter_next
    • Peeks an iterator from the stack
    • If that iterator still has values to yield:
      • Push the value from the iterator
      • Push true
      • Advance the iterator by 1
    • else:
      • Push false
  • array_store
    • Then pops the array from the stack
    • Then pops the index from the stack
    • Pops the value from the stack
    • Stores value at index in array
    • Pushes array to the stack.
  • array_load
    • Pops array from the stack
    • Pops index from the stack
    • Loads a value from the array at index
    • Pushes value to the stack
  • ret returns from the current function with Void
    • returns from the function call with a void value
  • store_local stores a local variable [index : u16 ]
    • Pops a value from the stack
    • Stores that value in the function-local variable at index.
  • load_local loads a local variable [index : u16 ]
    • Loads a value from the function-local index.
    • Pushes that value to the stack.
  • retval returns from the current function with a value
    • pops a value from the stack
    • returns from the function call with the popped value
  • jif jump when false [ target:u32 ]
    • Pops a value from the stack
    • If that value is false
      • Sets the instruction pointer to target
  • store_global_idx stores global variable by index [ idx:u16 ]
    • Pops a value from the stack
    • Stores this value in the object-global storage
  • load_global_idx loads global variable by index [ idx:u16 ]
    • Loads a value from the object-global storage
    • Pushes that value to the stack
  • push_true
    • pushes literal boolean true
  • push_false
    • pushes literal boolean false
  • push_void
    • pushes void value

Encoding

Instructions

The instructions are encoded in an intermediate language. Each instruction is encoded by a single byte, followed by arguments different for each instruction.

Argument types are noted in name:type notation where type is one of the following: str, f64, u16, u8, u32. The encoding of these types is described below the table.

Instruction Value Arguments Description
nop 0 No operation
scope_push 1 reserved
scope_pop 2 reserved
declare 3 var:str reserved
store_global_name 4 var:str stores global variable by name
load_global_name 5 var:str loads global variable by name
push_str 6 val:str pushes string literal
push_num 7 val:f64 pushes number literal
array_pack 8 num:u16 packs num elements into an array
call_fn 9 fun:str, argc:u8 calls a function
call_obj 10 fun:str, argc:u8 calls an object method
pop 11 destroys stack top
add 12 adds rhs and lhs together
sub 13 subtracts rhs and lhs together
mul 14 multiplies rhs and lhs together
div 15 divides rhs and lhs together
mod 16 reminder division of rhs and lhs
bool_and 17 conjunct rhs and lhs
bool_or 18 disjuncts rhs and lhs
bool_not 19 logically inverts stack top
negate 20 arithmetically inverts stack top
eq 21
neq 22
less_eq 23
greater_eq 24
less 25
greater 26
jmp 27 target:u32 jumps unconditionally
jnf 28 target:u32 jump when not false
iter_make 29
iter_next 30
array_store 31
array_load 32
ret 33 returns from the current function with Void
store_local 34 index:u16
load_local 35 index:u16
retval 37 returns from the current function with a value
jif 38 target:u32 jump when false
store_global_idx 39 idx:u16 stores global variable by index
load_global_idx 40 idx:u16 loads global variable by index
push_true 41 pushes a boolean true
push_false 42 pushes a boolean false
push_void 43 pushes a void value.

Types

u8, u16, u32

Each of these corresponds to a single, little endian encoded unsigned integer with either 8, 16 or 32 bits width.

f64

A 64 bit floating point number, encoded with IEEE 754 binary64 format, also known as double.

str

A literal string value with a maximum of 65535 bytes length. It's text is encoded in an application-defined encoding where all values below 128 must follow the ASCII encoding scheme. Values equal or above 128 are interpreted by an application-defined logic.

A string is started by a 16 bit unsigned integer defining the length of the string, followed by length bytes of content.

Rationale: The encoding is not fixed to UTF-8 as the language is meant to be embedded into games where a unicode encoding would be a burden to the player. Thus, a string is defined to be "at least" ASCII-compatible and allows UTF-8 encoding, but does not enforce this.