Mercurial > hg-old > index.cgi
annotate lwlib/lw_expr.c @ 354:60568b123281
Added os9 opcodes and ERROR
author | lost@starbug |
---|---|
date | Tue, 30 Mar 2010 23:10:01 -0600 |
parents | 1649bc7bda5a |
children | 34dfc9747f23 |
rev | line source |
---|---|
334 | 1 /* |
2 lwexpr.c | |
3 | |
4 Copyright © 2010 William Astle | |
5 | |
6 This file is part of LWTOOLS. | |
7 | |
8 LWTOOLS is free software: you can redistribute it and/or modify it under the | |
9 terms of the GNU General Public License as published by the Free Software | |
10 Foundation, either version 3 of the License, or (at your option) any later | |
11 version. | |
12 | |
13 This program is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
16 more details. | |
17 | |
18 You should have received a copy of the GNU General Public License along with | |
19 this program. If not, see <http://www.gnu.org/licenses/>. | |
20 */ | |
21 | |
22 #include <config.h> | |
23 | |
24 #include <stdarg.h> | |
25 #include <stdio.h> | |
26 #include <string.h> | |
27 | |
28 #define ___lw_expr_c_seen___ | |
29 #include "lw_alloc.h" | |
30 #include "lw_expr.h" | |
31 #include "lw_error.h" | |
32 #include "lw_string.h" | |
33 | |
342 | 34 static lw_expr_fn_t *evaluate_special = NULL; |
35 static lw_expr_fn2_t *evaluate_var = NULL; | |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
36 static lw_expr_fn3_t *parse_term = NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
37 |
347 | 38 int lw_expr_istype(lw_expr_t e, int t) |
39 { | |
40 if (e -> type == t) | |
41 return 1; | |
42 return 0; | |
43 } | |
44 | |
45 int lw_expr_intval(lw_expr_t e) | |
46 { | |
47 if (e -> type == lw_expr_type_int) | |
48 return e -> value; | |
49 return -1; | |
50 } | |
51 | |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
52 void lw_expr_set_term_parser(lw_expr_fn3_t *fn) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
53 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
54 parse_term = fn; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
55 } |
337 | 56 |
342 | 57 void lw_expr_set_special_handler(lw_expr_fn_t *fn) |
337 | 58 { |
59 evaluate_special = fn; | |
60 } | |
61 | |
342 | 62 void lw_expr_set_var_handler(lw_expr_fn2_t *fn) |
337 | 63 { |
64 evaluate_var = fn; | |
65 } | |
66 | |
334 | 67 lw_expr_t lw_expr_create(void) |
68 { | |
69 lw_expr_t r; | |
70 | |
71 r = lw_alloc(sizeof(struct lw_expr_priv)); | |
72 r -> operands = NULL; | |
73 | |
74 return r; | |
75 } | |
76 | |
77 void lw_expr_destroy(lw_expr_t E) | |
78 { | |
337 | 79 struct lw_expr_opers *o; |
80 for (o = E -> operands; o; o = o -> next) | |
81 lw_expr_destroy(o -> p); | |
82 if (E -> type == lw_expr_type_var) | |
83 lw_free(E -> value2); | |
84 lw_free(E); | |
334 | 85 } |
86 | |
337 | 87 /* actually duplicates the entire expression */ |
88 void lw_expr_add_operand(lw_expr_t E, lw_expr_t O); | |
334 | 89 lw_expr_t lw_expr_copy(lw_expr_t E) |
90 { | |
337 | 91 lw_expr_t r, t; |
92 struct lw_expr_opers *o; | |
93 | |
94 r = lw_alloc(sizeof(struct lw_expr_priv)); | |
95 *r = *E; | |
96 r -> operands = NULL; | |
97 | |
98 if (E -> type == lw_expr_type_var) | |
99 r -> value2 = lw_strdup(E -> value2); | |
100 for (o = E -> operands; o; o = o -> next) | |
101 { | |
102 lw_expr_add_operand(r, lw_expr_copy(o -> p)); | |
103 } | |
104 | |
105 return r; | |
334 | 106 } |
107 | |
108 void lw_expr_add_operand(lw_expr_t E, lw_expr_t O) | |
109 { | |
110 struct lw_expr_opers *o, *t; | |
111 | |
112 o = lw_alloc(sizeof(struct lw_expr_opers)); | |
113 o -> p = lw_expr_copy(O); | |
114 o -> next = NULL; | |
115 for (t = E -> operands; t && t -> next; t = t -> next) | |
116 /* do nothing */ ; | |
117 | |
118 if (t) | |
119 t -> next = o; | |
120 else | |
121 E -> operands = o; | |
122 } | |
123 | |
335 | 124 lw_expr_t lw_expr_build_aux(int exprtype, va_list args) |
334 | 125 { |
126 lw_expr_t r; | |
127 int t; | |
128 void *p; | |
129 | |
130 lw_expr_t te1, te2; | |
131 | |
132 r = lw_expr_create(); | |
133 | |
134 switch (exprtype) | |
135 { | |
136 case lw_expr_type_int: | |
137 t = va_arg(args, int); | |
138 r -> type = lw_expr_type_int; | |
139 r -> value = t; | |
140 break; | |
141 | |
142 case lw_expr_type_var: | |
143 p = va_arg(args, char *); | |
144 r -> type = lw_expr_type_var; | |
145 r -> value2 = lw_strdup(p); | |
146 break; | |
147 | |
148 case lw_expr_type_special: | |
149 t = va_arg(args, int); | |
150 p = va_arg(args, char *); | |
151 r -> type = lw_expr_type_special; | |
337 | 152 r -> value = t; |
334 | 153 r -> value2 = p; |
154 break; | |
155 | |
156 case lw_expr_type_oper: | |
157 t = va_arg(args, int); | |
158 te1 = va_arg(args, lw_expr_t); | |
159 if (t != lw_expr_oper_com && t != lw_expr_oper_neg) | |
160 te2 = va_arg(args, lw_expr_t); | |
161 else | |
162 te2 = NULL; | |
163 | |
164 r -> type = lw_expr_type_oper; | |
165 r -> value = t; | |
166 lw_expr_add_operand(r, te1); | |
167 lw_expr_add_operand(r, te2); | |
168 break; | |
169 | |
170 default: | |
171 lw_error("Invalid expression type specified to lw_expr_build"); | |
172 } | |
173 | |
335 | 174 return r; |
175 } | |
176 | |
177 lw_expr_t lw_expr_build(int exprtype, ...) | |
178 { | |
179 va_list args; | |
180 lw_expr_t r; | |
181 | |
182 va_start(args, exprtype); | |
183 r = lw_expr_build_aux(exprtype, args); | |
184 va_end(args); | |
185 return r; | |
186 } | |
187 | |
334 | 188 void lw_expr_print(lw_expr_t E) |
189 { | |
190 struct lw_expr_opers *o; | |
335 | 191 int c = 0; |
192 | |
334 | 193 for (o = E -> operands; o; o = o -> next) |
194 { | |
335 | 195 c++; |
334 | 196 lw_expr_print(o -> p); |
197 } | |
198 | |
199 switch (E -> type) | |
200 { | |
201 case lw_expr_type_int: | |
202 printf("%d ", E -> value); | |
203 break; | |
335 | 204 |
205 case lw_expr_type_var: | |
206 printf("V(%s) ", (char *)(E -> value2)); | |
207 break; | |
208 | |
209 case lw_expr_type_special: | |
210 printf("S(%d,%p) ", E -> value, E -> value2); | |
211 break; | |
212 | |
334 | 213 case lw_expr_type_oper: |
335 | 214 printf("[%d]", c); |
334 | 215 switch (E -> value) |
216 { | |
217 case lw_expr_oper_plus: | |
218 printf("+ "); | |
219 break; | |
220 | |
221 case lw_expr_oper_minus: | |
222 printf("- "); | |
223 break; | |
224 | |
225 case lw_expr_oper_times: | |
226 printf("* "); | |
227 break; | |
228 | |
229 case lw_expr_oper_divide: | |
230 printf("/ "); | |
231 break; | |
232 | |
233 case lw_expr_oper_mod: | |
234 printf("%% "); | |
235 break; | |
236 | |
237 case lw_expr_oper_intdiv: | |
238 printf("\\ "); | |
239 break; | |
240 | |
241 case lw_expr_oper_bwand: | |
242 printf("BWAND "); | |
243 break; | |
244 | |
245 case lw_expr_oper_bwor: | |
246 printf("BWOR "); | |
247 break; | |
248 | |
249 case lw_expr_oper_bwxor: | |
250 printf("BWXOR "); | |
251 break; | |
252 | |
253 case lw_expr_oper_and: | |
254 printf("AND "); | |
255 break; | |
256 | |
257 case lw_expr_oper_or: | |
258 printf("OR "); | |
259 break; | |
260 | |
261 case lw_expr_oper_neg: | |
262 printf("NEG "); | |
263 break; | |
264 | |
265 case lw_expr_oper_com: | |
266 printf("COM "); | |
267 break; | |
268 | |
269 default: | |
270 printf("OPER "); | |
271 break; | |
272 } | |
273 break; | |
274 default: | |
275 printf("ERR "); | |
276 break; | |
277 } | |
278 } | |
279 | |
280 /* | |
281 Return: | |
282 nonzero if expressions are the same (identical pointers or matching values) | |
283 zero if expressions are not the same | |
284 | |
285 */ | |
286 int lw_expr_compare(lw_expr_t E1, lw_expr_t E2) | |
287 { | |
288 struct lw_expr_opers *o1, *o2; | |
289 | |
290 if (E1 == E2) | |
291 return 1; | |
292 | |
293 if (!(E1 -> type == E2 -> type && E1 -> value == E2 -> value)) | |
294 return 0; | |
295 | |
296 if (E1 -> type == lw_expr_type_var) | |
297 { | |
298 if (!strcmp(E1 -> value2, E2 -> value2)) | |
299 return 1; | |
300 else | |
301 return 0; | |
302 } | |
303 | |
304 if (E1 -> type == lw_expr_type_special) | |
305 { | |
306 if (E1 -> value2 == E2 -> value2) | |
307 return 1; | |
308 else | |
309 return 0; | |
310 } | |
311 | |
312 for (o1 = E1 -> operands, o2 = E2 -> operands; o1 && o2; o1 = o1 -> next, o2 = o2 -> next) | |
313 if (lw_expr_compare(o1 -> p, o2 -> p) == 0) | |
314 return 0; | |
315 if (o1 || o2) | |
316 return 0; | |
317 | |
318 return 1; | |
319 } | |
320 | |
321 /* return true if E is an operator of type oper */ | |
322 int lw_expr_isoper(lw_expr_t E, int oper) | |
323 { | |
324 if (E -> type == lw_expr_type_oper && E -> value == oper) | |
325 return 1; | |
326 return 0; | |
327 } | |
335 | 328 |
329 | |
330 void lw_expr_simplify_sortconstfirst(lw_expr_t E) | |
331 { | |
332 struct lw_expr_opers *o; | |
333 | |
334 for (o = E -> operands; o; o = o -> next) | |
335 lw_expr_simplify_sortconstfirst(o -> p); | |
336 | |
337 for (o = E -> operands; o; o = o -> next) | |
338 { | |
339 if (o -> p -> type == lw_expr_type_int && o != E -> operands) | |
340 { | |
341 struct lw_expr_opers *o2; | |
342 for (o2 = E -> operands; o2 -> next != o; o2 = o2 -> next) | |
343 /* do nothing */ ; | |
344 o2 -> next = o -> next; | |
345 o -> next = E -> operands; | |
346 E -> operands = o; | |
347 o = o2; | |
348 } | |
349 } | |
350 } | |
351 | |
336 | 352 void lw_expr_sortoperandlist(struct lw_expr_opers **o) |
353 { | |
354 fprintf(stderr, "lw_expr_sortoperandlist() not yet implemented\n"); | |
355 } | |
356 | |
335 | 357 // return 1 if the operand lists match, 0 if not |
358 // may re-order the argument lists | |
359 int lw_expr_simplify_compareoperandlist(struct lw_expr_opers **ol1, struct lw_expr_opers **ol2) | |
360 { | |
361 struct lw_expr_opers *o1, *o2; | |
362 | |
363 lw_expr_sortoperandlist(ol1); | |
364 lw_expr_sortoperandlist(ol2); | |
365 | |
366 for (o1 = *ol1, o2 = *ol2; o1 && o2; o1 = o1 -> next, o2 = o2 -> next) | |
367 { | |
368 if (!lw_expr_compare(o1 -> p, o2 -> p)) | |
369 return 0; | |
370 } | |
371 if (o1 || o2) | |
372 return 0; | |
373 return 1; | |
374 } | |
375 | |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
376 void lw_expr_simplify(lw_expr_t E, void *priv) |
335 | 377 { |
378 struct lw_expr_opers *o; | |
379 | |
337 | 380 again: |
381 // try to resolve non-constant terms to constants here | |
382 if (E -> type == lw_expr_type_special && evaluate_special) | |
383 { | |
384 lw_expr_t te; | |
385 | |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
386 te = evaluate_special(E -> value, E -> value2, priv); |
337 | 387 if (te) |
388 { | |
389 for (o = E -> operands; o; o = o -> next) | |
390 lw_expr_destroy(o -> p); | |
391 if (E -> type == lw_expr_type_var) | |
392 lw_free(E -> value2); | |
393 *E = *te; | |
394 E -> operands = NULL; | |
395 | |
396 if (te -> type == lw_expr_type_var) | |
397 E -> value2 = lw_strdup(te -> value2); | |
398 for (o = te -> operands; o; o = o -> next) | |
399 { | |
400 lw_expr_add_operand(E, lw_expr_copy(o -> p)); | |
401 } | |
402 lw_expr_destroy(te); | |
403 goto again; | |
404 } | |
405 return; | |
406 } | |
407 | |
408 if (E -> type == lw_expr_type_var && evaluate_var) | |
409 { | |
410 lw_expr_t te; | |
411 | |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
412 te = evaluate_var(E -> value2, priv); |
337 | 413 if (te) |
414 { | |
415 for (o = E -> operands; o; o = o -> next) | |
416 lw_expr_destroy(o -> p); | |
417 if (E -> type == lw_expr_type_var) | |
418 lw_free(E -> value2); | |
419 *E = *te; | |
420 E -> operands = NULL; | |
421 | |
422 if (te -> type == lw_expr_type_var) | |
423 E -> value2 = lw_strdup(te -> value2); | |
424 for (o = te -> operands; o; o = o -> next) | |
425 { | |
426 lw_expr_add_operand(E, lw_expr_copy(o -> p)); | |
427 } | |
428 lw_expr_destroy(te); | |
429 goto again; | |
430 } | |
431 return; | |
432 } | |
433 | |
434 // non-operators have no simplification to do! | |
435 if (E -> type != lw_expr_type_oper) | |
436 return; | |
437 | |
335 | 438 // sort "constants" to the start of each operand list for + and * |
439 lw_expr_simplify_sortconstfirst(E); | |
440 | |
337 | 441 // simplify operands |
442 for (o = E -> operands; o; o = o -> next) | |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
443 lw_expr_simplify(o -> p, priv); |
337 | 444 |
445 for (o = E -> operands; o; o = o -> next) | |
446 { | |
447 if (o -> p -> type != lw_expr_type_int) | |
448 break; | |
449 } | |
450 | |
451 if (!o) | |
452 { | |
453 // we can do the operation here! | |
454 int tr = -42424242; | |
455 | |
456 switch (E -> value) | |
457 { | |
458 case lw_expr_oper_neg: | |
459 tr = -(E -> operands -> p -> value); | |
460 break; | |
461 | |
462 case lw_expr_oper_com: | |
463 tr = ~(E -> operands -> p -> value); | |
464 break; | |
465 | |
466 case lw_expr_oper_plus: | |
467 tr = E -> operands -> p -> value; | |
468 for (o = E -> operands -> next; o; o = o -> next) | |
469 tr += o -> p -> value; | |
470 break; | |
471 | |
472 case lw_expr_oper_minus: | |
473 tr = E -> operands -> p -> value; | |
474 for (o = E -> operands -> next; o; o = o -> next) | |
475 tr -= o -> p -> value; | |
476 break; | |
477 | |
478 case lw_expr_oper_times: | |
479 tr = E -> operands -> p -> value; | |
480 for (o = E -> operands -> next; o; o = o -> next) | |
481 tr *= o -> p -> value; | |
482 break; | |
483 | |
484 case lw_expr_oper_divide: | |
485 tr = E -> operands -> p -> value / E -> operands -> next -> p -> value; | |
486 break; | |
487 | |
488 case lw_expr_oper_mod: | |
489 tr = E -> operands -> p -> value % E -> operands -> next -> p -> value; | |
490 break; | |
491 | |
492 case lw_expr_oper_intdiv: | |
493 tr = E -> operands -> p -> value / E -> operands -> next -> p -> value; | |
494 break; | |
495 | |
496 case lw_expr_oper_bwand: | |
497 tr = E -> operands -> p -> value & E -> operands -> next -> p -> value; | |
498 break; | |
499 | |
500 case lw_expr_oper_bwor: | |
501 tr = E -> operands -> p -> value | E -> operands -> next -> p -> value; | |
502 break; | |
503 | |
504 case lw_expr_oper_bwxor: | |
505 tr = E -> operands -> p -> value ^ E -> operands -> next -> p -> value; | |
506 break; | |
507 | |
508 case lw_expr_oper_and: | |
509 tr = E -> operands -> p -> value && E -> operands -> next -> p -> value; | |
510 break; | |
511 | |
512 case lw_expr_oper_or: | |
513 tr = E -> operands -> p -> value || E -> operands -> next -> p -> value; | |
514 break; | |
515 | |
516 } | |
517 | |
518 while (E -> operands) | |
519 { | |
520 o = E -> operands; | |
521 E -> operands = o -> next; | |
522 lw_expr_destroy(o -> p); | |
523 lw_free(o); | |
524 } | |
525 E -> type = lw_expr_type_int; | |
526 E -> value = tr; | |
335 | 527 return; |
337 | 528 } |
335 | 529 |
530 if (E -> value == lw_expr_oper_times) | |
531 { | |
532 for (o = E -> operands; o; o = o -> next) | |
533 { | |
534 if (o -> p -> type == lw_expr_type_int && o -> p -> value == 0) | |
535 { | |
536 // one operand of times is 0, replace operation with 0 | |
537 while (E -> operands) | |
538 { | |
539 o = E -> operands; | |
540 E -> operands = o -> next; | |
541 lw_expr_destroy(o -> p); | |
542 lw_free(o); | |
543 } | |
544 E -> type = lw_expr_type_int; | |
545 E -> value = 0; | |
546 return; | |
547 } | |
548 } | |
549 } | |
550 | |
551 // look for like terms and collect them together | |
552 if (E -> value == lw_expr_oper_plus) | |
553 { | |
554 for (o = E -> operands; o; o = o -> next) | |
555 { | |
556 if (o -> p -> type == lw_expr_type_oper && o -> p -> value == lw_expr_oper_times) | |
557 { | |
558 // we have a "times" here | |
559 // find first non-const operand | |
560 struct lw_expr_opers *op1, *op2, *o2; | |
561 for (op1 = o -> p -> operands; op1; op1 = op1 -> next) | |
562 if (op1 -> p -> type != lw_expr_type_int) | |
563 break; | |
564 | |
565 for (o2 = o -> next; o2; o2 = o2 -> next) | |
566 { | |
567 if (o2 -> p -> type == lw_expr_type_oper && o2 -> p -> value == lw_expr_oper_times) | |
568 { | |
569 // another "times" | |
570 for (op2 = o2 -> p -> operands; op2; op2 = op2 -> next) | |
571 if (op2 -> p -> type != lw_expr_type_int) | |
572 break; | |
573 | |
336 | 574 if (lw_expr_simplify_compareoperandlist(&op1, &op2)) |
335 | 575 { |
576 // we have like terms here | |
577 // do something about it | |
578 } | |
579 } | |
580 } | |
581 } | |
582 } | |
583 } | |
584 | |
585 | |
586 if (E -> value == lw_expr_oper_plus) | |
587 { | |
588 int c = 0, t = 0; | |
589 for (o = E -> operands; o; o = o -> next) | |
590 { | |
591 t++; | |
592 if (!(o -> p -> type == lw_expr_type_int && o -> p -> value == 0)) | |
593 { | |
594 c++; | |
595 } | |
596 } | |
597 if (c == 1) | |
598 { | |
599 lw_expr_t r; | |
600 // find the value and "move it up" | |
601 while (E -> operands) | |
602 { | |
603 o = E -> operands; | |
604 if (o -> p -> type != lw_expr_type_int || o -> p -> value != 0) | |
605 { | |
337 | 606 r = lw_expr_copy(o -> p); |
335 | 607 } |
608 E -> operands = o -> next; | |
609 lw_expr_destroy(o -> p); | |
610 lw_free(o); | |
611 } | |
612 *E = *r; | |
613 return; | |
614 } | |
615 else if (c == 0) | |
616 { | |
617 // replace with 0 | |
618 while (E -> operands) | |
619 { | |
620 o = E -> operands; | |
621 E -> operands = o -> next; | |
622 lw_expr_destroy(o -> p); | |
623 lw_free(o); | |
624 } | |
625 E -> type = lw_expr_type_int; | |
626 E -> value = 0; | |
627 return; | |
628 } | |
629 else if (c != t) | |
630 { | |
631 // collapse out zero terms | |
632 struct lw_expr_opers *o2; | |
633 | |
634 for (o = E -> operands; o; o = o -> next) | |
635 { | |
636 if (o -> p -> type == lw_expr_type_int && o -> p -> value == 0) | |
637 { | |
638 if (o == E -> operands) | |
639 { | |
640 E -> operands = o -> next; | |
641 lw_expr_destroy(o -> p); | |
642 lw_free(o); | |
643 o = E -> operands; | |
644 } | |
645 else | |
646 { | |
647 for (o2 = E -> operands; o2 -> next == o; o2 = o2 -> next) | |
648 /* do nothing */ ; | |
649 o2 -> next = o -> next; | |
650 lw_expr_destroy(o -> p); | |
651 lw_free(o); | |
652 o = o2; | |
653 } | |
654 } | |
655 } | |
656 } | |
657 return; | |
658 } | |
659 } | |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
660 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
661 /* |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
662 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
663 The following two functions are co-routines which evaluate an infix |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
664 expression. lw_expr_parse_term checks for unary prefix operators then, if |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
665 none found, passes the string off the the defined helper function to |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
666 determine what the term really is. It also handles parentheses. |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
667 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
668 lw_expr_parse_expr evaluates actual expressions with infix operators. It |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
669 respects the order of operations. |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
670 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
671 The end of an expression is determined by the presence of any of the |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
672 following conditions: |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
673 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
674 1. a NUL character |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
675 2. a whitespace character |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
676 3. a ) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
677 4. a , |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
678 5. any character that is not recognized as a term |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
679 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
680 lw_expr_parse_term returns NULL if there is no term (end of expr, etc.) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
681 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
682 lw_expr_parse_expr returns NULL if there is no expression or on a syntax |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
683 error. |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
684 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
685 */ |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
686 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
687 lw_expr_t lw_expr_parse_expr(char **p, void *priv, int prec); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
688 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
689 lw_expr_t lw_expr_parse_term(char **p, void *priv) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
690 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
691 lw_expr_t term, term2; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
692 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
693 eval_next: |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
694 if (!**p || isspace(**p) || **p == ')' || **p == ']') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
695 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
696 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
697 // parentheses |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
698 if (**p == '(') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
699 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
700 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
701 term = lw_expr_parse_expr(p, priv, 0); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
702 if (**p != ')') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
703 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
704 lw_expr_destroy(term); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
705 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
706 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
707 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
708 return term; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
709 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
710 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
711 // unary + |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
712 if (**p == '+') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
713 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
714 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
715 goto eval_next; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
716 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
717 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
718 // unary - (prec 200) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
719 if (**p == '-') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
720 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
721 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
722 term = lw_expr_parse_expr(p, priv, 200); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
723 if (!term) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
724 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
725 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
726 term2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_neg, term); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
727 lw_expr_destroy(term); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
728 return term2; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
729 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
730 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
731 // unary ^ or ~ (complement, prec 200) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
732 if (**p == '^' || **p == '~') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
733 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
734 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
735 term = lw_expr_parse_expr(p, priv, 200); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
736 if (!term) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
737 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
738 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
739 term2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_com, term); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
740 lw_expr_destroy(term); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
741 return term2; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
742 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
743 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
744 // non-operator - pass to caller |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
745 return parse_term(p, priv); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
746 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
747 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
748 lw_expr_t lw_expr_parse_expr(char **p, void *priv, int prec) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
749 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
750 static const struct operinfo |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
751 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
752 int opernum; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
753 char *operstr; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
754 int operprec; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
755 } operators[] = |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
756 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
757 { lw_expr_oper_plus, "+", 100 }, |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
758 { lw_expr_oper_minus, "-", 100 }, |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
759 { lw_expr_oper_times, "*", 100 }, |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
760 { lw_expr_oper_divide, "/", 150 }, |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
761 { lw_expr_oper_mod, "%", 150 }, |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
762 { lw_expr_oper_intdiv, "\\", 150 }, |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
763 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
764 { lw_expr_oper_and, "&&", 25 }, |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
765 { lw_expr_oper_or, "||", 25 }, |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
766 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
767 { lw_expr_oper_bwand, "&", 50 }, |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
768 { lw_expr_oper_bwor, "|", 50 }, |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
769 { lw_expr_oper_bwxor, "^", 50 }, |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
770 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
771 { lw_expr_oper_none, "", 0 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
772 }; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
773 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
774 int opern, i; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
775 lw_expr_t term1, term2, term3; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
776 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
777 if (!**p || isspace(**p) || **p == ')' || **p == ',' || **p == ']') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
778 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
779 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
780 term1 = lw_expr_parse_term(p, priv); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
781 if (!term1) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
782 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
783 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
784 eval_next: |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
785 if (!**p || isspace(**p) || **p == ')' || **p == ',' || **p == ']') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
786 return term1; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
787 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
788 // expecting an operator here |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
789 for (opern = 0; operators[opern].opernum != lw_expr_oper_none; opern++) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
790 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
791 for (i = 0; (*p)[i] && operators[opern].operstr[i] && ((*p)[i] == operators[opern].operstr[i]); i++) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
792 /* do nothing */; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
793 if (operators[opern].operstr[i] == '\0') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
794 break; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
795 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
796 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
797 if (operators[opern].opernum == lw_expr_oper_none) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
798 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
799 // unrecognized operator |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
800 lw_expr_destroy(term1); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
801 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
802 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
803 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
804 // operator number is in opern, length of oper in i |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
805 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
806 // logic: |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
807 // if the precedence of this operation is <= to the "prec" flag, |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
808 // we simply return without advancing the input pointer; the operator |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
809 // will be evaluated again in the enclosing function call |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
810 if (operators[opern].operprec <= prec) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
811 return term1; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
812 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
813 // logic: |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
814 // we have a higher precedence operator here so we will advance the |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
815 // input pointer to the next term and let the expression evaluator |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
816 // loose on it after which time we will push our operator onto the |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
817 // stack and then go on with the expression evaluation |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
818 (*p) += i; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
819 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
820 // evaluate next expression(s) of higher precedence |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
821 term2 = lw_expr_parse_expr(p, priv, operators[opern].operprec); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
822 if (!term2) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
823 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
824 lw_expr_destroy(term1); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
825 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
826 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
827 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
828 // now create operator |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
829 term3 = lw_expr_build(lw_expr_type_oper, operators[opern].opernum, term1, term2); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
830 lw_expr_destroy(term1); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
831 lw_expr_destroy(term2); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
832 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
833 // the new "expression" is the next "left operand" |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
834 term1 = term3; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
835 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
836 // continue evaluating |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
837 goto eval_next; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
838 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
839 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
840 lw_expr_t lw_expr_parse(char **p, void *priv) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
841 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
842 return lw_expr_parse_expr(p, priv, 0); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
342
diff
changeset
|
843 } |