aboutsummaryrefslogtreecommitdiff
path: root/bootstrap
diff options
context:
space:
mode:
Diffstat (limited to 'bootstrap')
-rw-r--r--bootstrap/parse.c44
-rw-r--r--bootstrap/test.cff8
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(&params, lexexpects(P, TKident, "parameter name").str);
+ c.bodyarg = 1;
+ lexmatch(P, &tok, ',');
+ lexexpect(P, ')');
+ break;
} else {
vec_push(&params, 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]);