#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); // prepass { prepass_t prepass; prepass_init(&prepass, &sym, &tysolver, &err); prepass_run(&prepass, node); prepass_free(&prepass); } // compile { compiler_t compiler; compiler_init(&compiler, &mod, &sym, &tysy, &err); int status = compiler_run(&compiler, node); 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; }