#include #include "module.h" #include "builtins.h" void module_init(struct module* self) { assert(self); status_init(&self->status); moka_init(&self->moka, &self->status); register_builtins(&self->moka); prog_init(&self->prog); self->handle = NULL; } void module_free(struct module* self) { assert(self); status_free(&self->status); prog_free(&self->prog); moka_free(&self->moka); if (self->handle) { dlclose(self->handle); self->handle = NULL; } } int module_load_from_dl(struct module* self, char const* path) { assert(self); assert(path); self->handle = dlopen(path, RTLD_NOW); if (!self->handle) { return EXIT_FAILURE; } void (*f)(struct module*) = dlsym(self->handle, "create_module"); if (!f) { dlclose(self->handle); return EXIT_FAILURE; } f(self); return EXIT_SUCCESS; } 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); 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); if (!status_is_ok(self->moka.status)) { status_dump(self->moka.status); } 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; }