summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
authorZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-16 00:19:37 +0000
committerZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-16 00:19:37 +0000
commit23d18925df02157e9330c3612992e40553bb5da1 (patch)
tree89a893944aa7555c59b7700aa608f39680c0a120 /src/main.c
parent301d9582884ec7d180791e5c9c6ec649dc01ff68 (diff)
Working on reducing function pollution
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c540
1 files changed, 232 insertions, 308 deletions
diff --git a/src/main.c b/src/main.c
index 2c33a6b..ab4c39f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -12,334 +12,258 @@
// Forward decl for LSP
int lsp_main(int argc, char **argv);
-void print_search_paths()
-{
- printf("Search paths:\n");
- printf(" ./\n");
- printf(" ./std/\n");
- printf(" /usr/local/share/zenc\n");
- printf(" /usr/share/zenc\n");
+void print_search_paths() {
+ printf("Search paths:\n");
+ printf(" ./\n");
+ printf(" ./std/\n");
+ printf(" /usr/local/share/zenc\n");
+ printf(" /usr/share/zenc\n");
}
-void print_version()
-{
- printf("Zen C version %s\n", ZEN_VERSION);
+void print_version() { printf("Zen C version %s\n", ZEN_VERSION); }
+
+void print_usage() {
+ printf("Usage: zc [command] [options] <file.zc>\n");
+ printf("Commands:\n");
+ printf(" run Compile and run the program\n");
+ printf(" build Compile to executable\n");
+ printf(" check Check for errors only\n");
+ printf(" repl Start Interactive REPL\n");
+ printf(" transpile Transpile to C code only (no compilation)\n");
+ printf(" lsp Start Language Server\n");
+ printf("Options:\n");
+ printf(" --version Print version information");
+ printf(" -o <file> Output executable name\n");
+ printf(" --emit-c Keep generated C file (out.c)\n");
+ printf(" --freestanding Freestanding mode (no stdlib)\n");
+ printf(" --cc <compiler> C compiler to use (gcc, clang, tcc, zig)\n");
+ printf(" -O<level> Optimization level\n");
+ printf(" -g Debug info\n");
+ printf(" -v, --verbose Verbose output\n");
+ printf(" -q, --quiet Quiet output\n");
+ printf(" -c Compile only (produce .o)\n");
}
-void print_usage()
-{
- printf("Usage: zc [command] [options] <file.zc>\n");
- printf("Commands:\n");
- printf(" run Compile and run the program\n");
- printf(" build Compile to executable\n");
- printf(" check Check for errors only\n");
- printf(" repl Start Interactive REPL\n");
- printf(" transpile Transpile to C code only (no compilation)\n");
- printf(" lsp Start Language Server\n");
- printf("Options:\n");
- printf(" --version Print version information");
- printf(" -o <file> Output executable name\n");
- printf(" --emit-c Keep generated C file (out.c)\n");
- printf(" --freestanding Freestanding mode (no stdlib)\n");
- printf(" --cc <compiler> C compiler to use (gcc, clang, tcc, zig)\n");
- printf(" -O<level> Optimization level\n");
- printf(" -g Debug info\n");
- printf(" -v, --verbose Verbose output\n");
- printf(" -q, --quiet Quiet output\n");
- printf(" -c Compile only (produce .o)\n");
-}
-
-int main(int argc, char **argv)
-{
- // Defaults
- memset(&g_config, 0, sizeof(g_config));
- strcpy(g_config.cc, "gcc");
+int main(int argc, char **argv) {
+ // Defaults
+ memset(&g_config, 0, sizeof(g_config));
+ strcpy(g_config.cc, "gcc");
- if (argc < 2)
- {
- print_usage();
- return 1;
- }
+ if (argc < 2) {
+ print_usage();
+ return 1;
+ }
- // Parse command
- char *command = argv[1];
- int arg_start = 2;
+ // Parse command
+ char *command = argv[1];
+ int arg_start = 2;
- if (strcmp(command, "lsp") == 0)
- {
- return lsp_main(argc, argv);
- }
- else if (strcmp(command, "repl") == 0)
- {
- run_repl(argv[0]); // Pass self path for recursive calls
- return 0;
- }
- else if (strcmp(command, "transpile") == 0)
- {
- g_config.mode_transpile = 1;
- g_config.emit_c = 1; // Transpile implies emitting C
- }
- else if (strcmp(command, "run") == 0)
- {
- g_config.mode_run = 1;
- }
- else if (strcmp(command, "check") == 0)
- {
- g_config.mode_check = 1;
- }
- else if (strcmp(command, "build") == 0)
- {
- // default mode
- }
- else if (command[0] == '-')
- {
- // implicit build or run? assume build if starts with flag, but usually
- // command first If file provided directly: "zc file.zc" -> build
- if (strchr(command, '.'))
- {
- // treat as filename
- g_config.input_file = command;
- arg_start = 2; // already consumed
- }
- else
- {
- // Flags
- arg_start = 1;
- }
+ if (strcmp(command, "lsp") == 0) {
+ return lsp_main(argc, argv);
+ } else if (strcmp(command, "repl") == 0) {
+ run_repl(argv[0]); // Pass self path for recursive calls
+ return 0;
+ } else if (strcmp(command, "transpile") == 0) {
+ g_config.mode_transpile = 1;
+ g_config.emit_c = 1; // Transpile implies emitting C
+ } else if (strcmp(command, "run") == 0) {
+ g_config.mode_run = 1;
+ } else if (strcmp(command, "check") == 0) {
+ g_config.mode_check = 1;
+ } else if (strcmp(command, "build") == 0) {
+ // default mode
+ } else if (command[0] == '-') {
+ // implicit build or run? assume build if starts with flag, but usually
+ // command first If file provided directly: "zc file.zc" -> build
+ if (strchr(command, '.')) {
+ // treat as filename
+ g_config.input_file = command;
+ arg_start = 2; // already consumed
+ } else {
+ // Flags
+ arg_start = 1;
}
- else
- {
- // Check if file
- if (strchr(command, '.'))
- {
- g_config.input_file = command;
- arg_start = 2;
- }
+ } else {
+ // Check if file
+ if (strchr(command, '.')) {
+ g_config.input_file = command;
+ arg_start = 2;
}
-
- // Parse args
- for (int i = arg_start; i < argc; i++)
- {
- char *arg = argv[i];
- if (strcmp(arg, "--emit-c") == 0)
- {
- g_config.emit_c = 1;
- }
- else if (strcmp(arg, "--version") == 0 || strcmp(arg, "-V") == 0)
- {
- print_version();
- return 0;
+ }
+
+ // Parse args
+ for (int i = arg_start; i < argc; i++) {
+ char *arg = argv[i];
+ if (strcmp(arg, "--emit-c") == 0) {
+ g_config.emit_c = 1;
+ } else if (strcmp(arg, "--version") == 0 || strcmp(arg, "-V") == 0) {
+ print_version();
+ return 0;
+ } else if (strcmp(arg, "--verbose") == 0 || strcmp(arg, "-v") == 0) {
+ g_config.verbose = 1;
+ } else if (strcmp(arg, "--quiet") == 0 || strcmp(arg, "-q") == 0) {
+ g_config.quiet = 1;
+ } else if (strcmp(arg, "--freestanding") == 0) {
+ g_config.is_freestanding = 1;
+ } else if (strcmp(arg, "--check") == 0) {
+ g_config.mode_check = 1;
+ } else if (strcmp(arg, "--cc") == 0) {
+ if (i + 1 < argc) {
+ char *cc_arg = argv[++i];
+ // Handle "zig" shorthand for "zig cc"
+ if (strcmp(cc_arg, "zig") == 0) {
+ strcpy(g_config.cc, "zig cc");
+ } else {
+ strcpy(g_config.cc, cc_arg);
}
- else if (strcmp(arg, "--verbose") == 0 || strcmp(arg, "-v") == 0)
- {
- g_config.verbose = 1;
- }
- else if (strcmp(arg, "--quiet") == 0 || strcmp(arg, "-q") == 0)
- {
- g_config.quiet = 1;
- }
- else if (strcmp(arg, "--freestanding") == 0)
- {
- g_config.is_freestanding = 1;
- }
- else if (strcmp(arg, "--check") == 0)
- {
- g_config.mode_check = 1;
- }
- else if (strcmp(arg, "--cc") == 0)
- {
- if (i + 1 < argc)
- {
- char *cc_arg = argv[++i];
- // Handle "zig" shorthand for "zig cc"
- if (strcmp(cc_arg, "zig") == 0)
- {
- strcpy(g_config.cc, "zig cc");
- }
- else
- {
- strcpy(g_config.cc, cc_arg);
- }
- }
- }
- else if (strcmp(arg, "-o") == 0)
- {
- if (i + 1 < argc)
- {
- g_config.output_file = argv[++i];
- }
- }
- else if (strncmp(arg, "-O", 2) == 0)
- {
- // Add to CFLAGS
- strcat(g_config.gcc_flags, " ");
- strcat(g_config.gcc_flags, arg);
- }
- else if (strcmp(arg, "-g") == 0)
- {
- strcat(g_config.gcc_flags, " -g");
- }
- else if (arg[0] == '-')
- {
- // Unknown flag or C flag
- strcat(g_config.gcc_flags, " ");
- strcat(g_config.gcc_flags, arg);
- }
- else
- {
- if (!g_config.input_file)
- {
- g_config.input_file = arg;
- }
- else
- {
- printf("Multiple input files not supported yet.\n");
- return 1;
- }
- }
- }
-
- if (!g_config.input_file)
- {
- printf("Error: No input file specified.\n");
- return 1;
- }
-
- g_current_filename = g_config.input_file;
-
- // Load file
- char *src = load_file(g_config.input_file);
- if (!src)
- {
- printf("Error: Could not read file %s\n", g_config.input_file);
+ }
+ } else if (strcmp(arg, "-o") == 0) {
+ if (i + 1 < argc) {
+ g_config.output_file = argv[++i];
+ }
+ } else if (strncmp(arg, "-O", 2) == 0) {
+ // Add to CFLAGS
+ strcat(g_config.gcc_flags, " ");
+ strcat(g_config.gcc_flags, arg);
+ } else if (strcmp(arg, "-g") == 0) {
+ strcat(g_config.gcc_flags, " -g");
+ } else if (arg[0] == '-') {
+ // Unknown flag or C flag
+ strcat(g_config.gcc_flags, " ");
+ strcat(g_config.gcc_flags, arg);
+ } else {
+ if (!g_config.input_file) {
+ g_config.input_file = arg;
+ } else {
+ printf("Multiple input files not supported yet.\n");
return 1;
+ }
}
-
- init_builtins();
- zen_init();
-
- // Initialize Plugin Manager
- zptr_plugin_mgr_init();
-
- // Parse context init
- ParserContext ctx;
- memset(&ctx, 0, sizeof(ctx));
-
- // Scan for build directives (e.g. //> link: -lm)
- scan_build_directives(&ctx, src);
-
- Lexer l;
- lexer_init(&l, src);
-
- ctx.hoist_out = tmpfile(); // Temp file for plugin hoisting
- if (!ctx.hoist_out)
- {
- perror("tmpfile for hoisting");
- return 1;
- }
- g_parser_ctx = &ctx;
-
- if (!g_config.quiet)
- {
- printf("[zc] Compiling %s...\n", g_config.input_file);
- }
-
- ASTNode *root = parse_program(&ctx, &l);
- if (!root)
- {
- // Parse failed
- return 1;
- }
-
- if (g_config.mode_check)
- {
- // Just verify
- printf("Check passed.\n");
- return 0;
- }
-
- // Codegen to C
- FILE *out = fopen("out.c", "w");
- if (!out)
- {
- perror("fopen out.c");
+ }
+
+ if (!g_config.input_file) {
+ printf("Error: No input file specified.\n");
+ return 1;
+ }
+
+ g_current_filename = g_config.input_file;
+
+ // Load file
+ char *src = load_file(g_config.input_file);
+ if (!src) {
+ printf("Error: Could not read file %s\n", g_config.input_file);
+ return 1;
+ }
+
+ init_builtins();
+ zen_init();
+
+ // Initialize Plugin Manager
+ zptr_plugin_mgr_init();
+
+ // Parse context init
+ ParserContext ctx;
+ memset(&ctx, 0, sizeof(ctx));
+
+ // Scan for build directives (e.g. //> link: -lm)
+ scan_build_directives(&ctx, src);
+
+ Lexer l;
+ lexer_init(&l, src);
+
+ ctx.hoist_out = tmpfile(); // Temp file for plugin hoisting
+ if (!ctx.hoist_out) {
+ perror("tmpfile for hoisting");
+ return 1;
+ }
+ g_parser_ctx = &ctx;
+
+ if (!g_config.quiet) {
+ printf("[zc] Compiling %s...\n", g_config.input_file);
+ }
+
+ ASTNode *root = parse_program(&ctx, &l);
+ if (!root) {
+ // Parse failed
+ return 1;
+ }
+
+ if (g_config.mode_check) {
+ // Just verify
+ printf("Check passed.\n");
+ return 0;
+ }
+
+ // Codegen to C
+ FILE *out = fopen("out.c", "w");
+ if (!out) {
+ perror("fopen out.c");
+ return 1;
+ }
+
+ codegen_node(&ctx, root, out);
+ fclose(out);
+
+ if (g_config.mode_transpile) {
+ if (g_config.output_file) {
+ // If user specified -o, rename out.c to that
+ if (rename("out.c", g_config.output_file) != 0) {
+ perror("rename out.c");
return 1;
+ }
+ if (!g_config.quiet) {
+ printf("[zc] Transpiled to %s\n", g_config.output_file);
+ }
+ } else {
+ if (!g_config.quiet) {
+ printf("[zc] Transpiled to out.c\n");
+ }
}
+ // Done, no C compilation
+ return 0;
+ }
- codegen_node(&ctx, root, out);
- fclose(out);
-
- if (g_config.mode_transpile)
- {
- if (g_config.output_file)
- {
- // If user specified -o, rename out.c to that
- if (rename("out.c", g_config.output_file) != 0)
- {
- perror("rename out.c");
- return 1;
- }
- if (!g_config.quiet)
- {
- printf("[zc] Transpiled to %s\n", g_config.output_file);
- }
- }
- else
- {
- if (!g_config.quiet)
- {
- printf("[zc] Transpiled to out.c\n");
- }
- }
- // Done, no C compilation
- return 0;
- }
-
- // Compile C
- char cmd[8192];
- char *outfile = g_config.output_file ? g_config.output_file : "a.out";
-
- // TCC-specific adjustments?
- // Already handled by user passing --cc tcc
-
- snprintf(cmd, sizeof(cmd), "%s %s %s %s %s -o %s out.c -lm %s -I./src %s", g_config.cc,
- g_config.gcc_flags, g_cflags, g_config.is_freestanding ? "-ffreestanding" : "", "",
- outfile, g_parser_ctx->has_async ? "-lpthread" : "", g_link_flags);
+ // Compile C
+ char cmd[8192];
+ char *outfile = g_config.output_file ? g_config.output_file : "a.out";
- if (g_config.verbose)
- {
- printf("[CMD] %s\n", cmd);
- }
+ // TCC-specific adjustments?
+ // Already handled by user passing --cc tcc
- int ret = system(cmd);
- if (ret != 0)
- {
- printf("C compilation failed.\n");
- if (!g_config.emit_c)
- {
- remove("out.c");
- }
- return 1;
- }
+ snprintf(cmd, sizeof(cmd), "%s %s %s %s %s -o %s out.c -lm %s -I./src %s",
+ g_config.cc, g_config.gcc_flags, g_cflags,
+ g_config.is_freestanding ? "-ffreestanding" : "", "", outfile,
+ g_parser_ctx->has_async ? "-lpthread" : "", g_link_flags);
- if (!g_config.emit_c)
- {
- // remove("out.c"); // Keep it for debugging for now or follow flag
- remove("out.c");
- }
+ if (g_config.verbose) {
+ printf("[CMD] %s\n", cmd);
+ }
- if (g_config.mode_run)
- {
- char run_cmd[2048];
- sprintf(run_cmd, "./%s", outfile);
- ret = system(run_cmd);
- remove(outfile);
- zptr_plugin_mgr_cleanup();
- zen_trigger_global();
- return ret;
+ int ret = system(cmd);
+ if (ret != 0) {
+ printf("C compilation failed.\n");
+ if (!g_config.emit_c) {
+ remove("out.c");
}
-
+ return 1;
+ }
+
+ if (!g_config.emit_c) {
+ // remove("out.c"); // Keep it for debugging for now or follow flag
+ remove("out.c");
+ }
+
+ if (g_config.mode_run) {
+ char run_cmd[2048];
+ sprintf(run_cmd, "./%s", outfile);
+ ret = system(run_cmd);
+ remove(outfile);
zptr_plugin_mgr_cleanup();
zen_trigger_global();
- return 0;
+ return ret;
+ }
+
+ zptr_plugin_mgr_cleanup();
+ zen_trigger_global();
+ return 0;
}