diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-09-05 14:38:37 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-09-05 14:38:37 -0400 |
| commit | a8be9efcd3c3db6f2d6b78de2074d87e296459f8 (patch) | |
| tree | 81a85caf343fe8010ca526ae2acb3e9700409d1a /tomo.c | |
| parent | e6aea8c1301739fb3b6547221d0432672fb6dcaa (diff) | |
Rework CLI compilation so that all of the argument parsing is written to
the .tm.c file and the runner program is *just* a single function call
to the function that parses args and runs the main function. Also
improved some CLI usage error code
Diffstat (limited to 'tomo.c')
| -rw-r--r-- | tomo.c | 54 |
1 files changed, 35 insertions, 19 deletions
@@ -421,17 +421,38 @@ int transpile_code(env_t *base_env, const char *filename, bool force_retranspile CORD c_code = compile_file(module_env, ast); + FILE *out; + bool is_popened = false; if (autofmt) { - FILE *prog = CORD_RUN(autofmt, " 2>/dev/null >", c_filename); - CORD_put(c_code, prog); - if (pclose(prog) == -1) - errx(1, "Failed to output autoformatted C code to %s: %s", c_filename, autofmt); + out = CORD_RUN(autofmt, " 2>/dev/null >'", c_filename, "'"); + if (!out) + errx(1, "Failed to run autoformat program: %s", autofmt); + is_popened = true; } else { - FILE *c_file = fopen(c_filename, "w"); - if (!c_file) + out = fopen(c_filename, "w"); + if (!out) errx(1, "Couldn't open file: %s", c_filename); - CORD_put(c_code, c_file); - if (fclose(c_file)) + is_popened = false; + } + + CORD_put(c_code, out); + + binding_t *main_binding = get_binding(module_env, "main"); + if (main_binding && main_binding->type->tag == FunctionType) { + CORD_put(CORD_all( + "int ", main_binding->code, "$parse_and_run(int argc, char *argv[]) {\n" + "tomo_init();\n" + "\n", + compile_cli_arg_call(module_env, main_binding->code, main_binding->type), + "return 0;\n" + "}\n"), out); + } + + if (is_popened) { + if (pclose(out) == -1) + errx(1, "Failed to output autoformatted C code to %s: %s", c_filename, autofmt); + } else { + if (fclose(out)) errx(1, "Failed to close file: %s", c_filename); } @@ -439,7 +460,7 @@ int transpile_code(env_t *base_env, const char *filename, bool force_retranspile printf("Transpiled to %s\n", c_filename); if (show_codegen) { - FILE *out = CORD_RUN("bat -P ", c_filename); + out = CORD_RUN("bat -P ", c_filename); pclose(out); } @@ -471,26 +492,21 @@ int compile_executable(env_t *base_env, const char *filename, CORD object_files) errx(1, "Could not parse file %s", filename); env_t *env = load_module_env(base_env, ast); binding_t *main_binding = get_binding(env, "main"); - if (!main_binding || main_binding->type->tag != FunctionType) { + if (!main_binding || main_binding->type->tag != FunctionType) errx(1, "No main() function has been defined for %s, so it can't be run!", filename); - } const char *bin_name = GC_strndup(filename, strlen(filename) - strlen(".tm")); - FILE *runner = CORD_RUN(autofmt, " | ", cc, " ", cflags, " ", ldflags, " ", ldlibs, " ", object_files, " -x c - -o ", bin_name); + FILE *runner = CORD_RUN(cc, " ", cflags, " ", ldflags, " ", ldlibs, " ", object_files, " -x c - -o ", bin_name); CORD program = CORD_all( - "#include <tomo/tomo.h>\n" - "#include \"", filename, ".h\"\n" - "\n" + "extern int ", main_binding->code, "$parse_and_run(int argc, char *argv[]);\n" "int main(int argc, char *argv[]) {\n" - "tomo_init();\n" - "\n", - CORD_all(compile_cli_arg_call(env, main_binding->code, main_binding->type), "return 0;\n"), + "\treturn ", main_binding->code, "$parse_and_run(argc, argv);\n" "}\n" ); if (show_codegen) { - FILE *out = CORD_RUN(autofmt, " | bat -P --file-name=run.c"); + FILE *out = CORD_RUN("bat -P --file-name=run.c"); CORD_put(program, out); pclose(out); } |
