213 lines
3.5 KiB
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;
|
|
}
|