Esempio n. 1
0
SIMCAR_Value *
get_array_element_lvalue(SIMCAR_Interpreter *inter, SIMCAR_LocalEnvironment *env,
                         Expression *expr)
{
    SIMCAR_Value   array;
    SIMCAR_Value   index;

    eval_expression(inter, env, expr->u.index_expression.array);
    eval_expression(inter, env, expr->u.index_expression.index);
    index = pop_value(inter);
    array = pop_value(inter);

    if (array.type != SIMCAR_ARRAY_VALUE) {
        crb_runtime_error(expr->line_number, INDEX_OPERAND_NOT_ARRAY_ERR,
                          MESSAGE_ARGUMENT_END);
    }
    if (index.type != SIMCAR_INT_VALUE) {
        crb_runtime_error(expr->line_number, INDEX_OPERAND_NOT_INT_ERR,
                          MESSAGE_ARGUMENT_END);
    }

    if (index.u.int_value < 0
        || index.u.int_value >= array.u.object->u.array.size) {
        crb_runtime_error(expr->line_number, ARRAY_INDEX_OUT_OF_BOUNDS_ERR,
                          INT_MESSAGE_ARGUMENT,
                          "size", array.u.object->u.array.size,
                          INT_MESSAGE_ARGUMENT, "index", index.u.int_value,
                          MESSAGE_ARGUMENT_END);
    }
    return &array.u.object->u.array.array[index.u.int_value];
}
Esempio n. 2
0
SIMCAR_Value
crb_eval_minus_expression(SIMCAR_Interpreter *inter, SIMCAR_LocalEnvironment *env,
                          Expression *operand)
{
    eval_minus_expression(inter, env, operand);
    return pop_value(inter);
}
Esempio n. 3
0
SIMCAR_Value
crb_eval_expression(SIMCAR_Interpreter *inter, SIMCAR_LocalEnvironment *env,
                    Expression *expr)
{
    eval_expression(inter, env, expr);
    return pop_value(inter);
}
Esempio n. 4
0
SIMCAR_Value
crb_eval_binary_expression(SIMCAR_Interpreter *inter, SIMCAR_LocalEnvironment *env,
                           ExpressionType operato,
                           Expression *left, Expression *right)
{
    eval_binary_expression(inter, env, operato, left, right);
    return pop_value(inter);
}
Esempio n. 5
0
static void
eval_logical_and_or_expression(SIMCAR_Interpreter *inter,
                               SIMCAR_LocalEnvironment *env,
                               ExpressionType operato,
                               Expression *left, Expression *right)
{
    SIMCAR_Value   left_val;
    SIMCAR_Value   right_val;
    SIMCAR_Value   result;

    result.type = SIMCAR_BOOLEAN_VALUE;
    eval_expression(inter, env, left);
    left_val = pop_value(inter);
    if (left_val.type != SIMCAR_BOOLEAN_VALUE) {
        crb_runtime_error(left->line_number, NOT_BOOLEAN_TYPE_ERR,
                          MESSAGE_ARGUMENT_END);
    }
    if (operato == LOGICAL_AND_EXPRESSION) {
        if (!left_val.u.boolean_value) {
            result.u.boolean_value = SIMCAR_FALSE;
            goto FUNC_END;
        }
    } else if (operato == LOGICAL_OR_EXPRESSION) {
        if (left_val.u.boolean_value) {
            result.u.boolean_value = SIMCAR_TRUE;
            goto FUNC_END;
        }
    } else {
        DBG_panic(("bad operator..%d\n", operato));
    }

    eval_expression(inter, env, right);
    right_val = pop_value(inter);
    result.u.boolean_value = right_val.u.boolean_value;

  FUNC_END:
    push_value(inter, &result);
}
Esempio n. 6
0
static void
call_crowbar_function(SIMCAR_Interpreter *inter, SIMCAR_LocalEnvironment *env,
                      SIMCAR_LocalEnvironment *caller_env,
                      Expression *expr, FunctionDefinition *func)
{
    SIMCAR_Value   value;
    StatementResult     result;
    ArgumentList        *arg_p;
    ParameterList       *param_p;


    for (arg_p = expr->u.function_call_expression.argument,
             param_p = func->u.crowbar_f.parameter;
         arg_p;
         arg_p = arg_p->next, param_p = param_p->next) {
        Variable *new_var;
        SIMCAR_Value arg_val;

         if (param_p == NULL) {
             crb_runtime_error(expr->line_number, ARGUMENT_TOO_MANY_ERR,
                               MESSAGE_ARGUMENT_END);
         }
         eval_expression(inter, caller_env, arg_p->expression);
         arg_val = pop_value(inter);
         new_var = crb_add_local_variable(env, param_p->name);
         new_var->value = arg_val;
    }
     if (param_p) {
         crb_runtime_error(expr->line_number, ARGUMENT_TOO_FEW_ERR,
                           MESSAGE_ARGUMENT_END);
     }
     result = crb_execute_statement_list(inter, env,
                                         func->u.crowbar_f.block
                                         ->statement_list);
     if (result.type == RETURN_STATEMENT_RESULT) {
         value = result.u.return_value;
     } else {
         value.type = SIMCAR_NULL_VALUE;
     }

     push_value(inter, &value);
}
Esempio n. 7
0
static void
eval_minus_expression(SIMCAR_Interpreter *inter, SIMCAR_LocalEnvironment *env,
                      Expression *operand)
{
    SIMCAR_Value   operand_val;
    SIMCAR_Value   result;

    eval_expression(inter, env, operand);
    operand_val = pop_value(inter);
    if (operand_val.type == SIMCAR_INT_VALUE) {
        result.type = SIMCAR_INT_VALUE;
        result.u.int_value = -operand_val.u.int_value;
    } else if (operand_val.type == SIMCAR_DOUBLE_VALUE) {
        result.type = SIMCAR_DOUBLE_VALUE;
        result.u.double_value = -operand_val.u.double_value;
    } else {
        crb_runtime_error(operand->line_number, MINUS_OPERAND_TYPE_ERR,
                          MESSAGE_ARGUMENT_END);
    }

    push_value(inter, &result);
}
Esempio n. 8
0
static void
eval_array_expression(SIMCAR_Interpreter *inter,
                      SIMCAR_LocalEnvironment *env, ExpressionList *list)
{
    SIMCAR_Value   v;
    int         size;
    ExpressionList *pos;
    int         i;

    size = 0;
    for (pos = list; pos; pos = pos->next) {
        size++;
    }
    v.type = SIMCAR_ARRAY_VALUE;
    v.u.object = crb_create_array_i(inter, size);
    push_value(inter, &v);

    for (pos = list, i = 0; pos; pos = pos->next, i++) {
        eval_expression(inter, env, pos->expression);
        v.u.object->u.array.array[i] = pop_value(inter);
    }

}
Esempio n. 9
0
static void op_pop_value(int byte, struct thread *thread)
{
    pop_value(thread, decode_arg(thread));
}
Esempio n. 10
0
static void op_pop_value_immed(int byte, struct thread *thread)
{
    pop_value(thread, byte & 0xf);
}
Esempio n. 11
0
static void
eval_method_call_expression(SIMCAR_Interpreter *inter, SIMCAR_LocalEnvironment *env,
                            Expression *expr)
{
    SIMCAR_Value *left;
    SIMCAR_Value result;
    SIMCAR_Boolean error_flag = SIMCAR_FALSE;

    eval_expression(inter, env, expr->u.method_call_expression.expression);
    left = peek_stack(inter, 0);

    if (left->type == SIMCAR_ARRAY_VALUE) {
        if (!strcmp(expr->u.method_call_expression.identifier, "add")) {
            SIMCAR_Value *add;
            check_method_argument_count(expr->line_number,
                                        expr->u.method_call_expression
                                        .argument, 1);
            eval_expression(inter, env,
                            expr->u.method_call_expression.argument
                            ->expression);
            add = peek_stack(inter, 0);
            crb_array_add(inter, left->u.object, *add);
            pop_value(inter);
            result.type = SIMCAR_NULL_VALUE;
        } else if (!strcmp(expr->u.method_call_expression.identifier,
                           "size")) {
            check_method_argument_count(expr->line_number,
                                        expr->u.method_call_expression
                                        .argument, 0);
            result.type = SIMCAR_INT_VALUE;
            result.u.int_value = left->u.object->u.array.size;
        } else if (!strcmp(expr->u.method_call_expression.identifier,
                           "resize")) {
            SIMCAR_Value new_size;
            check_method_argument_count(expr->line_number,
                                        expr->u.method_call_expression
                                        .argument, 1);
            eval_expression(inter, env,
                            expr->u.method_call_expression.argument
                            ->expression);
            new_size = pop_value(inter);
            if (new_size.type != SIMCAR_INT_VALUE) {
                crb_runtime_error(expr->line_number,
                                  ARRAY_RESIZE_ARGUMENT_ERR,
                                  MESSAGE_ARGUMENT_END);
            }
            crb_array_resize(inter, left->u.object, new_size.u.int_value);
            result.type = SIMCAR_NULL_VALUE;
        } else {
            error_flag = SIMCAR_TRUE;
        }

    } else if (left->type == SIMCAR_STRING_VALUE) {
        if (!strcmp(expr->u.method_call_expression.identifier, "length")) {
            check_method_argument_count(expr->line_number,
                                        expr->u.method_call_expression
                                        .argument, 0);
            result.type = SIMCAR_INT_VALUE;
            result.u.int_value = strlen(left->u.object->u.string.string);
        } else {
            error_flag = SIMCAR_TRUE;
        }
    } else {
        error_flag = SIMCAR_TRUE;
    }
    if (error_flag) {
        crb_runtime_error(expr->line_number, NO_SUCH_METHOD_ERR,
                          STRING_MESSAGE_ARGUMENT, "method_name",
                          expr->u.method_call_expression.identifier,
                          MESSAGE_ARGUMENT_END);
    }
    pop_value(inter);
    push_value(inter, &result);
}
Esempio n. 12
0
static void
eval_binary_expression(SIMCAR_Interpreter *inter, SIMCAR_LocalEnvironment *env,
                       ExpressionType operato,
                       Expression *left, Expression *right)
{
    SIMCAR_Value   *left_val;
    SIMCAR_Value   *right_val;
    SIMCAR_Value   result;

    eval_expression(inter, env, left);
    eval_expression(inter, env, right);
    left_val = peek_stack(inter, 1);
    right_val = peek_stack(inter, 0);

    if (left_val->type == SIMCAR_INT_VALUE
        && right_val->type == SIMCAR_INT_VALUE) {
        eval_binary_int(inter, operato,
                        left_val->u.int_value, right_val->u.int_value,
                        &result, left->line_number);
    } else if (left_val->type == SIMCAR_DOUBLE_VALUE
               && right_val->type == SIMCAR_DOUBLE_VALUE) {
        eval_binary_double(inter, operato,
                           left_val->u.double_value, right_val->u.double_value,
                           &result, left->line_number);
    } else if (left_val->type == SIMCAR_INT_VALUE
               && right_val->type == SIMCAR_DOUBLE_VALUE) {
        eval_binary_double(inter, operato,
                           (double)left_val->u.int_value,
                           right_val->u.double_value,
                           &result, left->line_number);
    } else if (left_val->type == SIMCAR_DOUBLE_VALUE
               && right_val->type == SIMCAR_INT_VALUE) {
        eval_binary_double(inter, operato,
                           left_val->u.double_value,
                           (double)right_val->u.int_value,
                           &result, left->line_number);
    } else if (left_val->type == SIMCAR_BOOLEAN_VALUE
               && right_val->type == SIMCAR_BOOLEAN_VALUE) {
        result.type = SIMCAR_BOOLEAN_VALUE;
        result.u.boolean_value
            = eval_binary_boolean(inter, operato,
                                  left_val->u.boolean_value,
                                  right_val->u.boolean_value,
                                  left->line_number);
    } else if (left_val->type == SIMCAR_STRING_VALUE
               && operato == ADD_EXPRESSION) {
        chain_string(inter, left_val, right_val, &result);
    } else if (left_val->type == SIMCAR_STRING_VALUE
               && right_val->type == SIMCAR_STRING_VALUE) {
        result.type = SIMCAR_BOOLEAN_VALUE;
        result.u.boolean_value
            = eval_compare_string(operato, left_val, right_val,
                                  left->line_number);
    } else if (left_val->type == SIMCAR_NULL_VALUE
               || right_val->type == SIMCAR_NULL_VALUE) {
        result.type = SIMCAR_BOOLEAN_VALUE;
        result.u.boolean_value
            = eval_binary_null(inter, operato, left_val, right_val,
                               left->line_number);
    } else {
        char *op_str = crb_get_operator_string(operato);
        crb_runtime_error(left->line_number, BAD_OPERAND_TYPE_ERR,
                          STRING_MESSAGE_ARGUMENT, "operator", op_str,
                          MESSAGE_ARGUMENT_END);
    }
    pop_value(inter);
    pop_value(inter);
    push_value(inter, &result);
}