mirror of https://github.com/rui314/chibicc
Support function call with up to 6 arguments
This commit is contained in:
parent
30a3992627
commit
964b1d2a0e
|
@ -108,6 +108,7 @@ struct Node {
|
|||
|
||||
// Function call
|
||||
char *funcname;
|
||||
Node *args;
|
||||
|
||||
Obj *var; // Used if kind == ND_VAR
|
||||
int val; // Used if kind == ND_NUM
|
||||
|
|
14
codegen.c
14
codegen.c
|
@ -1,6 +1,7 @@
|
|||
#include "chibicc.h"
|
||||
|
||||
static int depth;
|
||||
static char *argreg[] = {"%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9"};
|
||||
|
||||
static void gen_expr(Node *node);
|
||||
|
||||
|
@ -68,11 +69,22 @@ static void gen_expr(Node *node) {
|
|||
pop("%rdi");
|
||||
printf(" mov %%rax, (%%rdi)\n");
|
||||
return;
|
||||
case ND_FUNCALL:
|
||||
case ND_FUNCALL: {
|
||||
int nargs = 0;
|
||||
for (Node *arg = node->args; arg; arg = arg->next) {
|
||||
gen_expr(arg);
|
||||
push();
|
||||
nargs++;
|
||||
}
|
||||
|
||||
for (int i = nargs - 1; i >= 0; i--)
|
||||
pop(argreg[i]);
|
||||
|
||||
printf(" mov $0, %%rax\n");
|
||||
printf(" call %s\n", node->funcname);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
gen_expr(node->rhs);
|
||||
push();
|
||||
|
|
33
parse.c
33
parse.c
|
@ -418,8 +418,29 @@ static Node *unary(Token **rest, Token *tok) {
|
|||
return primary(rest, tok);
|
||||
}
|
||||
|
||||
// primary = "(" expr ")" | ident args? | num
|
||||
// args = "(" ")"
|
||||
// funcall = ident "(" (assign ("," assign)*)? ")"
|
||||
static Node *funcall(Token **rest, Token *tok) {
|
||||
Token *start = tok;
|
||||
tok = tok->next->next;
|
||||
|
||||
Node head = {};
|
||||
Node *cur = &head;
|
||||
|
||||
while (!equal(tok, ")")) {
|
||||
if (cur != &head)
|
||||
tok = skip(tok, ",");
|
||||
cur = cur->next = assign(&tok, tok);
|
||||
}
|
||||
|
||||
*rest = skip(tok, ")");
|
||||
|
||||
Node *node = new_node(ND_FUNCALL, start);
|
||||
node->funcname = strndup(start->loc, start->len);
|
||||
node->args = head.next;
|
||||
return node;
|
||||
}
|
||||
|
||||
// primary = "(" expr ")" | ident func-args? | num
|
||||
static Node *primary(Token **rest, Token *tok) {
|
||||
if (equal(tok, "(")) {
|
||||
Node *node = expr(&tok, tok->next);
|
||||
|
@ -429,12 +450,8 @@ static Node *primary(Token **rest, Token *tok) {
|
|||
|
||||
if (tok->kind == TK_IDENT) {
|
||||
// Function call
|
||||
if (equal(tok->next, "(")) {
|
||||
Node *node = new_node(ND_FUNCALL, tok);
|
||||
node->funcname = strndup(tok->loc, tok->len);
|
||||
*rest = skip(tok->next->next, ")");
|
||||
return node;
|
||||
}
|
||||
if (equal(tok->next, "("))
|
||||
return funcall(rest, tok);
|
||||
|
||||
// Variable
|
||||
Obj *var = find_var(tok);
|
||||
|
|
11
test.sh
11
test.sh
|
@ -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() {
|
||||
|
@ -99,5 +105,10 @@ assert 8 '{ int x=3, y=5; return x+y; }'
|
|||
|
||||
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); }'
|
||||
assert 66 '{ return add6(1,2,add6(3,4,5,6,7,8),9,10,11); }'
|
||||
assert 136 '{ return add6(1,2,add6(3,add6(4,5,6,7,8,9),10,11,12,13),14,15,16); }'
|
||||
|
||||
echo OK
|
||||
|
|
Loading…
Reference in New Issue