From 81500312dcfdde2bd07c5071c7948a61b1f952ba Mon Sep 17 00:00:00 2001 From: lemon Date: Sun, 7 Aug 2022 16:02:34 +0200 Subject: expand template at expression position --- bootstrap/parse.c | 9 +++++++-- bootstrap/test2.cff | 7 +++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/bootstrap/parse.c b/bootstrap/parse.c index 4094edb..e7f4a39 100644 --- a/bootstrap/parse.c +++ b/bootstrap/parse.c @@ -583,6 +583,7 @@ parseexpandtepl(struct parser *P, struct tepl *tepl) { const struct type *ty = NULL; int i = 0; + lexexpect(P, '<'); expan.span = container_of(tepl, struct decl, tepl)->span; expan.tepl = 1; while (!lexmatch(P, &tok, '>')) { @@ -726,7 +727,6 @@ parsetype(struct parser *P) { if (decl->t == Dtype) { return decl->ty; } else if (decl->t == Dtepl && decl->tepl.t == Dtype) { - lexexpect(P, '<'); return parseexpandtepl(P, (struct tepl *)&decl->tepl); } else fatal(P, P->tokspan, "%T is not a type", tok); @@ -974,8 +974,10 @@ pexprimary(struct parser *P) { decl: if (!decl) fatal(P, tok.span, "%T is not defined", tok); + const struct type *ty; if (decl->t == Dtype) { - const struct type *ty = decl->ty; + ty = decl->ty; + typedecl: if (ty->t == TYenum) { lexexpect(P, ':'); P->targty = ty; @@ -1001,6 +1003,9 @@ pexprimary(struct parser *P) { } else if (decl->t == Dmacro) { parseexpandmacro(P, &decl->macro); ex = parseexpr(P); + } else if (decl->t == Dtepl) { + ty = parseexpandtepl(P, (struct tepl *)&decl->tepl); + goto typedecl; } else { ex.t = Ename; ex.span = tok.span; diff --git a/bootstrap/test2.cff b/bootstrap/test2.cff index 66603ba..6fbb8fa 100644 --- a/bootstrap/test2.cff +++ b/bootstrap/test2.cff @@ -8,6 +8,10 @@ struct Node { } } +struct Bit { + fn neg(x T) T { return ~x; } +} + extern fn main() void { let n Node = {#null, 0}; let n Node = {&n, 1}; @@ -18,4 +22,7 @@ extern fn main() void { let x Node = {}; n->ok(); x->ok(); + + Bit:neg(3); + Bit:neg(3); } -- cgit v1.2.3