From 8b1b7aab9a580c0ff3879b8a011b422804872397 Mon Sep 17 00:00:00 2001 From: Mel Date: Mon, 4 May 2026 23:28:50 +0200 Subject: Initial structure for transpiler IR translation unit process Signed-off-by: Mel --- boot/transpile.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 3 deletions(-) (limited to 'boot') 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; } -- cgit 1.4.1