static void dump_sym_table(int level, struct map *m) { struct map_iterator i[1]; const struct map_entry *e; for(map_get_iterator(m, i); (e = map_iterator_next(i)) != NULL;) { LOG(level, ("sym_table: %s ", e->key)); expr_dump(level, e->value); } }
struct expr *new_expr_symref(const char *symbol) { struct expr *val; val = chunkpool_malloc(s_expr_pool); val->expr_op = SYMBOL; val->type.symref = symbol; expr_dump(LOG_DEBUG, val); return val; }
struct expr *new_expr_number(i32 number) { struct expr *val; LOG(LOG_DEBUG, ("creating new number %d\n", number)); val = chunkpool_malloc(s_expr_pool); val->expr_op = NUMBER; val->type.number = number; expr_dump(LOG_DEBUG, val); return val; }
struct expr *new_expr_op1(i16 op, struct expr *arg) { struct expr *val; if(op != vNEG && op != LNOT) { /* error, invalid unary operator */ LOG(LOG_ERROR, ("%d not allowed as unary operator\n", op)); exit(1); } val = chunkpool_malloc(s_expr_pool); val->expr_op = op; val->type.arg1 = arg; expr_dump(LOG_DEBUG, val); return val; }
struct expr *new_expr_op2(i16 op, struct expr *arg1, struct expr *arg2) { struct expr *val; if(op == vNEG || op == LNOT || op == NUMBER || op == SYMBOL) { /* error, invalid binary operator */ printf("op %d, vNEG %d, NUMBER %d, SYMBOL %d\n", op, vNEG, NUMBER, SYMBOL); LOG(LOG_ERROR, ("%d not allowed as binary operator\n", op)); exit(1); } val = chunkpool_malloc(s_expr_pool); val->expr_op = op; val->type.arg1 = arg1; val->expr_arg2 = arg2; expr_dump(LOG_DEBUG, val); return val; }
static const char *resolve_expr2(struct expr *e, i32 *valp) { struct expr *e2; i32 value; i32 value2; const char *p; p = NULL; LOG(LOG_DEBUG, ("resolve_expr: ")); expr_dump(LOG_DEBUG, e); switch (e->expr_op) { case NUMBER: /* we are already resolved */ value = e->type.number; break; case vNEG: p = resolve_expr2(e->type.arg1, &value); if(p != NULL) break; value = -value; break; case LNOT: p = resolve_expr2(e->type.arg1, &value); if(p != NULL) break; value = !value; break; case SYMBOL: p = NULL; e2 = NULL; if(s != NULL) { p = find_symref(e->type.symref, &e2); } if(p != NULL) break; if(e2 == NULL) { static char buf[1024]; /* error, symbol not found */ sprintf(buf, "symbol %s has no value.", e->type.symref); p = buf; LOG(LOG_DEBUG, ("%s\n", p)); break; } p = resolve_expr2(e2, &value); break; default: LOG(LOG_DEBUG, ("binary op %d\n", e->expr_op)); p = resolve_expr2(e->type.arg1, &value); if(p != NULL) break; /* short circuit the logical operators */ if(e->expr_op == LOR) { value = (value != 0); if(value) break; } else if(e->expr_op == LAND) { value = (value != 0); if(!value) break; } p = resolve_expr2(e->expr_arg2, &value2); if(p != NULL) break; switch(e->expr_op) { case MINUS: value -= value2; break; case PLUS: value += value2; break; case MULT: value *= value2; break; case DIV: value /= value2; break; case MOD: value %= value2; break; case LT: value = (value < value2); break; case GT: value = (value > value2); break; case EQ: value = (value == value2); break; case NEQ: value = (value != value2); break; case LOR: value = (value2 != 0); break; case LAND: value = (value2 != 0); break; default: LOG(LOG_ERROR, ("unsupported op %d\n", e->expr_op)); exit(1); } } if(p == NULL) { if(e->expr_op != NUMBER) { /* shortcut future recursion */ e->expr_op = NUMBER; e->type.number = value; } if(valp != NULL) { *valp = value; } } return p; }