From 0d1e125832d0fd8ca31c5f782e7c3db774ae5a02 Mon Sep 17 00:00:00 2001 From: lemon Date: Sun, 14 Aug 2022 11:16:03 +0200 Subject: woa --- bootstrap/ack.cff | 15 ----- bootstrap/all.h | 1 + bootstrap/cgen.c | 8 ++- bootstrap/env.c | 4 ++ bootstrap/parse.c | 17 +++-- examples/ack.cff | 15 +++++ examples/libc.hff | 32 ++++++++++ src/all.hff | 185 ------------------------------------------------------ src/cffc.hff | 131 ++++++++++++++++++++++++++++++++++++++ src/common.hff | 45 +++++++++++++ src/env.cff | 3 +- src/fmt.cff | 25 +++++--- src/main.cff | 5 +- src/map.hff | 5 +- src/mem.hff | 3 +- src/parse.cff | 23 ++++++- src/set.hff | 36 ++++++----- src/targ.cff | 3 +- src/targ.hff | 12 ++++ src/type.cff | 3 +- src/type.hff | 15 +++++ src/util.cff | 5 +- src/util.hff | 12 ++++ src/vec.hff | 9 +-- 24 files changed, 366 insertions(+), 246 deletions(-) delete mode 100644 bootstrap/ack.cff create mode 100644 examples/ack.cff create mode 100644 examples/libc.hff delete mode 100644 src/all.hff create mode 100644 src/cffc.hff create mode 100644 src/common.hff create mode 100644 src/targ.hff create mode 100644 src/type.hff create mode 100644 src/util.hff diff --git a/bootstrap/ack.cff b/bootstrap/ack.cff deleted file mode 100644 index 233abc2..0000000 --- a/bootstrap/ack.cff +++ /dev/null @@ -1,15 +0,0 @@ -import "libc.hff"; - -fn ack(m uint, n uint) uint { - if m == 0 { return n + 1; } - if n == 0 { return ack(m - 1, 1); } - return ack(m - 1, ack(m, n - 1)); -} - -extern fn main() void { - for let m = 0; m <= 4; ++m { - for let n = 0; n < 6 - m; ++n { - printf("A(%u,%u) = %u\n", m, n, ack(m, n)); - } - } -} diff --git a/bootstrap/all.h b/bootstrap/all.h index 9bbab37..bb0711a 100644 --- a/bootstrap/all.h +++ b/bootstrap/all.h @@ -290,6 +290,7 @@ struct decl { int loopid; }; int age; + bool _gen; }; struct teplparam { diff --git a/bootstrap/cgen.c b/bootstrap/cgen.c index 5c64a30..39cbba0 100644 --- a/bootstrap/cgen.c +++ b/bootstrap/cgen.c @@ -50,7 +50,11 @@ pristring(const char *s, u64 n) { extern int isprint(int); pri("\""); for (int i = 0; i < n; ++i) { - if (isprint(s[i])) + if (s[i] == '"') + pri("\\\""); + else if (s[i] == '\\') + pri("\\\\"); + else if (isprint(s[i])) pri("%c", s[i]); else fprintf(outfp, "\\%.3o", s[i]); @@ -699,6 +703,7 @@ genstatic(bool externp, const char *cname, struct var *var) { static void gendecl(struct decl *decl, bool toplevel) { const char *p = fileid2path(decl->span.fileid); + if (decl->_gen) return; switch (decl->t) { case Dfn: pri("#line %d %S\n", decl->span.line, p, (u64)strlen(p)); @@ -718,6 +723,7 @@ gendecl(struct decl *decl, bool toplevel) { case Dtype: case Ddef: case Dtepl: case Dmacro: case Dlabel: break; } + decl->_gen = 1; } static void diff --git a/bootstrap/env.c b/bootstrap/env.c index 40392b9..21d9580 100644 --- a/bootstrap/env.c +++ b/bootstrap/env.c @@ -42,6 +42,10 @@ envput(struct env *env, const struct decl *decl) { return d0; if (d0->t == Dmacro && !memcmp(&decl->macro, &d0->macro, sizeof decl->macro)) return d0; + if (d0->t == Dtype && d0->ty == decl->ty) + return d0; + if (d0->t == Dfn && !memcmp(&decl->fn, &d0->fn, sizeof decl->fn)) + return d0; if (d0->t == Dtepl && !memcmp(&decl->tepl, &d0->tepl, sizeof decl->tepl)) return d0; for (int kind = TYstruct; kind <= TYeunion; ++kind) { diff --git a/bootstrap/parse.c b/bootstrap/parse.c index 4a1721d..0c619fc 100644 --- a/bootstrap/parse.c +++ b/bootstrap/parse.c @@ -2925,7 +2925,7 @@ getbasedir(const char *path) { static struct comfile doimport(struct parser *P, const char *path) { - static vec_t(struct entry { const char *s; struct comfile cf; }) seen; + static vec_t(struct entry { const char *s; struct comfile cf; bool wip; }) seen; char path2[PATH_MAX], _rpath[PATH_MAX], *rpath; struct comfile cf = {0}; struct parser P2; @@ -2934,16 +2934,23 @@ doimport(struct parser *P, const char *path) { if (!(rpath = realpath(path2, _rpath))) fatal(P, P->tokspan, "import %q: %s", path, strerror(errno)); - for (int i = 0; i < seen.length; ++i) - if (!strcmp(seen.data[i].s, rpath)) - return seen.data[i].cf; + for (int i = 0; i < seen.length; ++i) { + if (!strcmp(seen.data[i].s, rpath)) { + if (seen.data[i].wip) { + epri("warning: \"%s\": circular import detected: \"%s\" being processed\n", + P->curfile, path); + } + return seen.data[i].cf; + } + } rpath = xstrdup(rpath); // P2.primenv = P->primenv; initparser(&P2, rpath); P2.is_header = 1; - vec_push(&seen, ((struct entry) { rpath, cf })); + vec_push(&seen, ((struct entry) { rpath, cf, 1 })); parse(&cf, &P2); + seen.data[seen.length - 1].wip = 0; seen.data[seen.length - 1].cf = cf; return cf; } diff --git a/examples/ack.cff b/examples/ack.cff new file mode 100644 index 0000000..233abc2 --- /dev/null +++ b/examples/ack.cff @@ -0,0 +1,15 @@ +import "libc.hff"; + +fn ack(m uint, n uint) uint { + if m == 0 { return n + 1; } + if n == 0 { return ack(m - 1, 1); } + return ack(m - 1, ack(m, n - 1)); +} + +extern fn main() void { + for let m = 0; m <= 4; ++m { + for let n = 0; n < 6 - m; ++n { + printf("A(%u,%u) = %u\n", m, n, ack(m, n)); + } + } +} diff --git a/examples/libc.hff b/examples/libc.hff new file mode 100644 index 0000000..488a495 --- /dev/null +++ b/examples/libc.hff @@ -0,0 +1,32 @@ +// stdio.h +struct FILE; +extern static stdin *FILE, + stdout *FILE, + stderr *FILE; +extern fn printf(fmt *const u8, ...) int; +extern fn fprintf(fp *FILE, fmt *const u8, ...) int; +extern fn sprintf(*u8, fmt *const u8, ...) int; +extern fn snprintf(*u8, usize, fmt *const u8, ...) int; +extern fn fopen(path *const u8, mode *const u8) *FILE; +extern fn fclose(*FILE) int; +extern fn fgetc(*FILE) int; +extern fn fputc(int, *FILE) int; +def EOF = -1; + +// stdlib.h +extern fn abort() void; +extern fn exit(c int) void; +extern fn perror(s *const u8) void; +extern fn malloc(n usize) *void; +extern fn calloc(n usize, m usize) *void; +extern fn realloc(p *void, n usize) *void; +extern fn free(p *void) void; + +// string.h +extern fn strlen(s *const u8) usize; +extern fn strcmp(a *const u8, b *const u8) int; +extern fn memcpy(*void, *const void, usize) *void; +extern fn strcpy(*u8, *const u8) *u8; + +//ctype.h +extern fn tolower(int) int; diff --git a/src/all.hff b/src/all.hff deleted file mode 100644 index 4ae3e26..0000000 --- a/src/all.hff +++ /dev/null @@ -1,185 +0,0 @@ -import "mem.hff"; -import "libc.hff"; -import "option.hff"; - -/// Macros - -defmacro assert { -(ex, s, ...args) [ - (do - if not (ex) { - fprintf(stderr, "%s:%d: assertion failed: ", #FILE, #LINE); - fprintf(stderr, s, args); - fprintf(stderr, "\n"); - abort(); - } - ) -] -} - -defmacro foreach(x, i, a, ...body) [ - { - let $a = a; - for let i = 0; i < $a.#len; ++i { - let x = $a[i]; - { body } - } - } -] - -defmacro streq(a,b) [ (strcmp(a,b) == 0) ] - -/// Types - -struct Type; -struct Decl; -struct Expr; -struct Env; - -struct Loc { - fileid i16, - col i16, - line int, - idx isize, -} - -#[lax] -enum TokT : i32 { - // !sorted - kw_and, kw_as, kw_break, kw_case, kw_const, - kw_continue, kw_def, kw_defmacro, kw_do, - kw_else, kw_enum, kw_extern, kw_fn, - kw_for, kw_if, kw_import, kw_let, kw_not, - kw_or, kw_return, kw_sizeof, kw_static, - kw_struct, kw_switch, kw_typedef, kw_typeof, - kw_union, kw_while, - NUM_KEYWORDS, - int = -100, - flo, - bool, - str, - chr, - null, - ident, - macident, - gensym, - type, - label, - strify, - eof, -} -def NUM_KEYWORDS = TokT:NUM_KEYWORDS; - - -struct Tok { - t TokT, - loc Loc, - ty *const Type, - u union { - int i64, - uint u64, - flo f64, - bool bool, - str [#]const u8, - ident *const u8, - }, -} - -struct Type { - size usize, - align usize, - konst bool, - id uint, - u enum union { - Void, - Bool, - Int struct { sgn bool }, - Flo, - Ptr *Type, - Arr struct { child *Type, length i64 }, - Slice *Type, - } -} - -struct Parser { - fp *FILE, - alloc *Allocator, - curfile *const u8, - tokloc Loc, - curloc Loc, - eof bool, - peekchr Option, - peektok Option, -} - -struct Decl { - name *const u8, -} - -struct DeclList { - link *DeclList, - decl Decl, -} - -struct Targ { - name *const u8, - ptrsize u8, - intsize u8, - longsize u8, longalign u8, - llongsize u8, llongalign u8, - sizesize u8, - f64align u8, - valistsize u8, valistalign u8, - charsigned bool, - shortenum bool, -} - -// parse.cff -extern fn parser_init(*Parser, path *const u8) void; -extern fn parse(*Parser) [#]Decl; - -// util.cff -extern fn xmalloc(n usize) *void; -extern fn xcalloc(n usize, m usize) *void; -extern fn xrealloc(p *void, n usize) *void; -extern fn xstrdup(str *const u8) *u8; -def FNV1A_INI u32 = 0x811c9dc5; -extern fn fnv1a(h u32, [#]const u8) u32; -extern fn fnv1a_s(h u32, *const u8) u32; -extern fn fnv1a_i(h u32, i64) u32; -extern fn addfilepath(*const u8) int; -extern fn fatal(*Parser, Loc, fmt *const u8, ...) void; -extern fn internstr(*const u8) *const u8; - -// fmt.cff -extern fn vpfmt(proc *fn(u8, *void) void, parg *void, fmt *const u8, va_list) void; -extern fn pfmt(proc *fn(u8, *void) void, parg *void, fmt *const u8, ...) void; -extern fn vefmt(fmt *const u8, ap va_list) void; -extern fn efmt(fmt *const u8, ...) void; - -// type.cff - -// env.cff -extern fn mkenv(parent *Env, alloc *Allocator) *Env; -extern fn envput(*Env, *const Decl) *Decl; - -// targ.cff -extern static g_targ *const Targ; -extern fn targ_ini(name *const u8) bool; - -// Inline functions -fn bswap32(x u32) u32 { - return (x >> 24) - | ((x >> 8) & 0x00FF00) - | ((x << 8) & 0xFF0000) - | (x << 24); -} - -fn bswap64(x u64) u64 { - return (as(u64)bswap32(x) << 32) - | (bswap32(x >> 32)); -} - -fn spanz(x *const u8) [#]const u8 { - return x[0::strlen(x)]; -} diff --git a/src/cffc.hff b/src/cffc.hff new file mode 100644 index 0000000..dcb91f7 --- /dev/null +++ b/src/cffc.hff @@ -0,0 +1,131 @@ +import "libc.hff"; +import "mem.hff"; +import "option.hff"; + +/// Types + +struct Type; +struct Decl; +struct Expr; +struct Env; + +struct Loc { + fileid i16, + col i16, + line int, + idx isize, +} + +#[lax] +enum TokT : i32 { + // !sorted + kw_and, kw_as, kw_break, kw_case, kw_const, + kw_continue, kw_def, kw_defmacro, kw_do, + kw_else, kw_enum, kw_extern, kw_fn, + kw_for, kw_if, kw_import, kw_let, kw_not, + kw_or, kw_return, kw_sizeof, kw_static, + kw_struct, kw_switch, kw_typedef, kw_typeof, + kw_union, kw_while, + NUM_KEYWORDS, + int = -100, + flo, + bool, + str, + chr, + null, + ident, + macident, + gensym, + type, + label, + strify, + eof, +} +def NUM_KEYWORDS = TokT:NUM_KEYWORDS; + + +struct Tok { + t TokT, + loc Loc, + ty *const Type, + u union { + int i64, + uint u64, + flo f64, + bool bool, + str [#]const u8, + ident *const u8, + }, +} + +struct Type { + size usize, + align usize, + konst bool, + id uint, + u enum union { + Void, + Bool, + Int struct { sgn bool }, + Flo, + Ptr *Type, + Arr struct { child *Type, length i64 }, + Slice *Type, + } +} + +struct Parser { + fp *FILE, + alloc *Allocator, + curfile *const u8, + tokloc Loc, + curloc Loc, + eof bool, + peekchr Option, + peektok Option, +} + +struct Decl { + name *const u8, +} + +struct DeclList { + link *DeclList, + decl Decl, +} + +struct Targ { + name *const u8, + ptrsize u8, + intsize u8, + longsize u8, longalign u8, + llongsize u8, llongalign u8, + sizesize u8, + f64align u8, + valistsize u8, valistalign u8, + charsigned bool, + shortenum bool, +} + +// parse.cff +extern fn parser_init(*Parser, path *const u8) void; +extern fn parse(*Parser) [#]Decl; + +// fmt.cff +extern fn vpfmt(proc *fn(u8, *void) void, parg *void, fmt *const u8, va_list) void; +extern fn pfmt(proc *fn(u8, *void) void, parg *void, fmt *const u8, ...) void; +extern fn vefmt(fmt *const u8, ap va_list) void; +extern fn efmt(fmt *const u8, ...) void; + +// .. util.cff .. +extern fn fatal(*Parser, Loc, fmt *const u8, ...) void; + +// type.cff + +// env.cff +extern fn mkenv(parent *Env, alloc *Allocator) *Env; +extern fn envput(*Env, *const Decl) *Decl; + +// targ.cff +extern static g_targ *const Targ; +extern fn targ_ini(name *const u8) bool; diff --git a/src/common.hff b/src/common.hff new file mode 100644 index 0000000..aac733e --- /dev/null +++ b/src/common.hff @@ -0,0 +1,45 @@ +import "libc.hff"; + +/// Macros + +defmacro assert { +(ex, s, ...args) [ + (do + if not (ex) { + fprintf(stderr, "%s:%d: assertion failed: ", #FILE, #LINE); + fprintf(stderr, s, args); + fprintf(stderr, "\n"); + abort(); + } + ) +] +} + +defmacro foreach(x, i, a, ...body) [ + { + let $a = a; + for let i = 0; i < $a.#len; ++i { + let x = $a[i]; + { body } + } + } +] + +defmacro streq(a,b) [ (strcmp(a,b) == 0) ] + +// Inline functions +fn bswap32(x u32) u32 { + return (x >> 24) + | ((x >> 8) & 0x00FF00) + | ((x << 8) & 0xFF0000) + | (x << 24); +} + +fn bswap64(x u64) u64 { + return (as(u64)bswap32(x) << 32) + | (bswap32(x >> 32)); +} + +fn spanz(x *const u8) [#]const u8 { + return x[0::strlen(x)]; +} diff --git a/src/env.cff b/src/env.cff index 8878238..d1eab07 100644 --- a/src/env.cff +++ b/src/env.cff @@ -1,5 +1,6 @@ +import "cffc.hff"; import "map.hff"; -import "all.hff"; +import "util.hff"; struct StringKeyTraits { fn hash(s *const u8) u32 { return fnv1a_s(FNV1A_INI, s); } diff --git a/src/fmt.cff b/src/fmt.cff index 8212593..90fcd47 100644 --- a/src/fmt.cff +++ b/src/fmt.cff @@ -1,4 +1,5 @@ -import "all.hff"; +import "cffc.hff"; +import "common.hff"; extern fn vpfmt(proc *fn(u8, *void) void, parg *void, fmt *const u8, ap va_list) void { defmacro p(x) [ proc(x, parg) ] @@ -10,14 +11,22 @@ extern fn vpfmt(proc *fn(u8, *void) void, parg *void, fmt *const u8, ap va_list) defmacro pch(ch) [ { extern fn isprint(int) int; - let $ch = ch; - if isprint($ch) != 0 { + let $ch u8 = ch; + switch { + case $ch == '\''; + ps("\\'"); + case $ch == '\"'; + ps("\\\""); + case $ch == '\\'; + ps("\\\\"); + case isprint($ch) != 0; p($ch); - } else { - p('\\'); - p('0' + ($ch % 8)); - p('0' + (($ch / 8) % 8)); - p('0' + (($ch / 8 / 8) % 8)); + case $ch == '\n'; + ps("\\n"); + case else; + ps("\\x"); + p("0123456789ABCDEF"[($ch >> 4) & 15]); + p("0123456789ABCDEF"[$ch & 15]); } } ] diff --git a/src/main.cff b/src/main.cff index 596a411..7cc90a0 100644 --- a/src/main.cff +++ b/src/main.cff @@ -1,6 +1,5 @@ -import "all.hff"; -import "libc.hff"; -import "vec.hff"; +import "cffc.hff"; +import "common.hff"; extern fn main(argc int, argv **u8) int { assert(argc > 1, "args?"); diff --git a/src/map.hff b/src/map.hff index 87d0506..d7883dd 100644 --- a/src/map.hff +++ b/src/map.hff @@ -1,4 +1,5 @@ -import "all.hff"; +import "common.hff"; +import "util.hff"; // KTraits: // :hash(K) u32 @@ -32,6 +33,8 @@ struct Map { } fn _reallockvb(self *Map) void { + // keys, vals, bitmap are in a contiguous memory allocation, + // XXX ^ alignment let p = xcalloc((self.N * (sizeof K + sizeof V)) + (self.N / 8), 1); self.keys = p; self.vals = as(*V)(self.keys + self.N); diff --git a/src/mem.hff b/src/mem.hff index a86bee3..805c3ce 100644 --- a/src/mem.hff +++ b/src/mem.hff @@ -1,8 +1,7 @@ import "libc.hff"; -import "all.hff"; -def ARENA_SIZE = 16 * 1024; defmacro ALIGNUP(x,a) [ (((x) + ((a) - 1)) & -(a)) ] +def ARENA_SIZE = 16 * 1024; extern fn xmalloc(n usize) *void; extern fn xcalloc(n usize, m usize) *void; extern fn xrealloc(p *void, n usize) *void; diff --git a/src/parse.cff b/src/parse.cff index 0843ccf..25a2617 100644 --- a/src/parse.cff +++ b/src/parse.cff @@ -1,5 +1,7 @@ +import "mem.hff"; +import "util.hff"; import "vec.hff"; -import "all.hff"; +import "cffc.hff"; /////////// // Lexer // @@ -164,6 +166,15 @@ fn str2keyword(s *const u8) int { return -1; } +fn xdigit2num(c u8) int { + switch { + case isdigit(c); return c - '0'; + case c >= 'a' and c <= 'f'; return (c - 'a') + 10; + case c >= 'A' and c <= 'F'; return (c - 'A') + 10; + } + return -1; +} + fn readnumber(s *const u8) Option { let c u8 #?, acc = 0u64, @@ -198,8 +209,7 @@ fn readnumber(s *const u8) Option { accf = accf + ((c - '0') * fmul); fmul *= 0.1; } else { - c = tolower(c); - acc = (acc * base) + (c <= '9' ? c - '0' : (c - 'a') + 10); + acc = (acc * base) + xdigit2num(c); } } @@ -323,6 +333,13 @@ fn lex(P *Parser) Tok { case 'r'; str->push('\r'); case 't'; str->push('\t'); case 'v'; str->push('\v'); case 'f'; str->push('\f'); case '0'; str->push('\0'); + case 'x'; + let x0 = xdigit2num(chr(P)), + x1 = xdigit2num(chr(P)); + if x0 < 0 or x1 < 0 { + fatal(P, P.tokloc, "not a hex byte escape sequence"); + } + str->push((x0 << 4) | x1); case else fatal(P, P.tokloc, "unknown escape sequence '\\%c'", c); } diff --git a/src/set.hff b/src/set.hff index 6ab44ea..82c213f 100644 --- a/src/set.hff +++ b/src/set.hff @@ -1,5 +1,4 @@ import "vec.hff"; -import "all.hff"; #{ Traits:hash(K) u32 @@ -12,6 +11,12 @@ struct Set { N int, count int, + + fn _nexthash(h *u32) u32 { + // return *h = (*h * 1664525) + 1013904223u; // double hashing + return ++*h; // linear probing + } + fn intern(self *Set, x T) *const T { if self.set == #null { self.set = xcalloc(self.N = 16, sizeof int); @@ -21,20 +26,22 @@ struct Set { free(self.set); self.set = xcalloc(self.N *= 2, sizeof int); vec_each(p, i, self.buf, - let j = Traits:hash(p) & (self.N - 1); + let h = Traits:hash(p); + let j = h & (self.N - 1); for ;; { if self.set[j] == 0 { self.set[j] = i + 1; break; } - j = (j + 1) & (self.N - 1); + j = _nexthash(&h) & (self.N - 1); } ) } - let i0 u32 = Traits:hash(x) & (self.N - 1); - let i int = i0; - do { + let h u32 = Traits:hash(x); + let i = h & (self.N - 1) & (self.N - 1); + let n = 0; + for ;; { if self.set[i] == 0 { ++self.count; self.buf->push(Traits:dup(x)); @@ -46,23 +53,22 @@ struct Set { return x2; } } - i = (i + 1) & (self.N - 1); - } while i != i0; - assert(#f, "unreachable"); + ++n; + i = _nexthash(&h) & (self.N - 1); + } } fn contains(self *Set, x T) bool { - let i0 u32 = Traits:hash(x) & (self.N - 1); - let i int = i0; - do { + let h u32 = Traits:hash(x); + let i = h & (self.N - 1); + for ;; { if self.set[i] == 0 { return #f; } else if Traits:eq(self.buf.dat[self.set[i] - 1], x) { return #t; } - i = (i + 1) & (self.N - 1); - } while i != i0; - assert(#f, "unreachable"); + i = _nexthash(&h) & (self.N - 1); + } } fn put(self *Set, x T) void { diff --git a/src/targ.cff b/src/targ.cff index 6490dff..59078a0 100644 --- a/src/targ.cff +++ b/src/targ.cff @@ -1,4 +1,5 @@ -import "all.hff"; +import "cffc.hff"; +import "common.hff"; static const targs []const Targ = { { diff --git a/src/targ.hff b/src/targ.hff new file mode 100644 index 0000000..9df8ee5 --- /dev/null +++ b/src/targ.hff @@ -0,0 +1,12 @@ +struct Targ { + name *const u8, + ptrsize u8, + intsize u8, + longsize u8, longalign u8, + llongsize u8, llongalign u8, + sizesize u8, + f64align u8, + valistsize u8, valistalign u8, + charsigned bool, + shortenum bool, +} diff --git a/src/type.cff b/src/type.cff index a6987b7..a3c7021 100644 --- a/src/type.cff +++ b/src/type.cff @@ -1,4 +1,5 @@ -import "all.hff"; +import "cffc.hff"; +import "util.hff"; fn hashtype(ty *const Type) u32 { let h = FNV1A_INI; diff --git a/src/type.hff b/src/type.hff new file mode 100644 index 0000000..ce04063 --- /dev/null +++ b/src/type.hff @@ -0,0 +1,15 @@ +struct Type { + size usize, + align usize, + konst bool, + id uint, + u enum union { + Void, + Bool, + Int struct { sgn bool }, + Flo, + Ptr *Type, + Arr struct { child *Type, length i64 }, + Slice *Type, + } +} diff --git a/src/util.cff b/src/util.cff index 18305b2..1b81ab4 100644 --- a/src/util.cff +++ b/src/util.cff @@ -1,5 +1,8 @@ +import "util.hff"; +import "cffc.hff"; import "set.hff"; -import "all.hff"; +import "mem.hff"; +import "common.hff"; extern fn xmalloc(n usize) *void { let p = malloc(n); diff --git a/src/util.hff b/src/util.hff new file mode 100644 index 0000000..5eb9c88 --- /dev/null +++ b/src/util.hff @@ -0,0 +1,12 @@ +// util.cff +extern fn xmalloc(n usize) *void; +extern fn xcalloc(n usize, m usize) *void; +extern fn xrealloc(p *void, n usize) *void; +extern fn xstrdup(str *const u8) *u8; +def FNV1A_INI u32 = 0x811c9dc5; +extern fn fnv1a(h u32, [#]const u8) u32; +extern fn fnv1a_s(h u32, *const u8) u32; +extern fn fnv1a_i(h u32, i64) u32; +extern fn addfilepath(*const u8) int; +// extern fn fatal(*Parser, Loc, fmt *const u8, ...) void; +extern fn internstr(*const u8) *const u8; diff --git a/src/vec.hff b/src/vec.hff index 35a9331..7f012aa 100644 --- a/src/vec.hff +++ b/src/vec.hff @@ -1,6 +1,7 @@ -import "all.hff"; +import "common.hff"; +import "mem.hff"; +import "util.hff"; -extern fn malloc(n usize) *void; struct Vec { dat *T, len uint, @@ -10,10 +11,10 @@ struct Vec { if vec.len >= vec.cap { vec.cap = (vec.len + 1) > 8 ? (vec.len + 1) * 2 : 8; if vec.dat == #null { - vec.dat = malloc(vec.cap * sizeof T); + vec.dat = xmalloc(vec.cap * sizeof T); assert(vec.dat != #null, "malloc"); } else { - vec.dat = realloc(vec.dat, vec.cap * sizeof T); + vec.dat = xrealloc(vec.dat, vec.cap * sizeof T); assert(vec.dat != #null, "realloc"); } } -- cgit v1.2.3