From 80b64cf21ebee5630609618aa599463ce13adf7e Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 12 Aug 2022 07:26:58 +0100 Subject: [PATCH] Fixed division by zero bugs --- source/interpreter.c | 16 ++++++++++++++-- source/lexer.c | 2 +- source/parser.c | 20 ++++++++++++++++---- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/source/interpreter.c b/source/interpreter.c index f063285..ef47ef7 100644 --- a/source/interpreter.c +++ b/source/interpreter.c @@ -80,14 +80,14 @@ static char* readString(unsigned char* tb, int* count) { static void consumeByte(unsigned char byte, unsigned char* tb, int* count) { if (byte != tb[*count]) { - printf("Failed to consume the correct byte\n"); + printf("[internal] Failed to consume the correct byte\n"); } *count += 1; } static void consumeShort(unsigned short bytes, unsigned char* tb, int* count) { if (bytes != *(unsigned short*)(tb + *count)) { - printf("Failed to consume the correct bytes\n"); + printf("[internal] Failed to consume the correct bytes\n"); } *count += 2; } @@ -190,10 +190,18 @@ static bool execArithmetic(Interpreter* interpreter, Opcode opcode) { return true; case OP_DIVISION: + if (AS_INTEGER(rhs) == 0) { + printf("Can't divide by zero (error found in interpreter)"); + return false; + } pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( AS_INTEGER(lhs) / AS_INTEGER(rhs) )); return true; case OP_MODULO: + if (AS_INTEGER(rhs) == 0) { + printf("Can't modulo by zero (error found in interpreter)"); + return false; + } pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( AS_INTEGER(lhs) % AS_INTEGER(rhs) )); return true; @@ -224,6 +232,10 @@ static bool execArithmetic(Interpreter* interpreter, Opcode opcode) { return true; case OP_DIVISION: + if (AS_FLOAT(rhs) == 0) { + printf("Can't divide by zero (error found in interpreter)"); + return false; + } pushLiteralArray(&interpreter->stack, TO_FLOAT_LITERAL( AS_FLOAT(lhs) / AS_FLOAT(rhs) )); return true; diff --git a/source/lexer.c b/source/lexer.c index a3a5ea5..2381e16 100644 --- a/source/lexer.c +++ b/source/lexer.c @@ -69,7 +69,7 @@ static void eatWhitespace(Lexer* lexer) { advance(lexer); break; } - break; + return; default: return; diff --git a/source/parser.c b/source/parser.c index b2a705b..2a859fd 100644 --- a/source/parser.c +++ b/source/parser.c @@ -477,7 +477,7 @@ ParseRule* getRule(TokenType type) { } //constant folding -static bool calcStaticBinaryArithmetic(Node** nodeHandle) { +static bool calcStaticBinaryArithmetic(Parser* parser, Node** nodeHandle) { switch((*nodeHandle)->binary.opcode) { case OP_ADDITION: case OP_SUBTRACTION: @@ -492,11 +492,11 @@ static bool calcStaticBinaryArithmetic(Node** nodeHandle) { //recurse to the left and right if ((*nodeHandle)->binary.left->type == NODE_BINARY) { - calcStaticBinaryArithmetic(&(*nodeHandle)->binary.left); + calcStaticBinaryArithmetic(parser, &(*nodeHandle)->binary.left); } if ((*nodeHandle)->binary.right->type == NODE_BINARY) { - calcStaticBinaryArithmetic(&(*nodeHandle)->binary.right); + calcStaticBinaryArithmetic(parser, &(*nodeHandle)->binary.right); } //make sure left and right are both literals @@ -534,10 +534,18 @@ static bool calcStaticBinaryArithmetic(Node** nodeHandle) { break; case OP_DIVISION: + if (AS_INTEGER(rhs) == 0) { + error(parser, parser->previous, "Can't divide by zero (error found in constant folding)"); + return false; + } result = TO_INTEGER_LITERAL( AS_INTEGER(lhs) / AS_INTEGER(rhs) ); break; case OP_MODULO: + if (AS_INTEGER(rhs) == 0) { + error(parser, parser->previous, "Can't modulo by zero (error found in constant folding)"); + return false; + } result = TO_INTEGER_LITERAL( AS_INTEGER(lhs) % AS_INTEGER(rhs) ); break; @@ -568,6 +576,10 @@ static bool calcStaticBinaryArithmetic(Node** nodeHandle) { break; case OP_DIVISION: + if (AS_FLOAT(rhs) == 0) { + error(parser, parser->previous, "Can't divide by zero (error found in constant folding)"); + return false; + } result = TO_FLOAT_LITERAL( AS_FLOAT(lhs) / AS_FLOAT(rhs) ); break; @@ -620,7 +632,7 @@ static void parsePrecedence(Parser* parser, Node** nodeHandle, PrecedenceRule ru const Opcode opcode = infixRule(parser, &rhsNode, canBeAssigned); //NOTE: infix rule must advance the parser emitNodeBinary(nodeHandle, rhsNode, opcode); - if (command.optimize >= 1 && !calcStaticBinaryArithmetic(nodeHandle)) { + if (command.optimize >= 1 && !calcStaticBinaryArithmetic(parser, nodeHandle)) { return; } }