aboutsummaryrefslogtreecommitdiffhomepage
path: root/main.c
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-05-04 22:04:11 +0900
committernsfisis <nsfisis@gmail.com>2025-05-04 22:04:11 +0900
commit1cc373ebe04686d1b577f1b95859e2858f4a6663 (patch)
treef1d75ed52aee080e65756ec8a7eb45e8e7df583c /main.c
parentc47efd763eeb55bc9b7cc81187aca3fcd3bd52a0 (diff)
downloadP4Dcc-1cc373ebe04686d1b577f1b95859e2858f4a6663.tar.gz
P4Dcc-1cc373ebe04686d1b577f1b95859e2858f4a6663.tar.zst
P4Dcc-1cc373ebe04686d1b577f1b95859e2858f4a6663.zip
desugar a lot of things; now, p4dcc can parse main.c itself!
Diffstat (limited to 'main.c')
-rw-r--r--main.c151
1 files changed, 82 insertions, 69 deletions
diff --git a/main.c b/main.c
index dd8fa44..58677dc 100644
--- a/main.c
+++ b/main.c
@@ -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) {