Skip to content

Commit

Permalink
Support function call with up to 6 arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
rui314 committed Aug 20, 2019
1 parent f5540b5 commit 5dea368
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 5 deletions.
1 change: 1 addition & 0 deletions chibicc.h
Expand Up @@ -96,6 +96,7 @@ struct Node {

// Function call
char *funcname;
Node *args;

Var *var; // Used if kind == ND_VAR
int val; // Used if kind == ND_NUM
Expand Down
13 changes: 12 additions & 1 deletion codegen.c
@@ -1,6 +1,7 @@
#include "chibicc.h"

int labelseq = 0;
char *argreg[] = {"rdi", "rsi", "rdx", "rcx", "r8", "r9"};

// Pushes the given node's address to the stack.
void gen_addr(Node *node) {
Expand Down Expand Up @@ -101,10 +102,20 @@ void gen(Node *node) {
for (Node *n = node->body; n; n = n->next)
gen(n);
return;
case ND_FUNCALL:
case ND_FUNCALL: {
int nargs = 0;
for (Node *arg = node->args; arg; arg = arg->next) {
gen(arg);
nargs++;
}

for (int i = nargs - 1; i >= 0; i--)
printf(" pop %s\n", argreg[i]);

printf(" call %s\n", node->funcname);
printf(" push rax\n");
return;
}
case ND_RETURN:
gen(node->lhs);
printf(" pop rax\n");
Expand Down
20 changes: 17 additions & 3 deletions parse.c
Expand Up @@ -237,8 +237,22 @@ Node *unary() {
return primary();
}

// primary = "(" expr ")" | ident args? | num
// args = "(" ")"
// func-args = "(" (assign ("," assign)*)? ")"
Node *func_args() {
if (consume(")"))
return NULL;

Node *head = assign();
Node *cur = head;
while (consume(",")) {
cur->next = assign();
cur = cur->next;
}
expect(")");
return head;
}

// primary = "(" expr ")" | ident func-args? | num
Node *primary() {
if (consume("(")) {
Node *node = expr();
Expand All @@ -249,9 +263,9 @@ Node *primary() {
Token *tok = consume_ident();
if (tok) {
if (consume("(")) {
expect(")");
Node *node = new_node(ND_FUNCALL);
node->funcname = strndup(tok->str, tok->len);
node->args = func_args();
return node;
}

Expand Down
9 changes: 9 additions & 0 deletions test.sh
Expand Up @@ -2,6 +2,12 @@
cat <<EOF | gcc -xc -c -o tmp2.o -
int ret3() { return 3; }
int ret5() { return 5; }
int add(int x, int y) { return x+y; }
int sub(int x, int y) { return x-y; }
int add6(int a, int b, int c, int d, int e, int f) {
return a+b+c+d+e+f;
}
EOF

assert() {
Expand Down Expand Up @@ -76,5 +82,8 @@ assert 3 'for (;;) return 3; return 5;'

assert 3 'return ret3();'
assert 5 'return ret5();'
assert 8 'return add(3, 5);'
assert 2 'return sub(5, 3);'
assert 21 'return add6(1,2,3,4,5,6);'

echo OK
6 changes: 5 additions & 1 deletion tokenize.c
@@ -1,5 +1,9 @@
#include "chibicc.h"

//
// Tokenizer
//

char *user_input;
Token *token;

Expand Down Expand Up @@ -138,7 +142,7 @@ Token *tokenize() {
}

// Single-letter punctuator
if (strchr("+-*/()<>;={}", *p)) {
if (strchr("+-*/()<>;={},", *p)) {
cur = new_token(TK_RESERVED, cur, p++, 1);
continue;
}
Expand Down

0 comments on commit 5dea368

Please sign in to comment.