roza/lib/loader.c

213 lines
3.5 KiB
C

#include "lexer.h"
#include "lib/commons.h"
#include "parser.h"
#include "loader.h"
#include "compiler.h"
#include "prepass.h"
#include "mod.h"
#include "vm.h"
#include "sym.h"
#include "tysolver.h"
void loader_init(loader_t* loader)
{
assert(loader);
}
void loader_free(loader_t* loader)
{
assert(loader);
}
int loader_ldfile(loader_t* loader, char const* path, int debug)
{
assert(loader);
str_t source;
str_init(&source);
// read sources
{
FILE* file = fopen(path, "r");
if (!file)
{
fprintf(stderr, "Cannot open file '%s'.\n", path);
abort();
}
char buf;
size_t sz;
while ( (sz = fread(&buf, sizeof(char), 1, file)) )
{
str_push(&source, buf);
}
fclose(file);
}
if (str_empty(&source))
{
str_free(&source);
return -1;
}
tysy_t tysy;
tysy_init(&tysy);
err_t err;
err_init(&err);
lexer_t lex;
lexer_init(&lex, source.data, &err);
if (err_dump(&err))
{
lexer_free(&lex);
err_free(&err);
tysy_free(&tysy);
abort();
}
parser_t parser;
parser_init(&parser, &lex, &err);
node_t* node = parser_try_new_tree(&parser);
if (!node)
{
str_free(&source);
err_dump(&err);
parser_free(&parser);
lexer_free(&lex);
err_free(&err);
tysy_free(&tysy);
return -1;
}
if (debug)
{
char msg[RZ_STR_LIMIT];
node_str(node, msg, RZ_STR_LIMIT);
printf("\n======== AST ========\n");
printf("%s\n", msg);
}
sym_t sym;
sym_init(&sym, &tysy, &err);
mod_t mod;
mod_init(&mod);
tysolver_t tysolver;
tysolver_init(&tysolver, &sym, &tysy);
int id = 0;
// prepass
{
prepass_t prepass;
prepass_init(&prepass, &id, &sym, &tysy, &tysolver, &err);
prepass_run(&prepass, node);
prepass_free(&prepass);
}
// compile
{
compiler_t compiler;
compiler_init(&compiler, &id, &sym, &tysy, &err);
int status = compiler_run(&compiler, node, &mod.program);
if (status != 0)
{
return -1;
}
compiler_free(&compiler);
}
tysolver_free(&tysolver);
node_free(node);
free(node);
// check compilation errors
if (err_dump(&err))
{
parser_free(&parser);
lexer_free(&lex);
str_free(&source);
err_free(&err);
mod_free(&mod);
sym_free(&sym);
tysy_free(&tysy);
return -1;
}
// execute
{
vm_t vm;
vm_init(&vm, &sym, &tysy, &err);
int status = vm_exec_mod(&vm, &mod);
if (status != 0)
{
vm_free(&vm);
mod_free(&mod);
sym_free(&sym);
parser_free(&parser);
lexer_free(&lex);
str_free(&source);
tysy_free(&tysy);
err_free(&err);
return status;
}
if (debug)
{
char msg[RZ_STR_LIMIT];
vm_stack_str(&vm, msg, RZ_STR_LIMIT);
printf("\n======== STACK ========\n");
printf("%s\n", msg);
}
vm_free(&vm);
}
if (debug)
{
char msg[RZ_STR_LIMIT];
mod_str(&mod, msg, RZ_STR_LIMIT);
printf("%s", msg);
char msg2[RZ_STR_LIMIT];
sym_str(&sym, msg2, RZ_STR_LIMIT);
printf("\n======== SYM TABLE ========\n");
printf("%s", msg2);
}
mod_free(&mod);
sym_free(&sym);
// free
parser_free(&parser);
lexer_free(&lex);
str_free(&source);
tysy_free(&tysy);
// check execution errors
if (err_dump(&err))
{
err_free(&err);
return -1;
}
err_free(&err);
return 0;
}