📄 expression.c
字号:
case expr_int_const: { long test; errno = 0; test = strtol(expr->token->name,(char**)NULL,0); if (test<INT_MIN || (errno==ERANGE && test == LONG_MIN)) error(expr->token, "integer constant (%s) lower than min value (%d)", expr->token->name, INT_MIN); if (test>INT_MAX || (errno==ERANGE && test == LONG_MAX)) error(expr->token, "integer constant (%s) higher than max value (%d)", expr->token->name, INT_MAX); } expr->type = new_simple_type(int_type); break; case expr_real_const: { double test; errno = 0; test = strtod(expr->token->name, NULL); if (errno==ERANGE) { if (test == 0) error(expr->token, "floating-point constant (%s) too small", expr->token->name); else error(expr->token, "floating-point constant (%s) higher than max value (%f)", expr->token->name, DBL_MAX); /* Note: negative numbers don't occur, as the - sign is parsed as a unary minus and not as part of the constant */ } } expr->type = new_simple_type(real_type); break; case expr_string_const: expr->type = new_array_type(new_simple_type(char_type)); EXPR_STRING_CONST(expr).length = check_string_const(expr->token); EXPR_STRING_CONST(expr).index = list_size(string_list); list_append(string_list, expr); break; case expr_null: expr->type = new_null_type(); break; case expr_and: case expr_or: match_type(expr->operand [0], bool_type, "bool"); match_type(expr->operand [1], bool_type, "bool"); expr->type = new_simple_type(bool_type); break; case expr_div: case expr_min: case expr_mul: case expr_plus: expr->type = match_type(expr->operand [0], arithmetic_type, "arithmetic"); match_type(expr->operand [1], arithmetic_type, "arithmetic"); check_operands_compatibility(expr); /*add important????????*/ inc_ref_count(expr->type, 1); break; case expr_eq: case expr_ne: match_type(expr->operand [0], basic_or_ref_type, "basic or reference"); match_type(expr->operand [1], basic_or_ref_type, "basic or reference"); check_operands_compatibility(expr); expr->type = new_simple_type(bool_type); break; case expr_ge: case expr_gt: case expr_se: case expr_st: match_type(expr->operand [0], scalar_type, "scalar"); match_type(expr->operand [1], scalar_type, "scalar"); check_operands_compatibility(expr); expr->type = new_simple_type(bool_type); break; case expr_not: match_type(expr->operand [0], bool_type, "bool"); expr->type = new_simple_type(bool_type); break; case expr_unary_min: case expr_unary_plus: expr->type = match_type(expr->operand [0], arithmetic_type, "arithmetic"); inc_ref_count(expr->type, 1); break; case expr_ident: type_check_identifier(expr); break; case expr_new: match_type(expr->operand [0], int_type, "int"); break; case expr_index: if ((type = match_type(expr->operand[0], array_type, "array")) != 0) { expr->type = ARRAY_TYPE(type).base_type; inc_ref_count(expr->type, 1); } match_type(expr->operand [1], int_type, "int"); break; case expr_size: match_type(expr->operand [0], array_type, "array"); expr->type = new_simple_type(int_type); break; case expr_func_call: type_check_function_call(expr); break; case expr_record: /* add : check expression of record */ type_check_expr_record(expr); break; } return expr->type;}static void generate_prefix_operator(Expression *expr, const char *symbol){ fprintf(c_out, "(%s", symbol); generate_expression(expr->operand [0]); putc(')', c_out);}static void generate_infix_operator(Expression *expr, const char *symbol){ putc('(', c_out); generate_expression(expr->operand [0]); fprintf(c_out, "%s", symbol); generate_expression(expr->operand [1]); putc(')', c_out);}static void generate_identifier(Expression *expr){ fprintf(c_out, expr->type->call_by_ref ? "(*cb_%s)" : "cb_%s", expr->token->name);}static void generate_new_expression(Expression *expr){ fprintf(c_out, "new_array("); generate_expression(expr->operand [0]); fprintf(c_out, ",sizeof("); generate_type(c_out, ARRAY_TYPE(expr->type).base_type); fprintf(c_out, "))");}static void generate_index_operation(Expression *expr){ Type *base_type = ARRAY_TYPE(expr->operand [0]->type).base_type; fprintf(c_out, "(*("); generate_type(c_out, base_type); fprintf(c_out, "*)array_index("); generate_expression(expr->operand [0]); fprintf(c_out, ",sizeof("); generate_type(c_out, base_type); fprintf(c_out, "),"); generate_expression(expr->operand [1]); fprintf(c_out, "))");}static void generate_size_operation(Expression *expr){ fprintf(c_out, "array_size("); generate_expression(expr->operand [0]); fprintf(c_out, ")");}static void generate_function_call(Expression *expr){ unsigned i; List *formal_args = EXPR_FUNC_CALL(expr).formal_args; List *actual_args = EXPR_FUNC_CALL(expr).actual_args; generate_expression(expr->operand [0]); putc('(', c_out); for (i = 0; i < list_size(actual_args); i ++) { Expression *actual_arg = list_index(actual_args, i); Declaration *formal_arg = list_index(formal_args, i); if (i > 0) putc(',', c_out); if (VAR_DECL(formal_arg).type->call_by_ref) putc('&', c_out); generate_expression(actual_arg); } putc(')', c_out);}/*add : create C code for expression of record */static void generate_record_expression(Expression *expr){ if(expr->operand[0]!=0) { fprintf(c_out,"("); generate_expression(expr->operand[0]); fprintf(c_out,")."); } fprintf(c_out,"cb_%s",expr->token->name);}void generate_expression(Expression *expr){ switch (expr->subtype) { case expr_and: generate_infix_operator(expr, "&&"); break; case expr_bool_const: putc(strcmp(expr->token->name, "true") == 0 ? '1' : '0', c_out); break; case expr_char_const: fprintf(c_out, "%s", expr->token->name); break; case expr_int_const: fprintf(c_out, "%s", expr->token->name); break; case expr_real_const: fprintf(c_out, "%s", expr->token->name); break; case expr_div: generate_infix_operator(expr, "/"); break; case expr_eq: generate_infix_operator(expr, "=="); break; case expr_func_call: generate_function_call(expr); break; case expr_ge: generate_infix_operator(expr, ">="); break; case expr_gt: generate_infix_operator(expr, ">"); break; case expr_ident: generate_identifier(expr); break; case expr_index: generate_index_operation(expr); break; case expr_min: generate_infix_operator(expr, "-"); break; case expr_mul: generate_infix_operator(expr, "*"); break; case expr_ne: generate_infix_operator(expr, "!="); break; case expr_new: generate_new_expression(expr); break; case expr_not: generate_prefix_operator(expr, "!"); break; case expr_null: putc('0', c_out); break; case expr_or: generate_infix_operator(expr, "||"); break; case expr_plus: generate_infix_operator(expr, "+"); break; case expr_se: generate_infix_operator(expr, "<="); break; case expr_size: generate_size_operation(expr); break; case expr_st: generate_infix_operator(expr, "<"); break; case expr_string_const: fprintf(c_out, "(strings[%u].a)", EXPR_STRING_CONST(expr).index); break; case expr_unary_min: generate_prefix_operator(expr, "-"); break; case expr_unary_plus: generate_expression(expr->operand [0]); break; case expr_record:/* add : create expression of record */ generate_record_expression(expr); break; }}/* Called directly from main.c to generate the array of string constants. */void generate_string_list(void){ unsigned i; fprintf(c_out, "struct strings strings [] = {\n"); for (i = 0; i < list_size(string_list); i ++) { Expression *str = (Expression *) list_index(string_list, i); fprintf(c_out, "{0,%d,%s},\n", EXPR_STRING_CONST(str).length, str->token->name); } fprintf(c_out, "{0,0,0}};\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -