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
|
# out is not allocated
fn read-cell in: (addr gap-buffer), out: (addr handle cell), trace: (addr trace) {
# TODO:
# tokenize
# insert parens
# transform infix
# token tree
# syntax tree
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
}
}
fn next-token in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) {
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
return
}
next-symbol-token in, out, trace
}
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
}
}
|