#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; } 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; }