ccm/lib/module.c

120 lines
2.1 KiB
C
Raw Normal View History

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);
if (!ast)
{
goto free_parser;
}
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;
}
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;
}