2025-11-23 13:37:08 +11:00
|
|
|
#include "parser.h"
|
2025-11-23 18:34:30 +11:00
|
|
|
#include "interpreter.h"
|
2026-01-21 11:17:19 +11:00
|
|
|
#include "compiler.h"
|
2026-01-31 09:08:38 +11:00
|
|
|
#include "types.h"
|
2026-03-04 10:40:54 +11:00
|
|
|
#include "serialize.h"
|
2026-03-19 16:00:46 +11:00
|
|
|
#include "repl.h"
|
2025-11-23 13:37:08 +11:00
|
|
|
#include <stdio.h>
|
2026-03-04 10:40:54 +11:00
|
|
|
#include <string.h>
|
2025-11-23 13:37:08 +11:00
|
|
|
|
2026-04-17 12:57:30 +10:00
|
|
|
char* getFileContents(const char* filename);
|
2025-11-23 13:37:08 +11:00
|
|
|
|
|
|
|
|
int main(int argc, char** argv) {
|
2026-03-19 16:00:46 +11:00
|
|
|
if (argc == 1) {
|
|
|
|
|
exit(repl());
|
2026-01-21 11:17:19 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool compile = false;
|
2026-03-04 10:40:54 +11:00
|
|
|
bool writeBytecode = false;
|
|
|
|
|
bool readBytecode = false;
|
2026-01-21 11:17:19 +11:00
|
|
|
char* fileName = NULL;
|
2026-03-04 10:40:54 +11:00
|
|
|
char* outFileName = NULL;
|
2026-01-31 09:08:38 +11:00
|
|
|
List groundArgs = createList();
|
2026-01-21 11:17:19 +11:00
|
|
|
for (int i = 1; i < argc; i++) {
|
|
|
|
|
if (strcmp("--compile", argv[i]) == 0 || strcmp("-c", argv[i]) == 0) {
|
2026-03-04 10:40:54 +11:00
|
|
|
if (writeBytecode) {
|
|
|
|
|
printf("Cannot choose both bytecode and compilation");
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
2026-01-21 11:17:19 +11:00
|
|
|
compile = true;
|
|
|
|
|
}
|
|
|
|
|
else if (strcmp("--help", argv[i]) == 0 || strcmp("-h", argv[i]) == 0) {
|
|
|
|
|
printf("GroundVM help\n");
|
2026-03-04 10:40:54 +11:00
|
|
|
printf("Usage: %s <file> [-c] [--compile] [-h] [--help] [-w <output>] [--writeBytecode <output>] [-b] [--bytecode]\n", argv[0]);
|
2026-01-21 11:17:19 +11:00
|
|
|
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");
|
2026-03-04 10:40:54 +11:00
|
|
|
printf(" -w <output> or --writebytecode <output>: Outputs binary Ground bytecode");
|
|
|
|
|
printf(" -b <output> or --bytecode <output>: Inputs binary Ground bytecode");
|
2026-01-21 11:17:19 +11:00
|
|
|
exit(0);
|
2026-03-19 16:00:46 +11:00
|
|
|
} else if (strcmp("--writeBytecode", argv[i]) == 0 || strcmp("-w", argv[i]) == 0) {
|
2026-03-04 10:40:54 +11:00
|
|
|
if (compile) {
|
|
|
|
|
printf("Cannot choose both bytecode and compilation");
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
writeBytecode = true;
|
|
|
|
|
if (i + 1 >= argc) {
|
|
|
|
|
printf("Usage: %s %s <output>", argv[0], argv[i]);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
i++;
|
|
|
|
|
outFileName = argv[i];
|
|
|
|
|
} else if (strcmp("--bytecode", argv[i]) == 0 || strcmp("-b", argv[i]) == 0) {
|
|
|
|
|
readBytecode = true;
|
2026-01-21 11:17:19 +11:00
|
|
|
} else {
|
2026-01-31 09:08:38 +11:00
|
|
|
if (fileName == NULL) {
|
|
|
|
|
fileName = argv[i];
|
|
|
|
|
} else {
|
|
|
|
|
appendToList(&groundArgs, createStringGroundValue(argv[i]));
|
|
|
|
|
}
|
2026-01-21 11:17:19 +11:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fileName == NULL) {
|
2026-03-04 10:40:54 +11:00
|
|
|
printf("Usage: %s <file> [-c] [--compile] [-h] [--help] [-w <output>] [--writeBytecode <output>] [-b] [--bytecode]\n", argv[0]);
|
2026-01-21 11:17:19 +11:00
|
|
|
printf("Error: No file name provided\n");
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-04 10:40:54 +11:00
|
|
|
GroundProgram program;
|
|
|
|
|
|
|
|
|
|
if (readBytecode) {
|
|
|
|
|
deserializeProgramFromFile(fileName, &program);
|
|
|
|
|
} else {
|
|
|
|
|
char* file = getFileContents(fileName);
|
|
|
|
|
program = parseFile(file);
|
|
|
|
|
free(file);
|
|
|
|
|
}
|
2026-01-21 11:17:19 +11:00
|
|
|
|
|
|
|
|
if (compile) {
|
2026-04-11 12:31:37 +10:00
|
|
|
#ifdef GROUND_COMPILE_WITH_TRAM
|
2026-04-10 17:43:51 +10:00
|
|
|
compileGroundProgram(&program, "program.gexe");
|
2026-04-11 12:31:37 +10:00
|
|
|
#else
|
|
|
|
|
printf("This version of Ground has been compiled without Tram, so compilation is not supported.\n");
|
|
|
|
|
#endif
|
2026-03-04 10:40:54 +11:00
|
|
|
} else if (writeBytecode) {
|
|
|
|
|
serializeProgramToFile(outFileName, &program);
|
2026-01-21 11:17:19 +11:00
|
|
|
} else {
|
2026-01-31 09:08:38 +11:00
|
|
|
GroundVariable* variables = NULL;
|
|
|
|
|
GroundLabel* labels = NULL;
|
2026-04-15 10:37:14 +10:00
|
|
|
GroundCatch* catches = NULL;
|
2026-01-31 09:08:38 +11:00
|
|
|
|
|
|
|
|
GroundScope scope;
|
|
|
|
|
scope.variables = &variables;
|
|
|
|
|
scope.labels = &labels;
|
2026-04-15 10:37:14 +10:00
|
|
|
scope.catches = &catches;
|
2026-01-31 09:08:38 +11:00
|
|
|
scope.isMainScope = true;
|
|
|
|
|
addVariable(scope.variables, "CMDLINE_ARGS", createListGroundValue(groundArgs));
|
|
|
|
|
interpretGroundProgram(&program, &scope);
|
2026-01-21 11:17:19 +11:00
|
|
|
}
|
2025-11-23 13:37:08 +11:00
|
|
|
}
|