My own interpreter in JS

From Jonathan Gardner's Tech Wiki
Jump to: navigation, search

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)