aboutsummaryrefslogtreecommitdiff
path: root/bootstrap
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-16 09:19:33 +0200
committerlemon <lsof@mailbox.org>2022-08-16 09:19:33 +0200
commit1ca77f60626666fba792db407dd11ea9b597d9cf (patch)
tree0e5ea52e457474899ad5f0076bbe658e67626925 /bootstrap
parent04c7892134d49f3b295a51cc741affe9f02e374d (diff)
binary operators and more stuff
Diffstat (limited to 'bootstrap')
-rw-r--r--bootstrap/all.h1
-rwxr-xr-xbootstrap/bootstrap.sh13
-rw-r--r--bootstrap/cgen.c7
-rw-r--r--bootstrap/parse.c42
4 files changed, 56 insertions, 7 deletions
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, '#')) {