#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); assert(node); 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(); } if (debug) { char msg[RZ_STR_LIMIT]; mod_str(&mod, msg, RZ_STR_LIMIT); printf("%s", msg); } // 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]; 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; }