diff options
| author | 2022-08-16 09:19:33 +0200 | |
|---|---|---|
| committer | 2022-08-16 09:19:33 +0200 | |
| commit | 1ca77f60626666fba792db407dd11ea9b597d9cf (patch) | |
| tree | 0e5ea52e457474899ad5f0076bbe658e67626925 /bootstrap/parse.c | |
| parent | 04c7892134d49f3b295a51cc741affe9f02e374d (diff) | |
binary operators and more stuff
Diffstat (limited to 'bootstrap/parse.c')
| -rw-r--r-- | bootstrap/parse.c | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/bootstrap/parse.c b/bootstrap/parse.c index 2eda662..c76445f 100644 --- a/bootstrap/parse.c +++ b/bootstrap/parse.c @@ -395,6 +395,8 @@ lex(struct parser *P) { tok.t = '##'; } else if (!strcmp(s, "#len")) { tok.t = '#len'; + } else if (!strcmp(s, "#ptr")) { + tok.t = '#ptr'; } else if (!strcmp(s, "#when")) { tok.t = TKhwhen; } else if (!strcmp(s, "#tag")) { @@ -1197,9 +1199,14 @@ pexprimary(struct parser *P) { ex.euini.fnam = fld->name; ex.euini.tag = ex.ty->agg.enumty->enu.vals.d[i].i; P->targty = fld->ty; - if (fld->ty) + if (lexmatch(P, &tok, '(') || lexpeek(P).t == '{') { ex.euini.ini = exprdup(parseexpr(P)); - } + if (tok.t == '(') + lexexpect(P, ')'); + } + if (!!ex.euini.ini != !!fld->ty) + fatal(P, tok.span, "invalid tagged union initializer"); + } } else if (lexmatch(P, &tok, '{')) { aggini: P->used_targty = 1; @@ -1367,6 +1374,34 @@ pexpostfix(struct parser *P) { } else { fatal(P, ex.span, "invalid operand to `.#len' (%t)", ex.ty); } + } else if (lexmatch(P, &tok, '#ptr')) { + const struct type *ty = ex.ty; + const struct expr lhs = ex; + bool ptr = 0; + if (ty->t == TYptr) { + ty = ty->child; + ptr = 1; + } + if (ty->t == TYarr) { + ex.ty = interntype((struct type) { + TYptr, g_targ.ptrsize, .child = ty->child + }); + ex.span = tok.span; + if (ptr) { + ex.t = Eprefix; + ex.unop.op = '*'; + ex.unop.child = exprdup(lhs); + } + } else if (ty->t == TYslice) { + ex.ty = interntype((struct type) { + TYptr, g_targ.ptrsize, .child = ty->child + }); + ex = (struct expr) { + Eptr, tok.span, ex.ty, .child = exprdup(lhs) + }; + } else { + fatal(P, ex.span, "invalid operand to `.#ptr' (%t)", ex.ty); + } } else if (lexmatch (P, &tok, '#tag')) { const struct type *ty = ex.ty; if (ty->t == TYptr) @@ -3096,7 +3131,7 @@ parsedecl(decl_yielder_t yield, void *yarg, struct parser *P, bool toplevel) { struct attr attr = {0}; decl.container = P->container; - while (lexmatch(P, &tok, TKhwhen)) { + if (lexmatch(P, &tok, TKhwhen)) { struct expr test = parseexpr(P); if (!fold(&test) || test.ty->t != TYbool) fatal(P, test.span, "#when test is not a constant bool expression"); @@ -3119,6 +3154,7 @@ parsedecl(decl_yielder_t yield, void *yarg, struct parser *P, bool toplevel) { } } } + return; } if (lexmatch(P, &tok, '#')) { |