about summary refs log tree commit diff
path: root/boot/transpile.c
diff options
context:
space:
mode:
authorMel <mel@rnrd.eu>2026-05-04 23:28:50 +0200
committerMel <mel@rnrd.eu>2026-05-04 23:28:50 +0200
commit8b1b7aab9a580c0ff3879b8a011b422804872397 (patch)
tree0a0e49b314e3864f7dae4f837a25ea644018eb44 /boot/transpile.c
parent0453070560fa22a8c0c61bb4e4696dae26846087 (diff)
downloadcatskill-8b1b7aab9a580c0ff3879b8a011b422804872397.tar.zst
catskill-8b1b7aab9a580c0ff3879b8a011b422804872397.zip
Initial structure for transpiler IR translation unit process
Signed-off-by: Mel <mel@rnrd.eu>
Diffstat (limited to 'boot/transpile.c')
-rw-r--r--boot/transpile.c83
1 files changed, 80 insertions, 3 deletions
diff --git a/boot/transpile.c b/boot/transpile.c
index 38a700b..5b27967 100644
--- a/boot/transpile.c
+++ b/boot/transpile.c
@@ -82,6 +82,7 @@ transpile_output_file(struct Transpile_Output* output)
 struct Transpiler
 {
     struct Transpile_Output output;
+    struct Unit* unit;
 };
 
 void
@@ -92,12 +93,88 @@ transpiler_new(struct Transpiler* transpiler, struct Transpile_Output output)
     };
 }
 
+#define TRANSPILE_WRITE(...) transpile_output_write(&transpiler->output, __VA_ARGS__)
+
+// emit the forward declaration for a single type.
+// TODO: per-kind emission lands in a follow-up commit.
+void
+transpile_type_forward(struct Transpiler* transpiler, struct Type* type)
+{
+    (void)transpiler;
+    (void)type;
+}
+
+// emit the full definition for a single type.
+// TODO: per-kind emission lands in a follow-up commit.
+void
+transpile_type_definition(struct Transpiler* transpiler, struct Type* type)
+{
+    (void)transpiler;
+    (void)type;
+}
+
+// emit a function signature (used for both forward-decls and the line
+// preceding a function body).
+// TODO: per-kind emission lands in a follow-up commit.
+void
+transpile_function_signature(struct Transpiler* transpiler, struct Function* function)
+{
+    (void)transpiler;
+    (void)function;
+}
+
+// emit a function body in the form `signature { block }`.
+// TODO: per-kind emission lands in a follow-up commit.
+void
+transpile_function_body(struct Transpiler* transpiler, struct Function* function)
+{
+    (void)transpiler;
+    (void)function;
+}
+
 // walk a lowered translation unit and emit c source into the transpiler's output.
-// TODO: actual emission!
+// the order of the translation unit, and thus the final source output is fixed.
+// preamble, then imports, type forwards, type definitions in topological dependency
+// order, function forwads, function definitions, and runtime trailer (if main present).
 int
 transpile_unit(struct Transpiler* transpiler, struct Unit* unit)
 {
-    (void)transpiler;
-    (void)unit;
+    transpiler->unit = unit;
+
+    TRANSPILE_WRITE("#include \"core.c\"\n");
+
+    FOR_EACH_ARRAY (struct Import, import, &unit->imports) {
+        TRANSPILE_WRITE("#include \"%.*s\"\n", (int)import->path.length, import->path.data);
+    }
+
+    FOR_EACH_ARRAY (struct Type*, type_slot, &unit->types.entries) {
+        transpile_type_forward(transpiler, *type_slot);
+    }
+
+    FOR_EACH_ARRAY (Type_Id, ordered_id, &unit->type_emission_order) {
+        struct Type* type = *array_at(struct Type*, &unit->types.entries, *ordered_id);
+        transpile_type_definition(transpiler, type);
+    }
+
+    bool main_takes_args = false;
+    bool has_main = false;
+    FOR_EACH_ARRAY (struct Function*, function_slot, &unit->functions.entries) {
+        struct Function* function = *function_slot;
+        transpile_function_signature(transpiler, function);
+        if (function->is_main) {
+            has_main = true;
+            main_takes_args = function->main_takes_args;
+        }
+    }
+
+    FOR_EACH_ARRAY (struct Function*, function_slot, &unit->functions.entries) {
+        transpile_function_body(transpiler, *function_slot);
+    }
+
+    if (has_main) {
+        if (main_takes_args) TRANSPILE_WRITE("#define CATSKILL_MAIN_TAKES_ARGS\n");
+        TRANSPILE_WRITE("#include \"runtime.c\"\n");
+    }
+
     return 0;
 }