-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser.wl
135 lines (114 loc) · 3.01 KB
/
parser.wl
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
import "element.wl"
import "file.wl"
Element parseElement(File file) {
Element sym = nextElement(file)
return sym
}
Element parse(File file) {
Element ret
while(!file.eof()) {
skipWhitespace(file)
if(file.eof()) break
ret = parseElement(file)
}
return ret
}
void skipWhitespace(File file) {
int peek = file.peek()
while(peek == ' ' || peek == '\n') {
file.get()
peek = file.peek()
}
}
Element nextElement(File file) {
skipWhitespace(file)
int peek = file.peek()
if(peek == '('){
file.get() // ignore (
skipWhitespace(file)
Element first
Element next
while(file.peek() != ')') {
if(file.eof()) {
printf("error. unterminated list\n")
return null
}
if(next) {
next.next = nextElement(file)
next = next.next
} else {
next = nextElement(file)
}
if(!first) first = next
skipWhitespace(file)
}
if(file.peek() != ')') {
printf("error: invalid list termination\n")
}
file.get() // ignore ')'
return new ListElement(first)
}
/*
if(peek == ')') {
file.get()
return new TokenElement(RPAREN_KIND)
}*/
if(peek == '\"') {
char[64] strbuf
char stri = 0
file.get() // ignore "
peek = file.peek()
while(peek != '\"') {
strbuf[stri] = peek
stri++
file.get()
peek = file.peek()
if(file.eof()) {
printf("error: unterminated string\n")
break;
}
}
if(file.peek() != '\"') {
printf("error: expected terminating string quote\n")
}
file.get() // ignore closing
strbuf[stri] = 0
return new StringElement(strdup(strbuf.ptr))
}
// parse numeral
if(peek >= '0' && peek <= '9') {
bool isfloat = false
char[64] strbuf
char stri = 0
while((peek >= '0' && peek <= '9') || peek == '.') {
strbuf[stri] = peek
stri++
if(peek == '.') isfloat = true
file.get()
peek = file.peek()
}
strbuf[stri] = 0
if(isfloat) {
double val = atof(strbuf.ptr)
return new FloatElement(val)
} else {
long val = atoll(strbuf.ptr)
return new IntElement(val)
}
}
if((peek >= 'a' && peek <= 'z') || peek >= 'A' && peek <= 'Z') {
char[64] strbuf
char stri = 0
while((peek >= 'a' && peek <= 'z') ||
(peek >= 'A' && peek <= 'Z') ||
(peek >= '0' && peek <= '9')) {
file.get() // discard char
strbuf[stri] = peek
stri++
peek = file.peek()
}
strbuf[stri] = 0
return new IdElement(strdup(strbuf.ptr))
}
return null
}