mirror of https://github.com/rui314/chibicc
Allow variadic functions to be called
This commit is contained in:
parent
d85319fa28
commit
308dc70609
1
chibi.h
1
chibi.h
|
@ -212,6 +212,7 @@ struct Function {
|
|||
char *name;
|
||||
VarList *params;
|
||||
bool is_static;
|
||||
bool has_varargs;
|
||||
|
||||
Node *node;
|
||||
VarList *locals;
|
||||
|
|
21
parse.c
21
parse.c
|
@ -609,25 +609,30 @@ static VarList *read_func_param(void) {
|
|||
return vl;
|
||||
}
|
||||
|
||||
static VarList *read_func_params(void) {
|
||||
static void read_func_params(Function *fn) {
|
||||
if (consume(")"))
|
||||
return NULL;
|
||||
return;
|
||||
|
||||
Token *tok = token;
|
||||
if (consume("void") && consume(")"))
|
||||
return NULL;
|
||||
return;
|
||||
token = tok;
|
||||
|
||||
VarList *head = read_func_param();
|
||||
VarList *cur = head;
|
||||
fn->params = read_func_param();
|
||||
VarList *cur = fn->params;
|
||||
|
||||
while (!consume(")")) {
|
||||
expect(",");
|
||||
|
||||
if (consume("...")) {
|
||||
fn->has_varargs = true;
|
||||
expect(")");
|
||||
return;
|
||||
}
|
||||
|
||||
cur->next = read_func_param();
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
// function = basetype declarator "(" params? ")" ("{" stmt* "}" | ";")
|
||||
|
@ -651,7 +656,7 @@ static Function *function(void) {
|
|||
expect("(");
|
||||
|
||||
Scope *sc = enter_scope();
|
||||
fn->params = read_func_params();
|
||||
read_func_params(fn);
|
||||
|
||||
if (consume(";")) {
|
||||
leave_scope(sc);
|
||||
|
|
1
self.sh
1
self.sh
|
@ -36,7 +36,6 @@ EOF
|
|||
sed -i 's/\berrno\b/*__errno_location()/g' $TMP/$1
|
||||
sed -i 's/\btrue\b/1/g; s/\bfalse\b/0/g;' $TMP/$1
|
||||
sed -i 's/\bNULL\b/0/g' $TMP/$1
|
||||
sed -i 's/, \.\.\.//g' $TMP/$1
|
||||
sed -i 's/INT_MAX/2147483647/g' $TMP/$1
|
||||
|
||||
./chibicc $TMP/$1 > $TMP/${1%.c}.s
|
||||
|
|
9
tests
9
tests
|
@ -137,6 +137,9 @@ int counter() {
|
|||
_Bool true_fn();
|
||||
_Bool false_fn();
|
||||
|
||||
int add_all1(int x, ...);
|
||||
int add_all3(int z, int b, int c, ...);
|
||||
|
||||
int main() {
|
||||
assert(8, ({ int a=3; int z=5; a+z; }), "int a=3; int z=5; a+z;");
|
||||
|
||||
|
@ -700,6 +703,12 @@ int main() {
|
|||
assert(1, true_fn(), "true_fn()");
|
||||
assert(0, false_fn(), "false_fn()");
|
||||
|
||||
assert(6, add_all1(1,2,3,0), "add_all1(1,2,3,0)");
|
||||
assert(5, add_all1(1,2,3,-1,0), "add_all1(1,2,3,-1,0)");
|
||||
|
||||
assert(6, add_all3(1,2,3,0), "add_all3(1,2,3,0)");
|
||||
assert(5, add_all3(1,2,3,-1,0), "add_all3(1,2,3,-1,0)");
|
||||
|
||||
printf("OK\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
27
tests-extern
27
tests-extern
|
@ -1,7 +1,34 @@
|
|||
// -*- c -*-
|
||||
#include <stdarg.h>
|
||||
|
||||
int ext1;
|
||||
int *ext2;
|
||||
|
||||
int false_fn() { return 512; }
|
||||
int true_fn() { return 513; }
|
||||
int static_fn() { return 5; }
|
||||
|
||||
int add_all1(int x, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, x);
|
||||
|
||||
for (;;) {
|
||||
int y = va_arg(ap, int);
|
||||
if (y == 0)
|
||||
return x;
|
||||
x += y;
|
||||
}
|
||||
}
|
||||
|
||||
int add_all3(int x, int y, int z, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, z);
|
||||
x = x + y + z;
|
||||
|
||||
for (;;) {
|
||||
int y = va_arg(ap, int);
|
||||
if (y == 0)
|
||||
return x;
|
||||
x += y;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -160,8 +160,8 @@ static char *starts_with_reserved(char *p) {
|
|||
}
|
||||
|
||||
// Multi-letter punctuator
|
||||
static char *ops[] = {"<<=", ">>=", "==", "!=", "<=", ">=", "->",
|
||||
"++", "--", "<<", ">>", "+=", "-=", "*=",
|
||||
static char *ops[] = {"<<=", ">>=", "...", "==", "!=", "<=", ">=",
|
||||
"->", "++", "--", "<<", ">>", "+=", "-=", "*=",
|
||||
"/=", "&&", "||", "&=", "|=", "^="};
|
||||
|
||||
for (int i = 0; i < sizeof(ops) / sizeof(*ops); i++)
|
||||
|
|
Loading…
Reference in New Issue