Built-in Functions
Built-in functions aren’t opcodes — they’re entries in a native function table (funcMap, src/vmfuncmap.cpp) invoked through the single EXEC (0x04) opcode, which looks up a function index and calls the matching C++ lambda with the current stack and variable storage. The compiler maps each keyword to the same index via funcList (src/compiler.cpp).
| Keyword | Function index | Signature | Behavior |
|---|---|---|---|
println | 0x01 | println <value> | Pop the stack top, print it, then print a newline |
print | 0x02 | print <value> | Pop the stack top, print it, no trailing newline |
inputInt | 0x03 | inputInt &var | Read a token from stdin, parse as int64, store into the referenced variable slot as TAG_INT. On parse failure, prints Invalid value! and leaves the variable’s value untouched (whatever it held before, which defaults to 0) |
inputStr | 0x04 | inputStr &var | Read a whitespace-delimited token from stdin, store into the referenced variable slot as TAG_STRING |
Adding a new built-in function
Since dispatch goes through a single opcode and a lookup table, adding a new built-in doesn’t require touching the opcode set or the VM’s core loop:
- Add an entry to
funcMapinsrc/vmfuncmap.cpp— a lambda taking(stack, variables), with whatever native behavior you want. - Add a matching entry to
funcListinsrc/compiler.cppso the compiler recognizes the keyword and knows what index to emit. - Pick an unused function index —
0x01–0x04are taken by the four built-ins above.
That’s it; no changes to execute() in src/vm.cpp are needed, since EXEC already dispatches generically through the table.