static void self_check() { if (strcmp(dvm_error_message_format[0].format, "dummy") != 0) { DBG_panic(("runtime error message format error.\n")); } if (strcmp(dvm_error_message_format [RUNTIME_ERROR_COUNT_PLUS_1].format, "dummy") != 0) { DBG_panic(("runtime error message format error. " "RUNTIME_ERROR_COUNT_PLUS_1..%d\n", RUNTIME_ERROR_COUNT_PLUS_1)); } }
static void self_check() { if (strcmp(dkc_error_message_format[0].format, "dummy") != 0) { DBG_panic(("compile error message format error.\n")); } if (strcmp(dkc_error_message_format [COMPILE_ERROR_COUNT_PLUS_1].format, "dummy") != 0) { DBG_panic(("compile error message format error. " "COMPILE_ERROR_COUNT_PLUS_1..%d\n", COMPILE_ERROR_COUNT_PLUS_1)); } }
static CRB_Value eval_function_call_expression(CRB_Interpreter *inter, LcoalEnvriroment *env, Expression *expr) { CRB_Value value; FunctionDefinition *func; char *identifier = expr->u.function_call_expression.identifier; func = crb_search_function(identifier); if(func == NULL){ crb_runtime_error(expr->line_number, FUNCTION_NOT_FOUND_ERR, STRING_MESSAGE_ARGUMENT, "name", identifier, MESSAGE_ARGUMENT_END); } switch(func->type){ case CROWBAR_FUNCTION_DEFINITION: value = call_crowbar_function(inter, env, expr, func); break; case NATIVE_FUNCTION_DEFINITION: value = call_native_function(inter, env, expr, func->u.native_f.proc); break; default: DBG_panic(("bad case..%d\n", func->type)); } return value; }
DKC_Compiler * DKC_create_compiler(void) { MEM_Storage storage; DKC_Compiler *compiler; storage = MEM_open_storage(0); compiler = MEM_storage_malloc(storage, sizeof(struct DKC_Compiler_tag)); compiler->compile_storage = storage; compiler->function_list = NULL; compiler->function_count = 0; compiler->declaration_list = NULL; compiler->statement_list = NULL; compiler->current_block = NULL; compiler->current_line_number = 1; compiler->input_mode = DKC_FILE_INPUT_MODE; #ifdef EUC_SOURCE compiler->source_encoding = EUC_ENCODING; #else #ifdef SHIFT_JIS_SOURCE compiler->source_encoding = SHIFT_JIS_ENCODING; #else #ifdef UTF_8_SOURCE compiler->source_encoding = UTF_8_ENCODING; #else DBG_panic(("source encoding is not defined.\n")); #endif #endif #endif dkc_set_current_compiler(compiler); return compiler; }
static void eval_function_call_expression(SIMCAR_Interpreter *inter, SIMCAR_LocalEnvironment *env, Expression *expr) { FunctionDefinition *func; SIMCAR_LocalEnvironment *local_env; char *identifier = expr->u.function_call_expression.identifier; func = crb_search_function(identifier); if (func == NULL) { crb_runtime_error(expr->line_number, FUNCTION_NOT_FOUND_ERR, STRING_MESSAGE_ARGUMENT, "name", identifier, MESSAGE_ARGUMENT_END); } local_env = alloc_local_environment(inter); switch (func->type) { case CROWBAR_FUNCTION_DEFINITION: call_crowbar_function(inter, local_env, env, expr, func); break; case NATIVE_FUNCTION_DEFINITION: call_native_function(inter, local_env, env, expr, func->u.native_f.proc); break; case FUNCTION_DEFINITION_TYPE_COUNT_PLUS_1: default: DBG_panic(("bad case..%d\n", func->type)); } dispose_local_environment(inter); }
DKC_Compiler * DKC_create_compiler(void) { MEM_Storage storage; DKC_Compiler *compiler; DKC_Compiler *compiler_backup; compiler_backup = dkc_get_current_compiler(); storage = MEM_open_storage(0); compiler = MEM_storage_malloc(storage, sizeof(struct DKC_Compiler_tag)); dkc_set_current_compiler(compiler); compiler->compile_storage = storage; compiler->package_name = NULL; compiler->source_suffix = DKM_SOURCE; compiler->require_list = NULL; compiler->rename_list = NULL; compiler->function_list = NULL; compiler->dvm_function_count = 0; compiler->dvm_function = NULL; compiler->dvm_class_count = 0; compiler->dvm_class = NULL; compiler->declaration_list = NULL; compiler->statement_list = NULL; compiler->class_definition_list = NULL; compiler->current_block = NULL; compiler->current_line_number = 1; compiler->current_class_definition = NULL; compiler->current_catch_clause = NULL; compiler->input_mode = FILE_INPUT_MODE; compiler->required_list = NULL; compiler->array_method_count = ARRAY_SIZE(st_array_method); compiler->array_method = create_built_in_method(st_array_method, ARRAY_SIZE(st_array_method)); compiler->string_method_count = ARRAY_SIZE(st_string_method); compiler->string_method = create_built_in_method(st_string_method, ARRAY_SIZE(st_string_method)); #ifdef EUC_SOURCE compiler->source_encoding = EUC_ENCODING; #else #ifdef SHIFT_JIS_SOURCE compiler->source_encoding = SHIFT_JIS_ENCODING; #else #ifdef UTF_8_SOURCE compiler->source_encoding = UTF_8_ENCODING; #else DBG_panic(("source encoding is not defined.\n")); #endif #endif #endif dkc_set_current_compiler(compiler_backup); return compiler; }
/** * 检查写入硬编码的错误信息 * dummy作为一个标志符 */ void self_check(){ if (strcmp(hbb_compile_error_message_format[0].format,"dummy") != 0) { DBG_panic(("compile error message format error.\n")); } if (strcmp(hbb_compile_error_message_format [COMPILE_ERROR_COUNT_PLUS_1].format, "dummy") != 0) { DBG_panic(("compild error message format error. COMPILE_ERROR_COUNT_PLUS_1 ... %d \n"),COMPILE_ERROR_COUNT_PLUS_1); }
CRB_Interpreter * CRB_create_interpreter(void) { MEM_Storage storage; CRB_Interpreter *interpreter; #ifndef MINICROWBAR extern void crb_compile_built_in_script(CRB_Interpreter *inter); #endif /* MINICROWBAR */ storage = MEM_open_storage(0); interpreter = MEM_storage_malloc(storage, sizeof(struct CRB_Interpreter_tag)); interpreter->interpreter_storage = storage; interpreter->execute_storage = MEM_open_storage(0); interpreter->variable = NULL; interpreter->function_list = NULL; interpreter->statement_list = NULL; interpreter->current_line_number = 1; interpreter->stack.stack_alloc_size = 0; interpreter->stack.stack_pointer = 0; interpreter->stack.stack = MEM_malloc(sizeof(CRB_Value) * STACK_ALLOC_SIZE); interpreter->heap.current_heap_size = 0; interpreter->heap.current_threshold = HEAP_THRESHOLD_SIZE; interpreter->heap.header = NULL; interpreter->top_environment = NULL; interpreter->current_exception.type = CRB_NULL_VALUE; interpreter->input_mode = CRB_FILE_INPUT_MODE; interpreter->regexp_literals = NULL; #ifdef EUC_SOURCE interpreter->source_encoding = EUC_ENCODING; #else #ifdef SHIFT_JIS_SOURCE interpreter->source_encoding = SHIFT_JIS_ENCODING; #else #ifdef UTF_8_SOURCE interpreter->source_encoding = UTF_8_ENCODING; #else DBG_panic(("source encoding is not defined.\n")); #endif #endif #endif crb_set_current_interpreter(interpreter); crb_add_native_functions(interpreter); crb_add_regexp_functions(interpreter); #ifndef MINICROWBAR crb_compile_built_in_script(interpreter); #endif /* MINICROWBAR */ return interpreter; }
void self_check() { if (strcmp(crb_compile_error_message_format[0].format, "dummy") != 0) { DBG_panic(("compile error message format error.\n")); } if (strcmp(crb_compile_error_message_format [COMPILE_ERROR_COUNT_PLUS_1].format, "dummy") != 0) { DBG_panic(("compile error message format error. " "COMPILE_ERROR_COUNT_PLUS_1..%d\n", COMPILE_ERROR_COUNT_PLUS_1)); } if (strcmp(crb_runtime_error_message_format[0].format, "dummy") != 0) { DBG_panic(("runtime error message format error.\n")); } if (strcmp(crb_runtime_error_message_format [RUNTIME_ERROR_COUNT_PLUS_1].format, "dummy") != 0) { DBG_panic(("runtime error message format error. " "RUNTIME_ERROR_COUNT_PLUS_1..%d\n", RUNTIME_ERROR_COUNT_PLUS_1)); } }
char * CRB_get_type_name(CRB_ValueType type) { switch (type) { case CRB_BOOLEAN_VALUE: return "boolean"; break; case CRB_INT_VALUE: return "int"; break; case CRB_DOUBLE_VALUE: return "dobule"; break; case CRB_STRING_VALUE: return "string"; break; case CRB_NATIVE_POINTER_VALUE: return "native pointer"; break; case CRB_NULL_VALUE: return "null"; break; case CRB_ARRAY_VALUE: return "array"; break; case CRB_ASSOC_VALUE: return "object"; break; case CRB_CLOSURE_VALUE: return "closure"; break; case CRB_FAKE_METHOD_VALUE: return "method"; break; case CRB_SCOPE_CHAIN_VALUE: return "scope chain"; break; default: DBG_panic(("bad type..%d\n", type)); } return NULL; /* make compiler happy */ }
static StatementResult execute_statement(CRB_Interpreter *inter, CRB_LocalEnvironment *env, Statement *statement) { StatementResult result; result.type = NORMAL_STATEMENT_RESULT; switch (statement->type) { case EXPRESSION_STATEMENT: result = execute_expression_statement(inter, env, statement); break; case GLOBAL_STATEMENT: result = execute_global_statement(inter, env, statement); break; case IF_STATEMENT: result = execute_if_statement(inter, env, statement); break; case WHILE_STATEMENT: result = execute_while_statement(inter, env, statement); break; case FOR_STATEMENT: result = execute_for_statement(inter, env, statement); break; case RETURN_STATEMENT: result = execute_return_statement(inter, env, statement); break; case BREAK_STATEMENT: result = execute_break_statement(inter, env, statement); break; case CONTINUE_STATEMENT: result = execute_continue_statement(inter, env, statement); break; case STATEMENT_TYPE_COUNT_PLUS_1: /* FALLTHRU */ default: DBG_panic(("bad case...%d", statement->type)); } return result; }
static CRB_Value eval_logical_and_or_expression(CRB_Interpreter *inter, LocalEnviroment *env, ExpressionType operator, Expression *left, Expression *right) { CRB_Value left_val; CRB_Value right_val; CRB_Value result; result.type = CRB_BOOLEAN_VALUE; left_val = eval_expression(inter, env , left); if(left_val.type != CRB_BOOLEAN_VALUE){ crb_runtime_error(left->line_nmber, NOT_BOOLEAN_OPERATOR_ERR, MESSAGE_ARGUMENT_END); } if(operator == LOGICAL_AND_EXPRESSION){ if(!left_val.u.boolean_value){ result.u.boolean_value = CRB_FALSE; return result; } } else if(operator == LOGICAL_OR_EXPRESSION){ if(left_val.u.boolean_value){ result.u.booelean_value = CRB_TRUE; return result; } } else { DBG_panic(("bad operator..%d\n", operator")); } right_val = eval_expression(inter, env, rihgt); if(right_val.type != CRB_BOOLEAN_VALUE){ crb_runtime_error(right->line_number, NOT_BOOLEAN_TYPE_ERR, MESSAGE_ARGUGMENT_END); } result.u.boolean_value = right_val.u.boolean_value; return result; }
Statement * Asm_create_statement(char *label, Bytecode *code, Constant *const_opt) { NameSpace *name_space; Statement *ret; name_space = &Asm_get_current_compiler()->name_space[Asm_get_current_compiler()->current_name_space_index]; ret = ASM_malloc(sizeof(Statement)); ret->label = label; ret->bytecode = code; ret->constant = const_opt; ret->line_number = get_current_line_number(); if (code && code->name == NULL && code->next && !strcmp(code->next->name, Loopr_CR_Info[LCR_FUNCTION].assembly_name)) { if (name_space->function_definition) { name_space->function_definition = MEM_realloc(name_space->function_definition, sizeof(FunctionDefinition) * (name_space->function_count + 1)); } else { name_space->function_definition = MEM_malloc(sizeof(FunctionDefinition) * (name_space->function_count + 1)); } name_space->function_definition[name_space->function_count].is_void = LPR_False; while (const_opt && const_opt->type == CONST_KEYWORD) { switch (const_opt->u.keyword_value) { case ASM_VOID: name_space->function_definition[name_space->function_count].is_void = LPR_True; const_opt = const_opt->next; break; default: DBG_panic(("line %d: Unknown keyword %d\n", const_opt->line_number, const_opt->u.keyword_value)); break; } } name_space->function_definition[name_space->function_count].name = MEM_strdup(const_opt->u.string_value); name_space->function_count++; } return ret; }
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); }
static void eval_binary_int(SIMCAR_Interpreter *inter, ExpressionType operato, int left, int right, SIMCAR_Value *result, int line_number) { if (dkc_is_math_operator(operato)) { result->type = SIMCAR_INT_VALUE; } else if (dkc_is_compare_operator(operato)) { result->type = SIMCAR_BOOLEAN_VALUE; } else { DBG_panic(("operator..%d\n", operato)); } switch (operato) { case BOOLEAN_EXPRESSION: /* FALLTHRU */ case INT_EXPRESSION: /* FALLTHRU */ case DOUBLE_EXPRESSION: /* FALLTHRU */ case STRING_EXPRESSION: /* FALLTHRU */ case IDENTIFIER_EXPRESSION: /* FALLTHRU */ case ASSIGN_EXPRESSION: DBG_panic(("bad case...%d", operato)); break; case ADD_EXPRESSION: result->u.int_value = left + right; break; case SUB_EXPRESSION: result->u.int_value = left - right; break; case MUL_EXPRESSION: result->u.int_value = left * right; break; case DIV_EXPRESSION: result->u.int_value = left / right; break; case MOD_EXPRESSION: result->u.int_value = left % right; break; case LOGICAL_AND_EXPRESSION: /* FALLTHRU */ case LOGICAL_OR_EXPRESSION: DBG_panic(("bad case...%d", operato)); break; case EQ_EXPRESSION: result->u.boolean_value = left == right; break; case NE_EXPRESSION: result->u.boolean_value = left != right; break; case GT_EXPRESSION: result->u.boolean_value = left > right; break; case GE_EXPRESSION: result->u.boolean_value = left >= right; break; case LT_EXPRESSION: result->u.boolean_value = left < right; break; case LE_EXPRESSION: result->u.boolean_value = left <= right; break; case MINUS_EXPRESSION: /* FALLTHRU */ case FUNCTION_CALL_EXPRESSION: /* FALLTHRU */ case METHOD_CALL_EXPRESSION: /* FALLTHRU */ case NULL_EXPRESSION: /* FALLTHRU */ case ARRAY_EXPRESSION: /* FALLTHRU */ case INDEX_EXPRESSION: /* FALLTHRU */ case INCREMENT_EXPRESSION: /* FALLTHRU */ case DECREMENT_EXPRESSION: /* FALLTHRU */ case EXPRESSION_TYPE_COUNT_PLUS_1: /* FALLTHRU */ default: DBG_panic(("bad case...%d", operato)); } }
CRB_Char * CRB_value_to_string(CRB_Value *value) { VString vstr; char buf[LINE_BUF_SIZE]; CRB_Char wc_buf[LINE_BUF_SIZE]; int i; crb_vstr_clear(&vstr); switch (value->type) { case CRB_BOOLEAN_VALUE: if (value->u.boolean_value) { CRB_mbstowcs("true", wc_buf); } else { CRB_mbstowcs("false", wc_buf); } crb_vstr_append_string(&vstr, wc_buf); break; case CRB_INT_VALUE: sprintf(buf, "%d", value->u.int_value); CRB_mbstowcs(buf, wc_buf); crb_vstr_append_string(&vstr, wc_buf); break; case CRB_DOUBLE_VALUE: sprintf(buf, "%f", value->u.double_value); CRB_mbstowcs(buf, wc_buf); crb_vstr_append_string(&vstr, wc_buf); break; case CRB_STRING_VALUE: crb_vstr_append_string(&vstr, value->u.object->u.string.string); break; case CRB_NATIVE_POINTER_VALUE: sprintf(buf, "(%s:%p)", value->u.native_pointer.info->name, value->u.native_pointer.pointer); CRB_mbstowcs(buf, wc_buf); crb_vstr_append_string(&vstr, wc_buf); break; case CRB_NULL_VALUE: CRB_mbstowcs("null", wc_buf); crb_vstr_append_string(&vstr, wc_buf); break; case CRB_ARRAY_VALUE: CRB_mbstowcs("(", wc_buf); crb_vstr_append_string(&vstr, wc_buf); for (i = 0; i < value->u.object->u.array.size; i++) { CRB_Char *new_str; if (i > 0) { CRB_mbstowcs(", ", wc_buf); crb_vstr_append_string(&vstr, wc_buf); } new_str = CRB_value_to_string(&value->u.object->u.array.array[i]); crb_vstr_append_string(&vstr, new_str); MEM_free(new_str); } CRB_mbstowcs(")", wc_buf); crb_vstr_append_string(&vstr, wc_buf); break; default: DBG_panic(("value->type..%d\n", value->type)); } return vstr.string; }
char * crb_get_operator_string(ExpressionType type) { char *str; switch (type) { case BOOLEAN_EXPRESSION: /* FALLTHRU */ case INT_EXPRESSION: /* FALLTHRU */ case DOUBLE_EXPRESSION: /* FALLTHRU */ case STRING_EXPRESSION: /* FALLTHRU */ case IDENTIFIER_EXPRESSION: DBG_panic(("bad expression type..%d\n", type)); break; case ASSIGN_EXPRESSION: str = "="; break; case ADD_EXPRESSION: str = "+"; break; case SUB_EXPRESSION: str = "-"; break; case MUL_EXPRESSION: str = "*"; break; case DIV_EXPRESSION: str = "/"; break; case MOD_EXPRESSION: str = "%"; break; case EQ_EXPRESSION: str = "=="; break; case NE_EXPRESSION: str = "!="; break; case GT_EXPRESSION: str = "<"; break; case GE_EXPRESSION: str = "<="; break; case LT_EXPRESSION: str = ">"; break; case LE_EXPRESSION: str = ">="; break; case LOGICAL_AND_EXPRESSION: str = "&&"; break; case LOGICAL_OR_EXPRESSION: str = "||"; break; case MINUS_EXPRESSION: str = "-"; break; case FUNCTION_CALL_EXPRESSION: /* FALLTHRU */ case METHOD_CALL_EXPRESSION: /* FALLTHRU */ case NULL_EXPRESSION: /* FALLTHRU */ case ARRAY_EXPRESSION: /* FALLTHRU */ case INDEX_EXPRESSION: /* FALLTHRU */ case INCREMENT_EXPRESSION: /* FALLTHRU */ case DECREMENT_EXPRESSION: /* FALLTHRU */ case EXPRESSION_TYPE_COUNT_PLUS_1: default: DBG_panic(("bad expression type..%d\n", type)); } return str; }
static void eval_expression(SIMCAR_Interpreter *inter, SIMCAR_LocalEnvironment *env, Expression *expr) { switch (expr->type) { case BOOLEAN_EXPRESSION: eval_boolean_expression(inter, expr->u.boolean_value); break; case INT_EXPRESSION: eval_int_expression(inter, expr->u.int_value); break; case DOUBLE_EXPRESSION: eval_double_expression(inter, expr->u.double_value); break; case STRING_EXPRESSION: eval_string_expression(inter, expr->u.string_value); break; case IDENTIFIER_EXPRESSION: eval_identifier_expression(inter, env, expr); break; case ASSIGN_EXPRESSION: eval_assign_expression(inter, env, expr->u.assign_expression.left, expr->u.assign_expression.operand); break; case ADD_EXPRESSION: /* FALLTHRU */ case SUB_EXPRESSION: /* FALLTHRU */ case MUL_EXPRESSION: /* FALLTHRU */ case DIV_EXPRESSION: /* FALLTHRU */ case MOD_EXPRESSION: /* FALLTHRU */ case EQ_EXPRESSION: /* FALLTHRU */ case NE_EXPRESSION: /* FALLTHRU */ case GT_EXPRESSION: /* FALLTHRU */ case GE_EXPRESSION: /* FALLTHRU */ case LT_EXPRESSION: /* FALLTHRU */ case LE_EXPRESSION: /* FALLTHRU */ eval_binary_expression(inter, env, expr->type, expr->u.binary_expression.left, expr->u.binary_expression.right); break; case LOGICAL_AND_EXPRESSION:/* FALLTHRU */ case LOGICAL_OR_EXPRESSION: eval_logical_and_or_expression(inter, env, expr->type, expr->u.binary_expression.left, expr->u.binary_expression.right); break; case MINUS_EXPRESSION: eval_minus_expression(inter, env, expr->u.minus_expression); break; case FUNCTION_CALL_EXPRESSION: eval_function_call_expression(inter, env, expr); break; case METHOD_CALL_EXPRESSION: eval_method_call_expression(inter, env, expr); break; case NULL_EXPRESSION: eval_null_expression(inter); break; case ARRAY_EXPRESSION: eval_array_expression(inter, env, expr->u.array_literal); break; case INDEX_EXPRESSION: eval_index_expression(inter, env, expr); break; case INCREMENT_EXPRESSION: /* FALLTHRU */ case DECREMENT_EXPRESSION: eval_inc_dec_expression(inter, env, expr); break; case EXPRESSION_TYPE_COUNT_PLUS_1: /* FALLTHRU */ default: DBG_panic(("bad case. type..%d\n", expr->type)); } }
static void eval_binary_double(CRB_Interpreter *inter, ExpressionType operator, double left, double right, CRB_Value *result, int line_number) { if(dkc_is_math_operator(operator)){ result->type = CRB_DOUBLE_VALUE; } else if(dkc_is_compare_operator(operator)){ result->type = CRB_BOOLEAN_VALUE; } else { DBG_panic(("operator..%d\n", operator)); } switch(operator){ case BOOLEAN_EXPRESSION: case INT_EXPRESSION: case DOUBLE_EXPRESSION: case STIRNG_EXPRESSION: case IDENTIFIER_EXPERSSION: case ASSIGN_EXPRESSION: DBG_panic(("bad case..%d\n", operator)); break; case ADD_EXPRESSION: result->u.double_value = left + right; break; case SUB_EXPRESSION: result->u.double_value = left - right; break; case MUL_EXPERSSION: result->u.double_value = left * right; break; case DIV_EXPERSSION: result->u.double_value = left / right; break; case MOD_EXPRESSION: result->u.double_value = fmod(left, right); break; case LOGICAL_AND_EXPRESSION: case LOGICAL_OR_EXPRESSION: DBG_panic(("bad case ..%d", operator)); break; case EQ_EXPRESSION: result->u.double_value = left == right; break; case NE_EXPRESSION: result->u.dou_value = left != right; break; case GT_EXPRESSION: result->u.int_value = left > right; break; case GE_EXPRESSION: result->u.int_value = left >= right; break; case LT_EXPRESSION: result->u.int_value = left < right; break; case LE_EXPRESSION: result->u.int_value = left <= right; break; case MINUS_EXPRESSION: case FUNCTION_CALL_EXPRESSION: case NULL_EXPRESSION: case EXPRESSION_TYPE_COUNT_PLUS_1: default: DBG_panic(("bad defualt..%d", operator)); } }
CRB_Char * CRB_value_to_string(CRB_Interpreter *inter, CRB_LocalEnvironment *env, int line_number, CRB_Value *value) { VString vstr; char buf[LINE_BUF_SIZE]; CRB_Char wc_buf[LINE_BUF_SIZE]; int i; crb_vstr_clear(&vstr); switch (value->type) { case CRB_BOOLEAN_VALUE: if (value->u.boolean_value) { CRB_mbstowcs("true", wc_buf); } else { CRB_mbstowcs("false", wc_buf); } crb_vstr_append_string(&vstr, wc_buf); break; case CRB_INT_VALUE: sprintf(buf, "%d", value->u.int_value); CRB_mbstowcs(buf, wc_buf); crb_vstr_append_string(&vstr, wc_buf); break; case CRB_DOUBLE_VALUE: sprintf(buf, "%f", value->u.double_value); CRB_mbstowcs(buf, wc_buf); crb_vstr_append_string(&vstr, wc_buf); break; case CRB_STRING_VALUE: crb_vstr_append_string(&vstr, value->u.object->u.string.string); break; case CRB_NATIVE_POINTER_VALUE: sprintf(buf, "%s(%p)", value->u.object->u.native_pointer.info->name, value->u.object->u.native_pointer.pointer); CRB_mbstowcs(buf, wc_buf); crb_vstr_append_string(&vstr, wc_buf); break; case CRB_NULL_VALUE: CRB_mbstowcs("null", wc_buf); crb_vstr_append_string(&vstr, wc_buf); break; case CRB_ARRAY_VALUE: CRB_mbstowcs("(", wc_buf); crb_vstr_append_string(&vstr, wc_buf); for (i = 0; i < value->u.object->u.array.size; i++) { CRB_Char *new_str; if (i > 0) { CRB_mbstowcs(", ", wc_buf); crb_vstr_append_string(&vstr, wc_buf); } new_str = CRB_value_to_string(inter, env, line_number, &value->u.object->u.array.array[i]); crb_vstr_append_string(&vstr, new_str); MEM_free(new_str); } CRB_mbstowcs(")", wc_buf); crb_vstr_append_string(&vstr, wc_buf); break; case CRB_ASSOC_VALUE: CRB_mbstowcs("(", wc_buf); crb_vstr_append_string(&vstr, wc_buf); for (i = 0; i < value->u.object->u.assoc.member_count; i++) { CRB_Char *new_str; if (i > 0) { CRB_mbstowcs(", ", wc_buf); crb_vstr_append_string(&vstr, wc_buf); } new_str = CRB_mbstowcs_alloc(inter, env, line_number, value->u.object->u.assoc.member[i].name); DBG_assert(new_str != NULL, ("new_str is null.\n")); crb_vstr_append_string(&vstr, new_str); MEM_free(new_str); CRB_mbstowcs("=>", wc_buf); crb_vstr_append_string(&vstr, wc_buf); new_str = CRB_value_to_string(inter, env, line_number, &value->u.object ->u.assoc.member[i].value); crb_vstr_append_string(&vstr, new_str); MEM_free(new_str); } CRB_mbstowcs(")", wc_buf); crb_vstr_append_string(&vstr, wc_buf); break; case CRB_CLOSURE_VALUE: CRB_mbstowcs("closure(", wc_buf); crb_vstr_append_string(&vstr, wc_buf); if (value->u.closure.function->name == NULL) { CRB_mbstowcs("null", wc_buf); crb_vstr_append_string(&vstr, wc_buf); } else { CRB_Char *new_str; new_str = CRB_mbstowcs_alloc(inter, env, line_number, value->u.closure.function->name); DBG_assert(new_str != NULL, ("new_str is null.\n")); crb_vstr_append_string(&vstr, new_str); MEM_free(new_str); } CRB_mbstowcs(")", wc_buf); crb_vstr_append_string(&vstr, wc_buf); break; case CRB_FAKE_METHOD_VALUE: CRB_mbstowcs("fake_method(", wc_buf); crb_vstr_append_string(&vstr, wc_buf); { CRB_Char *new_str; new_str = CRB_mbstowcs_alloc(inter, env, line_number, value->u.fake_method.method_name); DBG_assert(new_str != NULL, ("new_str is null.\n")); crb_vstr_append_string(&vstr, new_str); MEM_free(new_str); } CRB_mbstowcs(")", wc_buf); crb_vstr_append_string(&vstr, wc_buf); break; case CRB_SCOPE_CHAIN_VALUE: /* FALLTHRU*/ default: DBG_panic(("value->type..%d\n", value->type)); } return vstr.string; }
static CRB_Value eval_expression(CRB_Interpreter *inter, LocalEnvrioment *env, Expression *expr) { CRB_Value v; switch(expr->type){ case BOOLEAN_EXPRESSION: v = eval_boolean_expression(expr->u.boolean_value); break; case INT_EXPRESSION: v = eval_int_expression(expr->u.int_value); break; case DOUBLE_EXPRESSION: v = eval_double_expression(expr->u.double_value); break; case STRING_EXPRESSION: v = eval_string_expression(inter, expr->u.string_value); break; case IDENTIFIER_EXPRESSION: v = eval_identifier_expression(inter, env, expr); break; case ASSIGN_EXPRESSION: v = eval_assign_expression(inter, env, expr->u.assign_expression.variable, expr->u.assign_expression.operand); break; case ADD_EXPRESSION: case SUB_EXPRESSION: case MUL_EXPRESSION: case DIV_EXPRESSION: case MOD_EXPRESSION: case EQ_EXPRESSION: case NE_EXPRESSION: case GT_EXPRESSION: case GE_EXPRESSION: case LT_EXPRESSION: case LE_EXPRESSION: v = crb_eval_binary_expression(inter, env, expr->type, expr->u.binary_expression.left, expr->u.binary_expression.right); break; case LOGICAL_AND_EXPRESSION: case LOGICAL_OR_EXPRESSION: v = crb_eval_and_or_expression(inter ,env, expr->type, expr->u.binary_expression.left, expr->u.binary_expression.right); break; case MINUS_EXPRESSION: v = crb_eval_minus_expression(inter, env, expr->u.minus_expression); break; case FUNCTION_CALL_EXPRESSION: v = eval_function_call_expression(inter, env, expr); break; case NULL_EXPRESSION: v = eval_null_expression(); break; case EXPRESSION_TYPE_COUNT_PLUS_1: default: DBG_panic(("bad case.type..%d\n", expr->type)); } return v; }