122 lines
3.8 KiB
C
122 lines
3.8 KiB
C
#include "../../include/ground.h"
|
|
#include <stdio.h>
|
|
|
|
enum ArgsAction {
|
|
ARGS_HELP, ARGS_EXECUTE, ARGS_DEBUG, ARGS_ASSEMBLE, ARGS_DISASSEMBLE
|
|
};
|
|
|
|
typedef struct Args {
|
|
enum ArgsAction action;
|
|
char* inputFile;
|
|
char* outputFile;
|
|
} Args;
|
|
|
|
Args parseArgs(int argc, char** argv) {
|
|
Args args = {
|
|
.action = ARGS_EXECUTE,
|
|
.inputFile = NULL,
|
|
.outputFile = NULL
|
|
};
|
|
|
|
if (argc == 1) {
|
|
args.action = ARGS_HELP;
|
|
return args;
|
|
}
|
|
|
|
for (int i = 1; i < argc; i++) {
|
|
char* arg = argv[i];
|
|
|
|
if (strcmp(arg, "-d") == 0 || strcmp(arg, "--debug") == 0) {
|
|
args.action = ARGS_DEBUG;
|
|
} else if (strcmp(arg, "-a") == 0 || strcmp(arg, "--assemble") == 0) {
|
|
args.action = ARGS_ASSEMBLE;
|
|
if (i + 1 < argc) {
|
|
i++;
|
|
args.outputFile = argv[i];
|
|
}
|
|
} else if (strcmp(arg, "-D") == 0 || strcmp(arg, "--disassemble") == 0) {
|
|
args.action = ARGS_DISASSEMBLE;
|
|
} else if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
|
|
args.action = ARGS_HELP;
|
|
} else {
|
|
args.inputFile = arg;
|
|
}
|
|
|
|
}
|
|
|
|
return args;
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
Args args = parseArgs(argc, argv);
|
|
|
|
switch (args.action) {
|
|
case ARGS_EXECUTE: {
|
|
if (args.inputFile == NULL) {
|
|
fprintf(stderr, "Please specify a bytecode file\n");
|
|
return 1;
|
|
}
|
|
|
|
GroundBytecode bc = Ground.Bytecode.load(args.inputFile);
|
|
if (Ground.Flags.error) {
|
|
fprintf(stderr, "Failed to load bytecode, printing errors...\n");
|
|
Ground.Log.printErrors();
|
|
return 1;
|
|
}
|
|
|
|
Ground.Bytecode.Program.execute(&bc.program, &bc.heap);
|
|
if (Ground.Flags.error) {
|
|
fprintf(stderr, "Failed to run program, printing errors...\n");
|
|
Ground.Log.printErrors();
|
|
return 1;
|
|
}
|
|
break;
|
|
}
|
|
case ARGS_DEBUG: {
|
|
fprintf(stderr, "Not yet implemented");
|
|
break;
|
|
}
|
|
case ARGS_ASSEMBLE: {
|
|
fprintf(stderr, "Not yet implemented");
|
|
break;
|
|
}
|
|
case ARGS_DISASSEMBLE: {
|
|
if (args.inputFile == NULL) {
|
|
fprintf(stderr, "Please specify a bytecode file\n");
|
|
return 1;
|
|
}
|
|
|
|
GroundBytecode bc = Ground.Bytecode.load(args.inputFile);
|
|
if (Ground.Flags.error) {
|
|
fprintf(stderr, "Failed to load bytecode, printing errors...\n");
|
|
Ground.Log.printErrors();
|
|
return 1;
|
|
}
|
|
|
|
char* str = Ground.Stringify.Bytecode(&bc);
|
|
printf("%s", str);
|
|
free(str);
|
|
break;
|
|
}
|
|
case ARGS_HELP: {
|
|
printf("GroundVM cli help\n");
|
|
printf("Usage: %s <file.gb> [-h] [--help] [-d] [--debug] [-a <file.grnd>] [--assemble <file.grnd>] [-D] [--disassemble]\n", argv[0]);
|
|
printf("Options:\n");
|
|
printf(" -h or --help\n");
|
|
printf(" Shows this help message\n");
|
|
printf(" -d or --debug\n");
|
|
printf(" Interactive debugger for a Ground program\n");
|
|
printf(" -a <file.grnd> or --assemble <file.grnd>\n");
|
|
printf(" Assembles a .grnd textual representation into a .gb bytecode file\n");
|
|
printf(" Inputs from <file.grnd>, outputs to <file.gb>\n");
|
|
printf(" -D or --disassemble\n");
|
|
printf(" Disassembles a .gb program, showing the heap, instructions, and offsets\n");
|
|
printf("If no options are specified, the provided <file.gb> will be executed.\n");
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|