📄 expression.c
字号:
#ifdef DEBUG printf("(%s", symbol); #endif generate_expression(expr->operand [0]); putc(')', c_out); printf(")");}static void generate_infix_operator(Expression *expr, const char *symbol){ putc('(', c_out); #ifdef DEBUG printf("("); #endif generate_expression(expr->operand [0]); fprintf(c_out, "%s", symbol); #ifdef DEBUG printf("%s", symbol); #endif generate_expression(expr->operand [1]); putc(')', c_out); #ifdef DEBUG printf(")"); #endif}static void generate_identifier(Expression *expr){ fprintf(c_out, expr->type->call_by_ref ? "(*cb_%s)" : "cb_%s", expr->token->name); #ifdef DEBUG printf(expr->type->call_by_ref ? "(*cb_%s)" : "cb_%s", expr->token->name); #endif}static void string_check_escapes(Token *t){ char *c = t->name; int i,inhex=-1; for (i=0;i<strlen(c);i++) { if (inhex!=-1) { if((c[i]>='A' && c[i]<='F') || (c[i]>='a' && c[i]<='f') || (c[i]>='0' && c[i]<='9')) inhex+=1; else { if (inhex>2) error(t,"Too long hex sequence"); inhex = -1; } } if (c[i]=='\\' && c[i+1]=='x') { inhex = 0; i++; continue; } } inhex=-1; for (i=0;i<strlen(c);i++) { if (inhex!=-1) { if(c[i]>='0' && c[i]<='7') inhex+=1; else { if (inhex>3) error(t,"Too long octal sequence"); inhex = -1; } } if (c[i]=='\\') { inhex = 0; continue; } } }static void generate_new_expression(Expression *expr){ fprintf(c_out, "new_array("); #ifdef DEBUG printf("new_array("); #endif generate_expression(expr->operand [0]); fprintf(c_out, ",sizeof("); #ifdef DEBUG printf(",sizeof("); #endif generate_type(c_out, ARRAY_TYPE(expr->type).base_type); fprintf(c_out, "))"); #ifdef DEBUG printf("))"); #endif}static void generate_index_operation(Expression *expr){ Type *base_type = ARRAY_TYPE(expr->operand [0]->type).base_type; fprintf(c_out, "(*("); #ifdef DEBUG printf("(*("); #endif generate_type(c_out, base_type); fprintf(c_out, "*)array_index("); #ifdef DEBUG printf("*)array_index("); #endif generate_expression(expr->operand [0]); fprintf(c_out, ",sizeof("); #ifdef DEBUG printf(",sizeof("); #endif generate_type(c_out, base_type); fprintf(c_out, "),"); #ifdef DEBUG printf("),"); #endif generate_expression(expr->operand [1]); fprintf(c_out, "))"); #ifdef DEBUG printf("))"); #endif}static void generate_size_operation(Expression *expr){ fprintf(c_out, "array_size("); #ifdef DEBUG printf("array_size("); #endif generate_expression(expr->operand [0]); fprintf(c_out, ")"); #ifdef DEBUG printf(")"); #endif}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); #ifdef DEBUG printf("("); #endif 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); #ifdef DEBUG printf(","); #endif } if (VAR_DECL(formal_arg).type->call_by_ref) { putc('&', c_out); #ifdef DEBUG printf("&"); #endif } generate_expression(actual_arg); } putc(')', c_out); #ifdef DEBUG printf(")"); #endif}static void generate_record_expr(Expression *expr){ generate_expression(expr->operand[0]); fprintf(c_out,".field_%s",expr->operand[1]->token->name); #ifdef DEBUG printf(".field_%s",expr->operand[1]->token->name); #endif}Scope *bepaal_scope(Expression *expr, Bool isrvalue){ Scope *temp; switch (expr->subtype) { case expr_ident: temp = EXPR_IDENT(expr).scope; break; case expr_index: temp = bepaal_scope(expr->operand[0],isrvalue); break; case expr_dot: temp = bepaal_scope(expr->operand[0],isrvalue); break; default: /* fprintf(asm_out,"case not covered bepaal_scope\n");*/ break; } return temp;}Token *bepaal_token(Expression *expr, Bool isrvalue){ Token *temp; switch (expr->subtype) { case expr_ident: temp = expr->token; break; case expr_index: temp = bepaal_token(expr->operand[0],isrvalue); break; case expr_dot: temp = bepaal_token(expr->operand[0],isrvalue); break; default: /* fprintf(asm_out,"case not covered bepaal_token\n");*/ error(expr->subtype, "Case not covered in bepaal_token"); break; } return temp;}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); #ifdef DEBUG printf("%c",strcmp(expr->token->name, "true") == 0 ? '1' : '0'); #endif break; case expr_char_const: fprintf(c_out, "%s", expr->token->name); #ifdef DEBUG printf("%s", expr->token->name); #endif break; case expr_int_const: { long 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); } fprintf(c_out, "%s", expr->token->name); #ifdef DEBUG printf("%s", expr->token->name); #endif break; case expr_real_const: { double test = strtod(expr->token->name, NULL); if (errno==ERANGE) { if (test == 0) error(expr->token, "Floating-point constant (%s) lower than min value (%f)", expr->token->name, DBL_MIN); else error(expr->token, "Floating-point constant (%s) higher than max value (%f)", expr->token->name, DBL_MAX); } } fprintf(c_out, "%s", expr->token->name); #ifdef DEBUG printf("%s", expr->token->name); #endif 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: fprintf(c_out, "("); #ifdef DEBUG printf("("); #endif generate_identifier(expr); fprintf(c_out, ")"); #ifdef DEBUG printf(")"); #endif 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); #ifdef DEBUG printf("0"); #endif 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); #ifdef DEBUG printf("(strings[%u].a)", EXPR_STRING_CONST(expr).index); #endif break; case expr_unary_min: generate_prefix_operator(expr, "-"); break; case expr_unary_plus: generate_expression(expr->operand [0]); break; case expr_dot: fprintf(c_out, "("); #ifdef DEBUG printf("("); #endif generate_record_expr(expr); fprintf(c_out, ")"); #ifdef DEBUG printf(")"); #endif break; }}static char *skip_hex_digits( char *str){ while (*str && isxdigit((int) *str)) str++; return str;}static char *skip_oct_digits( char *str, int max){ while (*str && max > 0 && '0' <= *str && *str <= '7') { str++; max--; } return str;}static int length( char *str){ assert( str != NULL); switch (str[0]) { case 0: return 0; case '\\': if (str[1] == 'x') { return 1+length(skip_hex_digits(str+2)); } else if ('0' <= str[1] && str[1] <= '1') { return 1+length(skip_oct_digits(str+2,2)); } else if ('2' <= str[1] && str[1] <= '7') { return 1+length(skip_oct_digits(str+2,1)); } else { return 1+length(str+2); } default: return 1+length(str+1); }}/* Called directly from main.c to generate the array of string constants. */void generate_string_list(void){ int i; fprintf(c_out, "struct strings strings [] = {\n"); #ifdef DEBUG printf("struct strings strings [] = {\n"); #endif for (i = 0; i < list_size(string_list); i ++) { char *str = (char *) list_index(string_list, i); fprintf(c_out, "{0,%d,%s},\n", length(str)-2, str); /* strip both " */ #ifdef DEBUG printf("{0,%d,%s},\n", length(str)-2, str); /* strip both " */ #endif } fprintf(c_out, "{0,0,0}\n};\n"); #ifdef DEBUG printf("{0,0,0}\n};\n"); #endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -