Mercurial > hg-old > index.cgi
diff 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 |
line wrap: on
line diff
--- a/src/expr.c Fri Jan 02 06:07:40 2009 +0000 +++ b/src/expr.c Sat Jan 03 04:20:49 2009 +0000 @@ -67,6 +67,8 @@ lwasm_expr_term_t *lwasm_expr_term_create_oper(int oper) { lwasm_expr_term_t *t; + +fprintf(stderr, "Creating operator term: %d\n", oper); t = lwasm_alloc(sizeof(lwasm_expr_term_t)); t -> term_type = LWASM_TERM_OPER; @@ -77,6 +79,7 @@ lwasm_expr_term_t *lwasm_expr_term_create_int(int val) { lwasm_expr_term_t *t; +fprintf(stderr, "Creating integer term: %d\n", val); t = lwasm_alloc(sizeof(lwasm_expr_term_t)); t -> term_type = LWASM_TERM_INT; @@ -88,6 +91,7 @@ { lwasm_expr_term_t *t; +fprintf(stderr, "Creating symbol term: %s\n", sym); t = lwasm_alloc(sizeof(lwasm_expr_term_t)); t -> term_type = LWASM_TERM_SYM; t -> symbol = lwasm_strdup(sym); @@ -177,10 +181,11 @@ int lwasm_expr_parse_term(lwasm_expr_stack_t *s, const char **p) { lwasm_expr_term_t *t; - +fprintf(stderr, "Expression string %s\n", *p); eval_next: if (**p == '(') { + fprintf(stderr, "Starting paren\n"); (*p)++; lwasm_expr_parse_expr(s, p, 0); if (**p != ')') @@ -191,6 +196,7 @@ if (**p == '+') { + fprintf(stderr, "Unary +\n"); (*p)++; goto eval_next; } @@ -424,6 +430,7 @@ { // otherwise we must be decimal (if we're still allowed one) val = decval; + fprintf(stderr, "End of decimal value\n"); break; } else @@ -492,7 +499,14 @@ dval -= '0'; if (dval > 9) dval -= 7; - + fprintf(stderr, "Got digit: %d\n", dval); +// if (dval > 1) +// valtype &= 14; +// if (dval > 7) +// valtype &= 12; +// if (dval > 9) +// valtype &= 8; + if (valtype & 8) { hexval = hexval * 16 + dval; @@ -520,11 +534,12 @@ } } // break out if we have a return value - if (valtype = -1) + if (valtype == -1) break; // return if no more valid possibilities! if (valtype == 0) return -1; + val = decval; // in case we fall through } // we get here when we have a value to return @@ -560,12 +575,15 @@ lwasm_expr_term_t *operterm; // return if we are at the end of the expression or a subexpression - if (!**p || isspace(**p) || **p == ')') + if (!**p || isspace(**p) || **p == ')' || **p == ',') return 0; -eval_next: if (lwasm_expr_parse_term(s, p) < 0) return -1; + +eval_next: + if (!**p || isspace(**p) || **p == ')' || **p == ',') + return 0; // expecting an operator here for (opern = 0; operators[opern].opernum != LWASM_OPER_NONE; opern++) @@ -625,15 +643,18 @@ contain the pointer to the next character after the expression if and only if there is no error. In the case of an error, *outp is undefined. */ -lwasm_expr_stack_t *lwasm_expr_eval(const char *inp, const char **outp) +lwasm_expr_stack_t *lwasm_expr_eval(const char *inp, const char **outp, int (*sfunc)(char *sym, void *state, int *val), void *state) { lwasm_expr_stack_t *s; const char *p; - + int rval; + // actually parse the expression p = inp; s = lwasm_expr_stack_create(); - if (lwasm_expr_parse_expr(s, &p, 0) < 0) + + rval = lwasm_expr_parse_expr(s, &p, 0); + if (rval < 0) goto cleanup_error; // save end of expression @@ -641,8 +662,11 @@ (*outp) = p; // return potentially partial expression - if (lwasm_expr_reval(s) < 0) + if (lwasm_expr_reval(s, sfunc, state) < 0) goto cleanup_error; + + if (lwasm_expr_is_constant(s)) + fprintf(stderr, "Constant expression evaluates to: %d\n", lwasm_expr_get_value(s)); return s; @@ -668,9 +692,26 @@ further operators or only a single term remains */ -int lwasm_expr_reval(lwasm_expr_stack_t *s) +int lwasm_expr_reval(lwasm_expr_stack_t *s, int (*sfunc)(char *sym, void *state, int *val), void *state) { lwasm_expr_stack_node_t *n; + int sval; + + // resolve symbols + // symbols that do not resolve to a constant are left alone + for (n = s -> head; n; n = n -> next) + { + if (n -> term -> term_type == LWASM_TERM_SYM) + { + if (sfunc(n -> term -> symbol, state, &sval) == 0) + { + n -> term -> term_type = LWASM_TERM_INT; + n -> term -> value = sval; + lwasm_free(n -> term -> symbol); + n -> term -> symbol = NULL; + } + } + } next_iter: // a single term