Skip to content

Commit

Permalink
[Not Working] Implement function call with no args
Browse files Browse the repository at this point in the history
  • Loading branch information
mikiken committed Jul 29, 2022
1 parent 3fdce9f commit 44992ea
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 22 deletions.
4 changes: 3 additions & 1 deletion 9cc.h
Expand Up @@ -72,6 +72,7 @@ typedef enum {
ND_RETURN, // return
ND_IF, // if
ND_FOR, // for | while
ND_FUNCALL,// function call
} NodeKind;

typedef struct Node Node;
Expand All @@ -93,7 +94,8 @@ struct Node {
// kind == ND_STMT
Node *body; // statementの内容
Node *next; // next statement

// kind == ND_FUNCALL
char *func_name;
};

Node stmt_head; // stmtのリストの先頭(ダミーノード)
Expand Down
5 changes: 2 additions & 3 deletions README.md
Expand Up @@ -8,8 +8,7 @@ C言語(のサブセット)コンパイラ
- `return` statement
- `if` `else` statement
- `while` `for` statement


- `{…}` compound statements (blocks)

## BNF
```
Expand All @@ -27,5 +26,5 @@ relational = add ("<" add | "<=" add | ">" add | ">=" add)*
add = mul ("+" mul | "-" mul)*
mul = unary ("*" unary | "/" unary)*
unary = ("+" | "-")? primary
primary = num | ident | "(" expr ")"
primary = num | ident ("(" ")")? | "(" expr ")"
```
3 changes: 3 additions & 0 deletions codegen.c
Expand Up @@ -101,6 +101,9 @@ void gen(Node *node) {
printf(".L.end.%d:\n", label);
return;
}
case ND_FUNCALL:
printf(" call %s\n", node->func_name);
return;
}

gen(node->lhs);
Expand Down
54 changes: 36 additions & 18 deletions parse.c
Expand Up @@ -47,13 +47,32 @@ int expect_number() {
return val;
}

Lvar *find_lvar() {
Lvar *find_lvar(Token *tok) {
for (Lvar *var = locals; var != NULL; var = var->next)
if (var->len == token->len && !memcmp(token->start, var->name, var->len))
if (var->len == tok->len && !memcmp(tok->start, var->name, var->len))
return var;
return NULL;
}

Node *new_lvar_node(Token *tok) {
Node *node = new_node(ND_LVAR);
Lvar *lvar = find_lvar(tok);

if (lvar != NULL) {
node->offset = lvar->offset;
} else { // 初登場のローカル変数の場合、localsの先頭に繋ぐ
lvar = calloc(1, sizeof(Lvar));
lvar->len = tok->len;
lvar->offset = locals->offset + 8;
lvar->name = tok->start;
lvar->next = locals;
locals = lvar;

node->offset = lvar->offset;
}
return node;
}

void init_locals() {
tail.offset = 0;
tail.next = NULL;
Expand Down Expand Up @@ -234,25 +253,24 @@ Node *primary() {
expect(")");
return node;
}
else if (token->kind == TK_IDENT) { // ローカル変数の場合
Node *node = new_node(ND_LVAR);
Lvar *lvar = find_lvar();

if (lvar != NULL) {
node->offset = lvar->offset;
} else { // 初登場のローカル変数の場合、localsの先頭に繋ぐ
lvar = calloc(1, sizeof(Lvar));
lvar->len = token->len;
lvar->offset = locals->offset + 8;
lvar->name = token->start;
lvar->next = locals;
locals = lvar;

node->offset = lvar->offset;
}

else if (token->kind == TK_IDENT) {
Node *node;
Token *tok = token;
token = token->next;
if (consume(TK_RESERVED, "(")) { // 関数呼び出しの場合
// 今後ここに引数のparse処理が入るはず
expect(")");
node = new_node(ND_FUNCALL);
node->func_name = calloc(tok->len, sizeof(char));
memcpy(node->func_name, tok->start, tok->len);
}
else { // ローカル変数の場合
node = new_lvar_node(tok);
}
return node;
}

else
return new_num(expect_number()); // それ以外は整数のはず
}
3 changes: 3 additions & 0 deletions test.c
@@ -0,0 +1,3 @@
int foo() {
return 5;
}
2 changes: 2 additions & 0 deletions test.sh
Expand Up @@ -99,4 +99,6 @@ assert 10 'a=3; {b=7; if(a==3) return a+b;}'

assert 3 'a=3; if(a==1) return 1; if(a==2) return 2; if(a==3) return 3;'

assert 5 'return foo();'

echo OK

0 comments on commit 44992ea

Please sign in to comment.