aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbootstrap/bootstrap.sh5
-rwxr-xr-xbootstrap/cff2bin473824 -> 477920 bytes
-rw-r--r--bootstrap/parse.c22
-rw-r--r--src/cffc.hff2
-rw-r--r--src/fmt.cff2
-rw-r--r--src/fold.cff6
-rw-r--r--src/libc.hff2
-rw-r--r--src/parse.cff17
8 files changed, 40 insertions, 16 deletions
diff --git a/bootstrap/bootstrap.sh b/bootstrap/bootstrap.sh
index 4a45470..5669fd3 100755
--- a/bootstrap/bootstrap.sh
+++ b/bootstrap/bootstrap.sh
@@ -44,3 +44,8 @@ echo '==========================================================================
echo '=== Building self-hosted compiler using self-hosted compiler squared (cffc) ==='
echo '==============================================================================='
CFFC=$(dirname "$0")/cff2 make -C ../ clean all
+
+cd ..
+set -x
+md5sum bootstrap/cff2
+md5sum cffc
diff --git a/bootstrap/cff2 b/bootstrap/cff2
index 5a54715..a70d3e0 100755
--- a/bootstrap/cff2
+++ b/bootstrap/cff2
Binary files differ
diff --git a/bootstrap/parse.c b/bootstrap/parse.c
index b16ef13..0843940 100644
--- a/bootstrap/parse.c
+++ b/bootstrap/parse.c
@@ -3218,8 +3218,8 @@ defyield(struct decl *decl, void *arg) {
if (!decl->var.ini)
fatal(a->P, decl->span, "def must have a value");
fold(decl->var.ini);
- //if (!fold(decl->var.ini))
- // fatal(a->P, decl->var.ini->span, "def initializer must be constant expression");
+ if (!fold(decl->var.ini))
+ fatal(a->P, decl->var.ini->span, "def initializer must be constant expression");
putdecl(a->P, decl->span, decl);
if (a->yield)
a->yield(decl, a->yarg);
@@ -3309,10 +3309,20 @@ parsedecl(decl_yielder_t yield, void *yarg, struct parser *P, bool toplevel) {
} else if (lexmatch(P, &tok, TKkw_defmacro)) {
if (externp) fatal(P, tok.span, "macro cannot be `extern'");
name = lexexpects(P, TKident, "macro name").str;
- decl.t = Dmacro;
- decl.name = name;
- decl.macro = parsemacro(P);
- decl.macro.name = name;
+ if (lexmatch(P, &tok, '=')) {
+ // defmacro name = expr
+ struct expr ex = parseexpr(P);
+ decl.t = Ddef;
+ decl.name = name;
+ decl.var.ini = exprdup(ex);
+ decl.var.ty = ex.ty;
+ lexexpect(P, ';');
+ } else {
+ decl.t = Dmacro;
+ decl.name = name;
+ decl.macro = parsemacro(P);
+ decl.macro.name = name;
+ }
} else if (lexmatch(P, &tok, TKkw_enum)) {
decl.t = Dtype;
if (lexmatch(P, &tok, TKkw_union)) {
diff --git a/src/cffc.hff b/src/cffc.hff
index 3e6a66f..7338b8a 100644
--- a/src/cffc.hff
+++ b/src/cffc.hff
@@ -41,7 +41,7 @@ enum TokT : i32 {
typearg,
eof,
}
-def NUM_KEYWORDS = as(int)TokT:NUM_KEYWORDS;
+def NUM_KEYWORDS int = TokT:NUM_KEYWORDS;
struct Tok {
t TokT,
diff --git a/src/fmt.cff b/src/fmt.cff
index befde61..60ee5f9 100644
--- a/src/fmt.cff
+++ b/src/fmt.cff
@@ -392,7 +392,7 @@ extern fn warn(P *Parser, loc Loc, fmt *const u8, ...) void {
extern fn err(P *Parser, loc Loc, fmt *const u8, ...) void {
P.error = #t;
static nerr int = 0;
- if nerr++ == 20 {
+ if nerr++ == 7 {
efmt("Aborting due to too many errors.\n");
exit(1);
}
diff --git a/src/fold.cff b/src/fold.cff
index 8814d32..be08256 100644
--- a/src/fold.cff
+++ b/src/fold.cff
@@ -24,16 +24,18 @@ fn numcast(ex *Expr, to *const Type) void {
*f = *f;
case from->is(:Bool);
iu.i = *b ? 1 : 0;
- case from->is(:Int) and to == ty_u8;
+ case from->is(:Int) and to == ty_i8;
iu.i = as(i8)iu.i;
case from->is(:Int) and to == ty_u8;
iu.i = as(u8)iu.i;
case from->is(:Int) and to == ty_i16;
iu.i = as(i16)iu.i;
case from->is(:Int) and to == ty_u16;
- iu.i = as(u8)iu.i;
+ iu.i = as(u16)iu.i;
case from->is(:Int) and to == ty_i32;
iu.i = as(i32)iu.i;
+ case from->is(:Int) and to == ty_u32;
+ iu.i = as(u32)iu.i;
case from->is(:Int) and to == ty_i64;
iu.i = as(i64)iu.i;
case from->is(:Int) and to == ty_u64;
diff --git a/src/libc.hff b/src/libc.hff
index 0744d35..533a933 100644
--- a/src/libc.hff
+++ b/src/libc.hff
@@ -42,4 +42,4 @@ extern fn tolower(int) int;
// errno.h
extern fn c_errno() int;
-def errno = c_errno();
+defmacro errno = c_errno();
diff --git a/src/parse.cff b/src/parse.cff
index b1dca70..112c432 100644
--- a/src/parse.cff
+++ b/src/parse.cff
@@ -3159,8 +3159,6 @@ fn parsedecls(P *Parser, loc Loc, yield DeclYielder, yarg *void, toplevel bool)
case lexmatch(P, &tok, :kw_def);
do {
- let konst = lexmatch(P, #null, :kw_const);
-
let tok = lexexpect(P, :ident),
name = tok.u.ident,
ini Expr #?,
@@ -3177,8 +3175,10 @@ fn parsedecls(P *Parser, loc Loc, yield DeclYielder, yarg *void, toplevel bool)
if !typematchestarg(ty, ini.ty) {
err(P, ini.loc, "incompatible initializer (%t, expected %t)", ini.ty, ty);
}
- let f = fold(&ini);
- if konst and !f {
+ if ty != ini.ty {
+ ini = { ini.loc, ty, :Cast(exprdup(P.alloc, ini)) };
+ }
+ if !fold(&ini) {
err(P, ini.loc, "cannot evaluate expression at compile time");
}
decl = putdecl(P, tok.loc, { name, tok.loc, .u: :Def(ini) });
@@ -3194,7 +3194,14 @@ fn parsedecls(P *Parser, loc Loc, yield DeclYielder, yarg *void, toplevel bool)
case lexmatch(P, &tok, :kw_defmacro);
let name = lexexpects(P, :ident, "macro name").u.ident;
- decl = parsemacro(P, tok.loc, name);
+ if lexmatch(P, &tok, '=') {
+ // defmacro x = expr
+ let ini = parseexpr(P);
+ decl = putdecl(P, tok.loc, { name, tok.loc, .u: :Def(ini) });
+ lexexpect(P, ';');
+ } else {
+ decl = parsemacro(P, tok.loc, name);
+ }
case lexmatch(P, &tok, :kw_typedef);
let name = lexexpects(P, :ident, "typedef name").u.ident;