Пример #1
0
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);
    }
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}