aboutsummaryrefslogtreecommitdiff
path: root/bootstrap/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'bootstrap/parse.c')
-rw-r--r--bootstrap/parse.c21
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);