diff options
Diffstat (limited to 'bootstrap/parse.c')
| -rw-r--r-- | bootstrap/parse.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/bootstrap/parse.c b/bootstrap/parse.c index cd41b47..59d3b5f 100644 --- a/bootstrap/parse.c +++ b/bootstrap/parse.c @@ -808,6 +808,8 @@ islvalue(const struct expr *ex) { return 1; if (ex->t == Eindex || ex->t == Eget) return 1; + if (ex->t == Eini) + return 1; return 0; } @@ -1970,16 +1972,33 @@ psteuswitch(struct parser *P, const struct expr *test) { c.vval = c.fld - test->ty->agg.flds.d; if (!c.fld) fatal(P, tok.span, "%t has no such variant %T", test->ty, tok); + if (c.fld->ty && lexmatch(P, &tok, '*')) { + if (!islvalue(test)) { + fatal(P, tok.span, "cannot capture by pointer, test expression is not lvalue"); + } + c.captptr = 1; + st.euswitch.byptr = 1; + if (lexpeek(P).t != TKident) + lexexpect(P, TKident); + } if (c.fld->ty && lexmatch(P, &tok, TKident)) { struct env env = {P->curenv}; + const struct type *ty = c.fld->ty; + c.capt = tok.str; + if (c.captptr) { + ty = interntype((struct type) { + TYptr, g_targ.ptrsize, .child = test->ty->konst ? constify(ty) : ty + }); + } pushenv(P, &env); putdecl(P, tok.span, &(struct decl) { Dlet, c.capt, .span = tok.span, .var = { - c.fld->ty, NULL, c.captid = P->varid++, P->curfn->id + c.captty = ty, NULL, c.captid = P->varid++, P->curfn->id } }); } + lexexpect(P, ';'); c.t = parseblock0(P); if (c.capt) popenv(P); |