diff --git a/50cc.h b/50cc.h index 0134d39..13a6a40 100644 --- a/50cc.h +++ b/50cc.h @@ -80,6 +80,7 @@ struct Node { Node *els; Node **block; char *funcname; + Node **args; int len; int val; int offset; @@ -98,6 +99,7 @@ Node *add(); Node *mul(); Node *unary(); Node *primary(); +Node *variable(); Node *new_node(NodeKind kind, Node *lhs, Node *rhs); Node *new_node_num(int val); @@ -114,4 +116,5 @@ struct LVar { int offset; }; -extern LVar *locals; +extern LVar *locals[]; +extern int cur_func; diff --git a/codegen.c b/codegen.c index 8c3238a..dca401c 100644 --- a/codegen.c +++ b/codegen.c @@ -85,7 +85,6 @@ void gen(Node *node) { case ND_BLOCK: for (int i = 0; node->block[i]; i++) { gen(node->block[i]); - printf(" pop rax\n"); } return; case ND_FUNC_CALL: @@ -114,7 +113,17 @@ void gen(Node *node) { printf("%s:\n", node->funcname); printf(" push rbp\n"); printf(" mov rbp, rsp\n"); - printf(" sub rsp, 208\n"); + for (int i = 0; node->args[i]; i++) { + printf("push %s\n", argRegs[i]); + argCount++; + } + + if (locals[cur_func]) { + int offset = locals[cur_func][0].offset; + offset -= argCount * 8; + printf(" sub rsp, %d\n", offset); + } + gen(node->lhs); printf(" mov rsp, rbp\n"); printf(" pop rbp\n"); diff --git a/codegen.o b/codegen.o index 6fef9a4..6b97bf8 100644 Binary files a/codegen.o and b/codegen.o differ diff --git a/main.c b/main.c index 2c70e09..e5c9c1d 100644 --- a/main.c +++ b/main.c @@ -30,7 +30,6 @@ int main(int argc, char **argv) { return 1; } - locals = NULL; user_input = argv[1]; token = tokenize(); program(); @@ -38,7 +37,9 @@ int main(int argc, char **argv) { printf(".intel_syntax noprefix\n"); printf(".global main\n"); + cur_func = 0; for (int i = 0; code[i]; i++) { + cur_func++; gen(code[i]); } diff --git a/main.o b/main.o index 71fc811..1f12080 100644 Binary files a/main.o and b/main.o differ diff --git a/parser.c b/parser.c index 1ba580a..6adb810 100644 --- a/parser.c +++ b/parser.c @@ -1,7 +1,8 @@ #include "50cc.h" Node *code[100]; -LVar *locals; +LVar *locals[100]; +int cur_func = 0; Node *new_node(NodeKind kind, Node *lhs, Node *rhs) { Node *node = calloc(1, sizeof(Node)); @@ -83,7 +84,7 @@ int expect_number() { LVar *find_lvar(Token *tok) { int i = 0; - for (LVar *var = locals; var; var = var->next) { + for (LVar *var = locals[cur_func]; var; var = var->next) { i++; if (var->len == tok->len && !memcmp(tok->str, var->name, var->len)) return var; @@ -100,6 +101,7 @@ void program() { // func = ident "(" ")" stmt Node *func() { + cur_func++; Node *node; Token *tok = consume_ident(); if (tok == NULL) { @@ -108,9 +110,20 @@ Node *func() { node = calloc(1, sizeof(Node)); node->kind = ND_FUNC_DEF; node->funcname = calloc(100, sizeof(char)); + node->args = calloc(10, sizeof(Node *)); memcpy(node->funcname, tok->str, tok->len); expect("("); - expect(")"); + int i = 0; + for (int i = 0; !consume(")"); i++) { + Token *tok = consume_ident(); + if (tok != NULL) { + node->args[i] = variable(tok); + } + if (consume(")")) { + break; + } + expect(","); + } node->lhs = stmt(); return node; } @@ -290,28 +303,31 @@ Node *primary() { } return node; } - Node *node = calloc(1, sizeof(Node)); - node->kind = ND_LVAR; + return variable(tok); + } + + return new_node_num(expect_number()); +} - LVar *lvar = find_lvar(tok); +Node *variable(Token *tok) { + Node *node = calloc(1, sizeof(Node)); + node->kind = ND_LVAR; - if (lvar) { - node->offset = lvar->offset; + LVar *lvar = find_lvar(tok); + if (lvar) { + node->offset = lvar->offset; + } else { + lvar = calloc(1, sizeof(LVar)); + lvar->next = locals[cur_func]; + lvar->name = tok->str; + lvar->len = tok->len; + if (locals[cur_func] == NULL) { + lvar->offset = 8; } else { - lvar = calloc(1, sizeof(LVar)); - lvar->next = locals; - lvar->name = tok->str; - lvar->len = tok->len; - if (locals == NULL) { - lvar->offset = 8; - } else { - lvar->offset = locals->offset + 8; - } - node->offset = lvar->offset; - locals = lvar; + lvar->offset = locals[cur_func]->offset + 8; } - return node; + node->offset = lvar->offset; + locals[cur_func] = lvar; } - - return new_node_num(expect_number()); -} \ No newline at end of file + return node; +} diff --git a/parser.o b/parser.o index 8b64bbc..9e691be 100644 Binary files a/parser.o and b/parser.o differ diff --git a/test.sh b/test.sh index 48ec363..a9320b0 100755 --- a/test.sh +++ b/test.sh @@ -21,6 +21,26 @@ assert(){ } assert 2 "main () { return 2;}" +assert 3 " +main() return func(1, 2); +func(a, b) { return a + b; } +" + +assert 4 " +main() return func(1, 2, 3); +func(a, b, c) { return a + c; } +" + +assert 3 "main() { + a = 4; + return fib(a); +} +fib(n){ + if(n == 0) return 0; + if(n == 1) return 1; + return fib(n - 1)+ fib(n -2); +} +" # assert 42 "42;" # assert 21 "5+20-4;" # assert 2 " 5 - 3; " diff --git a/tokenize.o b/tokenize.o index 3f1f402..ac3c86f 100644 Binary files a/tokenize.o and b/tokenize.o differ