summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binfile.c20
-rw-r--r--main.c4
-rw-r--r--package.c43
-rw-r--r--test.toc2
4 files changed, 54 insertions, 15 deletions
diff --git a/binfile.c b/binfile.c
index 5ee6aeb..35f04ad 100644
--- a/binfile.c
+++ b/binfile.c
@@ -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);
diff --git a/main.c b/main.c
index cf9f627..e9d7bd5 100644
--- a/main.c
+++ b/main.c
@@ -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;
diff --git a/package.c b/package.c
index deaa06c..204a925 100644
--- a/package.c
+++ b/package.c
@@ -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);
diff --git a/test.toc b/test.toc
index f7db673..2a666a0 100644
--- a/test.toc
+++ b/test.toc
@@ -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];