From 386201b6e9738476f3b3799e132f40dd4f8aac2c Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 4 Feb 2023 16:54:59 +0000 Subject: [PATCH] Added fib-memo.toy, fixed bugs until it worked --- scripts/fib-memo.toy | 21 +++ scripts/small.toy | 8 +- source/toy_compiler.c | 35 +++- source/toy_interpreter.c | 257 ++++++++++++---------------- source/toy_literal.c | 19 +- source/toy_literal.h | 1 + test/scripts/index-dictionaries.toy | 8 +- 7 files changed, 189 insertions(+), 160 deletions(-) create mode 100644 scripts/fib-memo.toy diff --git a/scripts/fib-memo.toy b/scripts/fib-memo.toy new file mode 100644 index 0000000..5749eed --- /dev/null +++ b/scripts/fib-memo.toy @@ -0,0 +1,21 @@ +//memoize the fib function +var memo: [int : int] = [:]; + +fn fib(n : int) { + if (n < 2) { + return n; + } + + var result = memo[n]; + if (result == null) { + result = fib(n-1) + fib(n-2); + memo[n] = result; + } + + return result; +} + +for (var i = 0; i < 40; i++) { + var res = fib(i); + print string i + ": " + string res; +} \ No newline at end of file diff --git a/scripts/small.toy b/scripts/small.toy index 9b3cd5b..39d1e7f 100644 --- a/scripts/small.toy +++ b/scripts/small.toy @@ -1,3 +1,9 @@ -print " foo \n bar"; \ No newline at end of file +var d = ["foo" : ["bar" : ["bazz": ["fizz" : 5]]]]; + +print d; + +d["foo"]["bar"]["bazz"]["fizz"] = 66; + +print d; \ No newline at end of file diff --git a/source/toy_compiler.c b/source/toy_compiler.c index 93bc1c6..0f5520e 100644 --- a/source/toy_compiler.c +++ b/source/toy_compiler.c @@ -129,7 +129,7 @@ static int writeNodeCompoundToCache(Toy_Compiler* compiler, Toy_ASTNode* node) { //push the store to the cache, with instructions about how pack it Toy_Literal literal = TOY_TO_DICTIONARY_LITERAL(store); - literal.type = TOY_LITERAL_DICTIONARY_INTERMEDIATE; //god damn it + literal.type = TOY_LITERAL_DICTIONARY_INTERMEDIATE; //god damn it - nested in a dictionary index = Toy_pushLiteralArray(&compiler->literalCache, literal); Toy_freeLiteral(literal); } @@ -167,6 +167,7 @@ static int writeNodeCompoundToCache(Toy_Compiler* compiler, Toy_ASTNode* node) { //push the store to the cache, with instructions about how pack it Toy_Literal literal = TOY_TO_ARRAY_LITERAL(store); + literal.type = TOY_LITERAL_ARRAY_INTERMEDIATE; //god damn it - nested in an array index = Toy_pushLiteralArray(&compiler->literalCache, literal); Toy_freeLiteral(literal); } @@ -1095,7 +1096,22 @@ static unsigned char* collateCompilerHeaderOpt(Toy_Compiler* compiler, int* size } break; - case TOY_LITERAL_DICTIONARY_INTERMEDIATE: { + case TOY_LITERAL_ARRAY_INTERMEDIATE: { + emitByte(&collation, &capacity, &count, TOY_LITERAL_ARRAY_INTERMEDIATE); + + Toy_LiteralArray* ptr = TOY_AS_ARRAY(compiler->literalCache.literals[i]); + + //length of the array, as a short + Toy_emitShort(&collation, &capacity, &count, ptr->count); + + //each element of the array + for (int i = 0; i < ptr->count; i++) { + Toy_emitShort(&collation, &capacity, &count, (unsigned short)TOY_AS_INTEGER(ptr->literals[i])); //shorts representing the indexes of the values + } + } + break; + + case TOY_LITERAL_DICTIONARY: { emitByte(&collation, &capacity, &count, TOY_LITERAL_DICTIONARY); Toy_LiteralArray* ptr = TOY_AS_ARRAY(compiler->literalCache.literals[i]); //used an array for storage above @@ -1110,6 +1126,21 @@ static unsigned char* collateCompilerHeaderOpt(Toy_Compiler* compiler, int* size } break; + case TOY_LITERAL_DICTIONARY_INTERMEDIATE: { + emitByte(&collation, &capacity, &count, TOY_LITERAL_DICTIONARY_INTERMEDIATE); + + Toy_LiteralArray* ptr = TOY_AS_ARRAY(compiler->literalCache.literals[i]); //used an array for storage above + + //length of the array, as a short + Toy_emitShort(&collation, &capacity, &count, ptr->count); //count is the array size, NOT the dictionary size + + //each element of the array + for (int i = 0; i < ptr->count; i++) { + Toy_emitShort(&collation, &capacity, &count, (unsigned short)TOY_AS_INTEGER(ptr->literals[i])); //shorts representing the indexes of the values + } + } + break; + case TOY_LITERAL_FUNCTION_INTERMEDIATE: { //extract the compiler Toy_Literal fn = compiler->literalCache.literals[i]; diff --git a/source/toy_interpreter.c b/source/toy_interpreter.c index b52d564..7b96768 100644 --- a/source/toy_interpreter.c +++ b/source/toy_interpreter.c @@ -259,11 +259,8 @@ static bool execPrint(Toy_Interpreter* interpreter) { //print what is on top of the stack, then pop it Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); - if (TOY_IS_IDENTIFIER(lit)) { - Toy_Literal idn = lit; - if (!Toy_parseIdentifierToValue(interpreter, &lit)) { - return false; - } + Toy_Literal idn = lit; + if (TOY_IS_IDENTIFIER(lit) && Toy_parseIdentifierToValue(interpreter, &lit)) { Toy_freeLiteral(idn); } @@ -294,16 +291,12 @@ static bool execPushLiteral(Toy_Interpreter* interpreter, bool lng) { static bool rawLiteral(Toy_Interpreter* interpreter) { Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); - if (TOY_IS_IDENTIFIER(lit)) { - Toy_Literal idn = lit; - if (!Toy_parseIdentifierToValue(interpreter, &lit)) { - return false; - } + Toy_Literal idn = lit; + if (TOY_IS_IDENTIFIER(lit) && Toy_parseIdentifierToValue(interpreter, &lit)) { Toy_freeLiteral(idn); } Toy_pushLiteralArray(&interpreter->stack, lit); - Toy_freeLiteral(lit); return true; @@ -313,11 +306,8 @@ static bool execNegate(Toy_Interpreter* interpreter) { //negate the top literal on the stack (numbers only) Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); - if (TOY_IS_IDENTIFIER(lit)) { - Toy_Literal idn = lit; - if (!Toy_parseIdentifierToValue(interpreter, &lit)) { - return false; - } + Toy_Literal idn = lit; + if (TOY_IS_IDENTIFIER(lit) && Toy_parseIdentifierToValue(interpreter, &lit)) { Toy_freeLiteral(idn); } @@ -338,7 +328,6 @@ static bool execNegate(Toy_Interpreter* interpreter) { } Toy_pushLiteralArray(&interpreter->stack, lit); - Toy_freeLiteral(lit); return true; @@ -348,11 +337,8 @@ static bool execInvert(Toy_Interpreter* interpreter) { //negate the top literal on the stack (booleans only) Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); - if (TOY_IS_IDENTIFIER(lit)) { - Toy_Literal idn = lit; - if (!Toy_parseIdentifierToValue(interpreter, &lit)) { - return false; - } + Toy_Literal idn = lit; + if (TOY_IS_IDENTIFIER(lit) && Toy_parseIdentifierToValue(interpreter, &lit)) { Toy_freeLiteral(idn); } @@ -370,7 +356,6 @@ static bool execInvert(Toy_Interpreter* interpreter) { } Toy_pushLiteralArray(&interpreter->stack, lit); - Toy_freeLiteral(lit); return true; @@ -380,16 +365,14 @@ static bool execArithmetic(Toy_Interpreter* interpreter, Toy_Opcode opcode) { Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack); Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); - if (TOY_IS_IDENTIFIER(rhs)) { - Toy_Literal idn = rhs; - Toy_parseIdentifierToValue(interpreter, &rhs); - Toy_freeLiteral(idn); + Toy_Literal rhsIdn = rhs; + if (TOY_IS_IDENTIFIER(rhs) && Toy_parseIdentifierToValue(interpreter, &rhs)) { + Toy_freeLiteral(rhsIdn); } - if (TOY_IS_IDENTIFIER(lhs)) { - Toy_Literal idn = lhs; - Toy_parseIdentifierToValue(interpreter, &lhs); - Toy_freeLiteral(idn); + Toy_Literal lhsIdn = lhs; + if (TOY_IS_IDENTIFIER(lhs) && Toy_parseIdentifierToValue(interpreter, &lhs)) { + Toy_freeLiteral(lhsIdn); } //special case for string concatenation ONLY @@ -519,10 +502,9 @@ static bool execArithmetic(Toy_Interpreter* interpreter, Toy_Opcode opcode) { static Toy_Literal parseTypeToValue(Toy_Interpreter* interpreter, Toy_Literal type) { //if an identifier is embedded in the type, figure out what it iss - if (TOY_IS_IDENTIFIER(type)) { - Toy_Literal idn = type; - Toy_parseIdentifierToValue(interpreter, &type); - Toy_freeLiteral(idn); + Toy_Literal typeIdn = type; + if (TOY_IS_IDENTIFIER(type) && Toy_parseIdentifierToValue(interpreter, &type)) { + Toy_freeLiteral(typeIdn); } //if this is an array or dictionary, continue to the subtypes @@ -560,10 +542,9 @@ static bool execVarDecl(Toy_Interpreter* interpreter, bool lng) { Toy_Literal identifier = interpreter->literalCache.literals[identifierIndex]; Toy_Literal type = Toy_copyLiteral(interpreter->literalCache.literals[typeIndex]); - if (TOY_IS_IDENTIFIER(type)) { - Toy_Literal orig = type; - Toy_parseIdentifierToValue(interpreter, &type); - Toy_freeLiteral(orig); + Toy_Literal typeIdn = type; + if (TOY_IS_IDENTIFIER(type) && Toy_parseIdentifierToValue(interpreter, &type)) { + Toy_freeLiteral(typeIdn); } //BUGFIX: because identifiers are getting embedded in type definitions @@ -578,10 +559,9 @@ static bool execVarDecl(Toy_Interpreter* interpreter, bool lng) { Toy_Literal val = Toy_popLiteralArray(&interpreter->stack); - if (TOY_IS_IDENTIFIER(val)) { - Toy_Literal idn = val; - Toy_parseIdentifierToValue(interpreter, &val); - Toy_freeLiteral(idn); + Toy_Literal valIdn = val; + if (TOY_IS_IDENTIFIER(val) && Toy_parseIdentifierToValue(interpreter, &val)) { + Toy_freeLiteral(valIdn); } if (TOY_IS_ARRAY(val) || TOY_IS_DICTIONARY(val)) { @@ -659,10 +639,9 @@ static bool execVarAssign(Toy_Interpreter* interpreter) { Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack); Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); - if (TOY_IS_IDENTIFIER(rhs)) { - Toy_Literal idn = rhs; - Toy_parseIdentifierToValue(interpreter, &rhs); - Toy_freeLiteral(idn); + Toy_Literal rhsIdn = rhs; + if (TOY_IS_IDENTIFIER(rhs) && Toy_parseIdentifierToValue(interpreter, &rhs)) { + Toy_freeLiteral(rhsIdn); } if (TOY_IS_ARRAY(rhs) || TOY_IS_DICTIONARY(rhs)) { @@ -729,12 +708,9 @@ static bool execValCast(Toy_Interpreter* interpreter) { Toy_Literal value = Toy_popLiteralArray(&interpreter->stack); Toy_Literal type = Toy_popLiteralArray(&interpreter->stack); - if (TOY_IS_IDENTIFIER(value)) { - Toy_Literal idn = value; - if (!Toy_parseIdentifierToValue(interpreter, &value)) { - return false; - } - Toy_freeLiteral(idn); + Toy_Literal valueIdn = value; + if (TOY_IS_IDENTIFIER(value) && Toy_parseIdentifierToValue(interpreter, &value)) { + Toy_freeLiteral(valueIdn); } Toy_Literal result = TOY_TO_NULL_LITERAL; @@ -861,16 +837,14 @@ static bool execCompareEqual(Toy_Interpreter* interpreter, bool invert) { Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack); Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); - if (TOY_IS_IDENTIFIER(rhs)) { - Toy_Literal idn = rhs; - Toy_parseIdentifierToValue(interpreter, &rhs); - Toy_freeLiteral(idn); + Toy_Literal rhsIdn = rhs; + if (TOY_IS_IDENTIFIER(rhs) && Toy_parseIdentifierToValue(interpreter, &rhs)) { + Toy_freeLiteral(rhsIdn); } - if (TOY_IS_IDENTIFIER(lhs)) { - Toy_Literal idn = lhs; - Toy_parseIdentifierToValue(interpreter, &lhs); - Toy_freeLiteral(idn); + Toy_Literal lhsIdn = lhs; + if (TOY_IS_IDENTIFIER(lhs) && Toy_parseIdentifierToValue(interpreter, &lhs)) { + Toy_freeLiteral(lhsIdn); } bool result = Toy_literalsAreEqual(lhs, rhs); @@ -891,16 +865,14 @@ static bool execCompareLess(Toy_Interpreter* interpreter, bool invert) { Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack); Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); - if (TOY_IS_IDENTIFIER(rhs)) { - Toy_Literal idn = rhs; - Toy_parseIdentifierToValue(interpreter, &rhs); - Toy_freeLiteral(idn); + Toy_Literal rhsIdn = rhs; + if (TOY_IS_IDENTIFIER(rhs) && Toy_parseIdentifierToValue(interpreter, &rhs)) { + Toy_freeLiteral(rhsIdn); } - if (TOY_IS_IDENTIFIER(lhs)) { - Toy_Literal idn = lhs; - Toy_parseIdentifierToValue(interpreter, &lhs); - Toy_freeLiteral(idn); + Toy_Literal lhsIdn = lhs; + if (TOY_IS_IDENTIFIER(lhs) && Toy_parseIdentifierToValue(interpreter, &lhs)) { + Toy_freeLiteral(lhsIdn); } //not a number, return falure @@ -953,16 +925,14 @@ static bool execCompareLessEqual(Toy_Interpreter* interpreter, bool invert) { Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack); Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); - if (TOY_IS_IDENTIFIER(rhs)) { - Toy_Literal idn = rhs; - Toy_parseIdentifierToValue(interpreter, &rhs); - Toy_freeLiteral(idn); + Toy_Literal rhsIdn = rhs; + if (TOY_IS_IDENTIFIER(rhs) && Toy_parseIdentifierToValue(interpreter, &rhs)) { + Toy_freeLiteral(rhsIdn); } - if (TOY_IS_IDENTIFIER(lhs)) { - Toy_Literal idn = lhs; - Toy_parseIdentifierToValue(interpreter, &lhs); - Toy_freeLiteral(idn); + Toy_Literal lhsIdn = lhs; + if (TOY_IS_IDENTIFIER(lhs) && Toy_parseIdentifierToValue(interpreter, &lhs)) { + Toy_freeLiteral(lhsIdn); } //not a number, return falure @@ -1016,16 +986,14 @@ static bool execAnd(Toy_Interpreter* interpreter) { Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack); Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); - if (TOY_IS_IDENTIFIER(rhs)) { - Toy_Literal idn = rhs; - Toy_parseIdentifierToValue(interpreter, &rhs); - Toy_freeLiteral(idn); + Toy_Literal rhsIdn = rhs; + if (TOY_IS_IDENTIFIER(rhs) && Toy_parseIdentifierToValue(interpreter, &rhs)) { + Toy_freeLiteral(rhsIdn); } - if (TOY_IS_IDENTIFIER(lhs)) { - Toy_Literal idn = lhs; - Toy_parseIdentifierToValue(interpreter, &lhs); - Toy_freeLiteral(idn); + Toy_Literal lhsIdn = lhs; + if (TOY_IS_IDENTIFIER(lhs) && Toy_parseIdentifierToValue(interpreter, &lhs)) { + Toy_freeLiteral(lhsIdn); } if (TOY_IS_TRUTHY(lhs) && TOY_IS_TRUTHY(rhs)) { @@ -1045,16 +1013,14 @@ static bool execOr(Toy_Interpreter* interpreter) { Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack); Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); - if (TOY_IS_IDENTIFIER(rhs)) { - Toy_Literal idn = rhs; - Toy_parseIdentifierToValue(interpreter, &rhs); - Toy_freeLiteral(idn); + Toy_Literal rhsIdn = rhs; + if (TOY_IS_IDENTIFIER(rhs) && Toy_parseIdentifierToValue(interpreter, &rhs)) { + Toy_freeLiteral(rhsIdn); } - if (TOY_IS_IDENTIFIER(lhs)) { - Toy_Literal idn = lhs; - Toy_parseIdentifierToValue(interpreter, &lhs); - Toy_freeLiteral(idn); + Toy_Literal lhsIdn = lhs; + if (TOY_IS_IDENTIFIER(lhs) && Toy_parseIdentifierToValue(interpreter, &lhs)) { + Toy_freeLiteral(lhsIdn); } if (TOY_IS_TRUTHY(lhs) || TOY_IS_TRUTHY(rhs)) { @@ -1287,10 +1253,9 @@ bool Toy_callLiteralFn(Toy_Interpreter* interpreter, Toy_Literal func, Toy_Liter Toy_Literal arg = Toy_popLiteralArray(arguments); - if (TOY_IS_IDENTIFIER(arg)) { - Toy_Literal idn = arg; - Toy_parseIdentifierToValue(interpreter, &arg); - Toy_freeLiteral(idn); + Toy_Literal argIdn = arg; + if (TOY_IS_IDENTIFIER(arg) && Toy_parseIdentifierToValue(interpreter, &arg)) { + Toy_freeLiteral(argIdn); } if (!Toy_setScopeVariable(inner.scope, paramArray->literals[i], arg, false)) { @@ -1451,10 +1416,10 @@ static bool execFnReturn(Toy_Interpreter* interpreter) { //get the values of everything on the stack while (interpreter->stack.count > 0) { Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); - if (TOY_IS_IDENTIFIER(lit)) { - Toy_Literal idn = lit; - Toy_parseIdentifierToValue(interpreter, &lit); - Toy_freeLiteral(idn); + + Toy_Literal litIdn = lit; + if (TOY_IS_IDENTIFIER(lit) && Toy_parseIdentifierToValue(interpreter, &lit)) { + Toy_freeLiteral(litIdn); } if (TOY_IS_ARRAY(lit) || TOY_IS_DICTIONARY(lit)) { @@ -1522,19 +1487,10 @@ static bool execIndex(Toy_Interpreter* interpreter, bool assignIntermediate) { Toy_Literal first = Toy_popLiteralArray(&interpreter->stack); Toy_Literal compound = Toy_popLiteralArray(&interpreter->stack); - Toy_Literal idn = compound; + Toy_Literal compoundIdn = compound; bool freeIdn = false; - - if (TOY_IS_IDENTIFIER(compound)) { + if (TOY_IS_IDENTIFIER(compound) && Toy_parseIdentifierToValue(interpreter, &compound)) { freeIdn = true; - if (!Toy_parseIdentifierToValue(interpreter, &compound)) { - Toy_freeLiteral(third); - Toy_freeLiteral(second); - Toy_freeLiteral(first); - Toy_freeLiteral(compound); - //freeLiteral(idn); //since compound is freed, idn is still pointing there - return false; - } } if (!TOY_IS_ARRAY(compound) && !TOY_IS_DICTIONARY(compound) && !TOY_IS_STRING(compound)) { @@ -1544,9 +1500,11 @@ static bool execIndex(Toy_Interpreter* interpreter, bool assignIntermediate) { Toy_freeLiteral(second); Toy_freeLiteral(first); Toy_freeLiteral(compound); + if (freeIdn) { - Toy_freeLiteral(idn); + Toy_freeLiteral(compoundIdn); } + return false; } @@ -1563,8 +1521,8 @@ static bool execIndex(Toy_Interpreter* interpreter, bool assignIntermediate) { //leave the idn and compound on the stack if (assignIntermediate) { - if (TOY_IS_IDENTIFIER(idn)) { - Toy_pushLiteralArray(&interpreter->stack, idn); + if (TOY_IS_IDENTIFIER(compoundIdn)) { + Toy_pushLiteralArray(&interpreter->stack, compoundIdn); } Toy_pushLiteralArray(&interpreter->stack, compound); Toy_pushLiteralArray(&interpreter->stack, first); @@ -1574,8 +1532,8 @@ static bool execIndex(Toy_Interpreter* interpreter, bool assignIntermediate) { //call the _index function if (Toy_private_index(interpreter, &arguments) < 0) { - interpreter->errorOutput("Something went wrong while indexing: "); - Toy_printLiteralCustom(idn, interpreter->errorOutput); + interpreter->errorOutput("Something went wrong while indexing (simple index): "); + Toy_printLiteralCustom(compoundIdn, interpreter->errorOutput); interpreter->errorOutput("\n"); //clean up @@ -1584,7 +1542,7 @@ static bool execIndex(Toy_Interpreter* interpreter, bool assignIntermediate) { Toy_freeLiteral(first); Toy_freeLiteral(compound); if (freeIdn) { - Toy_freeLiteral(idn); + Toy_freeLiteral(compoundIdn); } Toy_freeLiteralArray(&arguments); return false; @@ -1596,7 +1554,7 @@ static bool execIndex(Toy_Interpreter* interpreter, bool assignIntermediate) { Toy_freeLiteral(first); Toy_freeLiteral(compound); if (freeIdn) { - Toy_freeLiteral(idn); + Toy_freeLiteral(compoundIdn); } Toy_freeLiteralArray(&arguments); @@ -1612,20 +1570,15 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) { Toy_Literal first = Toy_popLiteralArray(&interpreter->stack); Toy_Literal compound = Toy_popLiteralArray(&interpreter->stack); - Toy_Literal idn = compound; - bool freeIdn = false; + Toy_Literal assignIdn = assign; + if (TOY_IS_IDENTIFIER(assign) && Toy_parseIdentifierToValue(interpreter, &assign)) { + Toy_freeLiteral(assignIdn); + } - if (TOY_IS_IDENTIFIER(compound)) { + Toy_Literal compoundIdn = compound; + bool freeIdn = false; + if (TOY_IS_IDENTIFIER(compound) && Toy_parseIdentifierToValue(interpreter, &compound)) { freeIdn = true; - if (!Toy_parseIdentifierToValue(interpreter, &compound)) { - Toy_freeLiteral(assign); - Toy_freeLiteral(third); - Toy_freeLiteral(second); - Toy_freeLiteral(first); - Toy_freeLiteral(compound); - Toy_freeLiteral(idn); - return false; - } } if (!TOY_IS_ARRAY(compound) && !TOY_IS_DICTIONARY(compound) && !TOY_IS_STRING(compound)) { @@ -1636,7 +1589,7 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) { Toy_freeLiteral(first); Toy_freeLiteral(compound); if (freeIdn) { - Toy_freeLiteral(idn); + Toy_freeLiteral(compoundIdn); } return false; } @@ -1672,7 +1625,7 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) { Toy_freeLiteral(first); Toy_freeLiteral(compound); if (freeIdn) { - Toy_freeLiteral(idn); + Toy_freeLiteral(compoundIdn); } return false; } @@ -1700,7 +1653,7 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) { Toy_freeLiteral(first); Toy_freeLiteral(compound); if (freeIdn) { - Toy_freeLiteral(idn); + Toy_freeLiteral(compoundIdn); } Toy_freeLiteral(op); Toy_freeLiteralArray(&arguments); @@ -1711,11 +1664,11 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) { //save the result (assume top of the interpreter stack is the new compound value) Toy_Literal result = Toy_popLiteralArray(&interpreter->stack); - //if idn is NOT an identifier, assign backwards while there are things on the stack (inner-compound assignment, BIG assumptions here) - if (!TOY_IS_IDENTIFIER(idn)) { + //deep + if (!freeIdn) { while (interpreter->stack.count > 1) { //read the new values - Toy_freeLiteral(idn); + Toy_freeLiteral(compound); Toy_freeLiteral(third); Toy_freeLiteral(second); Toy_freeLiteral(first); @@ -1723,17 +1676,18 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) { Toy_initLiteralArray(&arguments); Toy_freeLiteral(op); + //reuse these like an idiot third = Toy_popLiteralArray(&interpreter->stack); second = Toy_popLiteralArray(&interpreter->stack); first = Toy_popLiteralArray(&interpreter->stack); - idn = Toy_popLiteralArray(&interpreter->stack); + compound = Toy_popLiteralArray(&interpreter->stack); char* opStr = "="; //shadow, but force assignment int opLength = strlen(opStr); op = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(opStr, opLength)); //TODO: static reference optimisation? //assign to the idn / compound - with _index - Toy_pushLiteralArray(&arguments, idn); + Toy_pushLiteralArray(&arguments, compound); // Toy_pushLiteralArray(&arguments, first); Toy_pushLiteralArray(&arguments, second); Toy_pushLiteralArray(&arguments, third); @@ -1741,8 +1695,8 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) { Toy_pushLiteralArray(&arguments, op); if (Toy_private_index(interpreter, &arguments) < 0) { - interpreter->errorOutput("Something went wrong while indexing: "); - Toy_printLiteralCustom(idn, interpreter->errorOutput); + interpreter->errorOutput("Something went wrong while indexing (index assign): "); + Toy_printLiteralCustom(compound, interpreter->errorOutput); interpreter->errorOutput("\n"); //clean up @@ -1750,13 +1704,11 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) { Toy_freeLiteral(third); Toy_freeLiteral(second); Toy_freeLiteral(first); - Toy_freeLiteral(compound); if (freeIdn) { - Toy_freeLiteral(idn); + Toy_freeLiteral(compoundIdn); } Toy_freeLiteral(op); Toy_freeLiteralArray(&arguments); - Toy_freeLiteral(result); return false; } @@ -1764,14 +1716,15 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) { result = Toy_popLiteralArray(&interpreter->stack); } - Toy_freeLiteral(idn); - idn = Toy_popLiteralArray(&interpreter->stack); - compound = idn; + Toy_freeLiteral(compound); + compound = Toy_popLiteralArray(&interpreter->stack); + compoundIdn = compound; + freeIdn = false; } - if (TOY_IS_IDENTIFIER(idn) && !Toy_setScopeVariable(interpreter->scope, idn, result, true)) { + if (TOY_IS_IDENTIFIER(compoundIdn) && !Toy_setScopeVariable(interpreter->scope, compoundIdn, result, true)) { interpreter->errorOutput("Incorrect type assigned to compound member "); - Toy_printLiteralCustom(idn, interpreter->errorOutput); + Toy_printLiteralCustom(compoundIdn, interpreter->errorOutput); interpreter->errorOutput("\n"); //clean up @@ -1781,7 +1734,7 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) { Toy_freeLiteral(first); Toy_freeLiteral(compound); if (freeIdn) { - Toy_freeLiteral(idn); + Toy_freeLiteral(compoundIdn); } Toy_freeLiteral(op); Toy_freeLiteralArray(&arguments); @@ -1796,7 +1749,7 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) { Toy_freeLiteral(first); Toy_freeLiteral(compound); if (freeIdn) { - Toy_freeLiteral(idn); + Toy_freeLiteral(compoundIdn); } Toy_freeLiteral(op); Toy_freeLiteralArray(&arguments); @@ -2128,6 +2081,7 @@ static void readInterpreterSections(Toy_Interpreter* interpreter) { } break; + case TOY_LITERAL_ARRAY_INTERMEDIATE: case TOY_LITERAL_ARRAY: { Toy_LiteralArray* array = TOY_ALLOCATE(Toy_LiteralArray, 1); Toy_initLiteralArray(array); @@ -2158,6 +2112,7 @@ static void readInterpreterSections(Toy_Interpreter* interpreter) { } break; + case TOY_LITERAL_DICTIONARY_INTERMEDIATE: case TOY_LITERAL_DICTIONARY: { Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1); Toy_initLiteralDictionary(dictionary); diff --git a/source/toy_literal.c b/source/toy_literal.c index 44f4a51..2d129c4 100644 --- a/source/toy_literal.c +++ b/source/toy_literal.c @@ -42,7 +42,7 @@ void Toy_freeLiteral(Toy_Literal literal) { } //compounds - if (TOY_IS_ARRAY(literal) || literal.type == TOY_LITERAL_DICTIONARY_INTERMEDIATE || literal.type == TOY_LITERAL_TYPE_INTERMEDIATE) { + if (TOY_IS_ARRAY(literal) || literal.type == TOY_LITERAL_ARRAY_INTERMEDIATE || literal.type == TOY_LITERAL_DICTIONARY_INTERMEDIATE || literal.type == TOY_LITERAL_TYPE_INTERMEDIATE) { Toy_freeLiteralArray(TOY_AS_ARRAY(literal)); TOY_FREE(Toy_LiteralArray, TOY_AS_ARRAY(literal)); return; @@ -172,6 +172,22 @@ Toy_Literal Toy_copyLiteral(Toy_Literal original) { return original; //literally a shallow copy } + case TOY_LITERAL_ARRAY_INTERMEDIATE: { + Toy_LiteralArray* array = TOY_ALLOCATE(Toy_LiteralArray, 1); + Toy_initLiteralArray(array); + + //copy each element + for (int i = 0; i < TOY_AS_ARRAY(original)->count; i++) { + Toy_Literal literal = Toy_copyLiteral(TOY_AS_ARRAY(original)->literals[i]); + Toy_pushLiteralArray(array, literal); + Toy_freeLiteral(literal); + } + + Toy_Literal ret = TOY_TO_ARRAY_LITERAL(array); + ret.type = TOY_LITERAL_ARRAY_INTERMEDIATE; + return ret; + } + case TOY_LITERAL_DICTIONARY_INTERMEDIATE: { Toy_LiteralArray* array = TOY_ALLOCATE(Toy_LiteralArray, 1); Toy_initLiteralArray(array); @@ -250,6 +266,7 @@ bool Toy_literalsAreEqual(Toy_Literal lhs, Toy_Literal rhs) { return Toy_equalsRefString(TOY_AS_STRING(lhs), TOY_AS_STRING(rhs)); case TOY_LITERAL_ARRAY: + case TOY_LITERAL_ARRAY_INTERMEDIATE: case TOY_LITERAL_DICTIONARY_INTERMEDIATE: //BUGFIX case TOY_LITERAL_TYPE_INTERMEDIATE: //BUGFIX: used for storing types as an array //mismatched sizes diff --git a/source/toy_literal.h b/source/toy_literal.h index 072bd5f..2f6c516 100644 --- a/source/toy_literal.h +++ b/source/toy_literal.h @@ -29,6 +29,7 @@ typedef enum { //these are meta-level types - not for general use TOY_LITERAL_TYPE_INTERMEDIATE, //used to process types in the compiler only + TOY_LITERAL_ARRAY_INTERMEDIATE, //used to process arrays in the compiler only TOY_LITERAL_DICTIONARY_INTERMEDIATE, //used to process dictionaries in the compiler only TOY_LITERAL_FUNCTION_INTERMEDIATE, //used to process functions in the compiler only TOY_LITERAL_FUNCTION_ARG_REST, //used to process function rest parameters only diff --git a/test/scripts/index-dictionaries.toy b/test/scripts/index-dictionaries.toy index c619326..e0a5faf 100644 --- a/test/scripts/index-dictionaries.toy +++ b/test/scripts/index-dictionaries.toy @@ -30,13 +30,11 @@ //test nested indexing { - var d = ["foo": ["bar": 0]]; + var d = ["foo" : ["bar" : ["bazz" : ["fizz" : 5]]]]; - d["foo"]["bar"] = 42; + d["foo"]["bar"]["bazz"]["fizz"] = 66; - print d; - - assert d == ["foo": ["bar": 42]], "nested indexing failed"; + assert d == ["foo": ["bar": ["bazz": ["fizz": 66]]]], "nested indexing failed"; }