Added silent cmd args

Fixed #145
This commit is contained in:
2024-11-10 10:27:50 +11:00
parent 1608a13b43
commit 436bd3ffca
4 changed files with 102 additions and 29 deletions

View File

@@ -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);
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;

View File

@@ -659,6 +659,11 @@ static void makeAssertStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_As
Toy_Ast* ast = NULL; //assert's emit function is a bit different
makeExpr(bucketHandle, parser, &ast);
//if assert is disabled, don't emit the assert
if (parser->removeAssert) {
Toy_private_emitAstPass(bucketHandle, rootHandle);
}
else {
//NOTE: if it's a compound, then it's got a second arg
if (ast->type == TOY_AST_COMPOUND) {
Toy_private_emitAstAssert(bucketHandle, rootHandle, ast->compound.left, ast->compound.right);
@@ -666,6 +671,7 @@ static void makeAssertStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_As
else {
Toy_private_emitAstAssert(bucketHandle, rootHandle, ast, NULL);
}
}
consume(parser, TOY_TOKEN_OPERATOR_SEMICOLON, "Expected ';' at the end of assert statement");
}
@@ -836,4 +842,10 @@ void Toy_resetParser(Toy_Parser* parser) {
parser->error = false;
parser->panic = false;
parser->removeAssert = false;
}
void Toy_configureParser(Toy_Parser* parser, bool removeAssert) {
parser->removeAssert = removeAssert;
}

View File

@@ -14,9 +14,14 @@ typedef struct Toy_Parser {
bool error;
bool panic; //currently processing an error
//configs
bool removeAssert;
} Toy_Parser;
TOY_API void Toy_bindParser(Toy_Parser* parser, Toy_Lexer* lexer);
TOY_API Toy_Ast* Toy_scanParser(Toy_Bucket** bucketHandle, Toy_Parser* parser);
TOY_API void Toy_resetParser(Toy_Parser* parser);
//configure certain options
TOY_API void Toy_configureParser(Toy_Parser* parser, bool removeAssert);

View File

@@ -372,7 +372,7 @@ static void processAssert(Toy_VM* vm) {
//do the check
if (TOY_VALUE_IS_NULL(value) || Toy_checkValueIsTruthy(value) == false) {
//on a failure, print the message
Toy_stringifyValue(message, Toy_error);
Toy_stringifyValue(message, Toy_assertFailure);
}
//cleanup