From 1ca77f60626666fba792db407dd11ea9b597d9cf Mon Sep 17 00:00:00 2001 From: lemon Date: Tue, 16 Aug 2022 09:19:33 +0200 Subject: binary operators and more stuff --- bootstrap/all.h | 1 + bootstrap/bootstrap.sh | 13 +++++++++++-- bootstrap/cgen.c | 7 +++++-- bootstrap/parse.c | 42 +++++++++++++++++++++++++++++++++++++++--- 4 files changed, 56 insertions(+), 7 deletions(-) (limited to 'bootstrap') diff --git a/bootstrap/all.h b/bootstrap/all.h index 932fbe0..720c7ea 100644 --- a/bootstrap/all.h +++ b/bootstrap/all.h @@ -327,6 +327,7 @@ enum exprtype { Emcall, Eslice, Elen, + Eptr, Eeuini, Eeutag, Evastart, diff --git a/bootstrap/bootstrap.sh b/bootstrap/bootstrap.sh index c2fd41e..f221ce2 100755 --- a/bootstrap/bootstrap.sh +++ b/bootstrap/bootstrap.sh @@ -2,11 +2,16 @@ cd $(dirname "$0") -./build.sh || exit 1 - if [ x"$CC" == x ]; then export CC=cc fi + +if command -v ccache > /dev/null; then + export CC="ccache $CC" +fi + +./build.sh || exit 1 + export CFLAGS="-Wno-builtin-declaration-mismatch -Wno-discarded-qualifiers -g" set -euo pipefail @@ -16,5 +21,9 @@ for f in $(find ../src/ -name '*.cff'); do out=obj1/$(basename "$f").o (set -x ; ./cff0 "$f" | $CC $CFLAGS -xc - -c -o $out) done +for f in $(find ../src/ -name '*.c'); do + out=obj1/$(basename "$f").o + (set -x ; $CC $CFLAGS "$f" -c -o $out) +done set -x $CC $CFLAGS -ocff1 obj1/*.o diff --git a/bootstrap/cgen.c b/bootstrap/cgen.c index 15fab93..0887ca7 100644 --- a/bootstrap/cgen.c +++ b/bootstrap/cgen.c @@ -288,7 +288,10 @@ genexpr(struct expr *ex) { ++id; break; case Elen: - pri("%e.len", ex->child); + pri("%e%slen", ex->child, ex->child->ty->t == TYptr ? "->" : "."); + break; + case Eptr: + pri("%e%sptr", ex->child, ex->child->ty->t == TYptr ? "->" : "."); break; case Eeutag: pri("%e%st", ex->child, ex->child->ty->t == TYptr ? "->" : "."); @@ -518,7 +521,7 @@ liftnestedex(struct expr *ex) { case Eblock: liftnested(blocktostmt(ex->block)); break; - case Eas: case Elen: case Eeutag: + case Eas: case Elen: case Eeutag: case Eptr: liftnestedex(ex->child); break; case Eini: 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, '#')) { -- cgit v1.2.3