diff options
Diffstat (limited to 'bootstrap')
| -rw-r--r-- | bootstrap/parse.c | 44 | ||||
| -rw-r--r-- | bootstrap/test.cff | 8 |
2 files changed, 45 insertions, 7 deletions
diff --git a/bootstrap/parse.c b/bootstrap/parse.c index efcf0b2..078e3dd 100644 --- a/bootstrap/parse.c +++ b/bootstrap/parse.c @@ -623,7 +623,9 @@ parsefntype(struct parser *P) { const struct type *param ; if (lexmatch(P, &tok, TKident)) { if (lexpeek(P).t == ',' || lexpeek(P).t == ')') - param = xident2type(P, tok); + param = xident2type(P, tok); + else + param = parsetype(P); } else { param = parsetype(P); } @@ -2317,6 +2319,35 @@ parseexpandmacro(struct parser *P, const struct macro *macro) { break; } } + eatspaces(P); + if (chrpeek(P) == '{') { + for (int i = 0; i < macro->cs.n; ++i) { + c = macro->cs.d[i]; + if (args.length == c.params.n - 1 && c.bodyarg) { + goto bodyarg; + } + } + goto not_bodyarg; + bodyarg:; + int bal = 0; + struct span espan = tok.span; + vec_t(struct tok) toks = {0}; + struct toktree ttoks; + do { + tok = lex(P); + switch (tok.t) { + case '{': ++bal; break; case '}': --bal; break; + case TKeof: + fatal(P, espan, "unterminated macro `%s' invokation", macro->name); + } + vec_push(&toks, tok); + } while (bal != 0); + + vec_slice_cpy(&ttoks, &toks); + vec_push(&args, ttoks); + goto ok; + } + not_bodyarg: for (int i = 0; i < macro->cs.n; ++i) { c = macro->cs.d[i]; @@ -2659,6 +2690,12 @@ parsemacrocase(struct parser *P) { lexmatch(P, &tok, ','); lexexpect(P, ')'); break; + } else if (lexmatch(P, &tok, '&')) { + vec_push(¶ms, lexexpects(P, TKident, "parameter name").str); + c.bodyarg = 1; + lexmatch(P, &tok, ','); + lexexpect(P, ')'); + break; } else { vec_push(¶ms, lexexpects(P, TKident, "parameter name").str); if (!lexmatch(P, &tok, ',')) { @@ -3113,8 +3150,9 @@ defyield(struct decl *decl, void *arg) { assert(decl->name); if (!decl->var.ini) fatal(a->P, decl->span, "def must have a value"); - if (!fold(decl->var.ini)) - fatal(a->P, decl->var.ini->span, "def initializer must be constant expression"); + fold(decl->var.ini); + //if (!fold(decl->var.ini)) + // fatal(a->P, decl->var.ini->span, "def initializer must be constant expression"); putdecl(a->P, decl->span, decl); if (a->yield) a->yield(decl, a->yarg); diff --git a/bootstrap/test.cff b/bootstrap/test.cff index d835b7e..6f5242d 100644 --- a/bootstrap/test.cff +++ b/bootstrap/test.cff @@ -10,10 +10,10 @@ enum Color { Red, Green, Blue } -defmacro each(i, x, arr, ...body) [ +defmacro each(i, x, arr, &body) [ for let i = 0; i < arr.#len; ++i { let x = arr[i]; - { body } + body } ] @@ -88,9 +88,9 @@ extern fn main (argc int, argv **u8) int { let is []int = { [4] = 1, 2, [1 - 1] = 3 }; isort(is, is.#len); - each(i, x, is, + each(i, x, is) { printf("%d\n", x); - ) + } let slice [#]int = is[3::5]; printf("sl %d\n", slice[0]); |