Top

In the latest version, Noc runs in a virtual machine written in C, this feature was implemented in order to earn performances, reduce time execution.

Here is the Noc codebase:


Noc generates a bytecode, an intermediate representation much easier to read for the VM.

Bytecode structure: Bytecode {sym = [], constant = [], doc = [], opcodes = []}

sym => The Noc symbols (primitive functions, noc functions, opcodes (for the quote => it used to push opcode like a symbol in a quote))

constant => All Noc values

doc => All Noc functions docstrings

The fields above are used to earn time in storing essential datas like (constants, call functions) in indexing her thanks to the operand in opcodes PUSH_CONST index_const_table for example. With this tables, we can avoid the use of hashtables that have usually O(n) time complexity against the indexing that have O(1) in complexity.

opcodes => The Noc program represented with a set of instructions named opcodes

The opcodes are linearly represented to avoid trees-recursion and execute each instructions with a basic for loop. A simple loop is much quicker.

Example:

def main = {
    5 5 + print
}

Bytecode output:

Bytecode {
sym = [FuncSym "main" 0,OpcodeSym ADD_OP,FuncPrim "print" 10], 
constant = [IntConst 5], 
doc = [], 
opcodes = [PUSH_CONST 0,PUSH_CONST 0,ADD_OP,CALL_SYMBOL 2,RETURN]}

Then, this bytecode is serialized in a file in order to read this bytecode in the VM (written C) in deserializing her.