aboutsummaryrefslogtreecommitdiffhomepage
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c489
1 files changed, 212 insertions, 277 deletions
diff --git a/main.c b/main.c
index 83f7a22..bb91a3b 100644
--- a/main.c
+++ b/main.c
@@ -19,18 +19,15 @@ void fatal_error(char* msg) {
exit(1);
}
-int read_all(char* buf) {
- int c;
- int n = 0;
+void read_all(char* buf) {
while (1) {
- c = getchar();
+ int c = getchar();
if (c == -1) {
break;
}
- buf[n] = c;
- n += 1;
+ *buf = c;
+ buf += 1;
}
- return n;
}
#define TK_EOF 0
@@ -90,7 +87,7 @@ struct Define {
struct Token* to;
};
-struct Token* tokenize(char* src, int len) {
+struct Token* tokenize(char* src) {
struct Token* tokens = calloc(1024*1024, sizeof(struct Token));
struct Token* tok = tokens;
struct Define* defines = calloc(1024, sizeof(struct Define));
@@ -98,136 +95,89 @@ struct Token* tokenize(char* src, int len) {
int pos = 0;
int ch;
int start;
- while (pos < len) {
+ while (src[pos]) {
char c = src[pos];
+ pos += 1;
if (c == '(') {
- pos += 1;
tok->kind = TK_PAREN_L;
- tok += 1;
} else if (c == ')') {
- pos += 1;
tok->kind = TK_PAREN_R;
- tok += 1;
} else if (c == '{') {
- pos += 1;
tok->kind = TK_BRACE_L;
- tok += 1;
} else if (c == '}') {
- pos += 1;
tok->kind = TK_BRACE_R;
- tok += 1;
} else if (c == '[') {
- pos += 1;
tok->kind = TK_BRACKET_L;
- tok += 1;
} else if (c == ']') {
- pos += 1;
tok->kind = TK_BRACKET_R;
- tok += 1;
} else if (c == ',') {
- pos += 1;
tok->kind = TK_COMMA;
- tok += 1;
} else if (c == ';') {
- pos += 1;
tok->kind = TK_SEMICOLON;
- tok += 1;
} else if (c == '+') {
- pos += 1;
if (src[pos] == '=') {
pos += 1;
tok->kind = TK_ASSIGN_ADD;
- tok += 1;
} else {
tok->kind = TK_PLUS;
- tok += 1;
}
} else if (c == '|') {
- pos += 2;
+ pos += 1;
tok->kind = TK_OROR;
- tok += 1;
} else if (c == '&') {
- pos += 1;
if (src[pos] == '&') {
pos += 1;
tok->kind = TK_ANDAND;
- tok += 1;
} else {
tok->kind = TK_AND;
- tok += 1;
}
} else if (c == '-') {
- pos += 1;
if (src[pos] == '>') {
pos += 1;
tok->kind = TK_ARROW;
- tok += 1;
} else if (src[pos] == '=') {
pos += 1;
tok->kind = TK_ASSIGN_SUB;
- tok += 1;
} else {
tok->kind = TK_MINUS;
- tok += 1;
}
} else if (c == '*') {
- pos += 1;
tok->kind = TK_STAR;
- tok += 1;
} else if (c == '/') {
- pos += 1;
tok->kind = TK_SLASH;
- tok += 1;
} else if (c == '%') {
- pos += 1;
tok->kind = TK_PERCENT;
- tok += 1;
} else if (c == '.') {
- pos += 1;
tok->kind = TK_DOT;
- tok += 1;
} else if (c == '!') {
- pos += 1;
if (src[pos] == '=') {
pos += 1;
tok->kind = TK_NE;
- tok += 1;
} else {
tok->kind = TK_NOT;
- tok += 1;
}
} else if (c == '=') {
- pos += 1;
if (src[pos] == '=') {
pos += 1;
tok->kind = TK_EQ;
- tok += 1;
} else {
tok->kind = TK_ASSIGN;
- tok += 1;
}
} else if (c == '<') {
- pos += 1;
if (src[pos] == '=') {
pos += 1;
tok->kind = TK_LE;
- tok += 1;
} else {
tok->kind = TK_LT;
- tok += 1;
}
} else if (c == '>') {
- pos += 1;
if (src[pos] == '=') {
pos += 1;
tok->kind = TK_GE;
- tok += 1;
} else {
tok->kind = TK_GT;
- tok += 1;
}
} else if (c == '\'') {
- pos += 1;
ch = src[pos];
if (ch == '\\') {
pos += 1;
@@ -240,9 +190,7 @@ struct Token* tokenize(char* src, int len) {
tok->kind = TK_L_INT;
tok->value = calloc(4, sizeof(char));
sprintf(tok->value, "%d", ch);
- tok += 1;
} else if (c == '"') {
- pos += 1;
start = pos;
while (1) {
ch = src[pos];
@@ -257,8 +205,8 @@ struct Token* tokenize(char* src, int len) {
tok->value = calloc(pos - start + 1, sizeof(char));
memcpy(tok->value, src + start, pos - start);
pos += 1;
- tok += 1;
} else if (isdigit(c)) {
+ pos -= 1;
start = pos;
while (isdigit(src[pos])) {
pos += 1;
@@ -266,8 +214,8 @@ struct Token* tokenize(char* src, int len) {
tok->kind = TK_L_INT;
tok->value = calloc(pos - start + 1, sizeof(char));
memcpy(tok->value, src + start, pos - start);
- tok += 1;
} else if (isalpha(c)) {
+ pos -= 1;
start = pos;
while (isalnum(src[pos]) || src[pos] == '_') {
pos += 1;
@@ -315,11 +263,9 @@ struct Token* tokenize(char* src, int len) {
tok->kind = TK_IDENT;
}
}
- tok += 1;
} else if (isspace(c)) {
- pos += 1;
+ continue;
} else if (c == '#') {
- pos += 1;
pos += 6;
while (isspace(src[pos])) {
pos += 1;
@@ -353,11 +299,13 @@ struct Token* tokenize(char* src, int len) {
def->to->value = calloc(pos - start2 + 1, sizeof(char));
memcpy(def->to->value, src + start2, pos - start2);
def += 1;
+ continue;
} else {
char* buf = calloc(1024, sizeof(char));
sprintf(buf, "!!! %d", c);
fatal_error(buf);
}
+ tok += 1;
}
return tokens;
}
@@ -392,7 +340,7 @@ struct Type* type_new_ptr(struct Type* to) {
return ty;
}
-int type_is_unsized_type(struct Type* ty) {
+int type_is_unsized(struct Type* ty) {
return ty->kind != TY_VOID;
}
@@ -400,7 +348,7 @@ int type_sizeof_struct(struct Type* ty);
int type_alignof_struct(struct Type* ty);
int type_sizeof(struct Type* ty) {
- if (!type_is_unsized_type(ty)) {
+ if (!type_is_unsized(ty)) {
fatal_error("type_sizeof: type size cannot be determined");
}
@@ -418,7 +366,7 @@ int type_sizeof(struct Type* ty) {
}
int type_alignof(struct Type* ty) {
- if (!type_is_unsized_type(ty)) {
+ if (!type_is_unsized(ty)) {
fatal_error("type_alignof: type size cannot be determined");
}
@@ -451,8 +399,8 @@ int type_alignof(struct Type* ty) {
#define AST_FUNC_DEF 12
#define AST_IF_STMT 13
#define AST_INT_LIT_EXPR 14
-#define AST_LVAR 15
-#define AST_OFFSETOF 16
+#define AST_LOGICAL_EXPR 15
+#define AST_LVAR 16
#define AST_PARAM 17
#define AST_PARAM_LIST 18
#define AST_PROGRAM 19
@@ -467,22 +415,38 @@ int type_alignof(struct Type* ty) {
#define AST_UNARY_EXPR 28
#define AST_VAR_DECL 29
+#define node_next next
+#define node_last last
+#define node_lhs expr1
+#define node_rhs expr2
+#define node_operand expr1
+#define node_cond expr1
+#define node_init expr2
+#define node_update expr3
+#define node_then expr2
+#define node_else expr3
+#define node_body expr4
+#define node_members expr1
+#define node_params expr1
+#define node_int_value ival
+#define node_index ival
+#define node_op ival
+
struct AstNode {
int kind;
struct AstNode* next;
struct AstNode* last;
char* name;
- struct AstNode* func_params;
- struct AstNode* func_body;
- int int_value;
struct AstNode* expr1;
struct AstNode* expr2;
struct AstNode* expr3;
- int op;
+ struct AstNode* expr4;
+ int ival;
struct Type* ty;
- int var_index;
- struct AstNode* node1;
- struct AstNode* node2;
+};
+
+struct Program {
+ struct AstNode* funcs;
char** str_literals;
};
@@ -497,36 +461,36 @@ struct AstNode* ast_new_list(int kind) {
fatal_error("ast_new_list: non-list ast");
}
struct AstNode* ast = ast_new(kind);
- ast->last = ast;
+ ast->node_last = ast;
return ast;
}
struct AstNode* ast_new_unary_expr(int op, struct AstNode* operand) {
struct AstNode* e = ast_new(AST_UNARY_EXPR);
- e->op = op;
- e->expr1 = operand;
+ e->node_op = op;
+ e->node_operand = operand;
return e;
}
struct AstNode* ast_new_binary_expr(int op, struct AstNode* lhs, struct AstNode* rhs) {
struct AstNode* e = ast_new(AST_BINARY_EXPR);
- e->op = op;
- e->expr1 = lhs;
- e->expr2 = rhs;
+ e->node_op = op;
+ e->node_lhs = lhs;
+ e->node_rhs = rhs;
return e;
}
struct AstNode* ast_new_assign_expr(int op, struct AstNode* lhs, struct AstNode* rhs) {
struct AstNode* e = ast_new(AST_ASSIGN_EXPR);
- e->op = op;
- e->expr1 = lhs;
- e->expr2 = rhs;
+ e->node_op = op;
+ e->node_lhs = lhs;
+ e->node_rhs = rhs;
return e;
}
struct AstNode* ast_new_int_lit(int v) {
struct AstNode* e = ast_new(AST_INT_LIT_EXPR);
- e->int_value = v;
+ e->node_int_value = v;
e->ty = type_new(TY_INT);
return e;
}
@@ -536,7 +500,7 @@ int type_sizeof_struct(struct Type* ty) {
int struct_align = 0;
int padding;
- struct AstNode* member = ty->struct_def->node1->next;
+ struct AstNode* member = ty->struct_def->node_members->node_next;
while (member) {
int size = type_sizeof(member->ty);
int align = type_alignof(member->ty);
@@ -550,7 +514,7 @@ int type_sizeof_struct(struct Type* ty) {
struct_align = align;
}
- member = member->next;
+ member = member->node_next;
}
if (next_offset % struct_align != 0) {
padding = struct_align - next_offset % struct_align;
@@ -562,7 +526,7 @@ int type_sizeof_struct(struct Type* ty) {
int type_alignof_struct(struct Type* ty) {
int struct_align = 0;
- struct AstNode* member = ty->struct_def->node1->next;
+ struct AstNode* member = ty->struct_def->node_members->node_next;
while (member) {
int align = type_alignof(member->ty);
@@ -570,7 +534,7 @@ int type_alignof_struct(struct Type* ty) {
struct_align = align;
}
- member = member->next;
+ member = member->node_next;
}
return struct_align;
}
@@ -582,7 +546,7 @@ int type_offsetof(struct Type* ty, char* name) {
int next_offset = 0;
- struct AstNode* member = ty->struct_def->node1->next;
+ struct AstNode* member = ty->struct_def->node_members->node_next;
while (member) {
int size = type_sizeof(member->ty);
int align = type_alignof(member->ty);
@@ -596,7 +560,7 @@ int type_offsetof(struct Type* ty, char* name) {
}
next_offset += size;
- member = member->next;
+ member = member->node_next;
}
fatal_error("type_offsetof: member not found");
@@ -607,12 +571,12 @@ struct Type* type_member_typeof(struct Type* ty, char* name) {
fatal_error("type_offsetof: type is not a struct");
}
- struct AstNode* member = ty->struct_def->node1->next;
+ struct AstNode* member = ty->struct_def->node_members->node_next;
while (member) {
if (strcmp(member->name, name) == 0) {
return member->ty;
}
- member = member->next;
+ member = member->node_next;
}
fatal_error("type_offsetof: member not found");
@@ -718,7 +682,7 @@ struct AstNode* parse_primary_expr(struct Parser* p) {
} else if (t->kind == TK_L_STR) {
int str_lit_index = register_str_lit(p, t->value);
e = ast_new(AST_STR_LIT_EXPR);
- e->int_value = str_lit_index;
+ e->node_index = str_lit_index;
return e;
} else if (t->kind == TK_PAREN_L) {
e = parse_expr(p);
@@ -749,7 +713,7 @@ struct AstNode* parse_primary_expr(struct Parser* p) {
e = ast_new(AST_LVAR);
e->name = name;
- e->var_index = var_index;
+ e->node_index = var_index;
e->ty = p->locals[var_index].ty;
return e;
} else {
@@ -763,10 +727,9 @@ struct AstNode* parse_arg_list(struct Parser* p) {
struct AstNode* list = ast_new_list(AST_ARG_LIST);
while (peek_token(p)->kind != TK_PAREN_R) {
struct AstNode* arg = parse_expr(p);
- list->last->next = arg;
- list->last = arg;
- int tk = peek_token(p)->kind;
- if (tk == TK_COMMA) {
+ list->node_last->node_next = arg;
+ list->node_last = arg;
+ if (peek_token(p)->kind == TK_COMMA) {
next_token(p);
} else {
break;
@@ -779,8 +742,6 @@ 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;
while (1) {
int tk = peek_token(p)->kind;
@@ -795,6 +756,8 @@ struct AstNode* parse_postfix_expr(struct Parser* p) {
expect(p, TK_BRACKET_R);
e = ast_new(AST_DEREF_EXPR);
+ idx = ast_new_binary_expr(TK_STAR, idx, ast_new_int_lit(type_sizeof(ret->ty->to)));
+ idx->ty = type_new(TY_INT);
ptr_expr = ast_new_binary_expr(TK_PLUS, ret, idx);
ptr_expr->ty = ret->ty;
e->expr1 = ptr_expr;
@@ -809,11 +772,7 @@ struct AstNode* parse_postfix_expr(struct Parser* p) {
struct AstNode* ref_of_ret = ast_new(AST_REF_EXPR);
ref_of_ret->expr1 = ret;
ref_of_ret->ty = type_new_ptr(ret->ty);
- offset = type_offsetof(ret->ty, name);
- offset_node = ast_new(AST_OFFSETOF);
- offset_node->int_value = offset;
- offset_node->ty = type_new(TY_INT);
- ptr_expr = ast_new_binary_expr(TK_PLUS, ref_of_ret, offset_node);
+ ptr_expr = ast_new_binary_expr(TK_PLUS, ref_of_ret, ast_new_int_lit(type_offsetof(ret->ty, name)));
ptr_expr->ty = ref_of_ret->ty;
e->expr1 = ptr_expr;
e->ty = type_member_typeof(ret->ty, name);
@@ -824,11 +783,7 @@ struct AstNode* parse_postfix_expr(struct Parser* p) {
name = parse_ident(p);
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);
- ptr_expr = ast_new_binary_expr(TK_PLUS, ret, offset_node);
+ ptr_expr = ast_new_binary_expr(TK_PLUS, ret, ast_new_int_lit(type_offsetof(ret->ty->to, name)));
ptr_expr->ty = ret->ty;
e->expr1 = ptr_expr;
e->ty = type_member_typeof(ret->ty->to, name);
@@ -881,8 +836,7 @@ struct Type* parse_type(struct Parser* p) {
fatal_error("unreachable");
}
while (1) {
- struct Token* t2 = peek_token(p);
- if (t2->kind == TK_STAR) {
+ if (peek_token(p)->kind == TK_STAR) {
next_token(p);
ty = type_new_ptr(ty);
} else {
@@ -912,14 +866,14 @@ struct AstNode* parse_prefix_expr(struct Parser* p) {
next_token(p);
operand = parse_prefix_expr(p);
e = ast_new(AST_REF_EXPR);
- e->expr1 = operand;
+ e->node_operand = operand;
e->ty = type_new_ptr(operand->ty);
return e;
} else if (op == TK_STAR) {
next_token(p);
operand = parse_prefix_expr(p);
e = ast_new(AST_DEREF_EXPR);
- e->expr1 = operand;
+ e->node_operand = operand;
e->ty = operand->ty->to;
return e;
} else if (op == TK_K_SIZEOF) {
@@ -959,23 +913,32 @@ struct AstNode* parse_additive_expr(struct Parser* p) {
rhs = parse_multiplicative_expr(p);
if (lhs->ty->kind == TY_PTR) {
result_type = lhs->ty;
+ rhs = ast_new_binary_expr(TK_STAR, rhs, ast_new_int_lit(type_sizeof(lhs->ty->to)));
+ rhs->ty = type_new(TY_INT);
+ lhs = ast_new_binary_expr(op, lhs, rhs);
+ lhs->ty = result_type;
} else if (rhs->ty->kind == TY_PTR) {
- result_type = rhs->ty;
+ lhs = ast_new_binary_expr(TK_STAR, lhs, ast_new_int_lit(type_sizeof(rhs->ty->to)));
+ lhs->ty = type_new(TY_INT);
+ lhs = ast_new_binary_expr(op, lhs, rhs);
+ lhs->ty = rhs->ty;
} else {
- result_type = type_new(TY_INT);
+ lhs = ast_new_binary_expr(op, lhs, rhs);
+ lhs->ty = type_new(TY_INT);
}
- lhs = ast_new_binary_expr(op, lhs, rhs);
- lhs->ty = result_type;
} else if (op == TK_MINUS) {
next_token(p);
rhs = parse_multiplicative_expr(p);
if (lhs->ty->kind == TY_PTR) {
result_type = lhs->ty;
+ rhs = ast_new_binary_expr(TK_STAR, rhs, ast_new_int_lit(type_sizeof(lhs->ty->to)));
+ rhs->ty = type_new(TY_INT);
+ lhs = ast_new_binary_expr(op, lhs, rhs);
+ lhs->ty = result_type;
} else {
- result_type = type_new(TY_INT);
+ lhs = ast_new_binary_expr(op, lhs, rhs);
+ lhs->ty = type_new(TY_INT);
}
- lhs = ast_new_binary_expr(op, lhs, rhs);
- lhs->ty = result_type;
} else {
break;
}
@@ -1033,8 +996,12 @@ struct AstNode* parse_logical_and_expr(struct Parser* p) {
if (op == TK_ANDAND) {
next_token(p);
struct AstNode* rhs = parse_equality_expr(p);
- lhs = ast_new_binary_expr(op, lhs, rhs);
- lhs->ty = type_new(TY_INT);
+ struct AstNode* e = ast_new(AST_LOGICAL_EXPR);
+ e->node_op = op;
+ e->node_lhs = lhs;
+ e->node_rhs = rhs;
+ e->ty = type_new(TY_INT);
+ lhs = e;
} else {
break;
}
@@ -1049,8 +1016,12 @@ struct AstNode* parse_logical_or_expr(struct Parser* p) {
if (op == TK_OROR) {
next_token(p);
struct AstNode* rhs = parse_logical_and_expr(p);
- lhs = ast_new_binary_expr(op, lhs, rhs);
- lhs->ty = type_new(TY_INT);
+ struct AstNode* e = ast_new(AST_LOGICAL_EXPR);
+ e->node_op = op;
+ e->node_lhs = lhs;
+ e->node_rhs = rhs;
+ e->ty = type_new(TY_INT);
+ lhs = e;
} else {
break;
}
@@ -1106,9 +1077,9 @@ struct AstNode* parse_if_stmt(struct Parser* p) {
}
struct AstNode* stmt = ast_new(AST_IF_STMT);
- stmt->expr1 = cond;
- stmt->node1 = then_body;
- stmt->node2 = else_body;
+ stmt->node_cond = cond;
+ stmt->node_then = then_body;
+ stmt->node_else = else_body;
return stmt;
}
@@ -1135,10 +1106,10 @@ struct AstNode* parse_for_stmt(struct Parser* p) {
struct AstNode* body = parse_stmt(p);
struct AstNode* stmt = ast_new(AST_FOR_STMT);
- stmt->expr1 = init;
- stmt->expr2 = cond;
- stmt->expr3 = update;
- stmt->node1 = body;
+ stmt->node_cond = cond;
+ stmt->node_init = init;
+ stmt->node_update = update;
+ stmt->node_body = body;
return stmt;
}
@@ -1150,8 +1121,8 @@ struct AstNode* parse_while_stmt(struct Parser* p) {
struct AstNode* body = parse_stmt(p);
struct AstNode* stmt = ast_new(AST_FOR_STMT);
- stmt->expr2 = cond;
- stmt->node1 = body;
+ stmt->node_cond = cond;
+ stmt->node_body = body;
return stmt;
}
@@ -1169,7 +1140,7 @@ struct AstNode* parse_continue_stmt(struct Parser* p) {
struct AstNode* parse_var_decl(struct Parser* p) {
struct Type* ty = parse_type(p);
- if (!type_is_unsized_type(ty)) {
+ if (!type_is_unsized(ty)) {
fatal_error("parse_var_decl: invalid type for variable");
}
char* name = parse_ident(p);
@@ -1194,7 +1165,7 @@ struct AstNode* parse_var_decl(struct Parser* p) {
if (init) {
struct AstNode* lhs = ast_new(AST_LVAR);
lhs->name = name;
- lhs->var_index = p->n_locals - 1;
+ lhs->node_index = p->n_locals - 1;
lhs->ty = ty;
struct AstNode* assign = ast_new_assign_expr(TK_ASSIGN, lhs, init);
assign->ty = ty;
@@ -1219,8 +1190,8 @@ struct AstNode* parse_block_stmt(struct Parser* p) {
expect(p, TK_BRACE_L);
while (peek_token(p)->kind != TK_BRACE_R) {
struct AstNode* stmt = parse_stmt(p);
- list->last->next = stmt;
- list->last = stmt;
+ list->node_last->node_next = stmt;
+ list->node_last = stmt;
}
expect(p, TK_BRACE_R);
return list;
@@ -1255,12 +1226,12 @@ void enter_func(struct Parser* p) {
}
void register_params(struct Parser* p, struct AstNode* params) {
- struct AstNode* param = params->next;
+ struct AstNode* param = params->node_next;
while (param) {
p->locals[p->n_locals].name = param->name;
p->locals[p->n_locals].ty = param->ty;
p->n_locals += 1;
- param = param->next;
+ param = param->node_next;
}
}
@@ -1272,7 +1243,7 @@ void register_func(struct Parser* p, char* name, struct Type* ty) {
struct AstNode* parse_param(struct Parser* p) {
struct Type* ty = parse_type(p);
- if (!type_is_unsized_type(ty)) {
+ if (!type_is_unsized(ty)) {
fatal_error("parse_param: invalid type for variable");
}
char* name = parse_ident(p);
@@ -1286,10 +1257,9 @@ struct AstNode* parse_param_list(struct Parser* p) {
struct AstNode* list = ast_new_list(AST_PARAM_LIST);
while (peek_token(p)->kind != TK_PAREN_R) {
struct AstNode* param = parse_param(p);
- list->last->next = param;
- list->last = param;
- int tk = peek_token(p)->kind;
- if (tk == TK_COMMA) {
+ list->node_last->node_next = param;
+ list->node_last = param;
+ if (peek_token(p)->kind == TK_COMMA) {
next_token(p);
} else {
break;
@@ -1315,8 +1285,8 @@ struct AstNode* parse_func_decl_or_def(struct Parser* p) {
struct AstNode* func = ast_new(AST_FUNC_DEF);
func->ty = ty;
func->name = name;
- func->func_params = params;
- func->func_body = body;
+ func->node_params = params;
+ func->node_body = body;
return func;
}
@@ -1334,8 +1304,8 @@ struct AstNode* parse_struct_members(struct Parser* p) {
struct AstNode* list = ast_new_list(AST_STRUCT_MEMBER_LIST);
while (peek_token(p)->kind != TK_BRACE_R) {
struct AstNode* member = parse_struct_member(p);
- list->last->next = member;
- list->last = member;
+ list->node_last->node_next = member;
+ list->node_last = member;
}
return list;
}
@@ -1364,7 +1334,7 @@ struct AstNode* parse_struct_decl_or_def(struct Parser* p) {
next_token(p);
return ast_new(AST_STRUCT_DECL);
}
- if (p->structs[struct_index].node1) {
+ if (p->structs[struct_index].node_members) {
char* buf = calloc(1024, sizeof(char));
sprintf(buf, "parse_struct_decl_or_def: struct %s redefined", name);
fatal_error(buf);
@@ -1373,7 +1343,7 @@ struct AstNode* parse_struct_decl_or_def(struct Parser* p) {
struct AstNode* members = parse_struct_members(p);
expect(p, TK_BRACE_R);
expect(p, TK_SEMICOLON);
- p->structs[struct_index].node1 = members;
+ p->structs[struct_index].node_members = members;
return p->structs + struct_index;
}
@@ -1385,15 +1355,20 @@ struct AstNode* parse_toplevel(struct Parser* p) {
}
}
-struct AstNode* parse(struct Parser* p) {
+struct Program* parse(struct Parser* p) {
struct AstNode* list = ast_new_list(AST_PROGRAM);
while (eof(p)) {
struct AstNode* n = parse_toplevel(p);
- list->last->next = n;
- list->last = n;
+ if (n->kind != AST_FUNC_DEF) {
+ continue;
+ }
+ list->node_last->node_next = n;
+ list->node_last = n;
}
- list->str_literals = p->str_literals;
- return list;
+ struct Program* prog = calloc(1, sizeof(struct Program));
+ prog->funcs = list;
+ prog->str_literals = p->str_literals;
+ return prog;
}
#define GEN_LVAL 0
@@ -1434,7 +1409,7 @@ void gen_func_prologue(struct CodeGen* g, struct AstNode* ast) {
printf(" push rbp\n");
printf(" mov rbp, rsp\n");
int param_index = 0;
- struct AstNode* param = ast->func_params->next;
+ struct AstNode* param = ast->node_params->node_next;
while (param) {
if (param_index == 0) {
printf(" push rdi\n");
@@ -1452,7 +1427,7 @@ void gen_func_prologue(struct CodeGen* g, struct AstNode* ast) {
fatal_error("gen_func_prologue: too many params");
}
param_index += 1;
- param = param->next;
+ param = param->node_next;
}
printf(" sub rsp, %d\n", 8 * LVAR_MAX);
}
@@ -1469,21 +1444,14 @@ void gen_int_lit_expr(struct CodeGen* g, struct AstNode* ast) {
assert_ast_kind(ast, AST_INT_LIT_EXPR);
printf(" # gen_int_lit_expr\n");
- printf(" push %d\n", ast->int_value);
-}
-
-void gen_offsetof(struct CodeGen* g, struct AstNode* ast) {
- assert_ast_kind(ast, AST_OFFSETOF);
- printf(" # gen_offsetof\n");
-
- printf(" push %d\n", ast->int_value);
+ printf(" push %d\n", ast->node_int_value);
}
void gen_str_lit_expr(struct CodeGen* g, struct AstNode* ast) {
assert_ast_kind(ast, AST_STR_LIT_EXPR);
printf(" # gen_str_lit_expr\n");
- printf(" mov rax, OFFSET FLAG:.Lstr__%d\n", ast->int_value);
+ printf(" mov rax, OFFSET FLAG:.Lstr__%d\n", ast->node_index);
printf(" push rax\n");
}
@@ -1491,8 +1459,8 @@ void gen_unary_expr(struct CodeGen* g, struct AstNode* ast) {
assert_ast_kind(ast, AST_UNARY_EXPR);
printf(" # gen_unary_expr\n");
- gen_expr(g, ast->expr1, GEN_RVAL);
- if (ast->op == TK_NOT) {
+ gen_expr(g, ast->node_operand, GEN_RVAL);
+ if (ast->node_op == TK_NOT) {
printf(" pop rax\n");
printf(" mov rdi, 0\n");
printf(" cmp rax, rdi\n");
@@ -1508,7 +1476,7 @@ void gen_ref_expr(struct CodeGen* g, struct AstNode* ast, int gen_mode) {
assert_ast_kind(ast, AST_REF_EXPR);
printf(" # gen_ref_expr\n");
- gen_expr(g, ast->expr1, GEN_LVAL);
+ gen_expr(g, ast->node_operand, GEN_LVAL);
}
void gen_lval2rval(struct Type* ty) {
@@ -1530,38 +1498,38 @@ void gen_deref_expr(struct CodeGen* g, struct AstNode* ast, int gen_mode) {
printf(" # gen_deref_expr\n");
if (gen_mode == GEN_LVAL) {
- gen_expr(g, ast->expr1, GEN_RVAL);
+ gen_expr(g, ast->node_operand, GEN_RVAL);
} else {
- gen_expr(g, ast->expr1, GEN_RVAL);
- gen_lval2rval(ast->expr1->ty->to);
+ gen_expr(g, ast->node_operand, GEN_RVAL);
+ gen_lval2rval(ast->node_operand->ty->to);
}
}
void gen_logical_expr(struct CodeGen* g, struct AstNode* ast) {
- assert_ast_kind(ast, AST_BINARY_EXPR);
+ assert_ast_kind(ast, AST_LOGICAL_EXPR);
printf(" # gen_logical_expr\n");
int label = gen_new_label(g);
- if (ast->op == TK_ANDAND) {
- gen_expr(g, ast->expr1, GEN_RVAL);
+ if (ast->node_op == TK_ANDAND) {
+ gen_expr(g, ast->node_lhs, GEN_RVAL);
printf(" pop rax\n");
printf(" cmp rax, 0\n");
printf(" je .Lelse%d\n", label);
- gen_expr(g, ast->expr2, GEN_RVAL);
+ gen_expr(g, ast->node_rhs, GEN_RVAL);
printf(" jmp .Lend%d\n", label);
printf(".Lelse%d:\n", label);
printf(" push 0\n");
printf(".Lend%d:\n", label);
} else {
- gen_expr(g, ast->expr1, GEN_RVAL);
+ gen_expr(g, ast->node_lhs, GEN_RVAL);
printf(" pop rax\n");
printf(" cmp rax, 0\n");
printf(" je .Lelse%d\n", label);
printf(" push 1\n");
printf(" jmp .Lend%d\n", label);
printf(".Lelse%d:\n", label);
- gen_expr(g, ast->expr2, GEN_RVAL);
+ gen_expr(g, ast->node_rhs, GEN_RVAL);
printf(".Lend%d:\n", label);
}
}
@@ -1570,66 +1538,42 @@ void gen_binary_expr(struct CodeGen* g, struct AstNode* ast, int gen_mode) {
assert_ast_kind(ast, AST_BINARY_EXPR);
printf(" # gen_binary_expr\n");
- if (ast->op == TK_ANDAND || ast->op == TK_OROR) {
- gen_logical_expr(g, ast);
- return;
- }
-
- gen_expr(g, ast->expr1, gen_mode);
- gen_expr(g, ast->expr2, gen_mode);
+ gen_expr(g, ast->node_lhs, gen_mode);
+ gen_expr(g, ast->node_rhs, gen_mode);
printf(" pop rdi\n");
printf(" pop rax\n");
- if (ast->op == TK_PLUS) {
- if (ast->expr1->ty->kind == TY_PTR) {
- if (ast->expr2->kind != AST_OFFSETOF) {
- printf(" imul rdi, %d\n", type_sizeof(ast->expr1->ty->to));
- }
- printf(" add rax, rdi\n");
- } else if (ast->expr2->ty->kind == TY_PTR) {
- if (ast->expr1->kind != AST_OFFSETOF) {
- printf(" imul rax, %d\n", type_sizeof(ast->expr2->ty->to));
- }
- printf(" add rax, rdi\n");
- } else {
- printf(" add rax, rdi\n");
- }
- } else if (ast->op == TK_MINUS) {
- if (ast->expr2->ty->kind == TY_PTR) {
- fatal_error("todo");
- } else if (ast->expr1->ty->kind == TY_PTR) {
- printf(" imul rdi, %d\n", type_sizeof(ast->expr1->ty->to));
- printf(" sub rax, rdi\n");
- } else {
- printf(" sub rax, rdi\n");
- }
- } else if (ast->op == TK_STAR) {
+ if (ast->node_op == TK_PLUS) {
+ printf(" add rax, rdi\n");
+ } else if (ast->node_op == TK_MINUS) {
+ printf(" sub rax, rdi\n");
+ } else if (ast->node_op == TK_STAR) {
printf(" imul rax, rdi\n");
- } else if (ast->op == TK_SLASH) {
+ } else if (ast->node_op == TK_SLASH) {
printf(" cqo\n");
printf(" idiv rdi\n");
- } else if (ast->op == TK_PERCENT) {
+ } else if (ast->node_op == TK_PERCENT) {
printf(" cqo\n");
printf(" idiv rdi\n");
printf(" mov rax, rdx\n");
- } else if (ast->op == TK_EQ) {
+ } else if (ast->node_op == TK_EQ) {
printf(" cmp rax, rdi\n");
printf(" sete al\n");
printf(" movzb rax, al\n");
- } else if (ast->op == TK_NE) {
+ } else if (ast->node_op == TK_NE) {
printf(" cmp rax, rdi\n");
printf(" setne al\n");
printf(" movzb rax, al\n");
- } else if (ast->op == TK_LT) {
+ } else if (ast->node_op == TK_LT) {
printf(" cmp rax, rdi\n");
printf(" setl al\n");
printf(" movzb rax, al\n");
- } else if (ast->op == TK_LE) {
+ } else if (ast->node_op == TK_LE) {
printf(" cmp rax, rdi\n");
printf(" setle al\n");
printf(" movzb rax, al\n");
} else {
char* buf = calloc(1024, sizeof(char));
- sprintf(buf, "gen_binary_expr: unknown op, %d", ast->op);
+ sprintf(buf, "gen_binary_expr: unknown op, %d", ast->node_op);
fatal_error(buf);
}
printf(" push rax\n");
@@ -1639,37 +1583,33 @@ void gen_assign_expr(struct CodeGen* g, struct AstNode* ast) {
assert_ast_kind(ast, AST_ASSIGN_EXPR);
printf(" # gen_assign_expr\n");
- gen_expr(g, ast->expr1, GEN_LVAL);
- gen_expr(g, ast->expr2, GEN_RVAL);
- if (ast->op == TK_ASSIGN) {
+ gen_expr(g, ast->node_lhs, GEN_LVAL);
+ gen_expr(g, ast->node_rhs, GEN_RVAL);
+ if (ast->node_op == TK_ASSIGN) {
printf(" pop rdi\n");
printf(" pop rax\n");
- if (type_sizeof(ast->expr1->ty) == 1) {
+ if (type_sizeof(ast->node_lhs->ty) == 1) {
printf(" mov BYTE PTR [rax], dil\n");
- } else if (type_sizeof(ast->expr1->ty) == 4) {
+ } else if (type_sizeof(ast->node_lhs->ty) == 4) {
printf(" mov DWORD PTR [rax], edi\n");
} else {
printf(" mov [rax], rdi\n");
}
printf(" push rdi\n");
- } else if (ast->op == TK_ASSIGN_ADD) {
+ } else if (ast->node_op == TK_ASSIGN_ADD) {
printf(" pop rdi\n");
printf(" pop rax\n");
printf(" push rax\n");
printf(" push rdi\n");
printf(" push rax\n");
- gen_lval2rval(ast->expr1->ty);
+ gen_lval2rval(ast->node_lhs->ty);
printf(" pop rax\n");
printf(" pop rdi\n");
- if (ast->expr1->ty->kind == TY_PTR) {
- if (ast->expr2->kind != AST_OFFSETOF) {
- printf(" imul rdi, %d\n", type_sizeof(ast->expr1->ty->to));
- }
+ if (ast->node_lhs->ty->kind == TY_PTR) {
+ printf(" imul rdi, %d\n", type_sizeof(ast->node_lhs->ty->to));
printf(" add rax, rdi\n");
- } else if (ast->expr2->ty->kind == TY_PTR) {
- if (ast->expr1->kind != AST_OFFSETOF) {
- printf(" imul rax, %d\n", type_sizeof(ast->expr2->ty->to));
- }
+ } else if (ast->node_rhs->ty->kind == TY_PTR) {
+ printf(" imul rax, %d\n", type_sizeof(ast->node_rhs->ty->to));
printf(" add rax, rdi\n");
} else {
printf(" add rax, rdi\n");
@@ -1677,27 +1617,25 @@ void gen_assign_expr(struct CodeGen* g, struct AstNode* ast) {
printf(" push rax\n");
printf(" pop rdi\n");
printf(" pop rax\n");
- if (type_sizeof(ast->expr1->ty) == 1) {
+ if (type_sizeof(ast->node_lhs->ty) == 1) {
printf(" mov BYTE PTR [rax], dil\n");
- } else if (type_sizeof(ast->expr1->ty) == 4) {
+ } else if (type_sizeof(ast->node_lhs->ty) == 4) {
printf(" mov DWORD PTR [rax], edi\n");
} else {
printf(" mov [rax], rdi\n");
}
printf(" push rdi\n");
- } else if (ast->op == TK_ASSIGN_SUB) {
+ } else if (ast->node_op == TK_ASSIGN_SUB) {
printf(" pop rdi\n");
printf(" pop rax\n");
printf(" push rax\n");
printf(" push rdi\n");
printf(" push rax\n");
- gen_lval2rval(ast->expr1->ty);
+ gen_lval2rval(ast->node_lhs->ty);
printf(" pop rax\n");
printf(" pop rdi\n");
- if (ast->expr2->ty->kind == TY_PTR) {
- fatal_error("todo");
- } else if (ast->expr1->ty->kind == TY_PTR) {
- printf(" imul rdi, %d\n", type_sizeof(ast->expr1->ty->to));
+ if (ast->node_lhs->ty->kind == TY_PTR) {
+ printf(" imul rdi, %d\n", type_sizeof(ast->node_lhs->ty->to));
printf(" sub rax, rdi\n");
} else {
printf(" sub rax, rdi\n");
@@ -1705,9 +1643,9 @@ void gen_assign_expr(struct CodeGen* g, struct AstNode* ast) {
printf(" push rax\n");
printf(" pop rdi\n");
printf(" pop rax\n");
- if (type_sizeof(ast->expr1->ty) == 1) {
+ if (type_sizeof(ast->node_lhs->ty) == 1) {
printf(" mov BYTE PTR [rax], dil\n");
- } else if (type_sizeof(ast->expr1->ty) == 4) {
+ } else if (type_sizeof(ast->node_lhs->ty) == 4) {
printf(" mov DWORD PTR [rax], edi\n");
} else {
printf(" mov [rax], rdi\n");
@@ -1724,12 +1662,12 @@ void gen_func_call(struct CodeGen* g, struct AstNode* ast) {
char* func_name = ast->name;
struct AstNode* args = ast->expr1;
- struct AstNode* arg = args->next;
+ struct AstNode* arg = args->node_next;
int n_args = 0;
while (arg) {
n_args += 1;
gen_expr(g, arg, GEN_RVAL);
- arg = arg->next;
+ arg = arg->node_next;
}
int i;
for (i = n_args - 1; i >= 0; i = i - 1) {
@@ -1777,7 +1715,7 @@ void gen_lvar(struct CodeGen* g, struct AstNode* ast, int gen_mode) {
assert_ast_kind(ast, AST_LVAR);
printf(" # gen_lvar\n");
- int offset = 8 + ast->var_index * 8;
+ int offset = 8 + ast->node_index * 8;
printf(" mov rax, rbp\n");
printf(" sub rax, %d\n", offset);
printf(" push rax\n");
@@ -1789,8 +1727,6 @@ void gen_lvar(struct CodeGen* g, struct AstNode* ast, int gen_mode) {
void gen_expr(struct CodeGen* g, struct AstNode* ast, int gen_mode) {
if (ast->kind == AST_INT_LIT_EXPR) {
gen_int_lit_expr(g, ast);
- } else if (ast->kind == AST_OFFSETOF) {
- gen_offsetof(g, ast);
} else if (ast->kind == AST_STR_LIT_EXPR) {
gen_str_lit_expr(g, ast);
} else if (ast->kind == AST_UNARY_EXPR) {
@@ -1801,6 +1737,8 @@ void gen_expr(struct CodeGen* g, struct AstNode* ast, int gen_mode) {
gen_deref_expr(g, ast, gen_mode);
} else if (ast->kind == AST_BINARY_EXPR) {
gen_binary_expr(g, ast, gen_mode);
+ } else if (ast->kind == AST_LOGICAL_EXPR) {
+ gen_logical_expr(g, ast);
} else if (ast->kind == AST_ASSIGN_EXPR) {
gen_assign_expr(g, ast);
} else if (ast->kind == AST_FUNC_CALL) {
@@ -1829,15 +1767,15 @@ void gen_if_stmt(struct CodeGen* g, struct AstNode* ast) {
int label = gen_new_label(g);
- gen_expr(g, ast->expr1, GEN_RVAL);
+ gen_expr(g, ast->node_cond, GEN_RVAL);
printf(" pop rax\n");
printf(" cmp rax, 0\n");
printf(" je .Lelse%d\n", label);
- gen_stmt(g, ast->node1);
+ gen_stmt(g, ast->node_then);
printf(" jmp .Lend%d\n", label);
printf(".Lelse%d:\n", label);
- if (ast->node2) {
- gen_stmt(g, ast->node2);
+ if (ast->node_else) {
+ gen_stmt(g, ast->node_else);
}
printf(".Lend%d:\n", label);
}
@@ -1850,19 +1788,19 @@ void gen_for_stmt(struct CodeGen* g, struct AstNode* ast) {
g->loop_labels += 1;
*g->loop_labels = label;
- if (ast->expr1) {
- gen_expr(g, ast->expr1, GEN_RVAL);
+ if (ast->node_init) {
+ gen_expr(g, ast->node_init, GEN_RVAL);
printf(" pop rax\n");
}
printf(".Lbegin%d:\n", label);
- gen_expr(g, ast->expr2, GEN_RVAL);
+ gen_expr(g, ast->node_cond, GEN_RVAL);
printf(" pop rax\n");
printf(" cmp rax, 0\n");
printf(" je .Lend%d\n", label);
- gen_stmt(g, ast->node1);
+ gen_stmt(g, ast->node_body);
printf(".Lcontinue%d:\n", label);
- if (ast->expr3) {
- gen_expr(g, ast->expr3, GEN_RVAL);
+ if (ast->node_update) {
+ gen_expr(g, ast->node_update, GEN_RVAL);
printf(" pop rax\n");
}
printf(" jmp .Lbegin%d\n", label);
@@ -1897,10 +1835,10 @@ void gen_var_decl(struct CodeGen* g, struct AstNode* ast) {
void gen_block_stmt(struct CodeGen* g, struct AstNode* ast) {
assert_ast_kind(ast, AST_BLOCK);
- struct AstNode* stmt = ast->next;
+ struct AstNode* stmt = ast->node_next;
while (stmt) {
gen_stmt(g, stmt);
- stmt = stmt->next;
+ stmt = stmt->node_next;
}
}
@@ -1933,43 +1871,40 @@ void gen_func(struct CodeGen* g, struct AstNode* ast) {
printf("%s:\n", ast->name);
gen_func_prologue(g, ast);
- gen_stmt(g, ast->func_body);
+ gen_stmt(g, ast->node_body);
gen_func_epilogue(g, ast);
printf("\n");
}
-void gen(struct CodeGen* g, struct AstNode* ast) {
- assert_ast_kind(ast, AST_PROGRAM);
-
+void gen(struct CodeGen* g, struct Program* prog) {
printf(".intel_syntax noprefix\n\n");
int idx = 0;
- for (idx = 0; ast->str_literals[idx]; idx += 1) {
+ for (idx = 0; prog->str_literals[idx]; idx += 1) {
printf(".Lstr__%d:\n", idx + 1);
- printf(" .string \"%s\"\n\n", ast->str_literals[idx]);
+ printf(" .string \"%s\"\n\n", prog->str_literals[idx]);
}
printf(".globl main\n\n");
- struct AstNode* func = ast->next;
+ assert_ast_kind(prog->funcs, AST_PROGRAM);
+ struct AstNode* func = prog->funcs->node_next;
while (func) {
- if (func->kind == AST_FUNC_DEF) {
- gen_func(g, func);
- }
- func = func->next;
+ gen_func(g, func);
+ func = func->node_next;
}
}
int main() {
char* source = calloc(1024*1024, sizeof(char));
- int source_len = read_all(source);
- struct Token* tokens = tokenize(source, source_len);
+ read_all(source);
+ struct Token* tokens = tokenize(source);
struct Parser* parser = parser_new(tokens);
- struct AstNode* ast = parse(parser);
+ struct Program* prog = parse(parser);
struct CodeGen* code_generator = codegen_new();
- gen(code_generator, ast);
+ gen(code_generator, prog);
return 0;
}