From 1875adc48de63577c24f00a6963ff1aabe552e0f Mon Sep 17 00:00:00 2001 From: bog Date: Wed, 27 Mar 2024 20:53:06 +0100 Subject: [PATCH] :art: clean main introducing modules. --- lib/CMakeLists.txt | 1 + lib/lexer.c | 20 ++++++++--- lib/module.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++ lib/module.h | 27 ++++++++++++++ lib/moka.c | 22 ++++++++++++ lib/moka.h | 12 +++++++ src/main.c | 78 +++++----------------------------------- 7 files changed, 176 insertions(+), 74 deletions(-) create mode 100644 lib/module.c create mode 100644 lib/module.h diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 128d7d1..05d5fa7 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -18,6 +18,7 @@ add_library(moka-core moka.c symtable.c native.c + module.c ) target_compile_options(moka-core diff --git a/lib/lexer.c b/lib/lexer.c index 24db680..5272853 100644 --- a/lib/lexer.c +++ b/lib/lexer.c @@ -33,6 +33,11 @@ struct token* lexer_try_new_next(struct lexer* self) assert(self); struct token* tok = NULL; + if (!status_is_ok(self->status) > 0) + { + return NULL; + } + lexer_skip_spaces(self); if ( (tok=lexer_try_new_text(self, TOKEN_OPAR, "(")) ) @@ -348,12 +353,17 @@ struct token* lexer_try_new_ident(struct lexer* self) cursor++; } - struct token* tok = malloc(sizeof(struct token)); - token_init(tok, TOKEN_IDENT, value.value); - str_free(&value); + if (value.size > 0) + { + struct token* tok = malloc(sizeof(struct token)); + token_init(tok, TOKEN_IDENT, value.value); + str_free(&value); - self->context.cursor = cursor; - return tok; + self->context.cursor = cursor; + return tok; + } + + return NULL; } bool lexer_is_sep(struct lexer* self, size_t index) diff --git a/lib/module.c b/lib/module.c new file mode 100644 index 0000000..e391878 --- /dev/null +++ b/lib/module.c @@ -0,0 +1,90 @@ +#include "module.h" + +void module_init(struct module* self) +{ + assert(self); + status_init(&self->status); + moka_init(&self->moka, &self->status); + prog_init(&self->prog); +} + +void module_free(struct module* self) +{ + assert(self); + status_free(&self->status); + prog_free(&self->prog); + moka_free(&self->moka); +} + +int module_load_from_file(struct module* self, char const* path) +{ + assert(self); + assert(path); + + struct str source; + str_init(&source); + + FILE* file = fopen(path, "r+"); + size_t sz; + char buf; + + while ( (sz=fread(&buf, sizeof(char), 1, file)) ) + { + str_push(&source, buf); + } + + fclose(file); + + int ret = module_load_from_str(self, source.value); + + str_free(&source); + + return ret; +} + +int module_load_from_str(struct module* self, char const* source) +{ + status_init(&self->status); + + struct lexer lex; + lexer_init(&lex, source, &self->status); + + struct parser parser; + parser_init(&parser, &lex); + struct node* root = parser_try_new_root(&parser); + + if (!root || !status_is_ok(&self->status)) + { + status_dump(&self->status); + goto free_parser; + } + + struct compiler compiler; + compiler_init(&compiler, &self->status); + + compiler_compile(&compiler, root, &self->prog, &self->moka.symtable); + + if (!status_is_ok(&self->status)) + { + status_dump(&self->status); + goto free_compiler; + } + + struct exec exec; + exec_init(&exec); + + exec_prog(&exec, &self->moka, &self->prog); + exec_free(&exec); + +free_compiler: + compiler_free(&compiler); + node_free(root); + free(root); +free_parser: + parser_free(&parser); + lexer_free(&lex); + + int ret = status_is_ok(&self->status) ? EXIT_SUCCESS : EXIT_FAILURE; + + return ret; +} diff --git a/lib/module.h b/lib/module.h new file mode 100644 index 0000000..d22fa7b --- /dev/null +++ b/lib/module.h @@ -0,0 +1,27 @@ +#ifndef MK_MODULE_H +#define MK_MODULE_H + +#include "commons.h" +#include "status.h" +#include "lexer.h" +#include "parser.h" +#include "prog.h" +#include "moka.h" +#include "compiler.h" +#include "exec.h" +#include "status.h" + +struct module +{ + struct status status; + struct prog prog; + struct moka moka; +}; + +void module_init(struct module* self); +void module_free(struct module* self); + +int module_load_from_file(struct module* self, char const* path); +int module_load_from_str(struct module* self, char const* source); + +#endif diff --git a/lib/moka.c b/lib/moka.c index e959b35..7c35bea 100644 --- a/lib/moka.c +++ b/lib/moka.c @@ -3,6 +3,23 @@ #include "compiler.h" #include "prog.h" #include "exec.h" +#include "module.h" + +void moka_mod_init(struct moka_mod* self, + char* name, + struct module* new_module) +{ + assert(self); + self->name = strdup(name); + self->module = new_module; +} + +void moka_mod_free(struct moka_mod* self) +{ + free(self->name); + module_free(self->module); + free(self->module); +} void moka_init(struct moka* self, struct status* status) { @@ -11,6 +28,7 @@ void moka_init(struct moka* self, struct status* status) symtable_init(&self->symtable); vec_init(&self->frame_stack); vec_init(&self->global_values); + vec_init(&self->modules); struct frame* frame = malloc(sizeof(struct frame)); frame_init(frame); @@ -37,6 +55,10 @@ void moka_free(struct moka* self) symtable_free(&self->symtable); vec_free_elements(&self->frame_stack, (void*) frame_free); vec_free(&self->frame_stack); + + vec_free_elements(&self->modules, (void*) moka_mod_free); + vec_free(&self->modules); + vec_free_elements(&self->global_values, (void*) value_free); vec_free(&self->global_values); } diff --git a/lib/moka.h b/lib/moka.h index 67223a0..e1552a6 100644 --- a/lib/moka.h +++ b/lib/moka.h @@ -12,14 +12,26 @@ struct frame struct vec local_values; }; +struct moka_mod +{ + char* name; + struct module* module; +}; + struct moka { struct status* status; struct symtable symtable; struct vec frame_stack; struct vec global_values; + struct vec modules; }; +void moka_mod_init(struct moka_mod* self, + char* name, + struct module* new_module); +void moka_mod_free(struct moka_mod* self); + void moka_init(struct moka* self, struct status* status); void frame_init(struct frame* self); void frame_free(struct frame* self); diff --git a/src/main.c b/src/main.c index ad87625..34ce03d 100644 --- a/src/main.c +++ b/src/main.c @@ -5,85 +5,25 @@ #include #include #include +#include int main(int argc, char** argv) { if (argc <= 1) { return EXIT_FAILURE; } + + struct module module; + module_init(&module); - struct status status; - status_init(&status); - - struct str source; - str_init(&source); + int ret = module_load_from_file(&module, argv[1]); + if (moka_has_top(&module.moka)) { - FILE* file = fopen(argv[1], "r+"); - size_t sz; - char buf; - while ( (sz=fread(&buf, sizeof(char), 1, file)) ) - { - str_push(&source, buf); - } - fclose(file); - } - - struct lexer lex; - lexer_init(&lex, source.value, &status); - - struct parser parser; - parser_init(&parser, &lex); - struct node* root = parser_try_new_root(&parser); - - if (!root || !status_is_ok(&status)) - { - status_dump(&status); - goto free_parser; - } - - struct compiler compiler; - compiler_init(&compiler, &status); - - struct prog prog; - prog_init(&prog); - - - struct moka moka; - moka_init(&moka, &status); - compiler_compile(&compiler, root, &prog, &moka.symtable); - - if (!status_is_ok(&status)) - { - status_dump(&status); - goto free_moka; - } - - - struct exec exec; - exec_init(&exec); - - exec_prog(&exec, &moka, &prog); - - if (moka_has_top(&moka)) - { - MOKA value = moka_top(&moka); - moka_dump(&moka, value); + MOKA value = moka_top(&module.moka); + moka_dump(&module.moka, value); printf("\n"); } - exec_free(&exec); -free_moka: - moka_free(&moka); - prog_free(&prog); - compiler_free(&compiler); - node_free(root); - free(root); -free_parser: - parser_free(&parser); - lexer_free(&lex); - str_free(&source); - - int ret = status_is_ok(&status) ? EXIT_SUCCESS : EXIT_FAILURE; - status_free(&status); + module_free(&module); return ret; }