diff options
-rw-r--r-- | binfile.c | 20 | ||||
-rw-r--r-- | main.c | 4 | ||||
-rw-r--r-- | package.c | 43 | ||||
-rw-r--r-- | test.toc | 2 |
4 files changed, 54 insertions, 15 deletions
@@ -19,6 +19,15 @@ static inline void write_u8(FILE *fp, U8 u8) { #endif } +static 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 +} + #undef BINFILE_PRINT /* don't need it anymore */ static inline void write_i8(FILE *fp, I8 i8) { @@ -153,11 +162,12 @@ static void write_bool(FILE *fp, bool b) { write_u8(fp, b); } -static void write_char(FILE *fp, char c) { - write_u8(fp, (U8)c); -} - - +/* + 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); @@ -126,7 +126,9 @@ int main(int argc, char **argv) { FILE *out_pkg = fopen("out.top", "wb"); exptr_create(&exptr, out_pkg); exptr.export_locations = false; - + exptr_start(&exptr, contents); + /* export_len(&exptr, 1782); */ + /* export_u8(&exptr, 0xab); */ #endif if (!block_enter(NULL, f.stmts, SCOPE_CHECK_REDECL)) /* enter global scope */ return false; @@ -3,18 +3,13 @@ This file is part of toc. toc is distributed under version 3 of the GNU General Public License, without any warranty whatsoever. You should have received a copy of the GNU General Public License along with toc. If not, see <https://www.gnu.org/licenses/>. */ + +#define TOP_FMT_VERSION 0 + static bool export_decl(Exporter *ex, Declaration *d); static bool export_block(Exporter *ex, Block *b); static bool export_expr(Exporter *ex, Expression *e); -static void exptr_create(Exporter *ex, FILE *out) { - ex->out = out; - ex->export_locations = true; - ex->exported_fns = NULL; - ex->exported_structs = NULL; -} - - static inline void export_u8(Exporter *ex, U8 u8) { write_u8(ex->out, u8); } @@ -54,6 +49,15 @@ static inline void export_char(Exporter *ex, char c) { static inline void export_vlq(Exporter *ex, U64 x) { write_vlq(ex->out, x); } +/* since char may be signed or unsigned, use this only if necessary */ +static inline void export_str(Exporter *ex, const char *str, size_t len) { +#ifdef TOC_DEBUG + for (size_t i = 0; i < len; ++i) + export_char(ex, *str++); +#else + fwrite(str, 1, len, ex->out); +#endif +} static void export_location(Exporter *ex, Location where) { if (ex->export_locations) { @@ -79,6 +83,29 @@ static inline void export_len(Exporter *ex, size_t len) { export_vlq(ex, (U64)len); } +static void exptr_create(Exporter *ex, FILE *out) { + ex->out = out; + ex->export_locations = true; + ex->exported_fns = NULL; + ex->exported_structs = NULL; +} + +/* writes the header */ +static void exptr_start(Exporter *ex, char *code) { + const U8 toc[3] = {116, 111, 99}; /* "toc" in ASCII */ + export_u8(ex, toc[0]); + export_u8(ex, toc[1]); + export_u8(ex, toc[2]); + export_u32(ex, TOP_FMT_VERSION); + bool has_code = code != NULL; + export_bool(ex, has_code); + if (has_code) { + size_t len = strlen(code); + export_len(ex, len); + export_str(ex, code, len); + } +} + static bool export_type(Exporter *ex, Type *type, Location where) { assert(type->flags & TYPE_IS_RESOLVED); export_u8(ex, (U8)type->kind); @@ -1,7 +1,7 @@ Foo ::= struct { x: int; }; -#export main ::= fn() Foo { +main ::= fn() Foo { g ::= fn() int { 3 }; a : [3]int; b := a[1:3]; |