mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Fixed nested assignment bug
This commit is contained in:
@@ -267,7 +267,9 @@ static int writeLiteralToCompiler(Compiler* compiler, Literal literal) {
|
||||
return index;
|
||||
}
|
||||
|
||||
static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* breakAddressesPtr, void* continueAddressesPtr, int jumpOffsets) { //NOTE: jumpOfsets are included, because function arg and return indexes are embedded in the code body i.e. need to include thier sizes in the jump
|
||||
//NOTE: jumpOfsets are included, because function arg and return indexes are embedded in the code body i.e. need to include thier sizes in the jump
|
||||
//NODE: rootNode should NOT include groupings and blocks
|
||||
static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* breakAddressesPtr, void* continueAddressesPtr, int jumpOffsets, Node* rootNode) {
|
||||
//grow if the bytecode space is too small
|
||||
if (compiler->count + 32 > compiler->capacity) {
|
||||
int oldCapacity = compiler->capacity;
|
||||
@@ -291,7 +293,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
|
||||
case NODE_UNARY: {
|
||||
//pass to the child node, then embed the unary command (print, negate, etc.)
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->unary.child, breakAddressesPtr, continueAddressesPtr, jumpOffsets);
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->unary.child, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode);
|
||||
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
@@ -304,12 +306,12 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
//all infixes come here
|
||||
case NODE_BINARY: {
|
||||
//pass to the child nodes, then embed the binary command (math, etc.)
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->binary.left, breakAddressesPtr, continueAddressesPtr, jumpOffsets);
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->binary.left, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode);
|
||||
|
||||
//special case for when indexing and assigning
|
||||
if (override != OP_EOF && node->binary.opcode >= OP_VAR_ASSIGN && node->binary.opcode <= OP_VAR_MODULO_ASSIGN) {
|
||||
writeCompilerWithJumps(compiler, node->binary.right, breakAddressesPtr, continueAddressesPtr, jumpOffsets);
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override + 1; //1 byte WARNING: enum arithmetic
|
||||
writeCompilerWithJumps(compiler, node->binary.right, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode);
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)OP_INDEX_ASSIGN; //1 byte WARNING: enum trickery
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)node->binary.opcode; //1 byte
|
||||
return OP_EOF;
|
||||
}
|
||||
@@ -320,7 +322,11 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
}
|
||||
|
||||
//return this if...
|
||||
Opcode ret = writeCompilerWithJumps(compiler, node->binary.right, breakAddressesPtr, continueAddressesPtr, jumpOffsets);
|
||||
Opcode ret = writeCompilerWithJumps(compiler, node->binary.right, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode);
|
||||
|
||||
if (node->binary.opcode == OP_INDEX && rootNode->type == NODE_BINARY && rootNode->binary.opcode == OP_VAR_ASSIGN) { //why var assign?
|
||||
return OP_INDEX_ASSIGN_INTERMEDIATE;
|
||||
}
|
||||
|
||||
//loopy logic - if opcode == index or dot
|
||||
if (node->binary.opcode == OP_INDEX || node->binary.opcode == OP_DOT) {
|
||||
@@ -340,7 +346,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
|
||||
case NODE_GROUPING: {
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)OP_GROUPING_BEGIN; //1 byte
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->grouping.child, breakAddressesPtr, continueAddressesPtr, jumpOffsets);
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->grouping.child, breakAddressesPtr, continueAddressesPtr, jumpOffsets, node->grouping.child);
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
@@ -352,7 +358,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)OP_SCOPE_BEGIN; //1 byte
|
||||
|
||||
for (int i = 0; i < node->block.count; i++) {
|
||||
Opcode override = writeCompilerWithJumps(compiler, &(node->block.nodes[i]), breakAddressesPtr, continueAddressesPtr, jumpOffsets);
|
||||
Opcode override = writeCompilerWithJumps(compiler, &(node->block.nodes[i]), breakAddressesPtr, continueAddressesPtr, jumpOffsets, &(node->block.nodes[i]));
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
@@ -388,7 +394,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
|
||||
case NODE_VAR_DECL: {
|
||||
//first, embed the expression (leaves it on the stack)
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->varDecl.expression, breakAddressesPtr, continueAddressesPtr, jumpOffsets);
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->varDecl.expression, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode);
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
@@ -427,7 +433,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
initCompiler(fnCompiler);
|
||||
writeCompiler(fnCompiler, node->fnDecl.arguments); //can be empty, but not NULL
|
||||
writeCompiler(fnCompiler, node->fnDecl.returns); //can be empty, but not NULL
|
||||
Opcode override = writeCompilerWithJumps(fnCompiler, node->fnDecl.block, NULL, NULL, -4); //can be empty, but not NULL
|
||||
Opcode override = writeCompilerWithJumps(fnCompiler, node->fnDecl.block, NULL, NULL, -4, rootNode); //can be empty, but not NULL
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
@@ -480,7 +486,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
for (int i = 0; i < node->fnCall.arguments->fnCollection.count; i++) { //reverse order, to count from the beginning in the interpreter
|
||||
//sub-calls
|
||||
if (node->fnCall.arguments->fnCollection.nodes[i].type != NODE_LITERAL) {
|
||||
Opcode override = writeCompilerWithJumps(compiler, &node->fnCall.arguments->fnCollection.nodes[i], breakAddressesPtr, continueAddressesPtr, jumpOffsets);
|
||||
Opcode override = writeCompilerWithJumps(compiler, &node->fnCall.arguments->fnCollection.nodes[i], breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode);
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
@@ -536,7 +542,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
|
||||
case NODE_PATH_IF: {
|
||||
//process the condition
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->path.condition, breakAddressesPtr, continueAddressesPtr, jumpOffsets);
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->path.condition, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode);
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
@@ -547,7 +553,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
compiler->count += sizeof(unsigned short); //2 bytes
|
||||
|
||||
//write the then path
|
||||
override = writeCompilerWithJumps(compiler, node->path.thenPath, breakAddressesPtr, continueAddressesPtr, jumpOffsets);
|
||||
override = writeCompilerWithJumps(compiler, node->path.thenPath, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode);
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
@@ -566,7 +572,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
|
||||
if (node->path.elsePath) {
|
||||
//if there's an else path, write it and
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->path.elsePath, breakAddressesPtr, continueAddressesPtr, jumpOffsets);
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->path.elsePath, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode);
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
@@ -589,7 +595,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
unsigned short jumpToStart = compiler->count;
|
||||
|
||||
//process the condition
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->path.condition, &breakAddresses, &continueAddresses, jumpOffsets);
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->path.condition, &breakAddresses, &continueAddresses, jumpOffsets, rootNode);
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
@@ -600,7 +606,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
compiler->count += sizeof(unsigned short); //2 bytes
|
||||
|
||||
//write the body
|
||||
override = writeCompilerWithJumps(compiler, node->path.thenPath, &breakAddresses, &continueAddresses, jumpOffsets);
|
||||
override = writeCompilerWithJumps(compiler, node->path.thenPath, &breakAddresses, &continueAddresses, jumpOffsets, rootNode);
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
@@ -644,14 +650,14 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
compiler->bytecode[compiler->count++] = OP_SCOPE_BEGIN; //1 byte
|
||||
|
||||
//initial setup
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->path.preClause, &breakAddresses, &continueAddresses, jumpOffsets);
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->path.preClause, &breakAddresses, &continueAddresses, jumpOffsets, rootNode);
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
|
||||
//conditional
|
||||
unsigned short jumpToStart = compiler->count;
|
||||
override = writeCompilerWithJumps(compiler, node->path.condition, &breakAddresses, &continueAddresses, jumpOffsets);
|
||||
override = writeCompilerWithJumps(compiler, node->path.condition, &breakAddresses, &continueAddresses, jumpOffsets, rootNode);
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
@@ -663,7 +669,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
|
||||
//write the body
|
||||
compiler->bytecode[compiler->count++] = OP_SCOPE_BEGIN; //1 byte
|
||||
override = writeCompilerWithJumps(compiler, node->path.thenPath, &breakAddresses, &continueAddresses, jumpOffsets);
|
||||
override = writeCompilerWithJumps(compiler, node->path.thenPath, &breakAddresses, &continueAddresses, jumpOffsets, rootNode);
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
@@ -673,7 +679,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
int jumpToIncrement = compiler->count;
|
||||
|
||||
//evaluate third clause, restart
|
||||
override = writeCompilerWithJumps(compiler, node->path.postClause, &breakAddresses, &continueAddresses, jumpOffsets);
|
||||
override = writeCompilerWithJumps(compiler, node->path.postClause, &breakAddresses, &continueAddresses, jumpOffsets, rootNode);
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
@@ -745,7 +751,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
case NODE_PATH_RETURN: {
|
||||
//read each returned literal onto the stack, and return the number of values to return
|
||||
for (int i = 0; i < node->path.thenPath->fnCollection.count; i++) {
|
||||
Opcode override = writeCompilerWithJumps(compiler, &node->path.thenPath->fnCollection.nodes[i], breakAddressesPtr, continueAddressesPtr, jumpOffsets);
|
||||
Opcode override = writeCompilerWithJumps(compiler, &node->path.thenPath->fnCollection.nodes[i], breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode);
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
@@ -829,7 +835,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
writeLiteralToCompiler(compiler, TO_NULL_LITERAL);
|
||||
}
|
||||
else {
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->index.first, breakAddressesPtr, continueAddressesPtr, jumpOffsets);
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->index.first, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode);
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
@@ -840,7 +846,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
writeLiteralToCompiler(compiler, TO_NULL_LITERAL);
|
||||
}
|
||||
else {
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->index.second, breakAddressesPtr, continueAddressesPtr, jumpOffsets);
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->index.second, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode);
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
@@ -851,7 +857,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
writeLiteralToCompiler(compiler, TO_NULL_LITERAL);
|
||||
}
|
||||
else {
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->index.third, breakAddressesPtr, continueAddressesPtr, jumpOffsets);
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->index.third, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode);
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
@@ -874,7 +880,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
}
|
||||
|
||||
void writeCompiler(Compiler* compiler, Node* node) {
|
||||
Opcode op = writeCompilerWithJumps(compiler, node, NULL, NULL, 0);
|
||||
Opcode op = writeCompilerWithJumps(compiler, node, NULL, NULL, 0, node); //pass in "node" as the root node
|
||||
|
||||
if (op != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)op; //1 byte
|
||||
|
||||
@@ -1397,7 +1397,7 @@ static bool execExport(Interpreter* interpreter) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool execIndex(Interpreter* interpreter) {
|
||||
static bool execIndex(Interpreter* interpreter, bool assignIntermediate) {
|
||||
//assume -> compound, first, second, third are all on the stack
|
||||
|
||||
Literal third = popLiteralArray(&interpreter->stack);
|
||||
@@ -1405,26 +1405,19 @@ static bool execIndex(Interpreter* interpreter) {
|
||||
Literal first = popLiteralArray(&interpreter->stack);
|
||||
Literal compound = popLiteralArray(&interpreter->stack);
|
||||
|
||||
if (!IS_IDENTIFIER(compound)) {
|
||||
interpreter->errorOutput("Unknown literal found in indexing notation\n");
|
||||
printLiteralCustom(compound, interpreter->errorOutput);
|
||||
interpreter->errorOutput("\n");
|
||||
freeLiteral(third);
|
||||
freeLiteral(second);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
return false;
|
||||
}
|
||||
|
||||
Literal idn = compound;
|
||||
bool freeIdn = false;
|
||||
|
||||
if (!parseIdentifierToValue(interpreter, &compound)) {
|
||||
freeLiteral(third);
|
||||
freeLiteral(second);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
//freeLiteral(idn); //since compound is freed, idn is still pointing there
|
||||
return false;
|
||||
if (IS_IDENTIFIER(compound)) {
|
||||
freeIdn = true;
|
||||
if (!parseIdentifierToValue(interpreter, &compound)) {
|
||||
freeLiteral(third);
|
||||
freeLiteral(second);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
//freeLiteral(idn); //since compound is freed, idn is still pointing there
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!IS_ARRAY(compound) && !IS_DICTIONARY(compound) && !IS_STRING(compound)) {
|
||||
@@ -1433,7 +1426,9 @@ static bool execIndex(Interpreter* interpreter) {
|
||||
freeLiteral(second);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
if (freeIdn) {
|
||||
freeLiteral(idn);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1449,7 +1444,9 @@ static bool execIndex(Interpreter* interpreter) {
|
||||
freeLiteral(second);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
if (freeIdn) {
|
||||
freeLiteral(idn);
|
||||
}
|
||||
freeLiteral(func);
|
||||
freeLiteral(key);
|
||||
return false;
|
||||
@@ -1466,6 +1463,17 @@ static bool execIndex(Interpreter* interpreter) {
|
||||
pushLiteralArray(&arguments, TO_NULL_LITERAL); //it expects an assignment command
|
||||
pushLiteralArray(&arguments, TO_NULL_LITERAL); //it expects an assignment "opcode"
|
||||
|
||||
//leave the idn and compound on the stack
|
||||
if (assignIntermediate) {
|
||||
if (IS_IDENTIFIER(idn)) {
|
||||
pushLiteralArray(&interpreter->stack, idn);
|
||||
}
|
||||
pushLiteralArray(&interpreter->stack, compound);
|
||||
pushLiteralArray(&interpreter->stack, first);
|
||||
pushLiteralArray(&interpreter->stack, second);
|
||||
pushLiteralArray(&interpreter->stack, third);
|
||||
}
|
||||
|
||||
//call the function
|
||||
NativeFn fn = (NativeFn)AS_FUNCTION(func).bytecode;
|
||||
fn(interpreter, &arguments);
|
||||
@@ -1475,7 +1483,9 @@ static bool execIndex(Interpreter* interpreter) {
|
||||
freeLiteral(second);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
if (freeIdn) {
|
||||
freeLiteral(idn);
|
||||
}
|
||||
freeLiteral(func);
|
||||
freeLiteral(key);
|
||||
freeLiteralArray(&arguments);
|
||||
@@ -1492,28 +1502,20 @@ static bool execIndexAssign(Interpreter* interpreter) {
|
||||
Literal first = popLiteralArray(&interpreter->stack);
|
||||
Literal compound = popLiteralArray(&interpreter->stack);
|
||||
|
||||
if (!IS_IDENTIFIER(compound)) {
|
||||
interpreter->errorOutput("Unknown literal found in index assigning notation\n");
|
||||
printLiteralCustom(compound, interpreter->errorOutput);
|
||||
interpreter->errorOutput("\n");
|
||||
freeLiteral(assign);
|
||||
freeLiteral(third);
|
||||
freeLiteral(second);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
return false;
|
||||
}
|
||||
|
||||
Literal idn = compound;
|
||||
bool freeIdn = false;
|
||||
|
||||
if (!parseIdentifierToValue(interpreter, &compound)) {
|
||||
freeLiteral(assign);
|
||||
freeLiteral(third);
|
||||
freeLiteral(second);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
return false;
|
||||
if (IS_IDENTIFIER(compound)) {
|
||||
freeIdn = true;
|
||||
if (!parseIdentifierToValue(interpreter, &compound)) {
|
||||
freeLiteral(assign);
|
||||
freeLiteral(third);
|
||||
freeLiteral(second);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!IS_ARRAY(compound) && !IS_DICTIONARY(compound) && !IS_STRING(compound)) {
|
||||
@@ -1523,23 +1525,28 @@ static bool execIndexAssign(Interpreter* interpreter) {
|
||||
freeLiteral(second);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
if (freeIdn) {
|
||||
freeLiteral(idn);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//check const-ness of "first" within "compound"
|
||||
Literal type = getScopeType(interpreter->scope, idn);
|
||||
if ((AS_TYPE(type).typeOf == LITERAL_ARRAY && AS_TYPE(((Literal*)(AS_TYPE(type).subtypes))[0]).constant) || (AS_TYPE(type).typeOf == LITERAL_DICTIONARY && AS_TYPE(((Literal*)(AS_TYPE(type).subtypes))[1]).constant)) {
|
||||
interpreter->errorOutput("couldn't assign to constant within compound within index assigning notation\n");
|
||||
freeLiteral(assign);
|
||||
freeLiteral(third);
|
||||
freeLiteral(second);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
freeLiteral(type);
|
||||
return false;
|
||||
}
|
||||
//TODO: come back to this
|
||||
// //check const-ness of "first" within "compound"
|
||||
// Literal type = getScopeType(interpreter->scope, idn);
|
||||
// if ((AS_TYPE(type).typeOf == LITERAL_ARRAY && AS_TYPE(((Literal*)(AS_TYPE(type).subtypes))[0]).constant) || (AS_TYPE(type).typeOf == LITERAL_DICTIONARY && AS_TYPE(((Literal*)(AS_TYPE(type).subtypes))[1]).constant)) {
|
||||
// interpreter->errorOutput("couldn't assign to constant within compound within index assigning notation\n");
|
||||
// freeLiteral(assign);
|
||||
// freeLiteral(third);
|
||||
// freeLiteral(second);
|
||||
// freeLiteral(first);
|
||||
// freeLiteral(compound);
|
||||
// if (freeIdn) {
|
||||
// freeLiteral(idn);
|
||||
// }
|
||||
// freeLiteral(type);
|
||||
// return false;
|
||||
// }
|
||||
|
||||
//get the index function
|
||||
Literal func = TO_NULL_LITERAL;
|
||||
@@ -1554,8 +1561,10 @@ static bool execIndexAssign(Interpreter* interpreter) {
|
||||
freeLiteral(second);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
freeLiteral(type);
|
||||
if (freeIdn) {
|
||||
freeLiteral(idn);
|
||||
}
|
||||
// freeLiteral(type);
|
||||
freeLiteral(func);
|
||||
freeLiteral(key);
|
||||
return false;
|
||||
@@ -1591,8 +1600,10 @@ static bool execIndexAssign(Interpreter* interpreter) {
|
||||
freeLiteral(second);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
freeLiteral(type);
|
||||
if (freeIdn) {
|
||||
freeLiteral(idn);
|
||||
}
|
||||
// freeLiteral(type);
|
||||
freeLiteral(func);
|
||||
freeLiteral(key);
|
||||
return false;
|
||||
@@ -1618,7 +1629,49 @@ static bool execIndexAssign(Interpreter* interpreter) {
|
||||
|
||||
//save the result (assume top of the interpreter stack is the new compound value)
|
||||
Literal result = popLiteralArray(&interpreter->stack);
|
||||
if (!setScopeVariable(interpreter->scope, idn, result, true)) {//TODO: check this const-ness
|
||||
|
||||
//if idn is NOT an identifier, assign backwards while there are things on the stack (inner-compound assignment, BIG assumptions here)
|
||||
if (!IS_IDENTIFIER(idn)) {
|
||||
while (interpreter->stack.count > 1) {
|
||||
//read the new values
|
||||
freeLiteral(idn);
|
||||
freeLiteral(third);
|
||||
freeLiteral(second);
|
||||
freeLiteral(first);
|
||||
freeLiteralArray(&arguments);
|
||||
initLiteralArray(&arguments);
|
||||
freeLiteral(op);
|
||||
|
||||
third = popLiteralArray(&interpreter->stack);
|
||||
second = popLiteralArray(&interpreter->stack);
|
||||
first = popLiteralArray(&interpreter->stack);
|
||||
idn = popLiteralArray(&interpreter->stack);
|
||||
|
||||
char* opStr = "="; //shadow, but force assignment
|
||||
int opLength = strlen(opStr);
|
||||
op = TO_STRING_LITERAL(copyString(opStr, opLength), opLength);
|
||||
|
||||
//assign to the idn / compound - with _index
|
||||
pushLiteralArray(&arguments, idn);
|
||||
pushLiteralArray(&arguments, first);
|
||||
pushLiteralArray(&arguments, second);
|
||||
pushLiteralArray(&arguments, third);
|
||||
pushLiteralArray(&arguments, result);
|
||||
pushLiteralArray(&arguments, op);
|
||||
|
||||
fn(interpreter, &arguments);
|
||||
|
||||
freeLiteral(result);
|
||||
result = popLiteralArray(&interpreter->stack);
|
||||
}
|
||||
|
||||
freeLiteral(idn);
|
||||
idn = popLiteralArray(&interpreter->stack);
|
||||
compound = idn;
|
||||
// freeIdn = true;
|
||||
}
|
||||
|
||||
if (IS_IDENTIFIER(idn) && !setScopeVariable(interpreter->scope, idn, result, true)) {
|
||||
interpreter->errorOutput("Incorrect type assigned to compound member: ");
|
||||
printLiteralCustom(result, interpreter->errorOutput);
|
||||
interpreter->errorOutput("\n");
|
||||
@@ -1629,9 +1682,11 @@ static bool execIndexAssign(Interpreter* interpreter) {
|
||||
freeLiteral(second);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
if (freeIdn) {
|
||||
freeLiteral(idn);
|
||||
}
|
||||
freeLiteral(func);
|
||||
freeLiteral(type);
|
||||
// freeLiteral(type);
|
||||
freeLiteral(key);
|
||||
freeLiteral(op);
|
||||
freeLiteralArray(&arguments);
|
||||
@@ -1645,9 +1700,11 @@ static bool execIndexAssign(Interpreter* interpreter) {
|
||||
freeLiteral(second);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
if (freeIdn) {
|
||||
freeLiteral(idn);
|
||||
}
|
||||
freeLiteral(func);
|
||||
freeLiteral(type);
|
||||
// freeLiteral(type);
|
||||
freeLiteral(key);
|
||||
freeLiteral(op);
|
||||
freeLiteralArray(&arguments);
|
||||
@@ -1871,7 +1928,13 @@ static void execInterpreter(Interpreter* interpreter) {
|
||||
break;
|
||||
|
||||
case OP_INDEX:
|
||||
if (!execIndex(interpreter)) {
|
||||
if (!execIndex(interpreter, false)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_INDEX_ASSIGN_INTERMEDIATE:
|
||||
if (!execIndex(interpreter, true)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -51,6 +51,7 @@ typedef enum Opcode {
|
||||
//for indexing
|
||||
OP_INDEX,
|
||||
OP_INDEX_ASSIGN,
|
||||
OP_INDEX_ASSIGN_INTERMEDIATE,
|
||||
OP_DOT,
|
||||
|
||||
//comparison of values
|
||||
|
||||
Reference in New Issue
Block a user