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 ALIGNUP(x,a) [ (((x) + ((a) - 1)) & -(a)) ] defmacro streq(a,b) [ (strcmp(a,b) == 0) ] /// Types struct Type; struct Decl; struct Expr; 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 Decl { } struct Parser { fp *FILE, curfile *const u8, tokloc Loc, curloc Loc, eof bool, peekchr Option, peektok Option, } // 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 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; // 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)); }