mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Removed a couple of small optimisations form the parser
This commit is contained in:
@@ -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) {
|
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
|
//'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) {
|
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
|
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);
|
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) {
|
else if (parser->previous.type == TOY_TOKEN_OPERATOR_NEGATE) {
|
||||||
parsePrecedence(bucketHandle, parser, rootHandle, PREC_UNARY);
|
parsePrecedence(bucketHandle, parser, rootHandle, PREC_UNARY);
|
||||||
|
Toy_private_emitAstUnary(bucketHandle, rootHandle, TOY_AST_FLAG_NEGATE);
|
||||||
//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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
@@ -462,8 +452,8 @@ static Toy_AstFlag group(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast*
|
|||||||
parsePrecedence(bucketHandle, parser, rootHandle, PREC_GROUP);
|
parsePrecedence(bucketHandle, parser, rootHandle, PREC_GROUP);
|
||||||
consume(parser, TOY_TOKEN_OPERATOR_PAREN_RIGHT, "Expected ')' at end of group");
|
consume(parser, TOY_TOKEN_OPERATOR_PAREN_RIGHT, "Expected ')' at end of group");
|
||||||
|
|
||||||
//Toy_AstGroup is omitted from generation, as an optimisation
|
//Toy_AstGroup could be omitted, but is kept for now
|
||||||
// Toy_private_emitAstGroup(bucketHandle, rootHandle);
|
Toy_private_emitAstGroup(bucketHandle, rootHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -250,6 +250,10 @@ static void writeInstructionBinary(Toy_Routine** rt, Toy_AstBinary ast) {
|
|||||||
EMIT_BYTE(rt, code,0);
|
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) {
|
static void writeInstructionPrint(Toy_Routine** rt, Toy_AstPrint ast) {
|
||||||
//the thing to print
|
//the thing to print
|
||||||
writeRoutineCode(rt, ast.child);
|
writeRoutineCode(rt, ast.child);
|
||||||
@@ -292,23 +296,21 @@ static void writeRoutineCode(Toy_Routine** rt, Toy_Ast* ast) {
|
|||||||
writeInstructionBinary(rt, ast->binary);
|
writeInstructionBinary(rt, ast->binary);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TOY_AST_GROUP:
|
||||||
|
writeInstructionGroup(rt, ast->group);
|
||||||
|
break;
|
||||||
|
|
||||||
case TOY_AST_PRINT:
|
case TOY_AST_PRINT:
|
||||||
writeInstructionPrint(rt, ast->print);
|
writeInstructionPrint(rt, ast->print);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//other disallowed instructions
|
//meta instructions are disallowed
|
||||||
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);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TOY_AST_PASS:
|
case TOY_AST_PASS:
|
||||||
//NOTE: this should be disallowed, but for now it's required for testing
|
//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);
|
// fprintf(stderr, TOY_CC_ERROR "ERROR: Invalid AST type found: Unknown pass\n" TOY_CC_RESET);
|
||||||
// exit(-1);
|
// exit(-1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//meta instructions are disallowed
|
|
||||||
case TOY_AST_ERROR:
|
case TOY_AST_ERROR:
|
||||||
fprintf(stderr, TOY_CC_ERROR "ERROR: Invalid AST type found: Unknown error\n" TOY_CC_RESET);
|
fprintf(stderr, TOY_CC_ERROR "ERROR: Invalid AST type found: Unknown error\n" TOY_CC_RESET);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
|||||||
@@ -232,42 +232,6 @@ int test_values(Toy_Bucket** bucketHandle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int test_unary(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
|
//test unary integer negation
|
||||||
{
|
{
|
||||||
Toy_Ast* ast = makeAstFromSource(bucketHandle, "-42;");
|
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.flag != TOY_AST_FLAG_MULTIPLY ||
|
||||||
|
|
||||||
ast->block.child->binary.left == NULL ||
|
ast->block.child->binary.left == NULL ||
|
||||||
ast->block.child->binary.left->type != TOY_AST_BINARY ||
|
ast->block.child->binary.left->type != TOY_AST_GROUP ||
|
||||||
ast->block.child->binary.left->binary.flag != TOY_AST_FLAG_ADD ||
|
ast->block.child->binary.left->group.child->type != TOY_AST_BINARY ||
|
||||||
ast->block.child->binary.left->binary.left == NULL ||
|
ast->block.child->binary.left->group.child->binary.flag != TOY_AST_FLAG_ADD ||
|
||||||
ast->block.child->binary.left->binary.left->type != TOY_AST_VALUE ||
|
ast->block.child->binary.left->group.child->binary.left == NULL ||
|
||||||
TOY_VALUE_IS_INTEGER(ast->block.child->binary.left->binary.left->value.value) == false ||
|
ast->block.child->binary.left->group.child->binary.left->type != TOY_AST_VALUE ||
|
||||||
TOY_VALUE_AS_INTEGER(ast->block.child->binary.left->binary.left->value.value) != 1 ||
|
TOY_VALUE_IS_INTEGER(ast->block.child->binary.left->group.child->binary.left->value.value) == false ||
|
||||||
ast->block.child->binary.left->binary.right == NULL ||
|
TOY_VALUE_AS_INTEGER(ast->block.child->binary.left->group.child->binary.left->value.value) != 1 ||
|
||||||
ast->block.child->binary.left->binary.right->type != TOY_AST_VALUE ||
|
ast->block.child->binary.left->group.child->binary.right == NULL ||
|
||||||
TOY_VALUE_IS_INTEGER(ast->block.child->binary.left->binary.right->value.value) == false ||
|
ast->block.child->binary.left->group.child->binary.right->type != TOY_AST_VALUE ||
|
||||||
TOY_VALUE_AS_INTEGER(ast->block.child->binary.left->binary.right->value.value) != 2 ||
|
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 == NULL ||
|
||||||
ast->block.child->binary.right->type != TOY_AST_BINARY ||
|
ast->block.child->binary.right->type != TOY_AST_GROUP ||
|
||||||
ast->block.child->binary.right->binary.flag != TOY_AST_FLAG_ADD ||
|
ast->block.child->binary.right->group.child->type != TOY_AST_BINARY ||
|
||||||
ast->block.child->binary.right->binary.left == NULL ||
|
ast->block.child->binary.right->group.child->binary.flag != TOY_AST_FLAG_ADD ||
|
||||||
ast->block.child->binary.right->binary.left->type != TOY_AST_VALUE ||
|
ast->block.child->binary.right->group.child->binary.left == NULL ||
|
||||||
TOY_VALUE_IS_INTEGER(ast->block.child->binary.right->binary.left->value.value) == false ||
|
ast->block.child->binary.right->group.child->binary.left->type != TOY_AST_VALUE ||
|
||||||
TOY_VALUE_AS_INTEGER(ast->block.child->binary.right->binary.left->value.value) != 3 ||
|
TOY_VALUE_IS_INTEGER(ast->block.child->binary.right->group.child->binary.left->value.value) == false ||
|
||||||
ast->block.child->binary.right->binary.right == NULL ||
|
TOY_VALUE_AS_INTEGER(ast->block.child->binary.right->group.child->binary.left->value.value) != 3 ||
|
||||||
ast->block.child->binary.right->binary.right->type != TOY_AST_VALUE ||
|
ast->block.child->binary.right->group.child->binary.right == NULL ||
|
||||||
TOY_VALUE_IS_INTEGER(ast->block.child->binary.right->binary.right->value.value) == false ||
|
ast->block.child->binary.right->group.child->binary.right->type != TOY_AST_VALUE ||
|
||||||
TOY_VALUE_AS_INTEGER(ast->block.child->binary.right->binary.right->value.value) != 4)
|
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);
|
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to run the parser precedence '(1 + 2) * (3 + 4)' (group)\n" TOY_CC_RESET);
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user