From d22b18ed17786e7e682a60994e7eb8223091b6c5 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 26 Oct 2024 10:35:47 +1100 Subject: [PATCH] Variable access is working --- source/toy_ast.c | 9 + source/toy_ast.h | 8 + source/toy_parser.c | 5 +- source/toy_routine.c | 258 ++++++++++-------- source/toy_vm.c | 33 ++- tests/cases/test_ast.c | 85 ++++-- .../test_variables_and_scopes.toy | 3 +- 7 files changed, 241 insertions(+), 160 deletions(-) diff --git a/source/toy_ast.c b/source/toy_ast.c index 7dc7ed9..83462a6 100644 --- a/source/toy_ast.c +++ b/source/toy_ast.c @@ -113,6 +113,15 @@ void Toy_private_emitAstVariableAssignment(Toy_Bucket** bucketHandle, Toy_Ast** (*astHandle) = tmp; } +void Toy_private_emitAstVariableAccess(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_String* name) { + Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast)); + + tmp->type = TOY_AST_VAR_ACCESS; + tmp->varAccess.name = name; + + (*astHandle) = tmp; +} + void Toy_private_emitAstPass(Toy_Bucket** bucketHandle, Toy_Ast** astHandle) { Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast)); diff --git a/source/toy_ast.h b/source/toy_ast.h index 9f0dbee..69f3d5d 100644 --- a/source/toy_ast.h +++ b/source/toy_ast.h @@ -20,6 +20,7 @@ typedef enum Toy_AstType { TOY_AST_VAR_DECLARE, TOY_AST_VAR_ASSIGN, + TOY_AST_VAR_ACCESS, TOY_AST_PASS, TOY_AST_ERROR, @@ -121,6 +122,11 @@ typedef struct Toy_AstVarAssign { Toy_Ast* expr; } Toy_AstVarAssign; +typedef struct Toy_AstVarAccess { + Toy_AstType type; + Toy_String* name; +} Toy_AstVarAccess; + typedef struct Toy_AstPass { Toy_AstType type; } Toy_AstPass; @@ -144,6 +150,7 @@ union Toy_Ast { //32 | 64 BITNESS Toy_AstPrint print; //8 | 16 Toy_AstVarDeclare varDeclare; //16 | 24 Toy_AstVarAssign varAssign; //16 | 24 + Toy_AstVarAccess varAccess; //8 | 16 Toy_AstPass pass; //4 | 4 Toy_AstError error; //4 | 4 Toy_AstEnd end; //4 | 4 @@ -162,6 +169,7 @@ void Toy_private_emitAstPrint(Toy_Bucket** bucketHandle, Toy_Ast** astHandle); void Toy_private_emitAstVariableDeclaration(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_String* name, Toy_Ast* expr); void Toy_private_emitAstVariableAssignment(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_String* name, Toy_AstFlag flag, Toy_Ast* expr); +void Toy_private_emitAstVariableAccess(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_String* name); void Toy_private_emitAstPass(Toy_Bucket** bucketHandle, Toy_Ast** astHandle); void Toy_private_emitAstError(Toy_Bucket** bucketHandle, Toy_Ast** astHandle); diff --git a/source/toy_parser.c b/source/toy_parser.c index fb7924e..af392db 100644 --- a/source/toy_parser.c +++ b/source/toy_parser.c @@ -254,9 +254,8 @@ static Toy_AstFlag nameString(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy return TOY_AST_FLAG_NONE; } - //access - printError(parser, parser->previous, "Unexpectedly found a variable access; this is not yet implemented"); - Toy_private_emitAstError(bucketHandle, rootHandle); + //assume it's an access + Toy_private_emitAstVariableAccess(bucketHandle, rootHandle, name); return TOY_AST_FLAG_NONE; } diff --git a/source/toy_routine.c b/source/toy_routine.c index e78f250..98283e5 100644 --- a/source/toy_routine.c +++ b/source/toy_routine.c @@ -196,121 +196,6 @@ static void writeInstructionBinary(Toy_Routine** rt, Toy_AstBinary ast) { EMIT_BYTE(rt, code,0); } -static void writeInstructionAssign(Toy_Routine** rt, Toy_AstVarAssign ast) { - //name, duplicate, right, opcode - if (ast.flag == TOY_AST_FLAG_ASSIGN) { - EMIT_BYTE(rt, code, TOY_OPCODE_READ); - EMIT_BYTE(rt, code, TOY_VALUE_STRING); - EMIT_BYTE(rt, code, TOY_STRING_NAME); - EMIT_BYTE(rt, code, ast.name->length); //store the length (max 255) - - emitString(rt, ast.name); - writeRoutineCode(rt, ast.expr); - - EMIT_BYTE(rt, code, TOY_OPCODE_ASSIGN); - EMIT_BYTE(rt, code, 0); - } - else if (ast.flag == TOY_AST_FLAG_ADD_ASSIGN) { - EMIT_BYTE(rt, code, TOY_OPCODE_READ); - EMIT_BYTE(rt, code, TOY_VALUE_STRING); - EMIT_BYTE(rt, code, TOY_STRING_NAME); - EMIT_BYTE(rt, code, ast.name->length); //store the length (max 255) - - emitString(rt, ast.name); - - EMIT_BYTE(rt, code,TOY_OPCODE_DUPLICATE); - EMIT_BYTE(rt, code,0); - EMIT_BYTE(rt, code,0); - EMIT_BYTE(rt, code,0); - - writeRoutineCode(rt, ast.expr); - - EMIT_BYTE(rt, code,TOY_OPCODE_ADD); - EMIT_BYTE(rt, code,TOY_OPCODE_ASSIGN); //squeezed - } - else if (ast.flag == TOY_AST_FLAG_SUBTRACT_ASSIGN) { - EMIT_BYTE(rt, code, TOY_OPCODE_READ); - EMIT_BYTE(rt, code, TOY_VALUE_STRING); - EMIT_BYTE(rt, code, TOY_STRING_NAME); - EMIT_BYTE(rt, code, ast.name->length); //store the length (max 255) - - emitString(rt, ast.name); - - EMIT_BYTE(rt, code,TOY_OPCODE_DUPLICATE); - EMIT_BYTE(rt, code,0); - EMIT_BYTE(rt, code,0); - EMIT_BYTE(rt, code,0); - - writeRoutineCode(rt, ast.expr); - - EMIT_BYTE(rt, code,TOY_OPCODE_SUBTRACT); - EMIT_BYTE(rt, code,TOY_OPCODE_ASSIGN); //squeezed - } - else if (ast.flag == TOY_AST_FLAG_MULTIPLY_ASSIGN) { - EMIT_BYTE(rt, code, TOY_OPCODE_READ); - EMIT_BYTE(rt, code, TOY_VALUE_STRING); - EMIT_BYTE(rt, code, TOY_STRING_NAME); - EMIT_BYTE(rt, code, ast.name->length); //store the length (max 255) - - emitString(rt, ast.name); - - EMIT_BYTE(rt, code,TOY_OPCODE_DUPLICATE); - EMIT_BYTE(rt, code,0); - EMIT_BYTE(rt, code,0); - EMIT_BYTE(rt, code,0); - - writeRoutineCode(rt, ast.expr); - - EMIT_BYTE(rt, code,TOY_OPCODE_MULTIPLY); - EMIT_BYTE(rt, code,TOY_OPCODE_ASSIGN); //squeezed - } - else if (ast.flag == TOY_AST_FLAG_DIVIDE_ASSIGN) { - EMIT_BYTE(rt, code, TOY_OPCODE_READ); - EMIT_BYTE(rt, code, TOY_VALUE_STRING); - EMIT_BYTE(rt, code, TOY_STRING_NAME); - EMIT_BYTE(rt, code, ast.name->length); //store the length (max 255) - - emitString(rt, ast.name); - - EMIT_BYTE(rt, code,TOY_OPCODE_DUPLICATE); - EMIT_BYTE(rt, code,0); - EMIT_BYTE(rt, code,0); - EMIT_BYTE(rt, code,0); - - writeRoutineCode(rt, ast.expr); - - EMIT_BYTE(rt, code,TOY_OPCODE_DIVIDE); - EMIT_BYTE(rt, code,TOY_OPCODE_ASSIGN); //squeezed - } - else if (ast.flag == TOY_AST_FLAG_MODULO_ASSIGN) { - EMIT_BYTE(rt, code, TOY_OPCODE_READ); - EMIT_BYTE(rt, code, TOY_VALUE_STRING); - EMIT_BYTE(rt, code, TOY_STRING_NAME); - EMIT_BYTE(rt, code, ast.name->length); //store the length (max 255) - - emitString(rt, ast.name); - - EMIT_BYTE(rt, code,TOY_OPCODE_DUPLICATE); - EMIT_BYTE(rt, code,0); - EMIT_BYTE(rt, code,0); - EMIT_BYTE(rt, code,0); - - writeRoutineCode(rt, ast.expr); - - EMIT_BYTE(rt, code,TOY_OPCODE_MODULO); - EMIT_BYTE(rt, code,TOY_OPCODE_ASSIGN); //squeezed - } - - else { - fprintf(stderr, TOY_CC_ERROR "ERROR: Invalid AST assign flag found\n" TOY_CC_RESET); - exit(-1); - } - - //4-byte alignment - EMIT_BYTE(rt, code,0); - EMIT_BYTE(rt, code,0); -} - static void writeInstructionCompare(Toy_Routine** rt, Toy_AstCompare ast) { //left, then right, then the compare's operation writeRoutineCode(rt, ast.left); @@ -381,6 +266,137 @@ static void writeInstructionVarDeclare(Toy_Routine** rt, Toy_AstVarDeclare ast) emitString(rt, ast.name); } +static void writeInstructionAssign(Toy_Routine** rt, Toy_AstVarAssign ast) { + //name, duplicate, right, opcode + if (ast.flag == TOY_AST_FLAG_ASSIGN) { + EMIT_BYTE(rt, code, TOY_OPCODE_READ); + EMIT_BYTE(rt, code, TOY_VALUE_STRING); + EMIT_BYTE(rt, code, TOY_STRING_NAME); + EMIT_BYTE(rt, code, ast.name->length); //store the length (max 255) + + emitString(rt, ast.name); + writeRoutineCode(rt, ast.expr); + + EMIT_BYTE(rt, code, TOY_OPCODE_ASSIGN); + EMIT_BYTE(rt, code, 0); + } + else if (ast.flag == TOY_AST_FLAG_ADD_ASSIGN) { + EMIT_BYTE(rt, code, TOY_OPCODE_READ); + EMIT_BYTE(rt, code, TOY_VALUE_STRING); + EMIT_BYTE(rt, code, TOY_STRING_NAME); + EMIT_BYTE(rt, code, ast.name->length); //store the length (max 255) + + emitString(rt, ast.name); + + EMIT_BYTE(rt, code,TOY_OPCODE_DUPLICATE); + EMIT_BYTE(rt, code,TOY_OPCODE_ACCESS); //squeezed + EMIT_BYTE(rt, code,0); + EMIT_BYTE(rt, code,0); + + writeRoutineCode(rt, ast.expr); + + EMIT_BYTE(rt, code,TOY_OPCODE_ADD); + EMIT_BYTE(rt, code,TOY_OPCODE_ASSIGN); //squeezed + } + else if (ast.flag == TOY_AST_FLAG_SUBTRACT_ASSIGN) { + EMIT_BYTE(rt, code, TOY_OPCODE_READ); + EMIT_BYTE(rt, code, TOY_VALUE_STRING); + EMIT_BYTE(rt, code, TOY_STRING_NAME); + EMIT_BYTE(rt, code, ast.name->length); //store the length (max 255) + + emitString(rt, ast.name); + + EMIT_BYTE(rt, code,TOY_OPCODE_DUPLICATE); + EMIT_BYTE(rt, code,TOY_OPCODE_ACCESS); //squeezed + EMIT_BYTE(rt, code,0); + EMIT_BYTE(rt, code,0); + + writeRoutineCode(rt, ast.expr); + + EMIT_BYTE(rt, code,TOY_OPCODE_SUBTRACT); + EMIT_BYTE(rt, code,TOY_OPCODE_ASSIGN); //squeezed + } + else if (ast.flag == TOY_AST_FLAG_MULTIPLY_ASSIGN) { + EMIT_BYTE(rt, code, TOY_OPCODE_READ); + EMIT_BYTE(rt, code, TOY_VALUE_STRING); + EMIT_BYTE(rt, code, TOY_STRING_NAME); + EMIT_BYTE(rt, code, ast.name->length); //store the length (max 255) + + emitString(rt, ast.name); + + EMIT_BYTE(rt, code,TOY_OPCODE_DUPLICATE); + EMIT_BYTE(rt, code,TOY_OPCODE_ACCESS); //squeezed + EMIT_BYTE(rt, code,0); + EMIT_BYTE(rt, code,0); + + writeRoutineCode(rt, ast.expr); + + EMIT_BYTE(rt, code,TOY_OPCODE_MULTIPLY); + EMIT_BYTE(rt, code,TOY_OPCODE_ASSIGN); //squeezed + } + else if (ast.flag == TOY_AST_FLAG_DIVIDE_ASSIGN) { + EMIT_BYTE(rt, code, TOY_OPCODE_READ); + EMIT_BYTE(rt, code, TOY_VALUE_STRING); + EMIT_BYTE(rt, code, TOY_STRING_NAME); + EMIT_BYTE(rt, code, ast.name->length); //store the length (max 255) + + emitString(rt, ast.name); + + EMIT_BYTE(rt, code,TOY_OPCODE_DUPLICATE); + EMIT_BYTE(rt, code,TOY_OPCODE_ACCESS); //squeezed + EMIT_BYTE(rt, code,0); + EMIT_BYTE(rt, code,0); + + writeRoutineCode(rt, ast.expr); + + EMIT_BYTE(rt, code,TOY_OPCODE_DIVIDE); + EMIT_BYTE(rt, code,TOY_OPCODE_ASSIGN); //squeezed + } + else if (ast.flag == TOY_AST_FLAG_MODULO_ASSIGN) { + EMIT_BYTE(rt, code, TOY_OPCODE_READ); + EMIT_BYTE(rt, code, TOY_VALUE_STRING); + EMIT_BYTE(rt, code, TOY_STRING_NAME); + EMIT_BYTE(rt, code, ast.name->length); //store the length (max 255) + + emitString(rt, ast.name); + + EMIT_BYTE(rt, code,TOY_OPCODE_DUPLICATE); + EMIT_BYTE(rt, code,TOY_OPCODE_ACCESS); //squeezed + EMIT_BYTE(rt, code,0); + EMIT_BYTE(rt, code,0); + + writeRoutineCode(rt, ast.expr); + + EMIT_BYTE(rt, code,TOY_OPCODE_MODULO); + EMIT_BYTE(rt, code,TOY_OPCODE_ASSIGN); //squeezed + } + + else { + fprintf(stderr, TOY_CC_ERROR "ERROR: Invalid AST assign flag found\n" TOY_CC_RESET); + exit(-1); + } + + //4-byte alignment + EMIT_BYTE(rt, code,0); + EMIT_BYTE(rt, code,0); +} + +static void writeInstructionAccess(Toy_Routine** rt, Toy_AstVarAccess ast) { + //push the name + EMIT_BYTE(rt, code, TOY_OPCODE_READ); + EMIT_BYTE(rt, code, TOY_VALUE_STRING); + EMIT_BYTE(rt, code, TOY_STRING_NAME); + EMIT_BYTE(rt, code, ast.name->length); //store the length (max 255) + + emitString(rt, ast.name); + + //convert name to value + EMIT_BYTE(rt, code, TOY_OPCODE_ACCESS); + EMIT_BYTE(rt, code,0); + EMIT_BYTE(rt, code,0); + EMIT_BYTE(rt, code,0); +} + //routine structure // static void writeRoutineParam(Toy_Routine* rt) { // // @@ -410,10 +426,6 @@ static void writeRoutineCode(Toy_Routine** rt, Toy_Ast* ast) { writeInstructionBinary(rt, ast->binary); break; - case TOY_AST_VAR_ASSIGN: - writeInstructionAssign(rt, ast->varAssign); - break; - case TOY_AST_COMPARE: writeInstructionCompare(rt, ast->compare); break; @@ -430,6 +442,14 @@ static void writeRoutineCode(Toy_Routine** rt, Toy_Ast* ast) { writeInstructionVarDeclare(rt, ast->varDeclare); break; + case TOY_AST_VAR_ASSIGN: + writeInstructionAssign(rt, ast->varAssign); + break; + + case TOY_AST_VAR_ACCESS: + writeInstructionAccess(rt, ast->varAccess); + break; + //meta instructions are disallowed case TOY_AST_PASS: //NOTE: this should be disallowed, but for now it's required for testing diff --git a/source/toy_vm.c b/source/toy_vm.c index bd2859a..8e0bb2a 100644 --- a/source/toy_vm.c +++ b/source/toy_vm.c @@ -165,7 +165,7 @@ static void processAssign(Toy_VM* vm) { Toy_Value value = Toy_popStack(&vm->stack); Toy_Value name = Toy_popStack(&vm->stack); - //check string type + //check name string type if (!TOY_VALUE_IS_STRING(name) && TOY_VALUE_AS_STRING(name)->type != TOY_STRING_NAME) { Toy_error("Invalid assignment target"); return; @@ -177,6 +177,22 @@ static void processAssign(Toy_VM* vm) { //cleanup Toy_freeValue(name); } +static void processAccess(Toy_VM* vm) { + Toy_Value name = Toy_popStack(&vm->stack); + + //check name string type + if (!TOY_VALUE_IS_STRING(name) && TOY_VALUE_AS_STRING(name)->type != TOY_STRING_NAME) { + Toy_error("Invalid access target"); + return; + } + + //find and push the value + Toy_Value value = Toy_accessScope(vm->scope, TOY_VALUE_AS_STRING(name)); + Toy_pushStack(&vm->stack, value); + + //cleanup + Toy_freeValue(name); +} static void processArithmetic(Toy_VM* vm, Toy_OpcodeType opcode) { Toy_Value right = Toy_popStack(&vm->stack); @@ -248,6 +264,12 @@ static void processDuplicate(Toy_VM* vm) { Toy_Value value = Toy_copyValue(Toy_peekStack(&vm->stack)); Toy_pushStack(&vm->stack, value); Toy_freeValue(value); + + //check for compound assignments + Toy_OpcodeType squeezed = READ_BYTE(vm); + if (squeezed == TOY_OPCODE_ACCESS) { + processAccess(vm); + } } static void processComparison(Toy_VM* vm, Toy_OpcodeType opcode) { @@ -421,6 +443,10 @@ static void process(Toy_VM* vm) { processAssign(vm); break; + case TOY_OPCODE_ACCESS: + processAccess(vm); + break; + case TOY_OPCODE_DUPLICATE: processDuplicate(vm); break; @@ -465,11 +491,6 @@ static void process(Toy_VM* vm) { processConcat(vm); break; - //not yet implemented - case TOY_OPCODE_ACCESS: - fprintf(stderr, TOY_CC_ERROR "ERROR: Incomplete opcode %d found, exiting\n" TOY_CC_RESET, opcode); - exit(-1); - case TOY_OPCODE_PASS: case TOY_OPCODE_ERROR: case TOY_OPCODE_EOF: diff --git a/tests/cases/test_ast.c b/tests/cases/test_ast.c index d9064c0..d9c4846 100644 --- a/tests/cases/test_ast.c +++ b/tests/cases/test_ast.c @@ -17,14 +17,15 @@ int test_sizeof_ast_64bit() { //run for each type TEST_SIZEOF(Toy_AstType, 4); TEST_SIZEOF(Toy_AstBlock, 32); - TEST_SIZEOF(Toy_AstVarDeclare, 24); TEST_SIZEOF(Toy_AstValue, 24); TEST_SIZEOF(Toy_AstUnary, 16); TEST_SIZEOF(Toy_AstBinary, 24); - TEST_SIZEOF(Toy_AstVarAssign, 24); TEST_SIZEOF(Toy_AstCompare, 24); TEST_SIZEOF(Toy_AstGroup, 16); TEST_SIZEOF(Toy_AstPrint, 16); + TEST_SIZEOF(Toy_AstVarDeclare, 24); + TEST_SIZEOF(Toy_AstVarAssign, 24); + TEST_SIZEOF(Toy_AstVarAccess, 16); TEST_SIZEOF(Toy_AstPass, 4); TEST_SIZEOF(Toy_AstError, 4); TEST_SIZEOF(Toy_AstEnd, 4); @@ -48,14 +49,15 @@ int test_sizeof_ast_32bit() { //run for each type TEST_SIZEOF(Toy_AstType, 4); TEST_SIZEOF(Toy_AstBlock, 16); - TEST_SIZEOF(Toy_AstVarDeclare, 12); TEST_SIZEOF(Toy_AstValue, 12); TEST_SIZEOF(Toy_AstUnary, 12); TEST_SIZEOF(Toy_AstBinary, 16); - TEST_SIZEOF(Toy_AstVarAssign, 16); TEST_SIZEOF(Toy_AstCompare, 16); TEST_SIZEOF(Toy_AstGroup, 8); TEST_SIZEOF(Toy_AstPrint, 8); + TEST_SIZEOF(Toy_AstVarDeclare, 12); + TEST_SIZEOF(Toy_AstVarAssign, 16); + TEST_SIZEOF(Toy_AstVarAccess, 8); TEST_SIZEOF(Toy_AstPass, 4); TEST_SIZEOF(Toy_AstError, 4); TEST_SIZEOF(Toy_AstEnd, 4); @@ -128,32 +130,6 @@ int test_type_emission(Toy_Bucket** bucketHandle) { } } - //emit assign - { - //build the AST - Toy_Ast* ast = NULL; - Toy_Ast* right = NULL; - Toy_String* name = Toy_createNameStringLength(bucketHandle, "foobar", 6, TOY_VALUE_INTEGER); - Toy_private_emitAstValue(bucketHandle, &right, TOY_VALUE_FROM_INTEGER(69)); - Toy_private_emitAstVariableAssignment(bucketHandle, &ast, name, TOY_AST_FLAG_ASSIGN, right); - - //check if it worked - if ( - ast == NULL || - ast->type != TOY_AST_VAR_ASSIGN || - ast->varAssign.flag != TOY_AST_FLAG_ASSIGN || - ast->varAssign.name == NULL || - ast->varAssign.name->type != TOY_STRING_NAME || - strcmp(ast->varAssign.name->as.name.data, "foobar") != 0 || - ast->varAssign.name->as.name.type != TOY_VALUE_INTEGER || - ast->varAssign.expr->type != TOY_AST_VALUE || - TOY_VALUE_AS_INTEGER(ast->varAssign.expr->value.value) != 69) - { - fprintf(stderr, TOY_CC_ERROR "ERROR: failed to emit an assign as 'Toy_Ast', state unknown\n" TOY_CC_RESET); - return -1; - } - } - //emit compare { //build the AST @@ -303,6 +279,55 @@ int test_type_emission(Toy_Bucket** bucketHandle) { Toy_freeString(name); } + //emit assign + { + //build the AST + Toy_Ast* ast = NULL; + Toy_Ast* right = NULL; + Toy_String* name = Toy_createNameStringLength(bucketHandle, "foobar", 6, TOY_VALUE_INTEGER); + Toy_private_emitAstValue(bucketHandle, &right, TOY_VALUE_FROM_INTEGER(69)); + Toy_private_emitAstVariableAssignment(bucketHandle, &ast, name, TOY_AST_FLAG_ASSIGN, right); + + //check if it worked + if ( + ast == NULL || + ast->type != TOY_AST_VAR_ASSIGN || + ast->varAssign.flag != TOY_AST_FLAG_ASSIGN || + ast->varAssign.name == NULL || + ast->varAssign.name->type != TOY_STRING_NAME || + strcmp(ast->varAssign.name->as.name.data, "foobar") != 0 || + ast->varAssign.name->as.name.type != TOY_VALUE_INTEGER || + ast->varAssign.expr->type != TOY_AST_VALUE || + TOY_VALUE_AS_INTEGER(ast->varAssign.expr->value.value) != 69) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: failed to emit an assign as 'Toy_Ast', state unknown\n" TOY_CC_RESET); + return -1; + } + } + + //emit access + { + //build the AST + Toy_Ast* ast = NULL; + Toy_Ast* right = NULL; + Toy_String* name = Toy_createNameStringLength(bucketHandle, "foobar", 6, TOY_VALUE_INTEGER); + Toy_private_emitAstVariableAccess(bucketHandle, &ast, name); + + //check if it worked + if ( + ast == NULL || + ast->type != TOY_AST_VAR_ACCESS || + ast->varAccess.name == NULL || + ast->varAccess.name->type != TOY_STRING_NAME || + strcmp(ast->varAccess.name->as.name.data, "foobar") != 0 || + ast->varAccess.name->as.name.type != TOY_VALUE_INTEGER) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: failed to emit an access as 'Toy_Ast', state unknown\n" TOY_CC_RESET); + return -1; + } + } + + return 0; } diff --git a/tests/integrations/test_variables_and_scopes.toy b/tests/integrations/test_variables_and_scopes.toy index fea931c..76bfddb 100644 --- a/tests/integrations/test_variables_and_scopes.toy +++ b/tests/integrations/test_variables_and_scopes.toy @@ -7,8 +7,8 @@ var empty; //assign a previously existing variable answer = 6 * 9; +answer = answer + 1; -/* TODO: implement compound assignments answer += 5; answer -= 5; @@ -19,4 +19,3 @@ answer /= 2; answer %= 10; -*/