diff options
| author | 2022-08-08 09:16:13 +0200 | |
|---|---|---|
| committer | 2022-08-08 09:16:13 +0200 | |
| commit | f8a8add7d0e74d20304b3194e836752a9986ddc3 (patch) | |
| tree | d4c72f796c9b97c229f299b1632c6a5c9ffc3e37 /bootstrap/parse.c | |
| parent | 0a57a8979a75ce5398b34817c86a55c6d0552bca (diff) | |
direct access of eunion fields
Diffstat (limited to 'bootstrap/parse.c')
| -rw-r--r-- | bootstrap/parse.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/bootstrap/parse.c b/bootstrap/parse.c index 93a3afb..3e14dc3 100644 --- a/bootstrap/parse.c +++ b/bootstrap/parse.c @@ -371,6 +371,8 @@ lex(struct parser *P) { tok.t = '##'; } else if (!strcmp(s, "#len")) { tok.t = '#len'; + } else if (!strcmp(s, "#tag")) { + tok.t = '#tag'; } else if (!strcmp(s, "#?")) { tok.t = '#?'; } else if (!strncmp(s, "#:", 2)) { @@ -1284,27 +1286,39 @@ pexpostfix(struct parser *P) { if (ty->t == TYarr) { assert(ty->length >= 0); ex.t = Eintlit; - ex.ty = ty_usize; + ex.ty = ty->konst ? constify(ty_usize) : ty_usize; ex.span = tok.span; ex.i = ty->length; } else if (ty->t == TYslice) { ex.child = exprdup(ex); ex.t = Elen; - ex.ty = ty_usize; + ex.ty = ty->konst ? constify(ty_usize) : ty_usize; ex.span = tok.span; } else { fatal(P, ex.span, "invalid operand to `.#len' (%t)", ex.ty); } + } else if (lexmatch (P, &tok, '#tag')) { + const struct type *ty = ex.ty; + if (ty->t == TYptr) + ty = ty->child; + if (ty->t != TYeunion) + fatal(P, ex.span, "invalid operand to `.#tag' (%t)", ex.ty); + ex.child = exprdup(ex); + ex.t = Eeutag; + ex.ty = ty->konst ? constify(ty->agg.enumty) : ty->agg.enumty; + ex.span = tok.span; } else { const char *fnam = (tok = lexexpect(P, TKident)).str; const struct type *ty = ex.ty; if (ty->t == TYptr) ty = ty->child; - if (ty->t == TYstruct || ty->t == TYunion) { + if (ty->t == TYstruct || ty->t == TYunion || ty->t == TYeunion) { int idx = structfldnam2idx(ty, fnam); struct aggfield *fld = &ty->agg.flds.d[idx]; if (idx < 0) fatal(P, tok.span, "%t has no such field `%s'", ty, fnam); + if (!fld->ty) + fatal(P, tok.span, "%t variant `%s' is empty", ty, fnam); ex.get.lhs = exprdup(ex); ex.t = Eget; @@ -1748,7 +1762,7 @@ parsevardecl(decl_yielder_t yield, void *yarg, struct parser *P, bool let, bool if (lexmatch(P, NULL, '=')) { ini = exprdup(parseexpr(P)); - ty = ini->ty; + ty = unconstify(ini->ty); } else { ty = parsetype(P); if (lexmatch(P, NULL, '=')) { |