-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbytecode design.txt
66 lines (51 loc) · 2.47 KB
/
bytecode design.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
VM STATE
code array of opcodes
pc program counter; index to the code array
env list of environments (map variables to values)
stack stack of heterogeneous values (numbers, strings, environments, closures, etc)
nargs argument count, used when calling functions
OPCODES
Internally, opcodes are not raw bytes - they're structs that hold a type, and arguments
in a form that's already processed (e.g. lists are lists, and not serialized byte arrays)
LABEL n label for jumps, only gets used during compilation
CONST x push x onto the stack
LVAR i, j push a local variable's value onto stack (ith frame, jth variable in that frame)
LSET i, j store top-of-stack in a local variable (ith frame, jth variable in that frame)
GVAR name push a global variable's value onto stack
GSET name store top-of-stack in a global variable
POP pop the stack, discarding the value
TJUMP label pop stack, and if the top value is true, go to label
FJUMP label pop stack, and if the top value is false, go to label
JUMP label go to label, don't touch the stack
ARGS n make a new env frame, move n values from stack into it, push on the env stack
ARGSDOT n same as ARGS, but supports varargs
DUPE duplicates (pushes a second reference to) the topmost entry on the stack
CALLJ n go to the function on top of the stack (don't save return point); n is arg count
SAVE save a return address on the stack
RETURN go to return address on the stack (by convention, second from top; ret val is at top)
FN fn create a closure from argument and current environment, push onto the stack
PRIM name performs a function call right off the stack, and stores return val back on stack
INTEROP CONVENTIONS
We adopt the Scheme notion of true/false values being different from nil,
which is used mainly as a list terminator. This maps cleanly to AS semantics.
AS FORM AS_LISP FORM
null nil
true #t
false #f
ORDER OF IMPLEMENTATION
+ Cons, Symbol, Package
+ S-Exp Parser
+ Trivial compile (atoms / quotes / begin only)
+ Environments, SET!, global variable lookup
+ Symbol packages
+ IF statements, jumps
+ Function compilation, local variable lookup
+ Tail-recursive functions
+ Function definitions, LAMBDA
+ Function calls
+ Primitive functions
+ Two-pass assembler, removing label names
+ Macros
+ Trivial assemble / optimize / execute loop
+ Optimize primitive lookup with dictionary
- Peephole optimizer