mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
104
repl/main.c
104
repl/main.c
@@ -105,6 +105,29 @@ int getFileName(char* dest, const char* src) {
|
||||
return len;
|
||||
}
|
||||
|
||||
//callbacks
|
||||
static void printCallback(const char* msg) {
|
||||
fprintf(stdout, "%s\n", msg);
|
||||
}
|
||||
|
||||
static void errorAndExitCallback(const char* msg) {
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
static void errorAndContinueCallback(const char* msg) {
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
}
|
||||
|
||||
static void noOpCallback(const char* msg) {
|
||||
//NO-OP
|
||||
}
|
||||
|
||||
static void silentExitCallback(const char* msg) {
|
||||
//NO-OP
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
//handle command line arguments
|
||||
typedef struct CmdLine {
|
||||
bool error;
|
||||
@@ -112,6 +135,9 @@ typedef struct CmdLine {
|
||||
bool version;
|
||||
char* infile;
|
||||
int infileLength;
|
||||
bool silentPrint;
|
||||
bool silentAssert;
|
||||
bool removeAssert;
|
||||
} CmdLine;
|
||||
|
||||
void usageCmdLine(int argc, const char* argv[]) {
|
||||
@@ -126,6 +152,9 @@ void helpCmdLine(int argc, const char* argv[]) {
|
||||
printf(" -h, --help\t\t\tShow this help then exit.\n");
|
||||
printf(" -v, --version\t\t\tShow version and copyright information then exit.\n");
|
||||
printf(" -f, --file infile\t\tParse, compile and execute the source file then exit.\n");
|
||||
printf(" --silent-print\t\tSuppress output from the print keyword.\n");
|
||||
printf(" --silent-assert\t\tSuppress output from the assert keyword.\n");
|
||||
printf(" --remove-assert\t\tDo not include the assert statement in the bytecode.\n");
|
||||
}
|
||||
|
||||
void versionCmdLine(int argc, const char* argv[]) {
|
||||
@@ -155,7 +184,16 @@ freely, subject to the following restrictions:\n\
|
||||
}
|
||||
|
||||
CmdLine parseCmdLine(int argc, const char* argv[]) {
|
||||
CmdLine cmd = { .error = false, .help = false, .version = false, .infile = NULL, .infileLength = 0 };
|
||||
CmdLine cmd = {
|
||||
.error = false,
|
||||
.help = false,
|
||||
.version = false,
|
||||
.infile = NULL,
|
||||
.infileLength = 0,
|
||||
.silentPrint = false,
|
||||
.silentAssert = false,
|
||||
.removeAssert = false
|
||||
};
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
|
||||
@@ -192,6 +230,18 @@ CmdLine parseCmdLine(int argc, const char* argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
else if (!strcmp(argv[i], "--silent-print")) {
|
||||
cmd.silentPrint = true;
|
||||
}
|
||||
|
||||
else if (!strcmp(argv[i], "--silent-assert")) {
|
||||
cmd.silentAssert = true;
|
||||
}
|
||||
|
||||
else if (!strcmp(argv[i], "--remove-assert")) {
|
||||
cmd.removeAssert = true;
|
||||
}
|
||||
|
||||
else {
|
||||
cmd.error = true;
|
||||
}
|
||||
@@ -201,13 +251,21 @@ CmdLine parseCmdLine(int argc, const char* argv[]) {
|
||||
}
|
||||
|
||||
//repl function
|
||||
static void errorAndContinueCallback(const char* msg) {
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
}
|
||||
int repl(const char* filepath, CmdLine cmd) {
|
||||
//output options
|
||||
if (cmd.silentPrint) {
|
||||
Toy_setPrintCallback(noOpCallback);
|
||||
}
|
||||
else {
|
||||
Toy_setPrintCallback(printCallback);
|
||||
}
|
||||
|
||||
int repl(const char* filepath) {
|
||||
Toy_setErrorCallback(errorAndContinueCallback);
|
||||
Toy_setAssertFailureCallback(errorAndContinueCallback);
|
||||
if (cmd.silentAssert) {
|
||||
Toy_setAssertFailureCallback(silentExitCallback);
|
||||
}
|
||||
else {
|
||||
Toy_setAssertFailureCallback(errorAndContinueCallback);
|
||||
}
|
||||
|
||||
//vars to use
|
||||
char prompt[256];
|
||||
@@ -246,6 +304,7 @@ int repl(const char* filepath) {
|
||||
Toy_bindLexer(&lexer, inputBuffer);
|
||||
Toy_Parser parser;
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
Toy_configureParser(&parser, cmd.removeAssert);
|
||||
Toy_Ast* ast = Toy_scanParser(&bucket, &parser); //Ast is in the bucket, so it doesn't need to be freed
|
||||
|
||||
//parsing error, retry
|
||||
@@ -403,30 +462,25 @@ static void debugScopePrint(Toy_Scope* scope, int depth) {
|
||||
}
|
||||
}
|
||||
|
||||
//callbacks
|
||||
static void printCallback(const char* msg) {
|
||||
fprintf(stdout, "%s\n", msg);
|
||||
}
|
||||
|
||||
static void errorAndExitCallback(const char* msg) {
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
//main file
|
||||
int main(int argc, const char* argv[]) {
|
||||
Toy_setPrintCallback(printCallback);
|
||||
Toy_setPrintCallback(noOpCallback);
|
||||
Toy_setErrorCallback(errorAndExitCallback);
|
||||
Toy_setAssertFailureCallback(errorAndExitCallback);
|
||||
|
||||
//repl
|
||||
if (argc == 1) {
|
||||
return repl(argv[0]);
|
||||
}
|
||||
|
||||
//if there's args, process them
|
||||
CmdLine cmd = parseCmdLine(argc, argv);
|
||||
|
||||
//output options
|
||||
if (cmd.silentPrint) {
|
||||
Toy_setPrintCallback(noOpCallback);
|
||||
}
|
||||
|
||||
if (cmd.silentAssert) {
|
||||
Toy_setAssertFailureCallback(silentExitCallback);
|
||||
}
|
||||
|
||||
//process
|
||||
if (cmd.error) {
|
||||
usageCmdLine(argc, argv);
|
||||
}
|
||||
@@ -470,6 +524,8 @@ int main(int argc, const char* argv[]) {
|
||||
Toy_Parser parser;
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
|
||||
Toy_configureParser(&parser, cmd.removeAssert);
|
||||
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
Toy_Ast* ast = Toy_scanParser(&bucket, &parser);
|
||||
|
||||
@@ -493,7 +549,7 @@ int main(int argc, const char* argv[]) {
|
||||
free(source);
|
||||
}
|
||||
else {
|
||||
usageCmdLine(argc, argv);
|
||||
repl(argv[0], cmd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user