diff --git a/repl/lib_compound.c b/repl/lib_compound.c index b65e594..a314c05 100644 --- a/repl/lib_compound.c +++ b/repl/lib_compound.c @@ -1448,11 +1448,8 @@ int Toy_hookCompound(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_L {"_getKeys", nativeGetKeys}, //dictionary {"_getValues", nativeGetValues}, //dictionary {"_indexOf", nativeIndexOf}, //array - // {"_insert", native}, //array, dictionary, string {"_map", nativeMap}, //array, dictionary {"_reduce", nativeReduce}, //array, dictionary - // {"_remove", native}, //array, dictionary - // {"_replace", native}, //string {"_some", nativeSome}, //array, dictionary // {"_sort", native}, //array {"_toLower", nativeToLower}, //string diff --git a/scripts/small.toy b/scripts/small.toy index 69e2c61..43428aa 100644 --- a/scripts/small.toy +++ b/scripts/small.toy @@ -1,10 +1,22 @@ +//polyfill the _insert function +fn _insert(self, k, v) { + var tmp1 = v; + var tmp2; + for (var i = k; i < self.length(); i++) { + tmp2 = self[i]; + self[i] = tmp1; + tmp1 = tmp2; + } -var xrel: int = 0; -var yrel: int = 0; - -if (xrel > 1 || xrel < -1 || yrel > 1 || yrel < -1) { - print "outside"; + self.push(tmp1); + return self; } -else { - print "inside"; -} \ No newline at end of file + +var a = [1, 2, 3]; + +a = a.insert(1, 42); + +assert a == [1, 5, 2, 3], "index assignment left failed"; + + +print "All good"; \ No newline at end of file diff --git a/source/toy_compiler.c b/source/toy_compiler.c index 7da1992..57088ba 100644 --- a/source/toy_compiler.c +++ b/source/toy_compiler.c @@ -302,6 +302,12 @@ static Toy_Opcode Toy_writeCompilerWithJumps(Toy_Compiler* compiler, Toy_ASTNode //special case for when indexing and assigning if (override != TOY_OP_EOF && node->binary.opcode >= TOY_OP_VAR_ASSIGN && node->binary.opcode <= TOY_OP_VAR_MODULO_ASSIGN) { Toy_writeCompilerWithJumps(compiler, node->binary.right, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); + + //Special case if there's an index on both sides of the sign, just set it as indexing + if (node->binary.left->type == TOY_AST_NODE_BINARY && node->binary.right->type == TOY_AST_NODE_BINARY && node->binary.left->binary.opcode == TOY_OP_INDEX && node->binary.right->binary.opcode == TOY_OP_INDEX) { + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_INDEX; + } + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_INDEX_ASSIGN; //1 byte WARNING: enum trickery compiler->bytecode[compiler->count++] = (unsigned char)node->binary.opcode; //1 byte return TOY_OP_EOF; @@ -315,7 +321,7 @@ static Toy_Opcode Toy_writeCompilerWithJumps(Toy_Compiler* compiler, Toy_ASTNode //return this if... Toy_Opcode ret = Toy_writeCompilerWithJumps(compiler, node->binary.right, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); - if (node->binary.opcode == TOY_OP_INDEX && rootNode->type == TOY_AST_NODE_BINARY && (rootNode->binary.opcode >= TOY_OP_VAR_ASSIGN && rootNode->binary.opcode <= TOY_OP_VAR_MODULO_ASSIGN)) { //range-based check for assignment type + if (node->binary.opcode == TOY_OP_INDEX && rootNode->type == TOY_AST_NODE_BINARY && (rootNode->binary.opcode >= TOY_OP_VAR_ASSIGN && rootNode->binary.opcode <= TOY_OP_VAR_MODULO_ASSIGN) && rootNode->binary.right != node) { //range-based check for assignment type; make sure the index is on the left of the assignment symbol return TOY_OP_INDEX_ASSIGN_INTERMEDIATE; } diff --git a/test/scripts/index-assignment-both-bugfix.toy b/test/scripts/index-assignment-both-bugfix.toy new file mode 100644 index 0000000..bf185cf --- /dev/null +++ b/test/scripts/index-assignment-both-bugfix.toy @@ -0,0 +1,15 @@ +/* + +This ensures that when indexing on both sides of an assignment, +it works correctly. + +*/ + +var a = [1, 2, 3]; +var b = [4, 5, 6]; + +a[1] = b[1]; + +assert a == [1, 5, 3], "index assignment both failed"; + +print "All good"; \ No newline at end of file diff --git a/test/scripts/index-assignment-left-bugfix.toy b/test/scripts/index-assignment-left-bugfix.toy new file mode 100644 index 0000000..8f105da --- /dev/null +++ b/test/scripts/index-assignment-left-bugfix.toy @@ -0,0 +1,19 @@ +/* + +Compiler note: +This is also to test a specific element in the compiler. +It ensures that when doing indexing and assignment in one statement, +the index is NOT on the right. If it is, then it is treated like a normal +assignment. + +*/ + +//polyfill the _insert function +var a = [1, 2, 3]; + +var b = a[1]; + +assert b == 2, "index assignment left failed"; + + +print "All good"; \ No newline at end of file diff --git a/test/scripts/lib/compound.toy b/test/scripts/lib/compound.toy index d0d9256..5d7b753 100644 --- a/test/scripts/lib/compound.toy +++ b/test/scripts/lib/compound.toy @@ -160,7 +160,8 @@ import compound; var a = [1, 2, 42, 3]; //results are zero-indexed - assert a.indexOf(42) == 2, "_indexOf failed"; + assert a.indexOf(42) == 2, "_indexOf() failed"; + assert a.indexOf(4) == null, "_indexOf() == null failed"; } diff --git a/test/scripts/polyfill-insert.toy b/test/scripts/polyfill-insert.toy new file mode 100644 index 0000000..9eca162 --- /dev/null +++ b/test/scripts/polyfill-insert.toy @@ -0,0 +1,22 @@ +//polyfill the _insert function +fn _insert(self, k, v) { + var tmp1 = v; + var tmp2; + for (var i = k; i < self.length(); i++) { + tmp2 = self[i]; + self[i] = tmp1; + tmp1 = tmp2; + } + + self.push(tmp1); + return self; +} + +var a = [1, 2, 3]; + +a = a.insert(1, 42); + +assert a == [1, 42, 2, 3], "polyfill insert failed"; + + +print "All good"; \ No newline at end of file diff --git a/test/scripts/polyfill-remove.toy b/test/scripts/polyfill-remove.toy new file mode 100644 index 0000000..3fcb2e0 --- /dev/null +++ b/test/scripts/polyfill-remove.toy @@ -0,0 +1,23 @@ +//polyfill the remove function +fn _remove(self, k) { + var result = []; + + for (var i = 0; i <= k - 1; i++) { + result.push( self[i] ); + } + + for (var i = k + 1; i < self.length(); i++) { + result.push( self[i] ); + } + + return result; +} + +var a = [1, 2, 3]; + +assert a.remove(0) == [2, 3], "polyfill remove(start) failed"; +assert a.remove(1) == [1, 3], "polyfill remove(middle) failed"; +assert a.remove(2) == [1, 2], "polyfill remove(end) failed"; + + +print "All good"; \ No newline at end of file diff --git a/test/test_interpreter.c b/test/test_interpreter.c index 1c15c86..3de9107 100644 --- a/test/test_interpreter.c +++ b/test/test_interpreter.c @@ -117,6 +117,8 @@ int main() { "dottify-bugfix.toy", "functions.toy", "index-arrays.toy", + "index-assignment-both-bugfix.toy", + "index-assignment-left-bugfix.toy", "index-dictionaries.toy", "index-strings.toy", "jumps.toy", @@ -128,6 +130,8 @@ int main() { "native-functions.toy", "or-chaining-bugfix.toy", "panic-within-functions.toy", + "polyfill-insert.toy", + "polyfill-remove.toy", "ternary-expressions.toy", "types.toy", NULL