aboutsummaryrefslogtreecommitdiff
path: root/tomo.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-09-05 14:38:37 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-09-05 14:38:37 -0400
commita8be9efcd3c3db6f2d6b78de2074d87e296459f8 (patch)
tree81a85caf343fe8010ca526ae2acb3e9700409d1a /tomo.c
parente6aea8c1301739fb3b6547221d0432672fb6dcaa (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.c54
1 files changed, 35 insertions, 19 deletions
diff --git a/tomo.c b/tomo.c
index 0bcdb29b..4f353ce0 100644
--- a/tomo.c
+++ b/tomo.c
@@ -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);
}