diff options
| -rw-r--r-- | .gitignore | 4 | ||||
| -rw-r--r-- | bootstrap/.gitignore | 1 | ||||
| -rw-r--r-- | bootstrap/all.h | 11 | ||||
| -rwxr-xr-x | bootstrap/bootstrap.sh | 20 | ||||
| -rwxr-xr-x | bootstrap/cff1 | bin | 0 -> 21520 bytes | |||
| -rw-r--r-- | bootstrap/obj1/main.cff.o | bin | 0 -> 4288 bytes | |||
| -rw-r--r-- | bootstrap/parse.c | 21 | ||||
| -rw-r--r-- | bootstrap/types.c | 6 | ||||
| -rw-r--r-- | src/libc.hff | 7 | ||||
| -rw-r--r-- | src/main.cff | 7 | ||||
| -rw-r--r-- | src/parse.hff | 18 |
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 Binary files differnew file mode 100755 index 0000000..7b0e748 --- /dev/null +++ b/bootstrap/cff1 diff --git a/bootstrap/obj1/main.cff.o b/bootstrap/obj1/main.cff.o Binary files differnew file mode 100644 index 0000000..7264f1c --- /dev/null +++ b/bootstrap/obj1/main.cff.o 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 + }, +} |