diff options
-rw-r--r-- | abbrevs.txt | 1 | ||||
-rw-r--r-- | binfile.c | 330 | ||||
-rw-r--r-- | parse.c | 17 | ||||
-rw-r--r-- | test.toc | 18 | ||||
-rw-r--r-- | tests.c | 1 | ||||
-rw-r--r-- | toc.c | 1 | ||||
-rw-r--r-- | tokenizer.c | 2 | ||||
-rw-r--r-- | types.h | 8 |
8 files changed, 30 insertions, 348 deletions
diff --git a/abbrevs.txt b/abbrevs.txt index 2449533..8e137c9 100644 --- a/abbrevs.txt +++ b/abbrevs.txt @@ -19,6 +19,7 @@ imptr - importer inc - include kw - keyword len - length +ns - namespace num - number op - operator param - parameter diff --git a/binfile.c b/binfile.c deleted file mode 100644 index 9777718..0000000 --- a/binfile.c +++ /dev/null @@ -1,330 +0,0 @@ -#define BINFILE_PORTABLE 1 - -#ifdef TOC_DEBUG -/* #define BINFILE_PRINT */ -static bool binfile_printing_enabled = true; -#endif - -static inline void write_u8(FILE *fp, U8 u8) { - putc(u8, fp); -#ifdef BINFILE_PRINT - if (binfile_printing_enabled) { - static int col = 0; - printf("%02x ", u8); - ++col; - if (col == 8) printf(" "); - if (col == 16) { - col = 0; - printf("\n"); - } - fflush(stdout); - } -#endif -} - -#undef BINFILE_PRINT /* don't need it anymore */ - -static inline U8 read_u8(FILE *fp) { - return (U8)getc(fp); -} - -static inline void write_char(FILE *fp, char c) { -#ifdef TOC_DEBUG - /* mayyybe this'd do the wrong thing for negative characters on systems where char is signed? */ - write_u8(fp, (U8)c); -#else - putc(c, fp); -#endif -} - -static inline char read_char(FILE *fp) { - return (char)getc(fp); -} - -static inline void write_i8(FILE *fp, I8 i8) { - write_u8(fp, (U8)i8); -} - -static inline I8 read_i8(FILE *fp) { - U8 u8 = read_u8(fp); - return (I8)((u8 & (1<<7)) ? -(1 + ~u8) : u8); -} - -/* - note: a bit of testing seems to reveal that the portable versions for u16/32 are faster than fwrite - (but this is not the case for u64). - */ - -static inline void write_u16(FILE *fp, U16 u16) { - write_u8(fp, (U8)(u16 & 0xFF)); - write_u8(fp, (U8)(u16 >> 8)); -} - -static inline U16 read_u16(FILE *fp) { - U8 a = read_u8(fp); - U8 b = read_u8(fp); - return (U16)(a + (((U16)b) << 8)); -} - -static inline void write_i16(FILE *fp, I16 i16) { - write_u16(fp, (U16)i16); -} - -static inline I16 read_i16(FILE *fp) { - U16 u16 = read_u16(fp); - return (I16)((u16 & (1U<<15)) ? -(1 + ~u16) : u16); -} - -static inline void write_u32(FILE *fp, U32 u32) { - write_u16(fp, u32 & 0xFFFF); - write_u16(fp, (U16)(u32 >> 16)); -} - -static inline U32 read_u32(FILE *fp) { - U16 a = read_u16(fp); - U16 b = read_u16(fp); - return (U32)(a + (((U32)b << 16))); -} - -static inline void write_i32(FILE *fp, I32 i32) { - write_u32(fp, (U32)i32); -} - -static inline I32 read_i32(FILE *fp) { - U32 u32 = read_u32(fp); - return (I32)((u32 & (1UL<<31)) ? -(1 + ~u32) : u32); -} - -static void write_u64(FILE *fp, U64 u64) { -#if BINFILE_PORTABLE - write_u32(fp, u64 & 0xFFFFFFFF); - write_u32(fp, (U32)(u64 >> 32)); -#else - fwrite(&u64, sizeof u64, 1, fp); -#endif -} - -static U64 read_u64(FILE *fp) { -#if BINFILE_PORTABLE - U32 a = read_u32(fp); - U32 b = read_u32(fp); - return (U64)(a + (((U64)b << 32))); -#else - U64 x; - fread(&x, sizeof x, 1, fp); - return x; -#endif -} - -static inline void write_i64(FILE *fp, I64 i64) { -#if BINFILE_PORTABLE - write_u64(fp, (U64)i64); -#else - fwrite(&i64, sizeof i64, 1, fp); -#endif -} - -static inline I64 read_i64(FILE *fp) { -#ifdef BINFILE_PORTABLE - U64 u64 = read_u64(fp); - return (I64)((u64 & ((U64)1<<63)) ? -(1 + ~u64) : u64); -#else - I64 x; - fread(&x, sizeof x, 1, fp); - return x; -#endif -} - -static void write_f32(FILE *fp, F32 f32) { -#if BINFILE_PORTABLE - /* writes as IEEE 754 32-bit floating-point number, the byte order is little endian */ - /* https://en.wikipedia.org/wiki/Single_precision_floating-point_format */ - /* TODO: infinity, NaN */ - U32 fraction = 0; - U32 fraction_bit = ((U32)1) << 22; - U32 exponent = 127; - U32 sign = f32 < 0; - if (sign) f32 = -f32; - while (f32 < (F32)1) { - f32 *= (F32)2; - --exponent; - } - while (f32 > (F32)2) { - f32 /= (F32)2; - ++exponent; - } - if (f32 > (F32)1) --f32; - f32 *= (F32)2; - while (fraction_bit) { - if (((U32)f32)) { - assert((U32)f32 == 1); - fraction |= fraction_bit; - --f32; - } - f32 *= (F32)2; - fraction_bit >>= 1; - } - write_u32(fp, fraction | (exponent << 23) | (sign << 31)); -#else - fwrite(&f32, sizeof f32, 1, fp); -#endif -} - -static F32 read_f32(FILE *fp) { -#if BINFILE_PORTABLE - /* TODO: infinity, NaN */ - U32 u32 = read_u32(fp); - U32 sign = (u32 & 0x80000000); - U32 exponent = (u32 & 0x7f800000) >> 23; - U32 fraction = (u32 & 0x007fffff); - F32 flt = (F32)1 + (F32)fraction / (F32)0x0800000; - int signed_exponent = (int)exponent - 127; - while (signed_exponent < 0) { - ++signed_exponent; - flt /= (F32)2; - } - while (signed_exponent > 0) { - --signed_exponent; - flt *= (F32)2; - } - if (sign) flt = -flt; - return flt; -#else - F32 f32; - fread(&f32, sizeof f32, 1, fp); - return f32; -#endif -} - -static void write_f64(FILE *fp, F64 f64) { -#if BINFILE_PORTABLE - U64 fraction = 0; - U64 fraction_bit = ((U64)1) << 51; - U64 exponent = 1023; - U64 sign = f64 < 0; - if (sign) f64 = -f64; - while (f64 < (F64)1) { - f64 *= (F64)2; - --exponent; - } - while (f64 > (F64)2) { - f64 /= (F64)2; - ++exponent; - } - if (f64 > (F64)1) --f64; - f64 *= (F64)2; - while (fraction_bit) { - if (((U64)f64)) { - assert((U64)f64 == 1); - fraction |= fraction_bit; - --f64; - } - f64 *= (F64)2; - fraction_bit >>= 1; - } - write_u64(fp, fraction | (exponent << 52) | (sign << 63)); -#else - fwrite(&f64, sizeof f64, 1, fp); -#endif -} - -static F64 read_f64(FILE *fp) { -#if BINFILE_PORTABLE - /* TODO: infinity, NaN */ - U64 u64 = read_u64(fp); - U64 sign = (u64 & 0x8000000000000000); - U64 exponent = (u64 & 0x7ff0000000000000) >> 52; - U64 fraction = (u64 & 0x000fffffffffffff); - F64 flt = (F64)fraction / (F64)0x10000000000000 + (F64)1; - int signed_exponent = (int)exponent - 1023; - while (signed_exponent < 0) { - ++signed_exponent; - flt /= (F64)2; - } - while (signed_exponent > 0) { - --signed_exponent; - flt *= (F64)2; - } - if (sign) flt = -flt; - return flt; -#else - F64 f64; - fread(&f64, sizeof f64, 1, fp); - return f64; -#endif -} - -static void write_bool(FILE *fp, bool b) { - write_u8(fp, b); -} - -static bool read_bool(FILE *fp) { - return read_u8(fp); -} - -/* - toc's vlq format: - a byte whose first (most significant) bit is 0 indicates the number is done. - a byte whose first bit is 1 indicates the number will continue. - starts with the 7 least significant bits of the number. -*/ -static void write_vlq(FILE *fp, U64 x) { - while (x >= 0x80) { - write_u8(fp, (U8)(x & 0x7f) | 0x80); - x >>= 7; - } - write_u8(fp, (U8)x); -} - -static U64 read_vlq(FILE *fp) { - U64 q = 0; - U64 bit = 0; - while (1) { - U8 byte = read_u8(fp); - assert(!feof(fp)); - q |= (U64)(byte & 0x7F) << bit; - bit += 7; - if (!(byte & 0x80)) return q; - } -} - -#ifdef TOC_DEBUG -static void binfile_test(void) { - binfile_printing_enabled = false; - FILE *fp = tmpfile(); - U64 a = 234873485734; - write_vlq(fp, a); - U64 s = 3; - write_vlq(fp, s); - I64 b = -123981232131; - write_i64(fp, b); - U8 c = 12; - write_u8(fp, c); - F32 d = (F32)-2.323198123; - write_f32(fp, d); - bool e = true; - write_bool(fp, e); - F64 f = (F64)34.69459324823; - write_f64(fp, f); - fseek(fp, 0L, SEEK_SET); - -#define expect(type, fmt, expr, to_be) { \ - type exp = to_be; \ - type got = expr; \ - if (exp != got) { \ - fprintf(stderr, "Expected " #expr " to be " fmt " but got " fmt "\n", exp, got); \ - abort(); \ - } \ - } - - expect(U64, U64_FMT, read_vlq(fp), a); - expect(U64, U64_FMT, read_vlq(fp), s); - expect(I64, I64_FMT, read_i64(fp), b); - expect(U8, U8_FMT, read_u8(fp), c); - expect(F32, F32_FMT, read_f32(fp), d); - expect(bool, "%d", read_bool(fp), e); - expect(F64, F64_FMT, read_f64(fp), f); - fclose(fp); - binfile_printing_enabled = true; -} -#endif @@ -2020,6 +2020,23 @@ static bool parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { t->token = end + 1; return success; } + case KW_NAMESPACE: { + s->kind = STMT_NAMESPACE; + ++t->token; + if (t->token->kind == TOKEN_IDENT) { + s->ns.name = t->token->ident; + } else { + s->ns.name = NULL; + } + if (!parse_block(p, &s->ns.body)) + return false; + arr_foreach(s->ns.body.stmts, Statement, sub) { + if (sub->kind != STMT_DECL) { + err_print(s->where, "Only declarations can be in namespaces."); + return false; + } + } + } break; default: break; } } else if (t->token->kind == TOKEN_DIRECT) { @@ -1,18 +1,6 @@ -#include "std/arr.toc"; -#include "std/io.toc"; - -do_thing ::= fn() int { - x: Arr([]char); - arr_add(&x, "HI"); - arr_add(&x, "Hello"); - arr_add(&x, "How's"); - arr_add(&x, "it"); - arr_add(&x, "going"); - for a := x.data { - puts(a); - } - 3 -}; +namespace foo { +bar ::= 12; +} main ::= fn() { x ::= do_thing(); @@ -33,5 +33,4 @@ static void test_all(void) { block_arr_test(); str_hash_table_test(); idents_test(); - binfile_test(); } @@ -82,7 +82,6 @@ static size_t compiler_alignof(Type *t); static size_t compiler_sizeof(Type *t); #include "instance_table.c" #include "copy.c" -#include "binfile.c" /* returns NULL on error */ static char *read_entire_file(Allocator *a, ErrCtx *ectx, const char *filename) { diff --git a/tokenizer.c b/tokenizer.c index b34bc65..7cd6edc 100644 --- a/tokenizer.c +++ b/tokenizer.c @@ -14,7 +14,7 @@ static const char *const keywords[KW_COUNT] = "int", "i8", "i16", "i32", "i64", "u8", "u16", "u32", "u64", "float", "f32", "f64", "Type", "Package", - "char", "bool", "true", "false"}; + "char", "bool", "true", "false", "namespace"}; static inline const char *kw_to_str(Keyword k) { return keywords[k]; } @@ -300,6 +300,7 @@ typedef enum { KW_BOOL, KW_TRUE, KW_FALSE, + KW_NAMESPACE, KW_COUNT } Keyword; @@ -812,6 +813,7 @@ typedef enum { STMT_DECL, STMT_EXPR, STMT_RET, + STMT_NAMESPACE, STMT_INCLUDE } StatementKind; @@ -832,6 +834,11 @@ typedef union { struct Statement *stmts; /* after typing */ } Include; +typedef struct { + Identifier name; /* NULL = anonymous */ + Block body; +} Namespace; + typedef struct Statement { Location where; StatementKind kind; @@ -841,6 +848,7 @@ typedef struct Statement { Expression expr; Return ret; Include inc; + Namespace ns; }; } Statement; |