/* * transpiler from a catskill intermediate translation unit, * to the c programming language, as the main translation target. * * walks a fully-lowered translation unit and emits (slightly ugly) * c source code. * * Copyright (c) 2025-2026, Mel G. * * SPDX-License-Identifier: MPL-2.0 */ #pragma once #include "catboot.h" // the output of the transpilation pass. // used for both file output and string buffer output. struct Transpile_Output { FILE* file; struct String_Buffer string; }; struct Transpile_Output transpile_output_from_file(FILE* file) { check(file != nil, "transpile output file is nil"); return (struct Transpile_Output){ .file = file, .string = string_buffer_empty(), }; } #define TRANSPILE_OUTPUT_MAX_LENGTH 262144 // 256 KiB struct Transpile_Output transpile_output_from_string(void) { return (struct Transpile_Output){ .file = nil, .string = string_buffer_new(TRANSPILE_OUTPUT_MAX_LENGTH), }; } #define TRANSPILE_OUTPUT_MAX_WRITE_LENGTH 4096 void transpile_output_write(struct Transpile_Output* output, const ascii* format, ...) { va_list args; va_start(args, format); if (output->file) { vfprintf(output->file, format, args); } else { ascii buffer[TRANSPILE_OUTPUT_MAX_WRITE_LENGTH]; int written = vsnprintf(buffer, TRANSPILE_OUTPUT_MAX_WRITE_LENGTH, format, args); check(written >= 0 && (uint)written < TRANSPILE_OUTPUT_MAX_LENGTH, "transpile output string buffer overflow"); string_buffer_append_c_str(&output->string, buffer); } va_end(args); } struct String transpile_output_string(struct Transpile_Output* output) { check(output->file == nil, "transpile output is not a string"); return string_buffer_to_string(&output->string); } FILE* transpile_output_file(struct Transpile_Output* output) { check(output->file != nil, "transpile output is not a file"); return output->file; } struct Transpiler { struct Transpile_Output output; }; void transpiler_new(struct Transpiler* transpiler, struct Transpile_Output output) { *transpiler = (struct Transpiler){ .output = output, }; } // walk a lowered translation unit and emit c source into the transpiler's output. // TODO: actual emission! int transpile_unit(struct Transpiler* transpiler, struct Unit* unit) { (void)transpiler; (void)unit; return 0; }