mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Variable access is working
This commit is contained in:
@@ -113,6 +113,15 @@ void Toy_private_emitAstVariableAssignment(Toy_Bucket** bucketHandle, Toy_Ast**
|
|||||||
(*astHandle) = tmp;
|
(*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) {
|
void Toy_private_emitAstPass(Toy_Bucket** bucketHandle, Toy_Ast** astHandle) {
|
||||||
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));
|
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ typedef enum Toy_AstType {
|
|||||||
|
|
||||||
TOY_AST_VAR_DECLARE,
|
TOY_AST_VAR_DECLARE,
|
||||||
TOY_AST_VAR_ASSIGN,
|
TOY_AST_VAR_ASSIGN,
|
||||||
|
TOY_AST_VAR_ACCESS,
|
||||||
|
|
||||||
TOY_AST_PASS,
|
TOY_AST_PASS,
|
||||||
TOY_AST_ERROR,
|
TOY_AST_ERROR,
|
||||||
@@ -121,6 +122,11 @@ typedef struct Toy_AstVarAssign {
|
|||||||
Toy_Ast* expr;
|
Toy_Ast* expr;
|
||||||
} Toy_AstVarAssign;
|
} Toy_AstVarAssign;
|
||||||
|
|
||||||
|
typedef struct Toy_AstVarAccess {
|
||||||
|
Toy_AstType type;
|
||||||
|
Toy_String* name;
|
||||||
|
} Toy_AstVarAccess;
|
||||||
|
|
||||||
typedef struct Toy_AstPass {
|
typedef struct Toy_AstPass {
|
||||||
Toy_AstType type;
|
Toy_AstType type;
|
||||||
} Toy_AstPass;
|
} Toy_AstPass;
|
||||||
@@ -144,6 +150,7 @@ union Toy_Ast { //32 | 64 BITNESS
|
|||||||
Toy_AstPrint print; //8 | 16
|
Toy_AstPrint print; //8 | 16
|
||||||
Toy_AstVarDeclare varDeclare; //16 | 24
|
Toy_AstVarDeclare varDeclare; //16 | 24
|
||||||
Toy_AstVarAssign varAssign; //16 | 24
|
Toy_AstVarAssign varAssign; //16 | 24
|
||||||
|
Toy_AstVarAccess varAccess; //8 | 16
|
||||||
Toy_AstPass pass; //4 | 4
|
Toy_AstPass pass; //4 | 4
|
||||||
Toy_AstError error; //4 | 4
|
Toy_AstError error; //4 | 4
|
||||||
Toy_AstEnd end; //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_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_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_emitAstPass(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
|
||||||
void Toy_private_emitAstError(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
|
void Toy_private_emitAstError(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
|
||||||
|
|||||||
@@ -254,9 +254,8 @@ static Toy_AstFlag nameString(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy
|
|||||||
return TOY_AST_FLAG_NONE;
|
return TOY_AST_FLAG_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//access
|
//assume it's an access
|
||||||
printError(parser, parser->previous, "Unexpectedly found a variable access; this is not yet implemented");
|
Toy_private_emitAstVariableAccess(bucketHandle, rootHandle, name);
|
||||||
Toy_private_emitAstError(bucketHandle, rootHandle);
|
|
||||||
return TOY_AST_FLAG_NONE;
|
return TOY_AST_FLAG_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -196,121 +196,6 @@ static void writeInstructionBinary(Toy_Routine** rt, Toy_AstBinary ast) {
|
|||||||
EMIT_BYTE(rt, code,0);
|
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) {
|
static void writeInstructionCompare(Toy_Routine** rt, Toy_AstCompare ast) {
|
||||||
//left, then right, then the compare's operation
|
//left, then right, then the compare's operation
|
||||||
writeRoutineCode(rt, ast.left);
|
writeRoutineCode(rt, ast.left);
|
||||||
@@ -381,6 +266,137 @@ static void writeInstructionVarDeclare(Toy_Routine** rt, Toy_AstVarDeclare ast)
|
|||||||
emitString(rt, ast.name);
|
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
|
//routine structure
|
||||||
// static void writeRoutineParam(Toy_Routine* rt) {
|
// static void writeRoutineParam(Toy_Routine* rt) {
|
||||||
// //
|
// //
|
||||||
@@ -410,10 +426,6 @@ static void writeRoutineCode(Toy_Routine** rt, Toy_Ast* ast) {
|
|||||||
writeInstructionBinary(rt, ast->binary);
|
writeInstructionBinary(rt, ast->binary);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOY_AST_VAR_ASSIGN:
|
|
||||||
writeInstructionAssign(rt, ast->varAssign);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TOY_AST_COMPARE:
|
case TOY_AST_COMPARE:
|
||||||
writeInstructionCompare(rt, ast->compare);
|
writeInstructionCompare(rt, ast->compare);
|
||||||
break;
|
break;
|
||||||
@@ -430,6 +442,14 @@ static void writeRoutineCode(Toy_Routine** rt, Toy_Ast* ast) {
|
|||||||
writeInstructionVarDeclare(rt, ast->varDeclare);
|
writeInstructionVarDeclare(rt, ast->varDeclare);
|
||||||
break;
|
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
|
//meta instructions are disallowed
|
||||||
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
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ static void processAssign(Toy_VM* vm) {
|
|||||||
Toy_Value value = Toy_popStack(&vm->stack);
|
Toy_Value value = Toy_popStack(&vm->stack);
|
||||||
Toy_Value name = 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) {
|
if (!TOY_VALUE_IS_STRING(name) && TOY_VALUE_AS_STRING(name)->type != TOY_STRING_NAME) {
|
||||||
Toy_error("Invalid assignment target");
|
Toy_error("Invalid assignment target");
|
||||||
return;
|
return;
|
||||||
@@ -177,6 +177,22 @@ static void processAssign(Toy_VM* vm) {
|
|||||||
//cleanup
|
//cleanup
|
||||||
Toy_freeValue(name);
|
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) {
|
static void processArithmetic(Toy_VM* vm, Toy_OpcodeType opcode) {
|
||||||
Toy_Value right = Toy_popStack(&vm->stack);
|
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_Value value = Toy_copyValue(Toy_peekStack(&vm->stack));
|
||||||
Toy_pushStack(&vm->stack, value);
|
Toy_pushStack(&vm->stack, value);
|
||||||
Toy_freeValue(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) {
|
static void processComparison(Toy_VM* vm, Toy_OpcodeType opcode) {
|
||||||
@@ -421,6 +443,10 @@ static void process(Toy_VM* vm) {
|
|||||||
processAssign(vm);
|
processAssign(vm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TOY_OPCODE_ACCESS:
|
||||||
|
processAccess(vm);
|
||||||
|
break;
|
||||||
|
|
||||||
case TOY_OPCODE_DUPLICATE:
|
case TOY_OPCODE_DUPLICATE:
|
||||||
processDuplicate(vm);
|
processDuplicate(vm);
|
||||||
break;
|
break;
|
||||||
@@ -465,11 +491,6 @@ static void process(Toy_VM* vm) {
|
|||||||
processConcat(vm);
|
processConcat(vm);
|
||||||
break;
|
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_PASS:
|
||||||
case TOY_OPCODE_ERROR:
|
case TOY_OPCODE_ERROR:
|
||||||
case TOY_OPCODE_EOF:
|
case TOY_OPCODE_EOF:
|
||||||
|
|||||||
@@ -17,14 +17,15 @@ int test_sizeof_ast_64bit() {
|
|||||||
//run for each type
|
//run for each type
|
||||||
TEST_SIZEOF(Toy_AstType, 4);
|
TEST_SIZEOF(Toy_AstType, 4);
|
||||||
TEST_SIZEOF(Toy_AstBlock, 32);
|
TEST_SIZEOF(Toy_AstBlock, 32);
|
||||||
TEST_SIZEOF(Toy_AstVarDeclare, 24);
|
|
||||||
TEST_SIZEOF(Toy_AstValue, 24);
|
TEST_SIZEOF(Toy_AstValue, 24);
|
||||||
TEST_SIZEOF(Toy_AstUnary, 16);
|
TEST_SIZEOF(Toy_AstUnary, 16);
|
||||||
TEST_SIZEOF(Toy_AstBinary, 24);
|
TEST_SIZEOF(Toy_AstBinary, 24);
|
||||||
TEST_SIZEOF(Toy_AstVarAssign, 24);
|
|
||||||
TEST_SIZEOF(Toy_AstCompare, 24);
|
TEST_SIZEOF(Toy_AstCompare, 24);
|
||||||
TEST_SIZEOF(Toy_AstGroup, 16);
|
TEST_SIZEOF(Toy_AstGroup, 16);
|
||||||
TEST_SIZEOF(Toy_AstPrint, 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_AstPass, 4);
|
||||||
TEST_SIZEOF(Toy_AstError, 4);
|
TEST_SIZEOF(Toy_AstError, 4);
|
||||||
TEST_SIZEOF(Toy_AstEnd, 4);
|
TEST_SIZEOF(Toy_AstEnd, 4);
|
||||||
@@ -48,14 +49,15 @@ int test_sizeof_ast_32bit() {
|
|||||||
//run for each type
|
//run for each type
|
||||||
TEST_SIZEOF(Toy_AstType, 4);
|
TEST_SIZEOF(Toy_AstType, 4);
|
||||||
TEST_SIZEOF(Toy_AstBlock, 16);
|
TEST_SIZEOF(Toy_AstBlock, 16);
|
||||||
TEST_SIZEOF(Toy_AstVarDeclare, 12);
|
|
||||||
TEST_SIZEOF(Toy_AstValue, 12);
|
TEST_SIZEOF(Toy_AstValue, 12);
|
||||||
TEST_SIZEOF(Toy_AstUnary, 12);
|
TEST_SIZEOF(Toy_AstUnary, 12);
|
||||||
TEST_SIZEOF(Toy_AstBinary, 16);
|
TEST_SIZEOF(Toy_AstBinary, 16);
|
||||||
TEST_SIZEOF(Toy_AstVarAssign, 16);
|
|
||||||
TEST_SIZEOF(Toy_AstCompare, 16);
|
TEST_SIZEOF(Toy_AstCompare, 16);
|
||||||
TEST_SIZEOF(Toy_AstGroup, 8);
|
TEST_SIZEOF(Toy_AstGroup, 8);
|
||||||
TEST_SIZEOF(Toy_AstPrint, 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_AstPass, 4);
|
||||||
TEST_SIZEOF(Toy_AstError, 4);
|
TEST_SIZEOF(Toy_AstError, 4);
|
||||||
TEST_SIZEOF(Toy_AstEnd, 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
|
//emit compare
|
||||||
{
|
{
|
||||||
//build the AST
|
//build the AST
|
||||||
@@ -303,6 +279,55 @@ int test_type_emission(Toy_Bucket** bucketHandle) {
|
|||||||
Toy_freeString(name);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ var empty;
|
|||||||
//assign a previously existing variable
|
//assign a previously existing variable
|
||||||
answer = 6 * 9;
|
answer = 6 * 9;
|
||||||
|
|
||||||
|
answer = answer + 1;
|
||||||
|
|
||||||
/* TODO: implement compound assignments
|
|
||||||
answer += 5;
|
answer += 5;
|
||||||
|
|
||||||
answer -= 5;
|
answer -= 5;
|
||||||
@@ -19,4 +19,3 @@ answer /= 2;
|
|||||||
|
|
||||||
answer %= 10;
|
answer %= 10;
|
||||||
|
|
||||||
*/
|
|
||||||
|
|||||||
Reference in New Issue
Block a user