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