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