#include #include #include #include #include #include #include "compiler/source_code/source_code.h" #include "fasm/code_generator/code_generator.h" #include "fasm/lexer/lexer.h" #include "fasm/linker/linker.h" #include "fasm/runner/runner.h" #include "utils/types.h" typedef enum FelanMode { FELAN_MODE_NONE, FELAN_MODE_COMPILE_FASM, FELAN_MODE_COMPILE_FELAN, FELAN_MODE_RUN_FASM, FELAN_MODE_RUN_FELAN, } FelanMode; int runFelan(const char *const filePath) { SourceCode sourceCode = makeSourceCode(); Code *code; code = read_whole_file("std/builtins.felan"); if (code == NULL) { goto RETURN_ERROR; } pushToSourceCode(&sourceCode, code); code = read_whole_file(filePath); if (code == NULL) { goto RETURN_ERROR; } pushToSourceCode(&sourceCode, code); if (!runner(&sourceCode)) { goto RETURN_ERROR; } deleteSourceCodeInners(sourceCode); return 0; RETURN_ERROR: deleteSourceCodeInners(sourceCode); return 1; } int compileFasm(const char *const filePath) { SourceCode sourceCode = makeSourceCode(); Code *code = read_whole_file(filePath); if (code == NULL) { goto RETURN_ERROR; } pushToSourceCode(&sourceCode, code); // printf("----lexing:\n"); FasmLines *lines; if ((lines = fasmLexer(&sourceCode)) == NULL) { goto RETURN_ERROR; } // for (size_t i = 0; i < sourceCode.size; ++i) { // fasmLinesPrint(lines[i]); // } // printf("----linking:\n"); FasmLinkedLines linkedLines = fasmLinker(lines, &sourceCode); if (linkedLines.lines_size == ERROR_SIZE) { goto RETURN_LINKED_ERROR; } // fasmLinkedLinesPrint(linkedLines); // printf("----bytecode:\n"); ByteCode bytecode = fasmCodeGenerator(&linkedLines); // for (size_t i = 0; i < bytecode.code_size; ++i) { // printf("0x%.2x ", bytecode.code[i]); //} // printf("\n"); deleteByteCodeInners(bytecode); fasmLinkedLinesDeleteInner(linkedLines); for (size_t i = 0; i < sourceCode.size; ++i) { fasmLinesDeleteInner(lines[i]); } free(lines); deleteSourceCodeInners(sourceCode); return 0; RETURN_LINKED_ERROR: for (size_t i = 0; i < sourceCode.size; ++i) { fasmLinesDeleteInner(lines[i]); } RETURN_ERROR: deleteSourceCodeInners(sourceCode); return 1; } int runFasm(const char *const filePath) { SourceCode sourceCode = makeSourceCode(); Code *code = read_whole_file(filePath); if (code == NULL) { goto RETURN_ERROR; } pushToSourceCode(&sourceCode, code); FasmLines *lines; if ((lines = fasmLexer(&sourceCode)) == NULL) { goto RETURN_ERROR; } FasmLinkedLines linkedLines = fasmLinker(lines, &sourceCode); if (linkedLines.lines_size == ERROR_SIZE) { goto RETURN_LINKED_ERROR; } ByteCode bytecode = fasmCodeGenerator(&linkedLines); uint32_t result = fasmRunner(bytecode); deleteByteCodeInners(bytecode); fasmLinkedLinesDeleteInner(linkedLines); for (size_t i = 0; i < sourceCode.size; ++i) { fasmLinesDeleteInner(lines[i]); } free(lines); deleteSourceCodeInners(sourceCode); return result; RETURN_LINKED_ERROR: for (size_t i = 0; i < sourceCode.size; ++i) { fasmLinesDeleteInner(lines[i]); } RETURN_ERROR: deleteSourceCodeInners(sourceCode); return 1; } int main(int argc, char *argv[]) { FelanMode compileMode = FELAN_MODE_NONE; char const *filePath = NULL; for (int i = 1; i < argc; ++i) { const char *const arg = argv[i]; if (strcmp(arg, "compile-fasm") == 0) { if (compileMode == FELAN_MODE_NONE) { compileMode = FELAN_MODE_COMPILE_FASM; } else { fprintf(stderr, "'%s' is not expected\n", arg); return 1; } } else if (strcmp(arg, "compile-felan") == 0) { if (compileMode == FELAN_MODE_NONE) { compileMode = FELAN_MODE_COMPILE_FELAN; } else { fprintf(stderr, "'%s' is not expected\n", arg); return 1; } fprintf(stderr, "'%s' is not yet supported\n", arg); return 1; } else if (strcmp(arg, "run-fasm") == 0) { if (compileMode == FELAN_MODE_NONE) { compileMode = FELAN_MODE_RUN_FASM; } else { fprintf(stderr, "'%s' is not expected\n", arg); return 1; } } else if (strcmp(arg, "run-felan") == 0) { if (compileMode == FELAN_MODE_NONE) { compileMode = FELAN_MODE_RUN_FELAN; } else { fprintf(stderr, "'%s' is not expected\n", arg); return 1; } } else if (filePath == NULL) { filePath = arg; } else { fprintf(stderr, "'%s' is not expected\n", arg); return 1; } } if (filePath == NULL) { fprintf(stderr, "Need a file path to operate\n"); } switch (compileMode) { case FELAN_MODE_COMPILE_FASM: return compileFasm(filePath); case FELAN_MODE_COMPILE_FELAN: return 1; case FELAN_MODE_RUN_FASM: return runFasm(filePath); case FELAN_MODE_NONE: case FELAN_MODE_RUN_FELAN: return runFelan(filePath); } }