Fixed division by zero bugs

This commit is contained in:
2022-08-12 07:26:58 +01:00
parent 42e55c1db6
commit 80b64cf21e
3 changed files with 31 additions and 7 deletions

View File

@@ -80,14 +80,14 @@ static char* readString(unsigned char* tb, int* count) {
static void consumeByte(unsigned char byte, unsigned char* tb, int* count) { static void consumeByte(unsigned char byte, unsigned char* tb, int* count) {
if (byte != tb[*count]) { if (byte != tb[*count]) {
printf("Failed to consume the correct byte\n"); printf("[internal] Failed to consume the correct byte\n");
} }
*count += 1; *count += 1;
} }
static void consumeShort(unsigned short bytes, unsigned char* tb, int* count) { static void consumeShort(unsigned short bytes, unsigned char* tb, int* count) {
if (bytes != *(unsigned short*)(tb + *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; *count += 2;
} }
@@ -190,10 +190,18 @@ static bool execArithmetic(Interpreter* interpreter, Opcode opcode) {
return true; return true;
case OP_DIVISION: 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) )); pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( AS_INTEGER(lhs) / AS_INTEGER(rhs) ));
return true; return true;
case OP_MODULO: 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) )); pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( AS_INTEGER(lhs) % AS_INTEGER(rhs) ));
return true; return true;
@@ -224,6 +232,10 @@ static bool execArithmetic(Interpreter* interpreter, Opcode opcode) {
return true; return true;
case OP_DIVISION: 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) )); pushLiteralArray(&interpreter->stack, TO_FLOAT_LITERAL( AS_FLOAT(lhs) / AS_FLOAT(rhs) ));
return true; return true;

View File

@@ -69,7 +69,7 @@ static void eatWhitespace(Lexer* lexer) {
advance(lexer); advance(lexer);
break; break;
} }
break; return;
default: default:
return; return;

View File

@@ -477,7 +477,7 @@ ParseRule* getRule(TokenType type) {
} }
//constant folding //constant folding
static bool calcStaticBinaryArithmetic(Node** nodeHandle) { static bool calcStaticBinaryArithmetic(Parser* parser, Node** nodeHandle) {
switch((*nodeHandle)->binary.opcode) { switch((*nodeHandle)->binary.opcode) {
case OP_ADDITION: case OP_ADDITION:
case OP_SUBTRACTION: case OP_SUBTRACTION:
@@ -492,11 +492,11 @@ static bool calcStaticBinaryArithmetic(Node** nodeHandle) {
//recurse to the left and right //recurse to the left and right
if ((*nodeHandle)->binary.left->type == NODE_BINARY) { if ((*nodeHandle)->binary.left->type == NODE_BINARY) {
calcStaticBinaryArithmetic(&(*nodeHandle)->binary.left); calcStaticBinaryArithmetic(parser, &(*nodeHandle)->binary.left);
} }
if ((*nodeHandle)->binary.right->type == NODE_BINARY) { if ((*nodeHandle)->binary.right->type == NODE_BINARY) {
calcStaticBinaryArithmetic(&(*nodeHandle)->binary.right); calcStaticBinaryArithmetic(parser, &(*nodeHandle)->binary.right);
} }
//make sure left and right are both literals //make sure left and right are both literals
@@ -534,10 +534,18 @@ static bool calcStaticBinaryArithmetic(Node** nodeHandle) {
break; break;
case OP_DIVISION: 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) ); result = TO_INTEGER_LITERAL( AS_INTEGER(lhs) / AS_INTEGER(rhs) );
break; break;
case OP_MODULO: 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) ); result = TO_INTEGER_LITERAL( AS_INTEGER(lhs) % AS_INTEGER(rhs) );
break; break;
@@ -568,6 +576,10 @@ static bool calcStaticBinaryArithmetic(Node** nodeHandle) {
break; break;
case OP_DIVISION: 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) ); result = TO_FLOAT_LITERAL( AS_FLOAT(lhs) / AS_FLOAT(rhs) );
break; 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 const Opcode opcode = infixRule(parser, &rhsNode, canBeAssigned); //NOTE: infix rule must advance the parser
emitNodeBinary(nodeHandle, rhsNode, opcode); emitNodeBinary(nodeHandle, rhsNode, opcode);
if (command.optimize >= 1 && !calcStaticBinaryArithmetic(nodeHandle)) { if (command.optimize >= 1 && !calcStaticBinaryArithmetic(parser, nodeHandle)) {
return; return;
} }
} }