Mercurial > repo
comparison src/ploki/op.c @ 4223:ac0403686959
<oerjan> rm -rf src/ploki; mv ploki src
author | HackBot |
---|---|
date | Fri, 20 Dec 2013 22:18:50 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
4222:b0f3e267bb1e | 4223:ac0403686959 |
---|---|
1 #include "IO.h" | |
2 #include "Str.h" | |
3 #include "expr.h" | |
4 #include "main_label.h" | |
5 #include "mars.h" | |
6 #include "op.h" | |
7 | |
8 #include <ctype.h> | |
9 #include <stddef.h> | |
10 #include <string.h> | |
11 | |
12 void op_init(struct op *op) { | |
13 St_init(&op->txt); | |
14 op->type = OP_NOP; | |
15 op->arg = NULL; | |
16 op->arh.expr = NULL; | |
17 op->next = NULL; | |
18 op->line = 0; | |
19 } | |
20 | |
21 void op_end(struct op *op) { | |
22 St_clear(&op->txt); | |
23 free_expr(op->arg); | |
24 switch (op->type) { | |
25 case OP_ASSIGN: | |
26 case OP_CALL_BACK: | |
27 case OP_MODIFY: | |
28 case OP_PRINT: | |
29 case OP_PUTC: | |
30 case OP_SET_VAL: | |
31 case OP_TEMP: | |
32 free_expr(op->arh.expr); | |
33 break; | |
34 | |
35 default: | |
36 break; | |
37 } | |
38 } | |
39 | |
40 void op_getop(struct op *p) { | |
41 p->next = NULL; | |
42 | |
43 switch (ST_FIRSTCHAR(&p->txt)) { | |
44 case '#': | |
45 if (ST_INDEX(&p->txt, 1) == '!') { | |
46 p->type = OP_NOP; | |
47 break; | |
48 } | |
49 p->type = OP_SYSTEM; | |
50 St_shift(&p->txt); | |
51 p->arg = get_expr(p); | |
52 break; | |
53 | |
54 case 'A': | |
55 switch (ST_INDEX(&p->txt, 1)) { | |
56 case 'B': | |
57 if (St_len(&p->txt) < 5 || St_ncmp_m(&p->txt, "ABRUF", 5)) { | |
58 goto defualt; | |
59 } | |
60 p->type = OP_CALL_BACK; | |
61 St_del(&p->txt, 0, 5); | |
62 p->arh.expr = get_iobj(p); | |
63 p->arg = get_expr(p); | |
64 break; | |
65 | |
66 case 'N': | |
67 if (St_len(&p->txt) < 5 || St_ncmp_m(&p->txt, "ANRUF", 5)) { | |
68 goto defualt; | |
69 } | |
70 p->type = OP_CALL_DYN; | |
71 St_del(&p->txt, 0, 5); | |
72 p->arg = get_expr(p); | |
73 break; | |
74 | |
75 default: | |
76 goto defualt; | |
77 } | |
78 break; | |
79 | |
80 case 'C': | |
81 if (St_len(&p->txt) < 6 || St_ncmp_m(&p->txt, "CLAUDS", 6)) { | |
82 goto defualt; | |
83 } | |
84 p->type = OP_CLOSE; | |
85 St_del(&p->txt, 0, 6); | |
86 p->arg = get_expr(p); | |
87 break; | |
88 | |
89 case 'E': | |
90 switch (ST_INDEX(&p->txt, 1)) { | |
91 case 'L': | |
92 if (St_len(&p->txt) < 4 || St_ncmp_m(&p->txt, "ELSE", 4)) { | |
93 goto defualt; | |
94 } | |
95 p->type = OP_ELSE; | |
96 St_del(&p->txt, 0, 4); | |
97 break; | |
98 | |
99 case 'N': | |
100 if (St_len(&p->txt) >= 6 && St_ncmp_m(&p->txt, "END IF", 6) == 0) { | |
101 p->type = OP_FI; | |
102 break; | |
103 } | |
104 if (St_len(&p->txt) < 3 || St_ncmp_m(&p->txt, "END", 3)) { | |
105 goto defualt; | |
106 } | |
107 p->type = OP_EXIT; | |
108 St_del(&p->txt, 0, 3); | |
109 p->arg = get_expr(p); | |
110 break; | |
111 | |
112 default: | |
113 goto defualt; | |
114 } | |
115 break; | |
116 | |
117 case 'F': | |
118 switch (ST_INDEX(&p->txt, 1)) { | |
119 case 'I': | |
120 p->type = OP_FI; | |
121 break; | |
122 | |
123 case 'L': | |
124 if (St_len(&p->txt) < 5 || St_ncmp_m(&p->txt, "FLUSH", 5)) { | |
125 goto defualt; | |
126 } | |
127 p->type = OP_FLUSH; | |
128 St_del(&p->txt, 0, 5); | |
129 p->arg = get_expr(p); | |
130 break; | |
131 | |
132 default: | |
133 goto defualt; | |
134 } | |
135 break; | |
136 | |
137 case 'G': | |
138 if (ST_INDEX(&p->txt, 1) != 'O') { | |
139 goto defualt; | |
140 } | |
141 switch (ST_INDEX(&p->txt, 2)) { | |
142 case 'F': | |
143 if (St_len(&p->txt) < 5 || St_ncmp_m(&p->txt, "GOFOR", 5)) { | |
144 goto defualt; | |
145 } | |
146 p->type = OP_GOBACK; | |
147 St_del(&p->txt, 0, 5); | |
148 p->arg = get_expr(p); | |
149 break; | |
150 | |
151 case 'T': | |
152 if (St_len(&p->txt) < 4 || St_ncmp_m(&p->txt, "GOTO", 4)) { | |
153 goto defualt; | |
154 } | |
155 p->type = OP_GOTO; | |
156 St_del(&p->txt, 0, 4); | |
157 p->arg = get_expr(p); | |
158 break; | |
159 | |
160 default: | |
161 goto defualt; | |
162 } | |
163 break; | |
164 | |
165 case 'I': | |
166 switch (ST_INDEX(&p->txt, 1)) { | |
167 case 'A': | |
168 if (St_len(&p->txt) < 4 || St_ncmp_m(&p->txt, "IACS", 4)) { | |
169 goto defualt; | |
170 } | |
171 p->type = OP_THROW; | |
172 St_del(&p->txt, 0, 4); | |
173 p->arg = get_expr(p); | |
174 break; | |
175 | |
176 case 'F': | |
177 p->type = OP_IF; | |
178 St_del(&p->txt, 0, 2); | |
179 p->arg = get_expr(p); | |
180 break; | |
181 | |
182 default: | |
183 goto defualt; | |
184 } | |
185 break; | |
186 | |
187 case 'K': | |
188 if (St_len(&p->txt) < 4 || St_ncmp_m(&p->txt, "KTHX", 4)) { | |
189 goto defualt; | |
190 } | |
191 p->type = OP_RETURN; | |
192 St_del(&p->txt, 0, 4); | |
193 p->arg = get_expr(p); | |
194 break; | |
195 | |
196 case 'L': | |
197 if (ST_INDEX(&p->txt, 1) != 'E') { | |
198 goto defualt; | |
199 } | |
200 switch (ST_INDEX(&p->txt, 2)) { | |
201 case 'E': | |
202 if (ST_INDEX(&p->txt, 3) != 'T') { | |
203 goto defualt; | |
204 } | |
205 p->type = OP_TEMP; | |
206 St_del(&p->txt, 0, 4); | |
207 p->arh.expr = get_lval(p); | |
208 p->arg = get_expr(p); | |
209 break; | |
210 | |
211 case 'T': | |
212 p->type = OP_ASSIGN; | |
213 St_del(&p->txt, 0, 3); | |
214 p->arh.expr = get_lval(p); | |
215 St_shiftws(&p->txt); | |
216 if (p->arh.expr && ST_INDEX(&p->txt, 1) == '=' && OPERATOR_P(ST_FIRSTCHAR(&p->txt))) { | |
217 p->arh.expr->op = expr_binop(ST_FIRSTCHAR(&p->txt)); | |
218 St_del(&p->txt, 0, 2); | |
219 p->type = OP_MODIFY; | |
220 } | |
221 p->arg = get_expr(p); | |
222 break; | |
223 | |
224 default: | |
225 goto defualt; | |
226 } | |
227 break; | |
228 | |
229 case 'N': | |
230 if (St_len(&p->txt) < 4 || St_ncmp_m(&p->txt, "NEXT", 4)) { | |
231 goto defualt; | |
232 } else { | |
233 size_t tmp; | |
234 p->type = OP_NOP; | |
235 St_del(&p->txt, 0, 4); | |
236 tmp = St_shiftws(&p->txt); | |
237 if (!(p->next = ma_find(&Mars, &p->txt))) { | |
238 St_tac_m(&p->txt, "NEXT ", 4 + !!tmp); | |
239 p->arg = get_expr(p); | |
240 p->arh.expr = NULL; | |
241 p->type = OP_PRINT; | |
242 } | |
243 } | |
244 break; | |
245 | |
246 case 'R': | |
247 if (ST_INDEX(&p->txt, 1) != 'E') { | |
248 goto defualt; | |
249 } | |
250 switch (ST_INDEX(&p->txt, 2)) { | |
251 case 'M': | |
252 p->type = OP_NOP; | |
253 break; | |
254 | |
255 case 'S': | |
256 if (St_len(&p->txt) < 5 || St_ncmp_m(&p->txt, "RESET", 5)) { | |
257 goto defualt; | |
258 } | |
259 p->type = OP_RESET; | |
260 St_del(&p->txt, 0, 5); | |
261 p->arg = get_expr(p); | |
262 break; | |
263 | |
264 default: | |
265 goto defualt; | |
266 } | |
267 break; | |
268 | |
269 case 'S': | |
270 if (St_len(&p->txt) < 3 || St_ncmp_m(&p->txt, "SET", 3)) { | |
271 goto defualt; | |
272 } | |
273 p->type = OP_PUTC; | |
274 St_del(&p->txt, 0, 3); | |
275 p->arg = get_iobj(p); | |
276 p->arh.expr = NULL; | |
277 St_shiftws(&p->txt); | |
278 if (ST_FIRSTCHAR(&p->txt) == ',') { | |
279 St_shift(&p->txt); | |
280 p->arh.expr = p->arg; | |
281 p->arg = get_expr(p); | |
282 } | |
283 break; | |
284 | |
285 case 'W': | |
286 if (St_len(&p->txt) < 4 || St_ncmp_m(&p->txt, "WUNT", 4)) { | |
287 goto defualt; | |
288 } | |
289 p->type = OP_PRINT; | |
290 St_del(&p->txt, 0, 4); | |
291 p->arg = get_iobj(p); | |
292 p->arh.expr = NULL; | |
293 St_shiftws(&p->txt); | |
294 if (ST_FIRSTCHAR(&p->txt) != EOF) { | |
295 p->arh.expr = p->arg; | |
296 p->arg = get_expr(p); | |
297 } | |
298 break; | |
299 | |
300 defualt: | |
301 default: | |
302 if ((p->arh.op = ma_find(&Mars, &p->txt))) { | |
303 p->type = OP_CALL; | |
304 p->arg = get_expr(p); | |
305 } else { | |
306 p->type = OP_PRINT; | |
307 p->arg = get_expr(p); | |
308 p->arh.expr = NULL; | |
309 } | |
310 break; | |
311 } | |
312 | |
313 St_clear(&p->txt); | |
314 } |