From 3a4e9a21361ac930f17fe18687f4a1bce6a5863b Mon Sep 17 00:00:00 2001 From: Mel Date: Wed, 23 Jul 2025 03:52:50 +0200 Subject: Add rudimentary catskill-to-C transpiler (yay!) Signed-off-by: Mel --- boot/catboot.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 12 deletions(-) (limited to 'boot/catboot.c') diff --git a/boot/catboot.c b/boot/catboot.c index 155c3c5..9afb710 100644 --- a/boot/catboot.c +++ b/boot/catboot.c @@ -105,9 +105,7 @@ debug_parse_pass(struct Source_File source_file) struct Tree tree; int parser_result = parser_do_your_thing(&parser, &tree); - if (parser_result != 0) { - fprintf(stderr, "parser finished with errors\n"); - } + if (parser_result != 0) fprintf(stderr, "parser finished with errors\n"); tree_printer(&tree); @@ -123,6 +121,7 @@ enum Command_Result struct Command_Arguments { const ascii* input; + const ascii* output; }; enum Command_Result @@ -167,18 +166,50 @@ test_parse_command(struct Command_Arguments* arguments) enum Command_Result default_command(struct Command_Arguments* arguments) { + enum Command_Result result = COMMAND_OK; + struct String source = read_file(arguments->input); struct Source_File source_file = { .source = source, .path = string_from_static_c_string(arguments->input), }; - debug_lex_pass(source); - printf("\n"); - if (debug_parse_pass(source_file)) return COMMAND_FAIL; - printf("\n"); + struct Lexer lexer; + lexer_new(&lexer, source); - return COMMAND_OK; + struct Parser parser; + parser_new(&parser, &lexer, source_file); + + struct Tree tree; + if (parser_do_your_thing(&parser, &tree) != 0) { + fprintf(stderr, "parser finished with errors\n"); + goto end; + } + + FILE* output_file = nil; + if (arguments->output) { + output_file = fopen(arguments->output, "w"); + if (!output_file) { + fprintf(stderr, "could not open output file: %s\n", arguments->output); + result = COMMAND_FAIL; + goto end; + } + } else { + output_file = stdout; + } + + struct Transpiler transpiler; + transpiler_new(&transpiler, output_file); + + if (transpiler_catskill_to_c(&transpiler, &tree) != 0) { + fprintf(stderr, "transpiler finished with errors\n"); + result = COMMAND_FAIL; + } + + if (output_file != stdout) fclose(output_file); + +end: + return result; } typedef enum Command_Result (*Command_Function)(struct Command_Arguments*); @@ -209,7 +240,7 @@ main(const int32 argc, ascii* argv[]) } bool have_command = false; - ascii *command_name = nil, short_command_name = '\0', *input = nil; + ascii *command_name = nil, short_command_name = '\0', *input = nil, *output = nil; for (uint a = 1; a < argc; ++a) { ascii* arg = argv[a]; @@ -224,12 +255,16 @@ main(const int32 argc, ascii* argv[]) } have_command = true; } else { - check(!input, "multiple inputs given"); - input = arg; + if (!input) + input = arg; + else if (!output) + output = arg; + else + failure("too many arguments, expected at most 2: input and output"); } } - struct Command_Arguments arguments = { .input = input }; + struct Command_Arguments arguments = { .input = input, .output = output }; for (uint d = 0; d < ARRAY_SIZE(command_definitions); ++d) { struct Command_Definition* definition = &command_definitions[d]; -- cgit 1.4.1