-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.aelys
More file actions
163 lines (147 loc) · 3.94 KB
/
parser.aelys
File metadata and controls
163 lines (147 loc) · 3.94 KB
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
161
162
163
// i'm stupid and haven't got struct properly working on aelys.. the actual parsing is done inline during the codegen.
// those are just parsing utilities used by the codegen
needs std.string as str
needs std.convert as convert
needs words
// tokens is a Vec of ["type", "value"] arrays
pub fn tok_type(tokens, idx) {
if idx >= tokens.len() {
return "eof"
}
return tokens[idx][0]
}
pub fn tok_val(tokens, idx) {
if idx >= tokens.len() {
return ""
}
return tokens[idx][1]
}
pub fn split_to_vec(s, delim) {
let result = Vec["_"]
result.pop()
let dlen = str.len(delim)
let slen = str.len(s)
if slen == 0 {
return result
}
let mut start = 0
let mut i = 0
while i <= slen - dlen {
if str.substr(s, i, dlen) == delim {
result.push(str.substr(s, start, i - start))
start = i + dlen
i = start
} else {
i = i + 1
}
}
result.push(str.substr(s, start, slen - start))
return result
}
// collect sentence words from token returns a vec of words string
pub fn collect_sentence_words(tokens, pos) {
let wds = Vec["_"]
wds.pop()
while pos[0] < tokens.len() {
let t = tok_type(tokens, pos[0])
if t == "word" {
wds.push(tok_val(tokens, pos[0]))
pos[0] = pos[0] + 1
} else if t == "comma" {
pos[0] = pos[0] + 1
} else if t == "period" or t == "exclamation" or t == "question" {
pos[0] = pos[0] + 1
break
} else {
break
}
}
return wds
}
// noun phrase eval, starting at wds[wi[0]] and returns the int value + modifies wi[0]
pub fn eval_noun_phrase(wds, wi) {
let mut adj_count = 0
// skip articles
while wi[0] < wds.len() {
if words.is_article(wds[wi[0]]) {
wi[0] = wi[0] + 1
} else {
break
}
}
// adjectives
while wi[0] < wds.len() {
if words.is_adjective(wds[wi[0]]) {
adj_count = adj_count + 1
wi[0] = wi[0] + 1
} else {
break
}
}
// noun
let mut base = 1
if wi[0] < wds.len() {
if words.is_noun(wds[wi[0]]) {
base = words.noun_value(wds[wi[0]])
wi[0] = wi[0] + 1
} else if words.is_nothing(wds[wi[0]]) {
wi[0] = wi[0] + 1
return 0
}
}
// calculate base * 2^adj_count
let mut value = base
let mut j = 0
while j < adj_count {
value = value * 2
j = j + 1
}
return value
}
// roman numeral parser for goto scene numbers
pub fn parse_roman(s) {
let mut result = 0
let mut i = 0
let n = str.len(s)
while i < n {
let c = str.substr(s, i, 1)
if c == "i" {
if i + 1 < n and str.substr(s, i + 1, 1) == "v" {
result = result + 4
i = i + 2
} else if i + 1 < n and str.substr(s, i + 1, 1) == "x" {
result = result + 9
i = i + 2
} else {
result = result + 1
i = i + 1
}
} else if c == "v" {
result = result + 5
i = i + 1
} else if c == "x" {
result = result + 10
i = i + 1
} else {
i = i + 1
}
}
if result == 0 { result = 1 }
return result
}
pub fn words_match(wds, i, w1) {
if i >= wds.len() { return false }
return wds[i] == w1
}
pub fn words_match2(wds, i, w1, w2) {
if i + 1 >= wds.len() { return false }
return wds[i] == w1 and wds[i + 1] == w2
}
pub fn words_match3(wds, i, w1, w2, w3) {
if i + 2 >= wds.len() { return false }
return wds[i] == w1 and wds[i + 1] == w2 and wds[i + 2] == w3
}
pub fn words_match4(wds, i, w1, w2, w3, w4) {
if i + 3 >= wds.len() { return false }
return wds[i] == w1 and wds[i + 1] == w2 and wds[i + 2] == w3 and wds[i + 3] == w4
}