Ejemplo n.º 1
0
static HRESULT compile_call_statement(compile_ctx_t *ctx, call_statement_t *stat)
{
    /* It's challenging for parser to distinguish parameterized assignment with one argument from call
     * with equality expression argument, so we do it in compiler. */
    if(!stat->is_strict && stat->expr->args && !stat->expr->args->next && stat->expr->args->type == EXPR_EQUAL) {
        binary_expression_t *eqexpr = (binary_expression_t*)stat->expr->args;

        if(eqexpr->left->type == EXPR_BRACKETS) {
            member_expression_t new_member = *stat->expr;

            WARN("converting call expr to assign expr\n");

            new_member.args = ((unary_expression_t*)eqexpr->left)->subexpr;
            return compile_assignment(ctx, &new_member, eqexpr->right, FALSE);
        }
    }

    return compile_member_expression(ctx, stat->expr, FALSE);
}
Ejemplo n.º 2
0
static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
{
    HRESULT hres;

    while(stat) {
        switch(stat->type) {
        case STAT_ASSIGN:
            hres = compile_assign_statement(ctx, (assign_statement_t*)stat, FALSE);
            break;
        case STAT_CALL:
            hres = compile_member_expression(ctx, ((call_statement_t*)stat)->expr, FALSE);
            break;
        case STAT_DIM:
            hres = compile_dim_statement(ctx, (dim_statement_t*)stat);
            break;
        case STAT_DOWHILE:
        case STAT_DOUNTIL:
            hres = compile_dowhile_statement(ctx, (while_statement_t*)stat);
            break;
        case STAT_EXITDO:
            hres = compile_exitdo_statement(ctx);
            break;
        case STAT_EXITFUNC:
            hres = compile_exitfunc_statement(ctx);
            break;
        case STAT_EXITPROP:
            hres = compile_exitprop_statement(ctx);
            break;
        case STAT_EXITSUB:
            hres = compile_exitsub_statement(ctx);
            break;
        case STAT_FUNC:
            hres = compile_function_statement(ctx, (function_statement_t*)stat);
            break;
        case STAT_IF:
            hres = compile_if_statement(ctx, (if_statement_t*)stat);
            break;
        case STAT_ONERROR:
            hres = compile_onerror_statement(ctx, (onerror_statement_t*)stat);
            break;
        case STAT_SET:
            hres = compile_assign_statement(ctx, (assign_statement_t*)stat, TRUE);
            break;
        case STAT_STOP:
            hres = push_instr(ctx, OP_stop) == -1 ? E_OUTOFMEMORY : S_OK;
            break;
        case STAT_UNTIL:
        case STAT_WHILE:
        case STAT_WHILELOOP:
            hres = compile_while_statement(ctx, (while_statement_t*)stat);
            break;
        default:
            FIXME("Unimplemented statement type %d\n", stat->type);
            hres = E_NOTIMPL;
        }

        if(FAILED(hres))
            return hres;
        stat = stat->next;
    }

    return S_OK;
}
Ejemplo n.º 3
0
static HRESULT compile_expression(compile_ctx_t *ctx, expression_t *expr)
{
    switch(expr->type) {
    case EXPR_ADD:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_add);
    case EXPR_AND:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_and);
    case EXPR_BOOL:
        return push_instr_int(ctx, OP_bool, ((bool_expression_t*)expr)->value);
    case EXPR_CONCAT:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_concat);
    case EXPR_DIV:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_div);
    case EXPR_DOUBLE:
        return push_instr_double(ctx, OP_double, ((double_expression_t*)expr)->value);
    case EXPR_EMPTY:
        return push_instr(ctx, OP_empty) != -1 ? S_OK : E_OUTOFMEMORY;
    case EXPR_EQUAL:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_equal);
    case EXPR_EQV:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_eqv);
    case EXPR_EXP:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_exp);
    case EXPR_GT:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_gt);
    case EXPR_GTEQ:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_gteq);
    case EXPR_IDIV:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_idiv);
    case EXPR_IS:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_is);
    case EXPR_IMP:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_imp);
    case EXPR_LT:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_lt);
    case EXPR_LTEQ:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_lteq);
    case EXPR_ME:
        return push_instr(ctx, OP_me) != -1 ? S_OK : E_OUTOFMEMORY;
    case EXPR_MEMBER:
        return compile_member_expression(ctx, (member_expression_t*)expr, TRUE);
    case EXPR_MOD:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_mod);
    case EXPR_MUL:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_mul);
    case EXPR_NEG:
        return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_neg);
    case EXPR_NEQUAL:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_nequal);
    case EXPR_NEW:
        return push_instr_str(ctx, OP_new, ((string_expression_t*)expr)->value);
    case EXPR_NOT:
        return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_not);
    case EXPR_NOTHING:
        return push_instr(ctx, OP_nothing) != -1 ? S_OK : E_OUTOFMEMORY;
    case EXPR_NULL:
        return push_instr(ctx, OP_null) != -1 ? S_OK : E_OUTOFMEMORY;
    case EXPR_OR:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_or);
    case EXPR_STRING:
        return push_instr_str(ctx, OP_string, ((string_expression_t*)expr)->value);
    case EXPR_SUB:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_sub);
    case EXPR_USHORT:
        return push_instr_int(ctx, OP_short, ((int_expression_t*)expr)->value);
    case EXPR_ULONG:
        return push_instr_int(ctx, OP_long, ((int_expression_t*)expr)->value);
    case EXPR_XOR:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_xor);
    default:
        FIXME("Unimplemented expression type %d\n", expr->type);
        return E_NOTIMPL;
    }

    return S_OK;
}
Ejemplo n.º 4
0
static HRESULT compile_expression_noret(compiler_ctx_t *ctx, expression_t *expr, BOOL *no_ret)
{
    switch(expr->type) {
    case EXPR_ADD:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_add);
    case EXPR_AND:
        return compile_logical_expression(ctx, (binary_expression_t*)expr, OP_cnd_z);
    case EXPR_ARRAY:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_array);
    case EXPR_ARRAYLIT:
        return compile_array_literal(ctx, (array_literal_expression_t*)expr);
    case EXPR_ASSIGN:
        return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_LAST);
    case EXPR_ASSIGNADD:
        return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_add);
    case EXPR_ASSIGNAND:
        return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_and);
    case EXPR_ASSIGNSUB:
        return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_sub);
    case EXPR_ASSIGNMUL:
        return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_mul);
    case EXPR_ASSIGNDIV:
        return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_div);
    case EXPR_ASSIGNMOD:
        return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_mod);
    case EXPR_ASSIGNOR:
        return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_or);
    case EXPR_ASSIGNLSHIFT:
        return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_lshift);
    case EXPR_ASSIGNRSHIFT:
        return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_rshift);
    case EXPR_ASSIGNRRSHIFT:
        return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_rshift2);
    case EXPR_ASSIGNXOR:
        return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_xor);
    case EXPR_BAND:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_and);
    case EXPR_BITNEG:
        return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_bneg);
    case EXPR_BOR:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_or);
    case EXPR_CALL:
        return compile_call_expression(ctx, (call_expression_t*)expr, no_ret);
    case EXPR_COMMA:
        return compile_comma_expression(ctx, (binary_expression_t*)expr);
    case EXPR_COND:
        return compile_conditional_expression(ctx, (conditional_expression_t*)expr);
    case EXPR_DELETE:
        return compile_delete_expression(ctx, (unary_expression_t*)expr);
    case EXPR_DIV:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_div);
    case EXPR_EQ:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_eq);
    case EXPR_EQEQ:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_eq2);
    case EXPR_FUNC:
        return compile_function_expression(ctx, (function_expression_t*)expr);
    case EXPR_GREATER:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_gt);
    case EXPR_GREATEREQ:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_gteq);
    case EXPR_IDENT:
        return push_instr_bstr(ctx, OP_ident, ((identifier_expression_t*)expr)->identifier);
    case EXPR_IN:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_in);
    case EXPR_INSTANCEOF:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_instanceof);
    case EXPR_LESS:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_lt);
    case EXPR_LESSEQ:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_lteq);
    case EXPR_LITERAL:
        return compile_literal(ctx, ((literal_expression_t*)expr)->literal);
    case EXPR_LOGNEG:
        return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_neg);
    case EXPR_LSHIFT:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_lshift);
    case EXPR_MEMBER:
        return compile_member_expression(ctx, (member_expression_t*)expr);
    case EXPR_MINUS:
        return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_minus);
    case EXPR_MOD:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_mod);
    case EXPR_MUL:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_mul);
    case EXPR_NEW:
        return compile_new_expression(ctx, (call_expression_t*)expr);
    case EXPR_NOTEQ:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_neq);
    case EXPR_NOTEQEQ:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_neq2);
    case EXPR_OR:
        return compile_logical_expression(ctx, (binary_expression_t*)expr, OP_cnd_nz);
    case EXPR_PLUS:
        return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_tonum);
    case EXPR_POSTDEC:
        return compile_increment_expression(ctx, (unary_expression_t*)expr, OP_postinc, -1);
    case EXPR_POSTINC:
        return compile_increment_expression(ctx, (unary_expression_t*)expr, OP_postinc, 1);
    case EXPR_PREDEC:
        return compile_increment_expression(ctx, (unary_expression_t*)expr, OP_preinc, -1);
    case EXPR_PREINC:
        return compile_increment_expression(ctx, (unary_expression_t*)expr, OP_preinc, 1);
    case EXPR_PROPVAL:
        return compile_object_literal(ctx, (property_value_expression_t*)expr);
    case EXPR_RSHIFT:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_rshift);
    case EXPR_RRSHIFT:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_rshift2);
    case EXPR_SUB:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_sub);
    case EXPR_THIS:
        return push_instr(ctx, OP_this) ? S_OK : E_OUTOFMEMORY;
    case EXPR_TYPEOF:
        return compile_typeof_expression(ctx, (unary_expression_t*)expr);
    case EXPR_VOID:
        return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_void);
    case EXPR_BXOR:
        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_xor);
    default:
        assert(0);
    }

    return S_OK;
}