diff options
Diffstat (limited to 'boot')
| -rw-r--r-- | boot/runtime/runtime.c | 48 | ||||
| -rw-r--r-- | boot/transpile.c | 40 |
2 files changed, 82 insertions, 6 deletions
diff --git a/boot/runtime/runtime.c b/boot/runtime/runtime.c new file mode 100644 index 0000000..47958a6 --- /dev/null +++ b/boot/runtime/runtime.c @@ -0,0 +1,48 @@ +/* + * the catskill transpiled-source runtime. + * wraps the catskill source entry point in a normal c main function, + * and provides some basic runtime startup and exit functionality. + * + * Copyright (c) 2025, Mel G. <mel@rnrd.eu> + * + * SPDX-License-Identifier: MPL-2.0 + */ + +// catskill programs that use the runtime are expected to +// provide a `main` which can have the following signatures: +// * main = fun () {} +// * main = fun (args [string]) {} +// the transpiler will define the macro `CATSKILL_MAIN_TAKES_ARGS` +// to indicate that the main function takes arguments. +// exit codes are returned with the use of the `exit` function. +#ifdef CATSKILL_MAIN_TAKES_ARGS +void catskill_main(Array(struct String) args); +#else +void catskill_main(void); +#endif + +// the main function that wraps the catskill main function +// and provides the runtime startup and exit functionality. +int +main(int argc, char* argv[]) +{ +#ifdef CATSKILL_MAIN_TAKES_ARGS + Array(struct String) args = array_new(struct String); + for (int i = 0; i < argc; i++) { + struct String arg = string_from(argv[i]); + array_push(&args, &arg); + } + + catskill_main(args); + + ARRAY_FREE_ELEMENTS(struct String, args, string_free); + array_free(&args); +#else + catskill_main(); + + (void)argc; + (void)argv; +#endif + // on error catskill_main will call `exit` with a non-zero code. + return 0; +} diff --git a/boot/transpile.c b/boot/transpile.c index 25a3d79..7ab13e9 100644 --- a/boot/transpile.c +++ b/boot/transpile.c @@ -11,14 +11,14 @@ #pragma once #include "catboot.h" -#include "visit.c" -#include <stdio.h> struct Transpile_Context { bool in_function; struct String function_name; struct String function_return_type; + bool main_function_found; + bool main_function_takes_args; }; #define CONTEXT_START(name) \ @@ -47,6 +47,8 @@ transpiler_new(struct Transpiler* transpiler, FILE* output) .in_function = false, .function_name = string_empty(), .function_return_type = string_empty(), + .main_function_found = false, + .main_function_takes_args = false, }, }; } @@ -293,7 +295,21 @@ transpiler_visit_expression_binary_operation(struct Visit* visit, struct Express VISIT(visit_type_node, header->return_type); fprintf(transpiler->output, " "); - VISIT(visit_expression, name_expr); + + // check if this is a main function assignment + if (name_expr && name_expr->kind == EXPRESSION_NAME) { + struct Expression_Name* name = &name_expr->value.name; + if (string_equals_c_str(name->name, "main")) { + transpiler->context.main_function_found = true; + transpiler->context.main_function_takes_args = + header->parameters_type_and_name != nil; + fprintf(transpiler->output, "catskill_main"); + } else { + VISIT(visit_expression, name_expr); + } + } else { + VISIT(visit_expression, name_expr); + } VISIT(visit_function_header_node, header); fprintf(transpiler->output, " "); @@ -380,13 +396,25 @@ transpiler_visit_tree(struct Visit* visit, struct Tree* tree) // for transpiled catskill programs. // other headers can be included by the user // with the pragma `| c-header "header.h"`. - fprintf(transpiler->output, "#include <stdio.h>\n"); - fprintf(transpiler->output, "#include <stdint.h>\n"); - fprintf(transpiler->output, "#include <stdbool.h>\n\n"); + // TODO: for now we just reference the path to it in this repo + // exactly, when we actually just want to fully include the string + // of the entire file into the transpiled output, for development it's + // okay for now. + fprintf(transpiler->output, "#include \"boot/runtime/core.c\"\n"); FOR_EACH (struct Statement*, statement, tree->top_level_statements) { VISIT(visit_statement, statement); } + + // check if we found a main function and define the appropriate macro for the runtime + // TODO: create a nice lookup table of all the functions and types we found through + // the catskill source. + if (transpiler->context.main_function_found) { + if (transpiler->context.main_function_takes_args) { + fprintf(transpiler->output, "\n#define CATSKILL_MAIN_TAKES_ARGS\n"); + } + fprintf(transpiler->output, "#include \"boot/runtime/runtime.c\"\n"); + } } struct Visit_Table transpiler_visit_functions = { |
