From 78320e53bb6e5141ac0938b435a44a7913e8e5e5 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 20 Sep 2024 21:39:02 +1000 Subject: [PATCH] Multiple bugfixes, read more * expand() will only touch the memory once * fixed missing if-else cascade at toy_routine.c:90 * unary negate will not optimise numbers unless the '-' character is immediately prior * fixed broken test for unary negation of groups --- source/toy_bytecode.c | 6 ++++-- source/toy_parser.c | 6 ++++-- source/toy_routine.c | 44 ++++++++++++++++++++------------------- tests/cases/test_parser.c | 24 ++++++++++++++++----- 4 files changed, 50 insertions(+), 30 deletions(-) diff --git a/source/toy_bytecode.c b/source/toy_bytecode.c index c971fc0..7d8b54c 100644 --- a/source/toy_bytecode.c +++ b/source/toy_bytecode.c @@ -9,10 +9,12 @@ //utils static void expand(Toy_Bytecode* bc, int amount) { - while (bc->count + amount > bc->capacity) { + if (bc->count + amount > bc->capacity) { int oldCapacity = bc->capacity; - bc->capacity = TOY_GROW_CAPACITY(oldCapacity); + while (bc->count + amount > bc->capacity) { + bc->capacity = TOY_GROW_CAPACITY(bc->capacity); + } bc->ptr = TOY_GROW_ARRAY(unsigned char, bc->ptr, oldCapacity, bc->capacity); } } diff --git a/source/toy_parser.c b/source/toy_parser.c index 92510a4..070f069 100644 --- a/source/toy_parser.c +++ b/source/toy_parser.c @@ -273,13 +273,15 @@ static Toy_AstFlag unary(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** root //this function takes the libery of peeking into the uppermost node, to see if it can apply this to it if (parser->previous.type == TOY_TOKEN_OPERATOR_SUBTRACT) { + + bool connectedDigit = parser->previous.lexeme[1] >= '0' && parser->previous.lexeme[1] <= '9'; //BUGFIX: '- 1' should not be optimised into a negative parsePrecedence(bucket, parser, root, PREC_UNARY); //negative numbers - if ((*root)->type == TOY_AST_VALUE && TOY_VALUE_IS_INTEGER((*root)->value.value)) { + if ((*root)->type == TOY_AST_VALUE && TOY_VALUE_IS_INTEGER((*root)->value.value) && connectedDigit) { (*root)->value.value = TOY_VALUE_TO_INTEGER( -TOY_VALUE_AS_INTEGER((*root)->value.value) ); } - else if ((*root)->type == TOY_AST_VALUE && TOY_VALUE_IS_FLOAT((*root)->value.value)) { + else if ((*root)->type == TOY_AST_VALUE && TOY_VALUE_IS_FLOAT((*root)->value.value) && connectedDigit) { (*root)->value.value = TOY_VALUE_TO_FLOAT( -TOY_VALUE_AS_FLOAT((*root)->value.value) ); } else { diff --git a/source/toy_routine.c b/source/toy_routine.c index aedb272..ce5d9de 100644 --- a/source/toy_routine.c +++ b/source/toy_routine.c @@ -11,10 +11,12 @@ //utils static void expand(void** handle, int* capacity, int* count, int amount) { - while ((*count) + amount > (*capacity)) { + if ((*count) + amount > (*capacity)) { int oldCapacity = (*capacity); - (*capacity) = TOY_GROW_CAPACITY(oldCapacity); //TODO: don't need GROW + while ((*count) + amount > (*capacity)) { + (*capacity) = TOY_GROW_CAPACITY(*capacity); + } (*handle) = TOY_GROW_ARRAY(unsigned char, (*handle), oldCapacity, (*capacity)); } } @@ -95,73 +97,73 @@ static void writeInstructionBinary(Toy_Routine** rt, Toy_AstBinary ast) { if (ast.flag == TOY_AST_FLAG_ADD) { EMIT_BYTE(rt, TOY_OPCODE_ADD); } - if (ast.flag == TOY_AST_FLAG_SUBTRACT) { + else if (ast.flag == TOY_AST_FLAG_SUBTRACT) { EMIT_BYTE(rt, TOY_OPCODE_SUBTRACT); } - if (ast.flag == TOY_AST_FLAG_MULTIPLY) { + else if (ast.flag == TOY_AST_FLAG_MULTIPLY) { EMIT_BYTE(rt, TOY_OPCODE_MULTIPLY); } - if (ast.flag == TOY_AST_FLAG_DIVIDE) { + else if (ast.flag == TOY_AST_FLAG_DIVIDE) { EMIT_BYTE(rt, TOY_OPCODE_DIVIDE); } - if (ast.flag == TOY_AST_FLAG_MODULO) { + else if (ast.flag == TOY_AST_FLAG_MODULO) { EMIT_BYTE(rt, TOY_OPCODE_MODULO); } - // if (ast.flag == TOY_AST_FLAG_ASSIGN) { + // else if (ast.flag == TOY_AST_FLAG_ASSIGN) { // EMIT_BYTE(rt, TOY_OPCODE_ASSIGN); // //TODO: emit the env symbol to store TOP(S) within // } - // if (ast.flag == TOY_AST_FLAG_ADD_ASSIGN) { + // else if (ast.flag == TOY_AST_FLAG_ADD_ASSIGN) { // EMIT_BYTE(rt, TOY_OPCODE_ADD); // EMIT_BYTE(rt, TOY_OPCODE_ASSIGN); // //TODO: emit the env symbol to store TOP(S) within // } - // if (ast.flag == TOY_AST_FLAG_SUBTRACT_ASSIGN) { + // else if (ast.flag == TOY_AST_FLAG_SUBTRACT_ASSIGN) { // EMIT_BYTE(rt, TOY_OPCODE_SUBTRACT); // EMIT_BYTE(rt, TOY_OPCODE_ASSIGN); // //TODO: emit the env symbol to store TOP(S) within // } - // if (ast.flag == TOY_AST_FLAG_MULTIPLY_ASSIGN) { + // else if (ast.flag == TOY_AST_FLAG_MULTIPLY_ASSIGN) { // EMIT_BYTE(rt, TOY_OPCODE_MULTIPLY); // EMIT_BYTE(rt, TOY_OPCODE_ASSIGN); // //TODO: emit the env symbol to store TOP(S) within // } - // if (ast.flag == TOY_AST_FLAG_DIVIDE_ASSIGN) { + // else if (ast.flag == TOY_AST_FLAG_DIVIDE_ASSIGN) { // EMIT_BYTE(rt, TOY_OPCODE_DIVIDE); // EMIT_BYTE(rt, TOY_OPCODE_ASSIGN); // //TODO: emit the env symbol to store TOP(S) within // } - // if (ast.flag == TOY_AST_FLAG_MODULO_ASSIGN) { + // else if (ast.flag == TOY_AST_FLAG_MODULO_ASSIGN) { // EMIT_BYTE(rt, TOY_OPCODE_MODULO); // EMIT_BYTE(rt, TOY_OPCODE_ASSIGN); // //TODO: emit the env symbol to store TOP(S) within // } - if (ast.flag == TOY_AST_FLAG_COMPARE_EQUAL) { + else if (ast.flag == TOY_AST_FLAG_COMPARE_EQUAL) { EMIT_BYTE(rt, TOY_OPCODE_COMPARE_EQUAL); } - if (ast.flag == TOY_AST_FLAG_COMPARE_NOT) { + else if (ast.flag == TOY_AST_FLAG_COMPARE_NOT) { EMIT_BYTE(rt, TOY_OPCODE_COMPARE_EQUAL); EMIT_BYTE(rt, TOY_OPCODE_NEGATE); } - if (ast.flag == TOY_AST_FLAG_COMPARE_LESS) { + else if (ast.flag == TOY_AST_FLAG_COMPARE_LESS) { EMIT_BYTE(rt, TOY_OPCODE_COMPARE_LESS); } - if (ast.flag == TOY_AST_FLAG_COMPARE_LESS_EQUAL) { + else if (ast.flag == TOY_AST_FLAG_COMPARE_LESS_EQUAL) { EMIT_BYTE(rt, TOY_OPCODE_COMPARE_LESS_EQUAL); } - if (ast.flag == TOY_AST_FLAG_COMPARE_GREATER) { + else if (ast.flag == TOY_AST_FLAG_COMPARE_GREATER) { EMIT_BYTE(rt, TOY_OPCODE_COMPARE_GREATER); } - if (ast.flag == TOY_AST_FLAG_COMPARE_GREATER_EQUAL) { + else if (ast.flag == TOY_AST_FLAG_COMPARE_GREATER_EQUAL) { EMIT_BYTE(rt, TOY_OPCODE_COMPARE_GREATER_EQUAL); } - if (ast.flag == TOY_AST_FLAG_AND) { + else if (ast.flag == TOY_AST_FLAG_AND) { EMIT_BYTE(rt, TOY_OPCODE_AND); } - if (ast.flag == TOY_AST_FLAG_OR) { + else if (ast.flag == TOY_AST_FLAG_OR) { EMIT_BYTE(rt, TOY_OPCODE_OR); } else { @@ -325,4 +327,4 @@ void* Toy_compileRoutine(Toy_Ast* ast) { TOY_FREE_ARRAY(unsigned char, rt.subs, rt.subsCapacity); return buffer; -} \ No newline at end of file +} diff --git a/tests/cases/test_parser.c b/tests/cases/test_parser.c index 409fbbc..61578d2 100644 --- a/tests/cases/test_parser.c +++ b/tests/cases/test_parser.c @@ -283,7 +283,7 @@ int test_unary(Toy_Bucket* bucket) { } } - //ensure unary negation doesn't affect other things (such as group) + //ensure unary negation doesn't occur with a group { Toy_Ast* ast = makeAstFromSource(&bucket, "-(42);"); @@ -292,15 +292,29 @@ int test_unary(Toy_Bucket* bucket) { ast == NULL || ast->type != TOY_AST_BLOCK || ast->block.child == NULL || - ast->block.child->type != TOY_AST_VALUE || - TOY_VALUE_IS_INTEGER(ast->block.child->value.value) == false || - TOY_VALUE_AS_INTEGER(ast->block.child->value.value) != -42) + ast->block.child->type == TOY_AST_VALUE) { fprintf(stderr, TOY_CC_ERROR "ERROR: unexpected successful unary negation in parser with grouped value -(42)\n" TOY_CC_RESET); return -1; } } + //ensure unary negation doesn't occur with a space + { + Toy_Ast* ast = makeAstFromSource(&bucket, "- 42;"); + + //check if it worked + if ( + ast == NULL || + ast->type != TOY_AST_BLOCK || + ast->block.child == NULL || + ast->block.child->type == TOY_AST_VALUE) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: unexpected successful unary negation in parser with space character '- 42'\n" TOY_CC_RESET); + return -1; + } + } + return 0; } @@ -619,4 +633,4 @@ int main() { } return total; -} \ No newline at end of file +}