2024-03-29 04:46:35 +00:00
|
|
|
#include <dlfcn.h>
|
2024-03-27 19:53:06 +00:00
|
|
|
#include "module.h"
|
2024-03-29 04:46:35 +00:00
|
|
|
#include "builtins.h"
|
2024-03-27 19:53:06 +00:00
|
|
|
|
|
|
|
void module_init(struct module* self)
|
|
|
|
{
|
|
|
|
assert(self);
|
|
|
|
status_init(&self->status);
|
|
|
|
moka_init(&self->moka, &self->status);
|
2024-03-29 04:46:35 +00:00
|
|
|
register_builtins(&self->moka);
|
|
|
|
|
2024-03-27 19:53:06 +00:00
|
|
|
prog_init(&self->prog);
|
2024-03-29 04:46:35 +00:00
|
|
|
self->handle = NULL;
|
2024-03-27 19:53:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void module_free(struct module* self)
|
|
|
|
{
|
|
|
|
assert(self);
|
|
|
|
status_free(&self->status);
|
|
|
|
prog_free(&self->prog);
|
|
|
|
moka_free(&self->moka);
|
2024-03-29 04:46:35 +00:00
|
|
|
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;
|
2024-03-27 19:53:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
2024-03-29 04:46:35 +00:00
|
|
|
compiler_compile(&compiler, root, &self->prog, &self->moka);
|
2024-03-27 19:53:06 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|