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
154
155
156
157
158
159
160
|
# out is not allocated
fn read-cell in: (addr gap-buffer), out: (addr handle cell), trace: (addr trace) {
trace-text trace, "read", ""
trace-lower trace
trace-text trace, "read", "tokenize"
rewind-gap-buffer in
var token-storage: (stream byte 0x1000) # strings can be large
var token/ecx: (addr stream byte) <- address token-storage
{
var done?/eax: boolean <- gap-buffer-scan-done? in
compare done?, 0/false
break-if-!=
next-token in, token, trace
var error?/eax: boolean <- has-errors? trace
compare error?, 0/false
break-if-!=
read-symbol token, out
loop
}
trace-higher trace # tokenize
# TODO:
# insert parens
# transform infix
# token tree
# syntax tree
trace-higher trace # read
}
fn next-token in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) {
trace-text trace, "read", "next-token"
trace-lower trace
$next-token:body: {
clear-stream out
skip-whitespace-from-gap-buffer in
var g/eax: grapheme <- peek-from-gap-buffer in
{
var digit?/eax: boolean <- is-decimal-digit? g
compare digit?, 0/false
break-if-=
next-number-token in, out, trace
break $next-token:body
}
next-symbol-token in, out, trace
}
trace-higher trace
var stream-storage: (stream byte 0x40)
var stream/eax: (addr stream byte) <- address stream-storage
write stream, "next-token: result"
trace trace, "read", stream
}
fn next-symbol-token in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) {
{
var done?/eax: boolean <- gap-buffer-scan-done? in
compare done?, 0/false
break-if-!=
var g/eax: grapheme <- peek-from-gap-buffer in
# if non-symbol, return
var symbol-grapheme?/eax: boolean <- is-symbol-grapheme? g
{
compare symbol-grapheme?, 0/false
break-if-!=
return
}
var g/eax: grapheme <- read-from-gap-buffer in
write-grapheme out, g
loop
}
}
fn is-symbol-grapheme? g: grapheme -> _/eax: boolean {
compare g, 0x20/space
{
break-if-!=
return 0/false
}
compare g, 0xa/newline
{
break-if-!=
return 0/false
}
compare g, 0x22/double-quote
{
break-if-!=
return 0/false
}
compare g, 0x28/open-paren
{
break-if-!=
return 0/false
}
compare g, 0x29/close-paren
{
break-if-!=
return 0/false
}
compare g, 0x5b/open-square-bracket
{
break-if-!=
return 0/false
}
compare g, 0x5d/close-square-bracket
{
break-if-!=
return 0/false
}
compare g, 0x7b/open-curly-bracket
{
break-if-!=
return 0/false
}
compare g, 0x7d/close-curly-bracket
{
break-if-!=
return 0/false
}
return 1/true
}
fn next-number-token in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) {
var done?/eax: boolean <- gap-buffer-scan-done? in
compare done?, 0/false
break-if-!=
var g/eax: grapheme <- peek-from-gap-buffer in
# if not symbol grapheme, return
{
var symbol-grapheme?/eax: boolean <- is-symbol-grapheme? g
compare symbol-grapheme?, 0/false
break-if-!=
return
}
# if not digit grapheme, abort
{
var digit?/eax: boolean <- is-decimal-digit? g
compare digit?, 0/false
break-if-!=
error trace, "invalid number"
return
}
var g/eax: grapheme <- read-from-gap-buffer in
write-grapheme out, g
loop
}
fn read-symbol in: (addr stream byte), _out: (addr handle cell) {
var out/eax: (addr handle cell) <- copy _out
new-symbol out
var out-a/eax: (addr cell) <- lookup *out
var out-data-ah/eax: (addr handle stream byte) <- get out-a, text-data
var _out-data/eax: (addr stream byte) <- lookup *out-data-ah
var out-data/edi: (addr stream byte) <- copy _out-data
{
var done?/eax: boolean <- stream-empty? in
compare done?, 0/false
break-if-!=
var g/eax: grapheme <- read-grapheme in
write-grapheme out-data, g
loop
}
}
|