#include "parser.h" #include "interpreter.h" #include "compiler.h" #include "types.h" #include "serialize.h" #include #include char* getFileContents(const char* filename) { // https://stackoverflow.com/questions/3747086/reading-the-whole-text-file-into-a-char-array-in-c FILE* fp; long lSize; char* file; fp = fopen(filename, "rb"); if (!fp) { perror(filename); exit(1); } fseek(fp, 0L, SEEK_END); lSize = ftell(fp); rewind(fp); file = calloc(1, lSize + 1); if (!file) { fclose(fp); fputs("memory allocation fail when reading file", stderr); exit(1); } if (1!=fread(file, lSize, 1, fp)) { fclose(fp); free(file); fputs("couldn't read entire file", stderr); exit(1); } // we done fclose(fp); return file; } int main(int argc, char** argv) { if (argc < 2) { printf("Usage: %s [-c] [--compile] [-h] [--help]\n", argv[0]); exit(1); } bool compile = false; bool writeBytecode = false; bool readBytecode = false; char* fileName = NULL; char* outFileName = NULL; List groundArgs = createList(); for (int i = 1; i < argc; i++) { if (strcmp("--compile", argv[i]) == 0 || strcmp("-c", argv[i]) == 0) { if (writeBytecode) { printf("Cannot choose both bytecode and compilation"); exit(1); } compile = true; } else if (strcmp("--help", argv[i]) == 0 || strcmp("-h", argv[i]) == 0) { printf("GroundVM help\n"); printf("Usage: %s [-c] [--compile] [-h] [--help] [-w ] [--writeBytecode ] [-b] [--bytecode]\n", argv[0]); printf("Options:\n"); printf(" -c or --compile: Outputs Linux x86_64 assembly instead of interpreting (WIP)\n"); printf(" -h or --help: Shows this help message\n"); printf(" -w or --writebytecode : Outputs binary Ground bytecode"); printf(" -b or --bytecode : Inputs binary Ground bytecode"); exit(0); } else if (strcmp("--writebytecode", argv[i]) == 0 || strcmp("-w", argv[i]) == 0) { if (compile) { printf("Cannot choose both bytecode and compilation"); exit(1); } writeBytecode = true; if (i + 1 >= argc) { printf("Usage: %s %s ", argv[0], argv[i]); exit(1); } i++; outFileName = argv[i]; } else if (strcmp("--bytecode", argv[i]) == 0 || strcmp("-b", argv[i]) == 0) { readBytecode = true; } else { if (fileName == NULL) { fileName = argv[i]; } else { appendToList(&groundArgs, createStringGroundValue(argv[i])); } } } if (fileName == NULL) { printf("Usage: %s [-c] [--compile] [-h] [--help] [-w ] [--writeBytecode ] [-b] [--bytecode]\n", argv[0]); printf("Error: No file name provided\n"); exit(1); } GroundProgram program; if (readBytecode) { deserializeProgramFromFile(fileName, &program); } else { char* file = getFileContents(fileName); program = parseFile(file); free(file); } if (compile) { char* compiled = compileGroundProgram(&program); printf("%s\n", compiled); } else if (writeBytecode) { serializeProgramToFile(outFileName, &program); } else { GroundVariable* variables = NULL; GroundLabel* labels = NULL; GroundScope scope; scope.variables = &variables; scope.labels = &labels; scope.isMainScope = true; addVariable(scope.variables, "CMDLINE_ARGS", createListGroundValue(groundArgs)); interpretGroundProgram(&program, &scope); } }