From ca4073a5ae84437215142d25b4b0ee1cf51a937d Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Thu, 10 Oct 2024 08:18:27 +1100 Subject: [PATCH] Removed a couple of small optimisations form the parser --- source/toy_parser.c | 16 ++------ source/toy_routine.c | 16 ++++---- tests/cases/test_parser.c | 78 +++++++++++---------------------------- 3 files changed, 34 insertions(+), 76 deletions(-) diff --git a/source/toy_parser.c b/source/toy_parser.c index 7fa9c4e..5ef5d52 100644 --- a/source/toy_parser.c +++ b/source/toy_parser.c @@ -310,10 +310,8 @@ static Toy_AstFlag literal(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_As static Toy_AstFlag unary(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) { //'subtract' can only be applied to numbers and groups, while 'negate' can only be applied to booleans and groups - //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(bucketHandle, parser, rootHandle, PREC_UNARY); @@ -332,15 +330,7 @@ static Toy_AstFlag unary(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast* else if (parser->previous.type == TOY_TOKEN_OPERATOR_NEGATE) { parsePrecedence(bucketHandle, parser, rootHandle, PREC_UNARY); - - //inverted booleans - if ((*rootHandle)->type == TOY_AST_VALUE && TOY_VALUE_IS_BOOLEAN((*rootHandle)->value.value)) { - (*rootHandle)->value.value = TOY_VALUE_FROM_BOOLEAN( !TOY_VALUE_AS_BOOLEAN((*rootHandle)->value.value) ); - } - else { - //actually emit the negation node - Toy_private_emitAstUnary(bucketHandle, rootHandle, TOY_AST_FLAG_NEGATE); - } + Toy_private_emitAstUnary(bucketHandle, rootHandle, TOY_AST_FLAG_NEGATE); } else { @@ -462,8 +452,8 @@ static Toy_AstFlag group(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast* parsePrecedence(bucketHandle, parser, rootHandle, PREC_GROUP); consume(parser, TOY_TOKEN_OPERATOR_PAREN_RIGHT, "Expected ')' at end of group"); - //Toy_AstGroup is omitted from generation, as an optimisation - // Toy_private_emitAstGroup(bucketHandle, rootHandle); + //Toy_AstGroup could be omitted, but is kept for now + Toy_private_emitAstGroup(bucketHandle, rootHandle); } else { diff --git a/source/toy_routine.c b/source/toy_routine.c index 55ea754..da6e3e1 100644 --- a/source/toy_routine.c +++ b/source/toy_routine.c @@ -250,6 +250,10 @@ static void writeInstructionBinary(Toy_Routine** rt, Toy_AstBinary ast) { EMIT_BYTE(rt, code,0); } +static void writeInstructionGroup(Toy_Routine** rt, Toy_AstGroup ast) { + writeRoutineCode(rt, ast.child); +} + static void writeInstructionPrint(Toy_Routine** rt, Toy_AstPrint ast) { //the thing to print writeRoutineCode(rt, ast.child); @@ -292,23 +296,21 @@ static void writeRoutineCode(Toy_Routine** rt, Toy_Ast* ast) { writeInstructionBinary(rt, ast->binary); break; - case TOY_AST_PRINT: - writeInstructionPrint(rt, ast->print); + case TOY_AST_GROUP: + writeInstructionGroup(rt, ast->group); break; - //other disallowed instructions - case TOY_AST_GROUP: - fprintf(stderr, TOY_CC_ERROR "ERROR: Invalid AST type found: Group shouldn't be used\n" TOY_CC_RESET); - exit(-1); + case TOY_AST_PRINT: + writeInstructionPrint(rt, ast->print); break; + //meta instructions are disallowed case TOY_AST_PASS: //NOTE: this should be disallowed, but for now it's required for testing // fprintf(stderr, TOY_CC_ERROR "ERROR: Invalid AST type found: Unknown pass\n" TOY_CC_RESET); // exit(-1); break; - //meta instructions are disallowed case TOY_AST_ERROR: fprintf(stderr, TOY_CC_ERROR "ERROR: Invalid AST type found: Unknown error\n" TOY_CC_RESET); exit(-1); diff --git a/tests/cases/test_parser.c b/tests/cases/test_parser.c index 5d545a4..68944a6 100644 --- a/tests/cases/test_parser.c +++ b/tests/cases/test_parser.c @@ -232,42 +232,6 @@ int test_values(Toy_Bucket** bucketHandle) { } int test_unary(Toy_Bucket** bucketHandle) { - //test unary boolean negation (!true) - { - Toy_Ast* ast = makeAstFromSource(bucketHandle, "!true;"); - - //check if it worked - if ( - ast == NULL || - ast->type != TOY_AST_BLOCK || - ast->block.child == NULL || - ast->block.child->type != TOY_AST_VALUE || - TOY_VALUE_IS_BOOLEAN(ast->block.child->value.value) == false || - TOY_VALUE_AS_BOOLEAN(ast->block.child->value.value) != false) - { - fprintf(stderr, TOY_CC_ERROR "ERROR: failed to run the parser with boolean value !true (unary negation)\n" TOY_CC_RESET); - return -1; - } - } - - //test unary boolean negation (!false, just to be safe) - { - Toy_Ast* ast = makeAstFromSource(bucketHandle, "!false;"); - - //check if it worked - if ( - ast == NULL || - ast->type != TOY_AST_BLOCK || - ast->block.child == NULL || - ast->block.child->type != TOY_AST_VALUE || - TOY_VALUE_IS_BOOLEAN(ast->block.child->value.value) == false || - TOY_VALUE_AS_BOOLEAN(ast->block.child->value.value) != true) - { - fprintf(stderr, TOY_CC_ERROR "ERROR: failed to run the parser with boolean value !false (unary negation)\n" TOY_CC_RESET); - return -1; - } - } - //test unary integer negation { Toy_Ast* ast = makeAstFromSource(bucketHandle, "-42;"); @@ -563,28 +527,30 @@ int test_precedence(Toy_Bucket** bucketHandle) { ast->block.child->binary.flag != TOY_AST_FLAG_MULTIPLY || ast->block.child->binary.left == NULL || - ast->block.child->binary.left->type != TOY_AST_BINARY || - ast->block.child->binary.left->binary.flag != TOY_AST_FLAG_ADD || - ast->block.child->binary.left->binary.left == NULL || - ast->block.child->binary.left->binary.left->type != TOY_AST_VALUE || - TOY_VALUE_IS_INTEGER(ast->block.child->binary.left->binary.left->value.value) == false || - TOY_VALUE_AS_INTEGER(ast->block.child->binary.left->binary.left->value.value) != 1 || - ast->block.child->binary.left->binary.right == NULL || - ast->block.child->binary.left->binary.right->type != TOY_AST_VALUE || - TOY_VALUE_IS_INTEGER(ast->block.child->binary.left->binary.right->value.value) == false || - TOY_VALUE_AS_INTEGER(ast->block.child->binary.left->binary.right->value.value) != 2 || + ast->block.child->binary.left->type != TOY_AST_GROUP || + ast->block.child->binary.left->group.child->type != TOY_AST_BINARY || + ast->block.child->binary.left->group.child->binary.flag != TOY_AST_FLAG_ADD || + ast->block.child->binary.left->group.child->binary.left == NULL || + ast->block.child->binary.left->group.child->binary.left->type != TOY_AST_VALUE || + TOY_VALUE_IS_INTEGER(ast->block.child->binary.left->group.child->binary.left->value.value) == false || + TOY_VALUE_AS_INTEGER(ast->block.child->binary.left->group.child->binary.left->value.value) != 1 || + ast->block.child->binary.left->group.child->binary.right == NULL || + ast->block.child->binary.left->group.child->binary.right->type != TOY_AST_VALUE || + TOY_VALUE_IS_INTEGER(ast->block.child->binary.left->group.child->binary.right->value.value) == false || + TOY_VALUE_AS_INTEGER(ast->block.child->binary.left->group.child->binary.right->value.value) != 2 || ast->block.child->binary.right == NULL || - ast->block.child->binary.right->type != TOY_AST_BINARY || - ast->block.child->binary.right->binary.flag != TOY_AST_FLAG_ADD || - ast->block.child->binary.right->binary.left == NULL || - ast->block.child->binary.right->binary.left->type != TOY_AST_VALUE || - TOY_VALUE_IS_INTEGER(ast->block.child->binary.right->binary.left->value.value) == false || - TOY_VALUE_AS_INTEGER(ast->block.child->binary.right->binary.left->value.value) != 3 || - ast->block.child->binary.right->binary.right == NULL || - ast->block.child->binary.right->binary.right->type != TOY_AST_VALUE || - TOY_VALUE_IS_INTEGER(ast->block.child->binary.right->binary.right->value.value) == false || - TOY_VALUE_AS_INTEGER(ast->block.child->binary.right->binary.right->value.value) != 4) + ast->block.child->binary.right->type != TOY_AST_GROUP || + ast->block.child->binary.right->group.child->type != TOY_AST_BINARY || + ast->block.child->binary.right->group.child->binary.flag != TOY_AST_FLAG_ADD || + ast->block.child->binary.right->group.child->binary.left == NULL || + ast->block.child->binary.right->group.child->binary.left->type != TOY_AST_VALUE || + TOY_VALUE_IS_INTEGER(ast->block.child->binary.right->group.child->binary.left->value.value) == false || + TOY_VALUE_AS_INTEGER(ast->block.child->binary.right->group.child->binary.left->value.value) != 3 || + ast->block.child->binary.right->group.child->binary.right == NULL || + ast->block.child->binary.right->group.child->binary.right->type != TOY_AST_VALUE || + TOY_VALUE_IS_INTEGER(ast->block.child->binary.right->group.child->binary.right->value.value) == false || + TOY_VALUE_AS_INTEGER(ast->block.child->binary.right->group.child->binary.right->value.value) != 4) { fprintf(stderr, TOY_CC_ERROR "ERROR: failed to run the parser precedence '(1 + 2) * (3 + 4)' (group)\n" TOY_CC_RESET); return -1;