This is my attempt to create a compliant lox implementation using the rpython translation toolchain to get a native & hopefully JIT compiled lox interpreter.
This isn't anywhere done but is rather my journey following the low level C guide from Bob Nystrom (@munificentbob) on craftinginterpreters.com
Running under python
This lox should be runnable using python2
or pypy
(with rpython
as the only dependency):
python2 -m lox [program.lox]
Example
pypy -m lox examples/simple_add.lox
debug: runFile called with: examples/simple_add.lox
232.0
debug: INTERPRET_OK
Note you will be dropped into a repl session if you don't provide a lox script to execute.
Translation using the rpython toolchain
The real fun is asking rpython
to compile to an executable:
rpython --opt=2 lox/target.py
Now run targetpylox-c
:
./targetpylox-c [program.lox]
Example:
$ ./lox-c examples/lots_of_basic_calculations.lox
3.191743
A tracing JIT
I've added the most basic annotation required for rpython to add its tracing JIT. However this is pretty untested and takes a couple of minutes to compile.
rpython --opt=jit lox/target.py
Current State
Currently an over-engineered basic calculator.
With debugging enabled you can see the generated bytecode and see the vm trace:
./lox-c
Welcome to pylox
https://github.com/hardbyte/pylox
> 3 + 4 * ((1/(2 * 3 * 4)) + (1/(4 * 5 * 6)) - (1/(6 * 7 * 8)))
== code ==
0000 1 OP_CONSTANT (00) '3.000000'
0002 | OP_CONSTANT (01) '4.000000'
0004 | OP_CONSTANT (02) '1.000000'
0006 | OP_CONSTANT (03) '2.000000'
0008 | OP_CONSTANT (04) '3.000000'
0010 | OP_MULTIPLY
0011 | OP_CONSTANT (05) '4.000000'
0013 | OP_MULTIPLY
0014 | OP_DIVIDE
0015 | OP_CONSTANT (06) '1.000000'
0017 | OP_CONSTANT (07) '4.000000'
0019 | OP_CONSTANT (08) '5.000000'
0021 | OP_MULTIPLY
0022 | OP_CONSTANT (09) '6.000000'
0024 | OP_MULTIPLY
0025 | OP_DIVIDE
0026 | OP_ADD
0027 | OP_CONSTANT (10) '1.000000'
0029 | OP_CONSTANT (11) '6.000000'
0031 | OP_CONSTANT (12) '7.000000'
0033 | OP_MULTIPLY
0034 | OP_CONSTANT (13) '8.000000'
0036 | OP_MULTIPLY
0037 | OP_DIVIDE
0038 | OP_SUBTRACT
0039 | OP_MULTIPLY
0040 | OP_ADD
0041 2 OP_RETURN
== VM TRACE ==
[]
0000 1 OP_CONSTANT (00) '3.000000'
[ 3.000000 ]
0002 | OP_CONSTANT (01) '4.000000'
[ 3.000000 ] [ 4.000000 ]
0004 | OP_CONSTANT (02) '1.000000'
[ 3.000000 ] [ 4.000000 ] [ 1.000000 ]
0006 | OP_CONSTANT (03) '2.000000'
[ 3.000000 ] [ 4.000000 ] [ 1.000000 ] [ 2.000000 ]
0008 | OP_CONSTANT (04) '3.000000'
[ 3.000000 ] [ 4.000000 ] [ 1.000000 ] [ 2.000000 ] [ 3.000000 ]
0010 | OP_MULTIPLY
[ 3.000000 ] [ 4.000000 ] [ 1.000000 ] [ 6.000000 ]
0011 | OP_CONSTANT (05) '4.000000'
[ 3.000000 ] [ 4.000000 ] [ 1.000000 ] [ 6.000000 ] [ 4.000000 ]
0013 | OP_MULTIPLY
[ 3.000000 ] [ 4.000000 ] [ 1.000000 ] [ 24.000000 ]
0014 | OP_DIVIDE
[ 3.000000 ] [ 4.000000 ] [ 0.041667 ]
0015 | OP_CONSTANT (06) '1.000000'
[ 3.000000 ] [ 4.000000 ] [ 0.041667 ] [ 1.000000 ]
0017 | OP_CONSTANT (07) '4.000000'
[ 3.000000 ] [ 4.000000 ] [ 0.041667 ] [ 1.000000 ] [ 4.000000 ]
0019 | OP_CONSTANT (08) '5.000000'
[ 3.000000 ] [ 4.000000 ] [ 0.041667 ] [ 1.000000 ] [ 4.000000 ] [ 5.000000 ]
0021 | OP_MULTIPLY
[ 3.000000 ] [ 4.000000 ] [ 0.041667 ] [ 1.000000 ] [ 20.000000 ]
0022 | OP_CONSTANT (09) '6.000000'
[ 3.000000 ] [ 4.000000 ] [ 0.041667 ] [ 1.000000 ] [ 20.000000 ] [ 6.000000 ]
0024 | OP_MULTIPLY
[ 3.000000 ] [ 4.000000 ] [ 0.041667 ] [ 1.000000 ] [ 120.000000 ]
0025 | OP_DIVIDE
[ 3.000000 ] [ 4.000000 ] [ 0.041667 ] [ 0.008333 ]
0026 | OP_ADD
[ 3.000000 ] [ 4.000000 ] [ 0.050000 ]
0027 | OP_CONSTANT (10) '1.000000'
[ 3.000000 ] [ 4.000000 ] [ 0.050000 ] [ 1.000000 ]
0029 | OP_CONSTANT (11) '6.000000'
[ 3.000000 ] [ 4.000000 ] [ 0.050000 ] [ 1.000000 ] [ 6.000000 ]
0031 | OP_CONSTANT (12) '7.000000'
[ 3.000000 ] [ 4.000000 ] [ 0.050000 ] [ 1.000000 ] [ 6.000000 ] [ 7.000000 ]
0033 | OP_MULTIPLY
[ 3.000000 ] [ 4.000000 ] [ 0.050000 ] [ 1.000000 ] [ 42.000000 ]
0034 | OP_CONSTANT (13) '8.000000'
[ 3.000000 ] [ 4.000000 ] [ 0.050000 ] [ 1.000000 ] [ 42.000000 ] [ 8.000000 ]
0036 | OP_MULTIPLY
[ 3.000000 ] [ 4.000000 ] [ 0.050000 ] [ 1.000000 ] [ 336.000000 ]
0037 | OP_DIVIDE
[ 3.000000 ] [ 4.000000 ] [ 0.050000 ] [ 0.002976 ]
0038 | OP_SUBTRACT
[ 3.000000 ] [ 4.000000 ] [ 0.047024 ]
0039 | OP_MULTIPLY
[ 3.000000 ] [ 0.188095 ]
0040 | OP_ADD
[ 3.188095 ]
0041 2 OP_RETURN
3.188095
>