diff --git a/CMakeLists.txt b/CMakeLists.txt index 09a66d9..4aa5707 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,6 +82,8 @@ set_target_properties(tomlc99 OUTPUT_NAME "toml" ARCHIVE_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/dep) +include_directories(${PROJECT_SOURCE_DIR}/dep/tomlc99) + # ------------------------------------------------ # # Source # # ------------------------------------------------ # diff --git a/src/cfg/opt.c b/src/cfg/opt.c new file mode 100644 index 0000000..bb74e51 --- /dev/null +++ b/src/cfg/opt.c @@ -0,0 +1,118 @@ +// +// Created by servostar on 5/31/24. +// + +#include +#include +#include + +TargetConfig default_target_config() { + TargetConfig config; + + config.name = "debug"; + config.print_ast = false; + config.print_asm = false; + config.print_ir = false; + + return config; +} + +TargetConfig default_target_config_from_args(int argc, char *argv[]) { + TargetConfig config = default_target_config(); + + for (int i = 0; i < argc; i++) { + char *option = argv[i]; + + if (strcmp(option, "--print-ast") == 0) { + config.print_ast = true; + } else if (strcmp(option, "--print-asm") == 0) { + config.print_asm = true; + } else if (strcmp(option, "--print-ir") == 0) { + config.print_ir = true; + } + } + + return config; +} + +void print_help(void) { + const char *lines[] = { + "Gemstone Compiler (C) GPL-2.0\n", + "Compile file(s): gsc [files]", + "Build project (build.toml): gsc [directory] [target]|all", + "Options:", + " --print-ast print resulting abstract syntax tree to a file", + " --print-asm print resulting assembly language to a file", + " --print-ir print resulting LLVM-IR to a file" + }; + + for (unsigned int i = 0; i < sizeof(lines) / sizeof(const char *); i++) { + printf("%s\n", lines[i]); + } +} + +#define PROJECT_OK 0 +#define PROJECT_TOML_ERR 1 +#define PROJECT_SEMANTIC_ERR 2 + +static int parse_project_table(ProjectConfig *config, toml_table_t *project_table) { + // project name + toml_datum_t name = toml_string_in(project_table, "name"); + if (!name.ok) { + printf("Invalid project configuration: project must have a name\n\n"); + return PROJECT_SEMANTIC_ERR; + } + + config->name = name.u.s; + + // project version + toml_datum_t version = toml_string_in(project_table, "version"); + if (version.ok) { + config->name = version.u.s; + } + + // author names + toml_array_t *authors = toml_array_in(project_table, "authors"); + if (authors) { + unsigned int len = 0; + config->authors = malloc(sizeof(const char *) * 2); + + for (int i = 0;; i++) { + toml_datum_t author = toml_string_at(authors, i); + if (!author.ok) + break; + + char** new_authors = realloc(config->authors, sizeof(const char *) * ++len); + config->authors = new_authors; + config->authors[len] = author.u.s; + } + } +} + +int load_project_config(ProjectConfig *config) { + FILE *config_file = fopen("build.toml", "r"); + if (config_file == NULL) { + return PROJECT_TOML_ERR; + } + + char err_buf[200]; + + toml_table_t *conf = toml_parse_file(config_file, err_buf, sizeof(err_buf)); + fclose(config_file); + + if (!conf) { + printf("Invalid project configuration: %s\n\n", err_buf); + return PROJECT_SEMANTIC_ERR; + } + + toml_table_t *project = toml_table_in(conf, "project"); + if (project) { + parse_project_table(config, project); + + return PROJECT_OK; + } + printf("Invalid project configuration: missing project table\n\n"); + + toml_free(conf); + return PROJECT_SEMANTIC_ERR; +} diff --git a/src/cfg/opt.h b/src/cfg/opt.h new file mode 100644 index 0000000..cf89d4f --- /dev/null +++ b/src/cfg/opt.h @@ -0,0 +1,34 @@ +// +// Created by servostar on 5/31/24. +// + +#ifndef GEMSTONE_OPT_H +#define GEMSTONE_OPT_H + +#include + +typedef struct TargetConfig_t { + char* name; + bool print_ast; + bool print_asm; + bool print_ir; +} TargetConfig; + +typedef struct ProjectConfig_t { + // name of the project + char* name; + // description + char* desc; + // version + char* version; + // list of authors + char** authors; +} ProjectConfig; + +TargetConfig default_target_config(); + +TargetConfig default_target_config_from_args(int argc, char* argv[]); + +void print_help(void); + +#endif //GEMSTONE_OPT_H diff --git a/src/main.c b/src/main.c index e9914ef..83e9705 100644 --- a/src/main.c +++ b/src/main.c @@ -9,10 +9,6 @@ extern FILE *yyin; -// Global array to store options -char options[5][10]; -int num_options = 0; - /** * @brief Log a debug message to inform about beginning exit procedures * @@ -20,34 +16,6 @@ int num_options = 0; void notify_exit(void) { DEBUG("Exiting gemstone..."); } -/** - * @brief add option to global option array - * - */ - -void add_option(const char* option) { - if (num_options < 5 ) { - strcpy(options[num_options], option); - num_options++; - } else { - PANIC("Too Many Options given"); - } -} - -/** - * @brief Check if Option is set - * - */ - -size_t check_option(const char* name) { - for (int i = 0; i < num_options; i++) { - if (strcmp(options[i], name) == 0) { - return 1; - } - } - return 0; -} - /** * @brief Closes File after compiling. * @@ -84,18 +52,6 @@ void setup(void) { int main(int argc, char *argv[]) { - // Iteration through arguments - for (int i = 1; i < argc; i++) { - // Check if the argument starts with "--" - if (argv[i][0] == '-' && argv[i][1] == '-') { - // Extract option name - char option[10]; - strcpy(option, argv[i] + 2); - - // Add option to the global array - add_option(option); - } - } setup(); atexit(close_file);