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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
type program {
defs: (handle function)
sandboxes: (handle sandbox)
}
type sandbox {
setup: (handle line)
data: (handle line)
next: (handle sandbox)
prev: (handle sandbox)
}
type function {
name: (handle array byte)
args: (handle word) # in reverse order
body: (handle line)
# some sort of indication of spatial location
next: (handle function)
}
type line {
name: (handle array byte)
data: (handle word)
result: (handle result) # might be cached
next: (handle line)
prev: (handle line)
}
type word {
# at most one of these will be non-null
scalar-data: (handle gap-buffer)
text-data: (handle array byte)
box-data: (handle line) # recurse
next: (handle word)
prev: (handle word)
}
type value {
scalar-data: int
text-data: (handle array byte)
box-data: (handle line)
}
type bind {
key: (handle array byte)
value: value
}
type table {
data: (handle array bind)
next: (handle table)
}
type result {
data: value-stack
error: (handle array byte) # single error message for now
}
# if 'out' is non-null, save the first word of the program there
fn initialize-program _program: (addr program), out: (addr handle word) {
var program/esi: (addr program) <- copy _program
var defs/eax: (addr handle function) <- get program, defs
create-primitive-defs defs
var sandbox-ah/eax: (addr handle sandbox) <- get program, sandboxes
allocate sandbox-ah
var sandbox/eax: (addr sandbox) <- lookup *sandbox-ah
initialize-sandbox sandbox, out
}
# if 'out' is non-null, save the first word of the sandbox there
fn initialize-sandbox _sandbox: (addr sandbox), out: (addr handle word) {
var sandbox/esi: (addr sandbox) <- copy _sandbox
var line-ah/eax: (addr handle line) <- get sandbox, data
allocate line-ah
var line/eax: (addr line) <- lookup *line-ah
initialize-line line, out
}
# initialize line with a single empty word
# if 'out' is non-null, save the word there as well
fn initialize-line _line: (addr line), out: (addr handle word) {
var line/esi: (addr line) <- copy _line
var word-ah/eax: (addr handle word) <- get line, data
allocate word-ah
{
compare out, 0
break-if-=
var dest/edi: (addr handle word) <- copy out
copy-object word-ah, dest
}
var word/eax: (addr word) <- lookup *word-ah
initialize-word word
}
fn initialize-word _self: (addr word) {
var self/esi: (addr word) <- copy _self
var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
allocate data-ah
var data/eax: (addr gap-buffer) <- lookup *data-ah
initialize-gap-buffer data
# TODO: sometimes initialize box-data rather than scalar-data
}
fn create-primitive-defs _self: (addr handle function) {
# x 2* = x 2 *
var self/esi: (addr handle function) <- copy _self
allocate self
var _f/eax: (addr function) <- lookup *self
var f/esi: (addr function) <- copy _f
var name-ah/eax: (addr handle array byte) <- get f, name
populate-text-with name-ah, "2*"
var args-ah/eax: (addr handle word) <- get f, args
allocate args-ah
var args/eax: (addr word) <- lookup *args-ah
initialize-word-with args, "x"
var body-ah/eax: (addr handle line) <- get f, body
allocate body-ah
var body/eax: (addr line) <- lookup *body-ah
initialize-line body, 0
var curr-word-ah/ecx: (addr handle word) <- get body, data
allocate curr-word-ah
var curr-word/eax: (addr word) <- lookup *curr-word-ah
initialize-word-with curr-word, "x"
curr-word-ah <- get curr-word, next
allocate curr-word-ah
curr-word <- lookup *curr-word-ah
initialize-word-with curr-word, "2"
curr-word-ah <- get curr-word, next
allocate curr-word-ah
curr-word <- lookup *curr-word-ah
initialize-word-with curr-word, "*"
# TODO: populate prev pointers
}
fn populate-text-with _out: (addr handle array byte), _in: (addr array byte) {
var in/esi: (addr array byte) <- copy _in
var n/ecx: int <- length in
var out/edx: (addr handle array byte) <- copy _out
populate out, n
var _out-addr/eax: (addr array byte) <- lookup *out
var out-addr/edx: (addr array byte) <- copy _out-addr
var i/eax: int <- copy 0
{
compare i, n
break-if->=
var src/esi: (addr byte) <- index in, i
var val/ecx: byte <- copy-byte *src
var dest/edi: (addr byte) <- index out-addr, i
copy-byte-to *dest, val
i <- increment
loop
}
}
|