Mercurial > hg-old > index.cgi
comparison src/expr.c @ 37:538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
author | lost |
---|---|
date | Sat, 03 Jan 2009 04:20:49 +0000 |
parents | ec0bf61a5502 |
children | efa19ec69df9 |
comparison
equal
deleted
inserted
replaced
36:99e3b3310bac | 37:538e15927776 |
---|---|
65 } | 65 } |
66 | 66 |
67 lwasm_expr_term_t *lwasm_expr_term_create_oper(int oper) | 67 lwasm_expr_term_t *lwasm_expr_term_create_oper(int oper) |
68 { | 68 { |
69 lwasm_expr_term_t *t; | 69 lwasm_expr_term_t *t; |
70 | |
71 fprintf(stderr, "Creating operator term: %d\n", oper); | |
70 | 72 |
71 t = lwasm_alloc(sizeof(lwasm_expr_term_t)); | 73 t = lwasm_alloc(sizeof(lwasm_expr_term_t)); |
72 t -> term_type = LWASM_TERM_OPER; | 74 t -> term_type = LWASM_TERM_OPER; |
73 t -> value = oper; | 75 t -> value = oper; |
74 return t; | 76 return t; |
75 } | 77 } |
76 | 78 |
77 lwasm_expr_term_t *lwasm_expr_term_create_int(int val) | 79 lwasm_expr_term_t *lwasm_expr_term_create_int(int val) |
78 { | 80 { |
79 lwasm_expr_term_t *t; | 81 lwasm_expr_term_t *t; |
82 fprintf(stderr, "Creating integer term: %d\n", val); | |
80 | 83 |
81 t = lwasm_alloc(sizeof(lwasm_expr_term_t)); | 84 t = lwasm_alloc(sizeof(lwasm_expr_term_t)); |
82 t -> term_type = LWASM_TERM_INT; | 85 t -> term_type = LWASM_TERM_INT; |
83 t -> value = val; | 86 t -> value = val; |
84 return t; | 87 return t; |
86 | 89 |
87 lwasm_expr_term_t *lwasm_expr_term_create_sym(char *sym) | 90 lwasm_expr_term_t *lwasm_expr_term_create_sym(char *sym) |
88 { | 91 { |
89 lwasm_expr_term_t *t; | 92 lwasm_expr_term_t *t; |
90 | 93 |
94 fprintf(stderr, "Creating symbol term: %s\n", sym); | |
91 t = lwasm_alloc(sizeof(lwasm_expr_term_t)); | 95 t = lwasm_alloc(sizeof(lwasm_expr_term_t)); |
92 t -> term_type = LWASM_TERM_SYM; | 96 t -> term_type = LWASM_TERM_SYM; |
93 t -> symbol = lwasm_strdup(sym); | 97 t -> symbol = lwasm_strdup(sym); |
94 return t; | 98 return t; |
95 } | 99 } |
175 as well as () | 179 as well as () |
176 */ | 180 */ |
177 int lwasm_expr_parse_term(lwasm_expr_stack_t *s, const char **p) | 181 int lwasm_expr_parse_term(lwasm_expr_stack_t *s, const char **p) |
178 { | 182 { |
179 lwasm_expr_term_t *t; | 183 lwasm_expr_term_t *t; |
180 | 184 fprintf(stderr, "Expression string %s\n", *p); |
181 eval_next: | 185 eval_next: |
182 if (**p == '(') | 186 if (**p == '(') |
183 { | 187 { |
188 fprintf(stderr, "Starting paren\n"); | |
184 (*p)++; | 189 (*p)++; |
185 lwasm_expr_parse_expr(s, p, 0); | 190 lwasm_expr_parse_expr(s, p, 0); |
186 if (**p != ')') | 191 if (**p != ')') |
187 return -1; | 192 return -1; |
188 (*p)++; | 193 (*p)++; |
189 return 0; | 194 return 0; |
190 } | 195 } |
191 | 196 |
192 if (**p == '+') | 197 if (**p == '+') |
193 { | 198 { |
199 fprintf(stderr, "Unary +\n"); | |
194 (*p)++; | 200 (*p)++; |
195 goto eval_next; | 201 goto eval_next; |
196 } | 202 } |
197 | 203 |
198 if (**p == '-') | 204 if (**p == '-') |
422 } | 428 } |
423 else if (valtype & 4) | 429 else if (valtype & 4) |
424 { | 430 { |
425 // otherwise we must be decimal (if we're still allowed one) | 431 // otherwise we must be decimal (if we're still allowed one) |
426 val = decval; | 432 val = decval; |
433 fprintf(stderr, "End of decimal value\n"); | |
427 break; | 434 break; |
428 } | 435 } |
429 else | 436 else |
430 { | 437 { |
431 // bad value | 438 // bad value |
490 default: | 497 default: |
491 // digit | 498 // digit |
492 dval -= '0'; | 499 dval -= '0'; |
493 if (dval > 9) | 500 if (dval > 9) |
494 dval -= 7; | 501 dval -= 7; |
495 | 502 fprintf(stderr, "Got digit: %d\n", dval); |
503 // if (dval > 1) | |
504 // valtype &= 14; | |
505 // if (dval > 7) | |
506 // valtype &= 12; | |
507 // if (dval > 9) | |
508 // valtype &= 8; | |
509 | |
496 if (valtype & 8) | 510 if (valtype & 8) |
497 { | 511 { |
498 hexval = hexval * 16 + dval; | 512 hexval = hexval * 16 + dval; |
499 } | 513 } |
500 if (valtype & 4) | 514 if (valtype & 4) |
518 else | 532 else |
519 binval = binval * 2 + dval; | 533 binval = binval * 2 + dval; |
520 } | 534 } |
521 } | 535 } |
522 // break out if we have a return value | 536 // break out if we have a return value |
523 if (valtype = -1) | 537 if (valtype == -1) |
524 break; | 538 break; |
525 // return if no more valid possibilities! | 539 // return if no more valid possibilities! |
526 if (valtype == 0) | 540 if (valtype == 0) |
527 return -1; | 541 return -1; |
542 val = decval; // in case we fall through | |
528 } | 543 } |
529 | 544 |
530 // we get here when we have a value to return | 545 // we get here when we have a value to return |
531 t = lwasm_expr_term_create_int(val); | 546 t = lwasm_expr_term_create_int(val); |
532 lwasm_expr_stack_push(s, t); | 547 lwasm_expr_stack_push(s, t); |
558 }; | 573 }; |
559 int opern, i; | 574 int opern, i; |
560 lwasm_expr_term_t *operterm; | 575 lwasm_expr_term_t *operterm; |
561 | 576 |
562 // return if we are at the end of the expression or a subexpression | 577 // return if we are at the end of the expression or a subexpression |
563 if (!**p || isspace(**p) || **p == ')') | 578 if (!**p || isspace(**p) || **p == ')' || **p == ',') |
564 return 0; | 579 return 0; |
565 | 580 |
566 eval_next: | |
567 if (lwasm_expr_parse_term(s, p) < 0) | 581 if (lwasm_expr_parse_term(s, p) < 0) |
568 return -1; | 582 return -1; |
583 | |
584 eval_next: | |
585 if (!**p || isspace(**p) || **p == ')' || **p == ',') | |
586 return 0; | |
569 | 587 |
570 // expecting an operator here | 588 // expecting an operator here |
571 for (opern = 0; operators[opern].opernum != LWASM_OPER_NONE; opern++) | 589 for (opern = 0; operators[opern].opernum != LWASM_OPER_NONE; opern++) |
572 { | 590 { |
573 for (i = 0; (*p)[i] && operators[opern].operstr[i] && (*p[i] == operators[opern].operstr[i]); i++) | 591 for (i = 0; (*p)[i] && operators[opern].operstr[i] && (*p[i] == operators[opern].operstr[i]); i++) |
623 | 641 |
624 Returns NULL on a parse error or otherwise invalid expression. *outp will | 642 Returns NULL on a parse error or otherwise invalid expression. *outp will |
625 contain the pointer to the next character after the expression if and only | 643 contain the pointer to the next character after the expression if and only |
626 if there is no error. In the case of an error, *outp is undefined. | 644 if there is no error. In the case of an error, *outp is undefined. |
627 */ | 645 */ |
628 lwasm_expr_stack_t *lwasm_expr_eval(const char *inp, const char **outp) | 646 lwasm_expr_stack_t *lwasm_expr_eval(const char *inp, const char **outp, int (*sfunc)(char *sym, void *state, int *val), void *state) |
629 { | 647 { |
630 lwasm_expr_stack_t *s; | 648 lwasm_expr_stack_t *s; |
631 const char *p; | 649 const char *p; |
632 | 650 int rval; |
651 | |
633 // actually parse the expression | 652 // actually parse the expression |
634 p = inp; | 653 p = inp; |
635 s = lwasm_expr_stack_create(); | 654 s = lwasm_expr_stack_create(); |
636 if (lwasm_expr_parse_expr(s, &p, 0) < 0) | 655 |
656 rval = lwasm_expr_parse_expr(s, &p, 0); | |
657 if (rval < 0) | |
637 goto cleanup_error; | 658 goto cleanup_error; |
638 | 659 |
639 // save end of expression | 660 // save end of expression |
640 if (outp) | 661 if (outp) |
641 (*outp) = p; | 662 (*outp) = p; |
642 | 663 |
643 // return potentially partial expression | 664 // return potentially partial expression |
644 if (lwasm_expr_reval(s) < 0) | 665 if (lwasm_expr_reval(s, sfunc, state) < 0) |
645 goto cleanup_error; | 666 goto cleanup_error; |
667 | |
668 if (lwasm_expr_is_constant(s)) | |
669 fprintf(stderr, "Constant expression evaluates to: %d\n", lwasm_expr_get_value(s)); | |
646 | 670 |
647 return s; | 671 return s; |
648 | 672 |
649 cleanup_error: | 673 cleanup_error: |
650 lwasm_expr_stack_free(s); | 674 lwasm_expr_stack_free(s); |
666 | 690 |
667 repeat the scan until no futher simplications are found or if there are no | 691 repeat the scan until no futher simplications are found or if there are no |
668 further operators or only a single term remains | 692 further operators or only a single term remains |
669 | 693 |
670 */ | 694 */ |
671 int lwasm_expr_reval(lwasm_expr_stack_t *s) | 695 int lwasm_expr_reval(lwasm_expr_stack_t *s, int (*sfunc)(char *sym, void *state, int *val), void *state) |
672 { | 696 { |
673 lwasm_expr_stack_node_t *n; | 697 lwasm_expr_stack_node_t *n; |
698 int sval; | |
699 | |
700 // resolve symbols | |
701 // symbols that do not resolve to a constant are left alone | |
702 for (n = s -> head; n; n = n -> next) | |
703 { | |
704 if (n -> term -> term_type == LWASM_TERM_SYM) | |
705 { | |
706 if (sfunc(n -> term -> symbol, state, &sval) == 0) | |
707 { | |
708 n -> term -> term_type = LWASM_TERM_INT; | |
709 n -> term -> value = sval; | |
710 lwasm_free(n -> term -> symbol); | |
711 n -> term -> symbol = NULL; | |
712 } | |
713 } | |
714 } | |
674 | 715 |
675 next_iter: | 716 next_iter: |
676 // a single term | 717 // a single term |
677 if (s -> head == s -> tail) | 718 if (s -> head == s -> tail) |
678 return 0; | 719 return 0; |