Data types

Type Length Description
Double 8
Int64 8
Float 4
Int32 4
Bool 4 True if 1, else false
Int24 3
Int16 2
TypePair 1 Each type is 4-bit long
String 4 Index of the string in the Strg chunk.

Enums

DataType : Byte
InstanceType : Int16
VariableType : Byte

Architecture

The interpreter is stack-based. Data is pushed and popped from the stack.

Variables and arrays

When parsing a Variable, if the Type is VariableType.Array: the index is at the stack top and has to be popped, and is followed by the Int16 -5, which also has to be popped. When an array is pushed and the Dup instruction occurs, the index is also duplicated. When Pop's or Push's InstanceType is InstanceType.StackTopOrGlobal, if Type is VariableType.StackTop then one additional value, representing the instance, will be popped from the stack.

References

Each ReferenceDefinition has a pointer to memory address of the first instruction that accesses it. In the second block of the instruction, there is the offset (calculated in blocks, not bytes) to the next occurrence of the reference. Note that the Type of the reference can change between different instances of said reference; for instance in one case an array item can be accessed, while in case the same array is accessed as a whole. Functions don't have a Type, only the offset to the next occurrence.

Instructions

Each instruction is composed of one or more 32-bit blocks. The most significant byte is the opcode.

Reference
Variable : Reference
DoubleTypeInstruction
SingleTypeInstruction
GotoInstruction
0x03: Conv : DoubleTypeInstruction //Push((Types.Second)Pop)
0x04: Mul : DoubleTypeInstruction //Push(Pop() * Pop())
0x05: Div : DoubleTypeInstruction //Push(Pop() / Pop())
0x06: Rem : DoubleTypeInstruction //Push(Pop() % Pop())
0x06: Rem : DoubleTypeInstruction //Push(Remainder(Pop(), Pop()))
0x07: Rem : DoubleTypeInstruction //Push(Pop() % Pop())
0x08: Add : DoubleTypeInstruction //Push(Pop() + Pop())
0x09: Sub : DoubleTypeInstruction //Push(Pop() - Pop())
0x0a: And : DoubleTypeInstruction //Push(Pop() & Pop())
0x0b: Or : DoubleTypeInstruction //Push(Pop() | Pop())
0x0e: Not : DoubleTypeInstruction //Push(!Pop())
0x11: Slt : DoubleTypeInstruction //Push(Pop() < Pop())
0x12: Sle : DoubleTypeInstruction //Push(Pop() <= Pop())
0x13: Seq : DoubleTypeInstruction //Push(Pop() == Pop())
0x14: Sne : DoubleTypeInstruction //Push(Pop() != Pop())
0x15: Sge : DoubleTypeInstruction //Push(Pop() >= Pop())
0x16: Sgt : DoubleTypeInstruction //Push(Pop() > Pop())
0x41: Pop //Instance.Destination = Pop(); //ATTENTION: if Types.First is Int32, the value will be on top of the stack, even before array access parameters!
0x82: Dup : SingleTypeInstruction //Push(Peek())
0x9d: Ret : SingleTypeInstruction //return Pop()
0x9e: Exit : SingleTypeInstruction //return;
0x9f: Popz : SingleTypeInstruction //Pop();
0xb7: B : GotoInstruction //goto Index + Offset*4;
0xb8: Bt : GotoInstruction //if (Pop()) goto Index + Offset*4;
0xb9: Bf : GotoInstruction //if (!Pop()) goto Index + Offset*4;
0xbb: Pushenv : GotoInstruction
0xbc: Popenv : GotoInstruction
0xc0: Push //Push(Value)
0xda: Call //Function(arg0, arg1, ..., argn) where arg = Pop() and n = ArgumentsCount
0xff: Break //Invalid access guard?

After parsing

If you want to decompile the code in high level language, you'll have to do some structuring. Some graph theory is required to get good output. There are while, do..while, for loops and special Repeat statements (essentially For loops without declared variables); no improper loops, but breaks and continues. There are ifs, if..else's and switch..case's. Also considering that there are returns and exits, you'll have to heuristically simulate the stack and branch it when the control flow breaks. For any questions or if I've made mistakes, message me on Reddit.