/* * Main entry point of the bootstrap compiler. * * Copyright © 2025 Samuel Lidén Borell * * SPDX-License-Identifier: EUPL-1.2+ */ #include #include #include #include "compiler.h" #if defined(_WIN32) || defined(_WIN64) #define DIRSEP '\\' #else #define DIRSEP '/' #endif #define PATH_LIMIT 512 static size_t rootdir_len = 0; static FILE *f = NULL; static char fullpath[PATH_LIMIT]; char *current_filename = NULL; int current_line = 0; NORETURN void error(const char *s) { fprintf(stderr, "%s:%d: %s\n", current_filename, current_line, s); exit(EXIT_FAILURE); } static void open_file(const char *filename) { size_t filename_len; filename_len = strlen(filename); if (filename_len + 1 + rootdir_len + 1 > PATH_LIMIT) { FAIL("filename too long"); } memcpy(fullpath+rootdir_len+1, filename, filename_len); memreplace(fullpath+rootdir_len+1, '/', DIRSEP, filename_len); fullpath[rootdir_len+1+filename_len] = '\0'; f = fopen(fullpath, "rb"); if (!f) { perror(fullpath); abort(); } current_filename = fullpath; current_line = 0; } static void close_file(void) { NO_NEG(fclose(f)); } static void parse(void) { int i; module_start(); /* TODO decide on a file name here. in particular, check that "sources.index" is not used for anything else. */ open_file("sources.index"); parse_source_index(f); close_file(); for (i = 0; i < num_sources; i++) { open_file(sources[i]); parse_file(f, path_basename(sources[i])); close_file(); } num_sources = 0; } static void set_rootdir(const char *rootdir) { rootdir_len = strlen(rootdir); if (rootdir_len+2 >= PATH_LIMIT) FAIL("source path too long"); memcpy(fullpath, rootdir, rootdir_len); fullpath[rootdir_len] = DIRSEP; } static void reset_sources_index(void) { num_sources = 0; } int main(int argc, char **argv) { int i; if (argc < 3) { fprintf(stderr, "usage: stage1 ...\n"); return EXIT_FAILURE; } /* Parse each module. This is a hack, that just throws everything together in a single namespace (which is incorrect, but works for compiling the SLUL compiler). */ modules = NULL; for (i = 2; i < argc; i++) { set_rootdir(argv[i]); parse(); reset_sources_index(); } emit_c_code(argv[1]); return EXIT_SUCCESS; }