roza/lib/loader.c

170 lines
2.9 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"
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);
parser_t parser;
parser_init(&parser, &lex, &err);
node_t* node = parser_try_new_tree(&parser);
if (debug)
{
char msg[RZ_STR_LIMIT];
node_str(node, msg, RZ_STR_LIMIT);
printf("\n======== AST ========\n");
printf("%s\n", msg);
}
if (node)
{
mod_t mod;
mod_init(&mod);
// prepass
{
prepass_t prepass;
prepass_init(&prepass, &err);
prepass_run(&prepass, node);
prepass_free(&prepass);
}
// compile
{
compiler_t compiler;
compiler_init(&compiler, &mod, &tysy, &err);
compiler_run(&compiler, node);
compiler_free(&compiler);
}
node_free(node);
free(node);
// check compilation errors
if (err_dump(&err))
{
parser_free(&parser);
lexer_free(&lex);
str_free(&source);
tysy_free(&tysy);
err_free(&err);
abort();
}
// execute
{
vm_t vm;
vm_init(&vm, &tysy, &err);
int status = vm_exec_mod(&vm, &mod);
if (status != 0)
{
vm_free(&vm);
mod_free(&mod);
parser_free(&parser);
lexer_free(&lex);
str_free(&source);
tysy_free(&tysy);
err_free(&err);
return status;
}
if (debug)
{
{
char msg[RZ_STR_LIMIT];
mod_str(&mod, msg, RZ_STR_LIMIT);
printf("%s", msg);
}
{
char msg[RZ_STR_LIMIT];
vm_stack_str(&vm, msg, RZ_STR_LIMIT);
printf("\n======== STACK ========\n");
printf("%s\n", msg);
}
}
vm_free(&vm);
}
mod_free(&mod);
}
// free
parser_free(&parser);
lexer_free(&lex);
str_free(&source);
tysy_free(&tysy);
// check execution errors
if (err_dump(&err))
{
err_free(&err);
abort();
}
err_free(&err);
return 0;
}