diff options
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 151 |
1 files changed, 82 insertions, 69 deletions
@@ -23,10 +23,6 @@ void fatal_error(char* msg) { exit(1); } -void todo() { - fatal_error("todo"); -} - int read_all(char* buf) { int c; int n = 0; @@ -97,6 +93,8 @@ struct Token* tokenize(char* src, int len) { struct Define* defines = calloc(1024, sizeof(struct Define)); struct Define* def = defines; int pos = 0; + int ch; + int start; for (0; pos < len; 0) { char c = src[pos]; if (c == '(') { @@ -217,7 +215,7 @@ struct Token* tokenize(char* src, int len) { } } else if (c == '\'') { pos = pos + 1; - int ch = src[pos]; + ch = src[pos]; if (ch == '\\') { pos = pos + 1; ch = src[pos]; @@ -232,9 +230,9 @@ struct Token* tokenize(char* src, int len) { tok = tok + 1; } else if (c == '"') { pos = pos + 1; - int start = pos; + start = pos; for (0; 1; 0) { - int ch = src[pos]; + ch = src[pos]; if (ch == '\\') { pos = pos + 1; } else if (ch == '"') { @@ -248,7 +246,7 @@ struct Token* tokenize(char* src, int len) { pos = pos + 1; tok = tok + 1; } else if (isdigit(c)) { - int start = pos; + start = pos; for (0; isdigit(src[pos]); 0) { pos = pos + 1; } @@ -257,38 +255,38 @@ struct Token* tokenize(char* src, int len) { memcpy(tok->value, src + start, pos - start); tok = tok + 1; } else if (isalpha(c)) { - int start = pos; + start = pos; for (0; isalnum(src[pos]) || src[pos] == '_'; 0) { pos = pos + 1; } - int len = pos - start; - if (len == 5 && strstr(src + start, "break") == src + start) { + int ident_len = pos - start; + if (ident_len == 5 && strstr(src + start, "break") == src + start) { tok->kind = TK_K_BREAK; - } else if (len == 4 && strstr(src + start, "char") == src + start) { + } else if (ident_len == 4 && strstr(src + start, "char") == src + start) { tok->kind = TK_K_CHAR; - } else if (len == 8 && strstr(src + start, "continue") == src + start) { + } else if (ident_len == 8 && strstr(src + start, "continue") == src + start) { tok->kind = TK_K_CONTINUE; - } else if (len == 4 && strstr(src + start, "else") == src + start) { + } else if (ident_len == 4 && strstr(src + start, "else") == src + start) { tok->kind = TK_K_ELSE; - } else if (len == 3 && strstr(src + start, "for") == src + start) { + } else if (ident_len == 3 && strstr(src + start, "for") == src + start) { tok->kind = TK_K_FOR; - } else if (len == 2 && strstr(src + start, "if") == src + start) { + } else if (ident_len == 2 && strstr(src + start, "if") == src + start) { tok->kind = TK_K_IF; - } else if (len == 3 && strstr(src + start, "int") == src + start) { + } else if (ident_len == 3 && strstr(src + start, "int") == src + start) { tok->kind = TK_K_INT; - } else if (len == 4 && strstr(src + start, "long") == src + start) { + } else if (ident_len == 4 && strstr(src + start, "long") == src + start) { tok->kind = TK_K_LONG; - } else if (len == 6 && strstr(src + start, "return") == src + start) { + } else if (ident_len == 6 && strstr(src + start, "return") == src + start) { tok->kind = TK_K_RETURN; - } else if (len == 6 && strstr(src + start, "sizeof") == src + start) { + } else if (ident_len == 6 && strstr(src + start, "sizeof") == src + start) { tok->kind = TK_K_SIZEOF; - } else if (len == 6 && strstr(src + start, "struct") == src + start) { + } else if (ident_len == 6 && strstr(src + start, "struct") == src + start) { tok->kind = TK_K_STRUCT; - } else if (len == 4 && strstr(src + start, "void") == src + start) { + } else if (ident_len == 4 && strstr(src + start, "void") == src + start) { tok->kind = TK_K_VOID; } else { - tok->value = calloc(len + 1, sizeof(char)); - memcpy(tok->value, src + start, len); + tok->value = calloc(ident_len + 1, sizeof(char)); + memcpy(tok->value, src + start, ident_len); int i = 0; for (0; defines + i != def; 0) { if (strcmp(tok->value, defines[i].from) == 0) { @@ -311,7 +309,7 @@ struct Token* tokenize(char* src, int len) { for (0; isspace(src[pos]); 0) { pos = pos + 1; } - int start = pos; + start = pos; for (0; isalnum(src[pos]) || src[pos] == '_'; 0) { pos = pos + 1; } @@ -501,6 +499,7 @@ struct AstNode* ast_new_assign_expr(int op, struct AstNode* lhs, struct AstNode* int type_sizeof_struct(struct Type* ty) { int next_offset = 0; int struct_align = 0; + int padding; struct AstNode* member = ty->struct_def->node1->next; for (0; member; 0) { @@ -508,7 +507,7 @@ int type_sizeof_struct(struct Type* ty) { int align = type_alignof(member->ty); if (next_offset % align != 0) { - int padding = align - next_offset % align; + padding = align - next_offset % align; next_offset = next_offset + padding; } next_offset = next_offset + size; @@ -519,7 +518,7 @@ int type_sizeof_struct(struct Type* ty) { member = member->next; } if (next_offset % struct_align != 0) { - int padding = struct_align - next_offset % struct_align; + padding = struct_align - next_offset % struct_align; next_offset = next_offset + padding; } return next_offset; @@ -677,28 +676,30 @@ int register_str_lit(struct Parser* p, char* s) { struct AstNode* parse_primary_expr(struct Parser* p) { struct Token* t = next_token(p); + struct AstNode* e; + char* buf; if (t->kind == TK_L_INT) { - struct AstNode* e = ast_new(AST_INT_LIT_EXPR); + e = ast_new(AST_INT_LIT_EXPR); e->int_value = atoi(t->value); e->ty = type_new(TY_INT); return e; } else if (t->kind == TK_L_STR) { int str_lit_index = register_str_lit(p, t->value); - struct AstNode* e = ast_new(AST_STR_LIT_EXPR); + e = ast_new(AST_STR_LIT_EXPR); e->int_value = str_lit_index; return e; } else if (t->kind == TK_PAREN_L) { - struct AstNode* e = parse_expr(p); + e = parse_expr(p); expect(p, TK_PAREN_R); return e; } else if (t->kind == TK_IDENT) { char* name = t->value; if (peek_token(p)->kind == TK_PAREN_L) { - struct AstNode* e = ast_new(AST_FUNC_CALL); + e = ast_new(AST_FUNC_CALL); int func_index = find_func(p, name); if (func_index == -1) { - char* buf = calloc(1024, sizeof(char)); + buf = calloc(1024, sizeof(char)); sprintf(buf, "undefined function: %s", name); fatal_error(buf); } @@ -709,18 +710,18 @@ struct AstNode* parse_primary_expr(struct Parser* p) { int var_index = find_lvar(p, name); if (var_index == -1) { - char* buf = calloc(1024, sizeof(char)); + buf = calloc(1024, sizeof(char)); sprintf(buf, "undefined variable: %s", name); fatal_error(buf); } - struct AstNode* e = ast_new(AST_LVAR); + e = ast_new(AST_LVAR); e->name = name; e->var_index = var_index; e->ty = p->locals[var_index].ty; return e; } else { - char* buf = calloc(1024, sizeof(char)); + buf = calloc(1024, sizeof(char)); sprintf(buf, "expected primary expression, but got %d", t->kind); fatal_error(buf); } @@ -744,6 +745,11 @@ struct AstNode* parse_arg_list(struct Parser* p) { struct AstNode* parse_postfix_expr(struct Parser* p) { struct AstNode* ret = parse_primary_expr(p); + struct AstNode* e; + struct AstNode* ptr_expr; + struct AstNode* offset_node; + int offset; + char* name; for (0; 1; 0) { int tk = peek_token(p)->kind; if (tk == TK_PAREN_L) { @@ -756,8 +762,8 @@ struct AstNode* parse_postfix_expr(struct Parser* p) { struct AstNode* idx = parse_expr(p); expect(p, TK_BRACKET_R); - struct AstNode* e = ast_new(AST_DEREF_EXPR); - struct AstNode* ptr_expr = ast_new_binary_expr(TK_PLUS, ret, idx); + e = ast_new(AST_DEREF_EXPR); + ptr_expr = ast_new_binary_expr(TK_PLUS, ret, idx); ptr_expr->ty = ret->ty; e->expr1 = ptr_expr; e->ty = ret->ty->to; @@ -765,17 +771,17 @@ struct AstNode* parse_postfix_expr(struct Parser* p) { ret = e; } else if (tk == TK_DOT) { next_token(p); - char* name = parse_ident(p); + name = parse_ident(p); - struct AstNode* e = ast_new(AST_DEREF_EXPR); + e = ast_new(AST_DEREF_EXPR); struct AstNode* ref_of_ret = ast_new(AST_REF_EXPR); ref_of_ret->expr1 = ret; ref_of_ret->ty = type_new_ptr(ret->ty); - int offset = type_offsetof(ret->ty, name); - struct AstNode* offset_node = ast_new(AST_OFFSETOF); + offset = type_offsetof(ret->ty, name); + offset_node = ast_new(AST_OFFSETOF); offset_node->int_value = offset; offset_node->ty = type_new(TY_INT); - struct AstNode* ptr_expr = ast_new_binary_expr(TK_PLUS, ref_of_ret, offset_node); + ptr_expr = ast_new_binary_expr(TK_PLUS, ref_of_ret, offset_node); ptr_expr->ty = ref_of_ret->ty; e->expr1 = ptr_expr; e->ty = type_member_typeof(ret->ty, name); @@ -783,14 +789,14 @@ struct AstNode* parse_postfix_expr(struct Parser* p) { ret = e; } else if (tk == TK_ARROW) { next_token(p); - char* name = parse_ident(p); + name = parse_ident(p); - struct AstNode* e = ast_new(AST_DEREF_EXPR); - int offset = type_offsetof(ret->ty->to, name); - struct AstNode* offset_node = ast_new(AST_OFFSETOF); + e = ast_new(AST_DEREF_EXPR); + offset = type_offsetof(ret->ty->to, name); + offset_node = ast_new(AST_OFFSETOF); offset_node->int_value = offset; offset_node->ty = type_new(TY_INT); - struct AstNode* ptr_expr = ast_new_binary_expr(TK_PLUS, ret, offset_node); + ptr_expr = ast_new_binary_expr(TK_PLUS, ret, offset_node); ptr_expr->ty = ret->ty; e->expr1 = ptr_expr; e->ty = type_member_typeof(ret->ty->to, name); @@ -809,8 +815,9 @@ int is_type_token(int token_kind) { struct Type* parse_type(struct Parser* p) { struct Token* t = next_token(p); + char* buf; if (!is_type_token(t->kind)) { - char* buf = calloc(1024, sizeof(char)); + buf = calloc(1024, sizeof(char)); sprintf(buf, "parse_type: unknown type, %d", t->kind); fatal_error(buf); } @@ -833,7 +840,7 @@ struct Type* parse_type(struct Parser* p) { } } if (struct_index == p->n_structs) { - char* buf = calloc(1024, sizeof(char)); + buf = calloc(1024, sizeof(char)); sprintf(buf, "parse_type: unknown struct, %s", name); fatal_error(buf); } @@ -854,33 +861,35 @@ struct Type* parse_type(struct Parser* p) { } struct AstNode* parse_prefix_expr(struct Parser* p) { + struct AstNode* e; + struct AstNode* operand; int op = peek_token(p)->kind; if (op == TK_MINUS) { next_token(p); - struct AstNode* operand = parse_prefix_expr(p); + operand = parse_prefix_expr(p); struct AstNode* lhs = ast_new(AST_INT_LIT_EXPR); lhs->int_value = 0; lhs->ty = type_new(TY_INT); - struct AstNode* e = ast_new_binary_expr(op, lhs, operand); + e = ast_new_binary_expr(op, lhs, operand); e->ty = type_new(TY_INT); return e; } else if (op == TK_NOT) { next_token(p); - struct AstNode* operand = parse_prefix_expr(p); - struct AstNode* e = ast_new_unary_expr(op, operand); + operand = parse_prefix_expr(p); + e = ast_new_unary_expr(op, operand); e->ty = type_new(TY_INT); return e; } else if (op == TK_AND) { next_token(p); - struct AstNode* operand = parse_prefix_expr(p); - struct AstNode* e = ast_new(AST_REF_EXPR); + operand = parse_prefix_expr(p); + e = ast_new(AST_REF_EXPR); e->expr1 = operand; e->ty = type_new_ptr(operand->ty); return e; } else if (op == TK_STAR) { next_token(p); - struct AstNode* operand = parse_prefix_expr(p); - struct AstNode* e = ast_new(AST_DEREF_EXPR); + operand = parse_prefix_expr(p); + e = ast_new(AST_DEREF_EXPR); e->expr1 = operand; e->ty = operand->ty->to; return e; @@ -889,7 +898,7 @@ struct AstNode* parse_prefix_expr(struct Parser* p) { expect(p, TK_PAREN_L); struct Type* ty = parse_type(p); expect(p, TK_PAREN_R); - struct AstNode* e = ast_new(AST_INT_LIT_EXPR); + e = ast_new(AST_INT_LIT_EXPR); e->int_value = type_sizeof(ty); e->ty = type_new(TY_INT); return e; @@ -915,12 +924,13 @@ struct AstNode* parse_multiplicative_expr(struct Parser* p) { struct AstNode* parse_additive_expr(struct Parser* p) { struct AstNode* lhs = parse_multiplicative_expr(p); + struct AstNode* rhs; + struct Type* result_type; for (0; 1; 0) { int op = peek_token(p)->kind; if (op == TK_PLUS) { next_token(p); - struct AstNode* rhs = parse_multiplicative_expr(p); - struct Type* result_type; + rhs = parse_multiplicative_expr(p); if (lhs->ty->kind == TY_PTR) { result_type = lhs->ty; } else if (rhs->ty->kind == TY_PTR) { @@ -932,8 +942,7 @@ struct AstNode* parse_additive_expr(struct Parser* p) { lhs->ty = result_type; } else if (op == TK_MINUS) { next_token(p); - struct AstNode* rhs = parse_multiplicative_expr(p); - struct Type* result_type; + rhs = parse_multiplicative_expr(p); if (lhs->ty->kind == TY_PTR) { result_type = lhs->ty; } else { @@ -950,21 +959,22 @@ struct AstNode* parse_additive_expr(struct Parser* p) { struct AstNode* parse_relational_expr(struct Parser* p) { struct AstNode* lhs = parse_additive_expr(p); + struct AstNode* rhs; for (0; 1; 0) { int op = peek_token(p)->kind; if (op == TK_LT || op == TK_LE) { next_token(p); - struct AstNode* rhs = parse_additive_expr(p); + rhs = parse_additive_expr(p); lhs = ast_new_binary_expr(op, lhs, rhs); lhs->ty = type_new(TY_INT); } else if (op == TK_GT) { next_token(p); - struct AstNode* rhs = parse_additive_expr(p); + rhs = parse_additive_expr(p); lhs = ast_new_binary_expr(TK_LT, rhs, lhs); lhs->ty = type_new(TY_INT); } else if (op == TK_GE) { next_token(p); - struct AstNode* rhs = parse_additive_expr(p); + rhs = parse_additive_expr(p); lhs = ast_new_binary_expr(TK_LE, rhs, lhs); lhs->ty = type_new(TY_INT); } else { @@ -1438,7 +1448,7 @@ void gen_unary_expr(struct CodeGen* g, struct AstNode* ast) { printf(" movzb rax, al\n"); printf(" push rax\n"); } else { - todo(); + fatal_error("gen_unary_expr: unknown unary op"); } } @@ -1553,7 +1563,9 @@ void gen_binary_expr(struct CodeGen* g, struct AstNode* ast, int gen_mode) { printf(" setle al\n"); printf(" movzb rax, al\n"); } else { - fatal_error("gen_binary_expr: unknown op"); + char* buf = calloc(1024, sizeof(char)); + sprintf(buf, "gen_binary_expr: unknown op, %d", ast->op); + fatal_error(buf); } printf(" push rax\n"); } @@ -1570,7 +1582,7 @@ void gen_assign_expr(struct CodeGen* g, struct AstNode* ast) { printf(" mov [rax], rdi\n"); printf(" push rdi\n"); } else { - todo(); + fatal_error("gen_assign_expr: unknown assign op"); } } @@ -1587,7 +1599,8 @@ void gen_func_call(struct CodeGen* g, struct AstNode* ast) { gen_expr(g, arg, GEN_RVAL); arg = arg->next; } - for (int i = n_args - 1; i >= 0; i = i - 1) { + int i; + for (i = n_args - 1; i >= 0; i = i - 1) { if (i == 0) { printf(" pop rdi\n"); } else if (i == 1) { |
