Open DylanSp opened 4 years ago
If I do this, link to this gist in README for instructions on assembling/running 32-bit ARM assembly. Also potentially provide a Docker image with that and qemu-static baked in (created in separate repo or subfolder).
Problem: at runtime, we need to have a way to denote the types of values so we can perform type-checking.
Potential solution 1: "tag" each value with another word representing the type. This gets stored into registers and checked for validity before performing operations; when pushing a value to the stack, we then push the type tag on top of it. If I do this, have an option that disables emitting type tags and assumes correct typing, segfaulting on type errors; check how much performance increase it provides.
Potential solution 2: NaN boxing. (See Crafting Interpreters chapter on optimization) Every value gets stored as double-precision floating-point numbers; null/true/false/pointers all get represented as quiet NaNs with a few bits used to denote the type.
May want to implement both, with a compiler option to switch between, and compare performance.
Native functions:
parseNum()
. Probably call out to C atof
; document differences between that and JS parseFloat
, specify different cases as implementation-defined (unless they're really bad, in which case do the extra work to make them match)print
to a putString
that just takes a string instead of being polymorphic. Also probably have a stdlib shortcut that composes the two: print(x) = putString(show(x))
. Also potentially separate putString
and putStringLine
?Create a script for CI (or augment test_examples.sh) that runs both the interpreter and compiler against all example programs, then checks that output is the same.
Use the same main driver for parsing CLI args, generating Args module.
Once array of modules is ready for compilation, compile it to one flat ARM assembly file. (Make sure namespacing is handled somehow)
Would be good to have benchmarks for comparing backends, also maybe profile interpreter performance to see where hot spots are.
After experimenting with https://github.com/DylanSp/llvm-bindings-test, using LLVM instead of generating assembly itself is another option.
(Original idea) See "Compiling to Assembly" about compiling to ARM assembly.