aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--bootstrap/.gitignore1
-rw-r--r--bootstrap/all.h11
-rwxr-xr-xbootstrap/bootstrap.sh20
-rwxr-xr-xbootstrap/cff1bin0 -> 21520 bytes
-rw-r--r--bootstrap/obj1/main.cff.obin0 -> 4288 bytes
-rw-r--r--bootstrap/parse.c21
-rw-r--r--bootstrap/types.c6
-rw-r--r--src/libc.hff7
-rw-r--r--src/main.cff7
-rw-r--r--src/parse.hff18
11 files changed, 90 insertions, 5 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..eb3e33c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+compile_commands.json
+a.out
+.gdb_history
+.cache/
diff --git a/bootstrap/.gitignore b/bootstrap/.gitignore
index 51939a1..0de93ae 100644
--- a/bootstrap/.gitignore
+++ b/bootstrap/.gitignore
@@ -3,3 +3,4 @@ a.out
cff0
.gdb_history
.cache/
+obj0/
diff --git a/bootstrap/all.h b/bootstrap/all.h
index 373aac9..3cadd4c 100644
--- a/bootstrap/all.h
+++ b/bootstrap/all.h
@@ -180,6 +180,7 @@ struct type {
const char *name;
i64 i;
}) vals;
+ bool lax;
int id;
} enu;
struct {
@@ -243,6 +244,16 @@ enum decltype {
Dlabel,
};
+struct attr {
+ union {
+ struct {
+ uint lax : 1;
+ };
+ uint bits;
+ };
+
+};
+
struct decl {
enum decltype t;
const char *name;
diff --git a/bootstrap/bootstrap.sh b/bootstrap/bootstrap.sh
new file mode 100755
index 0000000..1cb9f42
--- /dev/null
+++ b/bootstrap/bootstrap.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+cd $(dirname "$0")
+
+./build.sh
+
+if [ x"$CC" == x ]; then
+ export CC=cc
+fi
+export CFLAGS="-Wno-builtin-declaration-mismatch -g"
+
+set -euo pipefail
+
+mkdir -p obj1/
+for f in $(find ../src/ -name '*.cff'); do
+ out=obj1/$(basename "$f").o
+ (set -x ; ./cff0 "$f" | $CC $CFLAGS -xc - -c -o $out)
+done
+set -x
+$CC $CFLAGS -ocff1 obj1/*.o
diff --git a/bootstrap/cff1 b/bootstrap/cff1
new file mode 100755
index 0000000..7b0e748
--- /dev/null
+++ b/bootstrap/cff1
Binary files differ
diff --git a/bootstrap/obj1/main.cff.o b/bootstrap/obj1/main.cff.o
new file mode 100644
index 0000000..7264f1c
--- /dev/null
+++ b/bootstrap/obj1/main.cff.o
Binary files differ
diff --git a/bootstrap/parse.c b/bootstrap/parse.c
index 1327e71..67ec66d 100644
--- a/bootstrap/parse.c
+++ b/bootstrap/parse.c
@@ -621,7 +621,7 @@ exprdup(struct expr ex) {
}
static const struct type *parseagg(struct parser *P, const char *name, int kind, struct decl **retdecl);
-static const struct type *parseenum(struct parser *P, const char *name);
+static const struct type *parseenum(struct parser *P, const char *name, struct attr);
static const struct type *
parseexpandtepl(struct parser *P, struct tepl *tepl) {
@@ -763,7 +763,7 @@ parsetype(struct parser *P) {
struct decl *_decl;
return parseagg(P, NULL, TYunion, &_decl);
} else if (lexmatch(P, &tok, TKkw_enum)) {
- return parseenum(P, NULL);
+ return parseenum(P, NULL, (struct attr){0});
} else if (lexmatch(P, &tok, TKkw_typeof)) {
const struct type *ty = NULL, *ty2, *ty0;
lexexpect(P, '(');
@@ -2534,12 +2534,13 @@ parsemacro(struct parser *P) {
}
static const struct type *
-parseenum(struct parser *P, const char *name) {
+parseenum(struct parser *P, const char *name, struct attr attr) {
struct tok tok;
struct type ty = {TYenum};
static int id = 0;
i64 iota = 0, max = 0, min = 0;
vec_t(struct enumval) vals = {0};
+ ty.enu.lax = attr.lax;
if (lexmatch(P, &tok, ':')) {
ty.enu.intty = unconstify(parsetype(P));
@@ -2905,6 +2906,18 @@ parsedecl(decl_yielder_t yield, void *yarg, struct parser *P, bool toplevel) {
int kind;
struct decl decl = {0};
struct decl* decl2 = NULL;
+ struct attr attr = {0};
+
+ if (lexmatch(P, &tok, '#')) {
+ lexexpect(P, '[');
+ while (!lexmatch(P, NULL, ']')) {
+ const char *a = (tok = lexexpect(P, TKident)).str;
+ if (!strcmp(a, "lax"))
+ attr.lax = 1;
+ else
+ fatal(P, tok.span, "unknown attribute %T", tok);
+ }
+ }
if (lexmatch(P, &tok, TKkw_extern))
externp = 1;
@@ -2955,7 +2968,7 @@ parsedecl(decl_yielder_t yield, void *yarg, struct parser *P, bool toplevel) {
} else {
if (externp) fatal(P, tok.span, "enum cannot be `extern'");
decl.name = lexexpects(P, TKident, "enum name").str;
- decl.ty = parseenum(P, decl.name);
+ decl.ty = parseenum(P, decl.name, attr);
}
} else if (lexmatch(P, &tok, TKkw_struct)) {
kind = TYstruct;
diff --git a/bootstrap/types.c b/bootstrap/types.c
index 78a3df0..9118392 100644
--- a/bootstrap/types.c
+++ b/bootstrap/types.c
@@ -314,6 +314,10 @@ arraydecay(const struct type *ty) {
int
numtype2rank(const struct type *a) {
a = unconstify(a);
+ if (a->t == TYenum) {
+ assert(a->enu.lax);
+ a = a->enu.intty;
+ }
if (a->t == TYint) {
if (a->size < g_targ.intsize || a == ty_int)
return 0;
@@ -340,7 +344,7 @@ rank2numtype(int r) {
bool
isnumtype(const struct type *a) {
- return a->t == TYint || a->t == TYfloat;
+ return a->t == TYint || a->t == TYfloat || (a->t == TYenum && a->enu.lax);
}
// peer type resolution
diff --git a/src/libc.hff b/src/libc.hff
new file mode 100644
index 0000000..98a6f3c
--- /dev/null
+++ b/src/libc.hff
@@ -0,0 +1,7 @@
+! stdio.h
+struct FILE;
+extern static stdin FILE,
+ stdout FILE,
+ stderr FILE;
+extern fn printf(fmt *const u8, ...) void;
+extern fn fprintf(fp *FILE, fmt *const u8, ...) void;
diff --git a/src/main.cff b/src/main.cff
new file mode 100644
index 0000000..1dbbbee
--- /dev/null
+++ b/src/main.cff
@@ -0,0 +1,7 @@
+import "libc.hff";
+import "parse.hff";
+
+extern fn main(argc int, argv **u8) int {
+ let t Tok = { TokT:kw_or, { .i: 1 } };
+ printf("%d\n", TokT:kw_or);
+}
diff --git a/src/parse.hff b/src/parse.hff
new file mode 100644
index 0000000..463dd26
--- /dev/null
+++ b/src/parse.hff
@@ -0,0 +1,18 @@
+struct Loc {
+ fileid u16,
+ idx isize,
+ col int,
+ line int,
+}
+
+#[lax]
+enum TokT {
+ kw_or
+}
+
+struct Tok {
+ t int,
+ u union {
+ i i64
+ },
+}