My own interpreter in JS
Contents
Introduction
As Javascript gets faster and faster, it makes sense to use it as the foundation for a better language. The core of this is a virtual machine.
Virtual Machine Spec
Stack-based machines are easy to build and think about, but they are also very slow and hard to optimize. Let's not go that way.
Let's instead try a register-based machine not unlike most CPU cores. That means we have:
- Memory (and Registers)
- the program (sequence of instructions with parameters)
- The program counter
- The stack
Memory
Memory is a giant list. Store and retrieve items by index.
Registers
Registers are local variables that can be assigned to or read from. It's no different from regular memory, so it is just part of regular memory.
The program
The program is a list of instructions with their parameters. The instructions and parameters are flattened. Each instruction takes a specific number of arguments. The processor reads them in and then advances the Program Counter beyond them.
The stack
The stack is stored in memory. It's simply an array.
The instructions
Instructions are actual objects. They are called by the virtual machine.
Instructions are stored by name in the virtual machine.
The arguments come in a variety of forms:
- The value itself: Interpreted as a literal. [jump, literal(5)] goes to the 5th instruction.
- A reference: Interpreted as the value of the memory slot at that index. [jump, ref(5)] goes to the instruction stored in the 6th slot in memory.
- A reference to a reference: Interpreted as the value in memory of the value in memory. [jump, ref(ref(5))] goes to the 6th slot in memory, retrieves that number, and then goes to that number and retrieves the line to jump to.
halt | Ends the program by raising a "HaltException". |
store | Stores B in A. |
store_js | Stores B (in Javascript) in A. |
jump | Jumps to A. |
if | Jumps to B if A is not false. |
js_unop | Performs the javascript unary operator A on C and store the result in B. |
js_binop | Performs the javascript binary operator A on C and D and store the result in B. |
The above should be enough to write any program.
Basic Operations
These are some basic operations I'd like to have.
- Objects
-
- Create object
- Get, Set, Delete attribute
- Call
- Int Type
-
- Arithmetic
- Support for big int (in Javascript, you need a bigint beyond a certain range.)
- Float Type
- Decimal Type
- Rational Type
- String (unicode) Type
- String (bytes) Type
- Module type
- Function calls
- Jumps to the program of the function after setting up the namespace. Includes dynamic, lexical namespaces.
- Common control flow
-
- return
- break, continue
- for, while
- if, elif, else
- try, catch, finally, else & throw
- with (Python-style)