2024-03-18 17:20:40 +00:00
|
|
|
#include "module.h"
|
|
|
|
#include "lexer.h"
|
|
|
|
#include "parser.h"
|
|
|
|
#include "compiler.h"
|
|
|
|
|
|
|
|
void module_init(module_t* self)
|
|
|
|
{
|
|
|
|
assert(self);
|
|
|
|
self->source = NULL;
|
|
|
|
prog_init(&self->prog);
|
|
|
|
err_init(&self->err);
|
|
|
|
ccm_init(&self->ccm);
|
|
|
|
}
|
|
|
|
|
|
|
|
void module_free(module_t* self)
|
|
|
|
{
|
|
|
|
assert(self);
|
|
|
|
|
|
|
|
if (self->source)
|
|
|
|
{
|
|
|
|
free(self->source);
|
|
|
|
}
|
|
|
|
|
|
|
|
ccm_free(&self->ccm);
|
|
|
|
prog_free(&self->prog);
|
|
|
|
err_free(&self->err);
|
|
|
|
}
|
|
|
|
|
|
|
|
int module_load(module_t* self, char const* path)
|
|
|
|
{
|
|
|
|
assert(self);
|
|
|
|
assert(path);
|
|
|
|
|
|
|
|
if (module_load_source(self, path) != 0)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
lexer_t lexer;
|
|
|
|
lexer_init(&lexer);
|
|
|
|
|
|
|
|
lexer_scan(&lexer, self->source);
|
|
|
|
|
|
|
|
parser_t parser;
|
|
|
|
parser_init(&parser, &lexer);
|
|
|
|
|
|
|
|
node_t* ast = parser_try_new_parse(&parser);
|
2024-03-19 13:23:11 +00:00
|
|
|
|
2024-03-18 17:20:40 +00:00
|
|
|
if (!err_is_ok(&lexer.err) || !err_is_ok(&parser.err))
|
|
|
|
{
|
|
|
|
err_print_stack_trace(&lexer.err);
|
|
|
|
err_print_stack_trace(&parser.err);
|
|
|
|
err_push(&self->err, lexer.line, "invalid module");
|
|
|
|
goto free_parser;
|
|
|
|
}
|
2024-03-19 13:23:11 +00:00
|
|
|
|
|
|
|
if (!ast)
|
|
|
|
{
|
|
|
|
goto free_parser;
|
|
|
|
}
|
|
|
|
|
2024-03-18 17:20:40 +00:00
|
|
|
compiler_t compiler;
|
|
|
|
compiler_init(&compiler, self);
|
|
|
|
|
|
|
|
compiler_compile(&compiler, ast, &self->prog);
|
|
|
|
|
|
|
|
compiler_free(&compiler);
|
|
|
|
node_free(ast);
|
|
|
|
free(ast);
|
|
|
|
free_parser:
|
|
|
|
parser_free(&parser);
|
|
|
|
lexer_free(&lexer);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int module_load_source(module_t* self, char const* path)
|
|
|
|
{
|
|
|
|
assert(self);
|
|
|
|
FILE* file = fopen(path, "r+");
|
|
|
|
|
|
|
|
if (!file)
|
|
|
|
{
|
|
|
|
err_push(&self->err, 0, "cannot load file '%s'", path);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t sz = 0;
|
|
|
|
size_t cap = 2;
|
|
|
|
char* data = malloc(sizeof(char) * cap);
|
|
|
|
|
|
|
|
char buf;
|
|
|
|
size_t size;
|
|
|
|
|
|
|
|
while ( (size = fread(&buf, 1, sizeof(char), file)) )
|
|
|
|
{
|
|
|
|
if (sz + 1 >= cap)
|
|
|
|
{
|
|
|
|
cap *= 2;
|
|
|
|
char* next = realloc(data, sizeof(char) * cap);
|
|
|
|
|
|
|
|
if (next)
|
|
|
|
{
|
|
|
|
data = next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
data[sz] = buf;
|
|
|
|
sz++;
|
|
|
|
}
|
|
|
|
|
|
|
|
data[sz] = '\0';
|
|
|
|
|
|
|
|
self->source = strdup(data);
|
|
|
|
|
|
|
|
free(data);
|
|
|
|
fclose(file);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|