static CRB_Value eval_assign_expression(CRB_Interpreter *inter, LocalEnvironment *env, char *identifier, Expression *expression) { CRB_Value v; Variable *left; v = eval_expression(inter, env, expression); left = crb_search_local_variable(env, identifier); if(left == NULL){ left = search_global_variable_from_env(inter, env, identifier); } if(left != NULL){ release_if_string(&left->vaule); left->value = v; release_if_string(&v); } else { if(env != NULL){ crb_add_local_variable(env, identifier, &v); } else { CRB_add_global_variable(inter, identifier, &v); } refer_if_string(&v); } return v; }
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); }
static CRB_Value call_crowbar_function(CRB_Interpreter *inter, LocalEnvironment *env, Expression *expr, FunctionDefinition *func) { CRB_Value value; StatementList result; ArgumentList *arg_p; ParamenterList *param_p; LocalEnvironment *local_env; local_env = alloc_local_envroment(); for(arg_p = expr->u.function_call_expression.argument, param_p = func->u.crowbar_f.parameter; arg_p; arg_p = arg->next, param_p = param_p->next){ CRB_Value arg_val; if(param_p == NULL){ crb_runtime_error(expr->line_number, ARGUMENT_TOO_MANY_ERR, MESSAGE_ARGUMENT_END); } arg_val = eval_expression(inter, env, arg_p->expression); crb_add_local_variable(local_env, param_p->name, &arg_val); } if(param_p){ crb_runtime_error(expr->line_number, ARGUMENT_TOO_FEW_ERR, MESSAGE_ARUMENT_END); } result = crb_execute_statement_list(inter, local_env, func->u.crowbar_f.block ->statement_list); if(result.type == RETURN_STATEMENT_RESULT){ value.type = result.u.return_value; } else { value.type = CRB_NULL_VALUE; } dispose_local_enviroment(inter, local_env); return value; }
static SIMCAR_Value * get_identifier_lvalue(SIMCAR_Interpreter *inter, SIMCAR_LocalEnvironment *env, char *identifier) { Variable *new_var; Variable *left; left = crb_search_local_variable(env, identifier); if (left == NULL) { left = search_global_variable_from_env(inter, env, identifier); } if (left != NULL) return &left->value; if (env != NULL) { new_var = crb_add_local_variable(env, identifier); left = new_var; } else { new_var = crb_add_global_variable(inter, identifier); left = new_var; } return &left->value; }