diff options
| author | 2022-08-05 04:27:38 +0200 | |
|---|---|---|
| committer | 2022-08-05 04:27:38 +0200 | |
| commit | b0d95956fcade40a2d608ccea79e2e989f97b72f (patch) | |
| tree | c14f21aba1acc52d0f2fd1320b48fac42de634bc /bootstrap/parse.c | |
| parent | 0fec7de747d93586eda66ce190f5f3d6715421a4 (diff) | |
more struct
Diffstat (limited to 'bootstrap/parse.c')
| -rw-r--r-- | bootstrap/parse.c | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/bootstrap/parse.c b/bootstrap/parse.c index 659f756..e473f23 100644 --- a/bootstrap/parse.c +++ b/bootstrap/parse.c @@ -666,6 +666,7 @@ parsestructini(struct parser *P, const struct type *ty) { } fld = structidx2fld(ty, idx++); + P->targty = fld->ty; e = parseexpr(P); if (!fld) fatal(P, e.span, @@ -713,6 +714,7 @@ parsearrini(struct parser *P, const struct type *ty) { lexexpect(P, '='); } + P->targty = ty->child; e = parseexpr(P); if (!typeof2(ty->child, e.ty)) fatal(P, e.span, "incompatible element type in array initializer"); @@ -737,7 +739,7 @@ pexprimary(struct parser *P) { struct expr ex = {0}; struct tok tok; - P->used_targetty = 0; + P->used_targty = 0; if (lexmatch(P, &tok, TKintlit) || lexmatch(P, &tok, TKchrlit)) { ex.t = Eintlit; @@ -785,6 +787,10 @@ pexprimary(struct parser *P) { lexexpect(P, ':'); P->targty = ty; goto enumlit; + } else if (ty->t == TYstruct || ty->t == TYenum) { + lexexpect(P, '{'); + P->targty = ty; + goto aggini; } else { goto experr; } @@ -819,7 +825,6 @@ pexprimary(struct parser *P) { struct stmt *last = &block.stmts.d[block.stmts.n - 1]; if (last->t == Sexpr) ex.ty = last->expr.ty; - } } else { ex = parseexpr(P); @@ -828,7 +833,7 @@ pexprimary(struct parser *P) { } else if (lexmatch(P, &tok, ':')) { const char *vname; int i; - enumlit: + enumlit: vname = (tok = lexexpect(P, TKident)).str; if (!(ex.ty = P->targty) || ex.ty->t != TYenum) fatal(P, tok.span, "cannot infer type for enum literal `:%s'", vname); @@ -838,12 +843,13 @@ pexprimary(struct parser *P) { fatal(P, tok.span, "enum `%s' contains no variant `%s'", ex.ty->enu.name, vname); found: - P->used_targetty = 1; + P->used_targty = 1; ex.t = Eenumval; ex.enu.vname = vname; ex.enu.i = ex.ty->enu.vals.d[i].i; } else if (lexmatch(P, &tok, '{')) { - P->used_targetty = 1; + aggini: + P->used_targty = 1; if (!P->targty) fatal(P, tok.span, "cannot infer type for compound initializer"); if (lexmatch(P, &tok, '}')) @@ -866,7 +872,7 @@ pexpostfix(struct parser *P) { struct expr ex = pexprimary(P); struct tok tok; - if (P->used_targetty) return ex; + if (P->used_targty) return ex; for (;;) if (lexmatch(P, &tok, '(')) { vec_t(struct expr) args = {0}; @@ -924,6 +930,23 @@ pexpostfix(struct parser *P) { tok.t, exprdup(ex) } }; + } else if (lexmatch(P, &tok, '.')) { + const char *fnam = (tok = lexexpect(P, TKident)).str; + if (ex.ty->t == TYstruct || ex.ty->t == TYunion) { + int idx = structfldnam2idx(ex.ty, fnam); + struct aggfield *fld = &ex.ty->agg.flds.d[idx]; + if (idx < 0) + fatal(P, tok.span, "no such field `%s'", fnam); + + ex.get.lhs = exprdup(ex); + ex.t = Eget; + ex.span = tok.span; + ex.ty = fld->ty; + ex.get.fld = fnam; + } else { + fatal(P, tok.span, "cannot acces `%s': left-hand-side is not an aggregate", + fnam); + } } else { break; } @@ -1054,7 +1077,7 @@ pexbitarith(struct parser *P) { int oret; ex = pexprefix(P); - if (P->used_targetty) return ex; + if (P->used_targty) return ex; if (!(oret = peeksbitarithop(P, &tok))) return ex; tokt = tok.t; @@ -1130,7 +1153,7 @@ pexcmp(struct parser *P) { struct tok tok; ex = pexbitarith(P); - if (P->used_targetty) return ex; + if (P->used_targty) return ex; if (matchcmpop(P, &tok)) { struct expr rhs = pexbitarith(P); if (!typeof2(ex.ty, rhs.ty)) @@ -1155,7 +1178,7 @@ pexlog(struct parser *P) { int tokt; ex = pexcmp(P); - if (P->used_targetty) return ex; + if (P->used_targty) return ex; tok = lexpeek(P); tokt = tok.t; if (tokt != TKkw_and && tokt != TKkw_or) @@ -1183,7 +1206,7 @@ pexcond(struct parser *P) { struct tok tok; ex = pexlog(P); - if (P->used_targetty) return ex; + if (P->used_targty) return ex; if (lexmatch(P, &tok, '?')) { struct expr ex2 = parseexpr(P); struct expr ex3; @@ -1228,7 +1251,7 @@ pexassign(struct parser *P) { int oret; ex = pexcond(P); - if (P->used_targetty) return ex; + if (P->used_targty) return ex; if ((oret = matchassignop(P, &tok))) { struct expr rhs = pexcond(P); if (!islvalue(&ex)) |