Added fib-memo.toy, fixed bugs until it worked

This commit is contained in:
2023-02-04 16:54:59 +00:00
parent 8d278077b1
commit 386201b6e9
7 changed files with 189 additions and 160 deletions

21
scripts/fib-memo.toy Normal file
View File

@@ -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;
}

View File

@@ -1,3 +1,9 @@
print " foo \n bar"; var d = ["foo" : ["bar" : ["bazz": ["fizz" : 5]]]];
print d;
d["foo"]["bar"]["bazz"]["fizz"] = 66;
print d;

View File

@@ -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 //push the store to the cache, with instructions about how pack it
Toy_Literal literal = TOY_TO_DICTIONARY_LITERAL(store); 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); index = Toy_pushLiteralArray(&compiler->literalCache, literal);
Toy_freeLiteral(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 //push the store to the cache, with instructions about how pack it
Toy_Literal literal = TOY_TO_ARRAY_LITERAL(store); 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); index = Toy_pushLiteralArray(&compiler->literalCache, literal);
Toy_freeLiteral(literal); Toy_freeLiteral(literal);
} }
@@ -1095,7 +1096,22 @@ static unsigned char* collateCompilerHeaderOpt(Toy_Compiler* compiler, int* size
} }
break; 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); emitByte(&collation, &capacity, &count, TOY_LITERAL_DICTIONARY);
Toy_LiteralArray* ptr = TOY_AS_ARRAY(compiler->literalCache.literals[i]); //used an array for storage above 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; 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: { case TOY_LITERAL_FUNCTION_INTERMEDIATE: {
//extract the compiler //extract the compiler
Toy_Literal fn = compiler->literalCache.literals[i]; Toy_Literal fn = compiler->literalCache.literals[i];

View File

@@ -259,11 +259,8 @@ static bool execPrint(Toy_Interpreter* interpreter) {
//print what is on top of the stack, then pop it //print what is on top of the stack, then pop it
Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack);
if (TOY_IS_IDENTIFIER(lit)) {
Toy_Literal idn = lit; Toy_Literal idn = lit;
if (!Toy_parseIdentifierToValue(interpreter, &lit)) { if (TOY_IS_IDENTIFIER(lit) && Toy_parseIdentifierToValue(interpreter, &lit)) {
return false;
}
Toy_freeLiteral(idn); Toy_freeLiteral(idn);
} }
@@ -294,16 +291,12 @@ static bool execPushLiteral(Toy_Interpreter* interpreter, bool lng) {
static bool rawLiteral(Toy_Interpreter* interpreter) { static bool rawLiteral(Toy_Interpreter* interpreter) {
Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack);
if (TOY_IS_IDENTIFIER(lit)) {
Toy_Literal idn = lit; Toy_Literal idn = lit;
if (!Toy_parseIdentifierToValue(interpreter, &lit)) { if (TOY_IS_IDENTIFIER(lit) && Toy_parseIdentifierToValue(interpreter, &lit)) {
return false;
}
Toy_freeLiteral(idn); Toy_freeLiteral(idn);
} }
Toy_pushLiteralArray(&interpreter->stack, lit); Toy_pushLiteralArray(&interpreter->stack, lit);
Toy_freeLiteral(lit); Toy_freeLiteral(lit);
return true; return true;
@@ -313,11 +306,8 @@ static bool execNegate(Toy_Interpreter* interpreter) {
//negate the top literal on the stack (numbers only) //negate the top literal on the stack (numbers only)
Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack);
if (TOY_IS_IDENTIFIER(lit)) {
Toy_Literal idn = lit; Toy_Literal idn = lit;
if (!Toy_parseIdentifierToValue(interpreter, &lit)) { if (TOY_IS_IDENTIFIER(lit) && Toy_parseIdentifierToValue(interpreter, &lit)) {
return false;
}
Toy_freeLiteral(idn); Toy_freeLiteral(idn);
} }
@@ -338,7 +328,6 @@ static bool execNegate(Toy_Interpreter* interpreter) {
} }
Toy_pushLiteralArray(&interpreter->stack, lit); Toy_pushLiteralArray(&interpreter->stack, lit);
Toy_freeLiteral(lit); Toy_freeLiteral(lit);
return true; return true;
@@ -348,11 +337,8 @@ static bool execInvert(Toy_Interpreter* interpreter) {
//negate the top literal on the stack (booleans only) //negate the top literal on the stack (booleans only)
Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack);
if (TOY_IS_IDENTIFIER(lit)) {
Toy_Literal idn = lit; Toy_Literal idn = lit;
if (!Toy_parseIdentifierToValue(interpreter, &lit)) { if (TOY_IS_IDENTIFIER(lit) && Toy_parseIdentifierToValue(interpreter, &lit)) {
return false;
}
Toy_freeLiteral(idn); Toy_freeLiteral(idn);
} }
@@ -370,7 +356,6 @@ static bool execInvert(Toy_Interpreter* interpreter) {
} }
Toy_pushLiteralArray(&interpreter->stack, lit); Toy_pushLiteralArray(&interpreter->stack, lit);
Toy_freeLiteral(lit); Toy_freeLiteral(lit);
return true; return true;
@@ -380,16 +365,14 @@ static bool execArithmetic(Toy_Interpreter* interpreter, Toy_Opcode opcode) {
Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack); Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack);
Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack);
if (TOY_IS_IDENTIFIER(rhs)) { Toy_Literal rhsIdn = rhs;
Toy_Literal idn = rhs; if (TOY_IS_IDENTIFIER(rhs) && Toy_parseIdentifierToValue(interpreter, &rhs)) {
Toy_parseIdentifierToValue(interpreter, &rhs); Toy_freeLiteral(rhsIdn);
Toy_freeLiteral(idn);
} }
if (TOY_IS_IDENTIFIER(lhs)) { Toy_Literal lhsIdn = lhs;
Toy_Literal idn = lhs; if (TOY_IS_IDENTIFIER(lhs) && Toy_parseIdentifierToValue(interpreter, &lhs)) {
Toy_parseIdentifierToValue(interpreter, &lhs); Toy_freeLiteral(lhsIdn);
Toy_freeLiteral(idn);
} }
//special case for string concatenation ONLY //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) { static Toy_Literal parseTypeToValue(Toy_Interpreter* interpreter, Toy_Literal type) {
//if an identifier is embedded in the type, figure out what it iss //if an identifier is embedded in the type, figure out what it iss
if (TOY_IS_IDENTIFIER(type)) { Toy_Literal typeIdn = type;
Toy_Literal idn = type; if (TOY_IS_IDENTIFIER(type) && Toy_parseIdentifierToValue(interpreter, &type)) {
Toy_parseIdentifierToValue(interpreter, &type); Toy_freeLiteral(typeIdn);
Toy_freeLiteral(idn);
} }
//if this is an array or dictionary, continue to the subtypes //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 identifier = interpreter->literalCache.literals[identifierIndex];
Toy_Literal type = Toy_copyLiteral(interpreter->literalCache.literals[typeIndex]); Toy_Literal type = Toy_copyLiteral(interpreter->literalCache.literals[typeIndex]);
if (TOY_IS_IDENTIFIER(type)) { Toy_Literal typeIdn = type;
Toy_Literal orig = type; if (TOY_IS_IDENTIFIER(type) && Toy_parseIdentifierToValue(interpreter, &type)) {
Toy_parseIdentifierToValue(interpreter, &type); Toy_freeLiteral(typeIdn);
Toy_freeLiteral(orig);
} }
//BUGFIX: because identifiers are getting embedded in type definitions //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); Toy_Literal val = Toy_popLiteralArray(&interpreter->stack);
if (TOY_IS_IDENTIFIER(val)) { Toy_Literal valIdn = val;
Toy_Literal idn = val; if (TOY_IS_IDENTIFIER(val) && Toy_parseIdentifierToValue(interpreter, &val)) {
Toy_parseIdentifierToValue(interpreter, &val); Toy_freeLiteral(valIdn);
Toy_freeLiteral(idn);
} }
if (TOY_IS_ARRAY(val) || TOY_IS_DICTIONARY(val)) { 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 rhs = Toy_popLiteralArray(&interpreter->stack);
Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack);
if (TOY_IS_IDENTIFIER(rhs)) { Toy_Literal rhsIdn = rhs;
Toy_Literal idn = rhs; if (TOY_IS_IDENTIFIER(rhs) && Toy_parseIdentifierToValue(interpreter, &rhs)) {
Toy_parseIdentifierToValue(interpreter, &rhs); Toy_freeLiteral(rhsIdn);
Toy_freeLiteral(idn);
} }
if (TOY_IS_ARRAY(rhs) || TOY_IS_DICTIONARY(rhs)) { 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 value = Toy_popLiteralArray(&interpreter->stack);
Toy_Literal type = Toy_popLiteralArray(&interpreter->stack); Toy_Literal type = Toy_popLiteralArray(&interpreter->stack);
if (TOY_IS_IDENTIFIER(value)) { Toy_Literal valueIdn = value;
Toy_Literal idn = value; if (TOY_IS_IDENTIFIER(value) && Toy_parseIdentifierToValue(interpreter, &value)) {
if (!Toy_parseIdentifierToValue(interpreter, &value)) { Toy_freeLiteral(valueIdn);
return false;
}
Toy_freeLiteral(idn);
} }
Toy_Literal result = TOY_TO_NULL_LITERAL; 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 rhs = Toy_popLiteralArray(&interpreter->stack);
Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack);
if (TOY_IS_IDENTIFIER(rhs)) { Toy_Literal rhsIdn = rhs;
Toy_Literal idn = rhs; if (TOY_IS_IDENTIFIER(rhs) && Toy_parseIdentifierToValue(interpreter, &rhs)) {
Toy_parseIdentifierToValue(interpreter, &rhs); Toy_freeLiteral(rhsIdn);
Toy_freeLiteral(idn);
} }
if (TOY_IS_IDENTIFIER(lhs)) { Toy_Literal lhsIdn = lhs;
Toy_Literal idn = lhs; if (TOY_IS_IDENTIFIER(lhs) && Toy_parseIdentifierToValue(interpreter, &lhs)) {
Toy_parseIdentifierToValue(interpreter, &lhs); Toy_freeLiteral(lhsIdn);
Toy_freeLiteral(idn);
} }
bool result = Toy_literalsAreEqual(lhs, rhs); 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 rhs = Toy_popLiteralArray(&interpreter->stack);
Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack);
if (TOY_IS_IDENTIFIER(rhs)) { Toy_Literal rhsIdn = rhs;
Toy_Literal idn = rhs; if (TOY_IS_IDENTIFIER(rhs) && Toy_parseIdentifierToValue(interpreter, &rhs)) {
Toy_parseIdentifierToValue(interpreter, &rhs); Toy_freeLiteral(rhsIdn);
Toy_freeLiteral(idn);
} }
if (TOY_IS_IDENTIFIER(lhs)) { Toy_Literal lhsIdn = lhs;
Toy_Literal idn = lhs; if (TOY_IS_IDENTIFIER(lhs) && Toy_parseIdentifierToValue(interpreter, &lhs)) {
Toy_parseIdentifierToValue(interpreter, &lhs); Toy_freeLiteral(lhsIdn);
Toy_freeLiteral(idn);
} }
//not a number, return falure //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 rhs = Toy_popLiteralArray(&interpreter->stack);
Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack);
if (TOY_IS_IDENTIFIER(rhs)) { Toy_Literal rhsIdn = rhs;
Toy_Literal idn = rhs; if (TOY_IS_IDENTIFIER(rhs) && Toy_parseIdentifierToValue(interpreter, &rhs)) {
Toy_parseIdentifierToValue(interpreter, &rhs); Toy_freeLiteral(rhsIdn);
Toy_freeLiteral(idn);
} }
if (TOY_IS_IDENTIFIER(lhs)) { Toy_Literal lhsIdn = lhs;
Toy_Literal idn = lhs; if (TOY_IS_IDENTIFIER(lhs) && Toy_parseIdentifierToValue(interpreter, &lhs)) {
Toy_parseIdentifierToValue(interpreter, &lhs); Toy_freeLiteral(lhsIdn);
Toy_freeLiteral(idn);
} }
//not a number, return falure //not a number, return falure
@@ -1016,16 +986,14 @@ static bool execAnd(Toy_Interpreter* interpreter) {
Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack); Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack);
Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack);
if (TOY_IS_IDENTIFIER(rhs)) { Toy_Literal rhsIdn = rhs;
Toy_Literal idn = rhs; if (TOY_IS_IDENTIFIER(rhs) && Toy_parseIdentifierToValue(interpreter, &rhs)) {
Toy_parseIdentifierToValue(interpreter, &rhs); Toy_freeLiteral(rhsIdn);
Toy_freeLiteral(idn);
} }
if (TOY_IS_IDENTIFIER(lhs)) { Toy_Literal lhsIdn = lhs;
Toy_Literal idn = lhs; if (TOY_IS_IDENTIFIER(lhs) && Toy_parseIdentifierToValue(interpreter, &lhs)) {
Toy_parseIdentifierToValue(interpreter, &lhs); Toy_freeLiteral(lhsIdn);
Toy_freeLiteral(idn);
} }
if (TOY_IS_TRUTHY(lhs) && TOY_IS_TRUTHY(rhs)) { 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 rhs = Toy_popLiteralArray(&interpreter->stack);
Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack);
if (TOY_IS_IDENTIFIER(rhs)) { Toy_Literal rhsIdn = rhs;
Toy_Literal idn = rhs; if (TOY_IS_IDENTIFIER(rhs) && Toy_parseIdentifierToValue(interpreter, &rhs)) {
Toy_parseIdentifierToValue(interpreter, &rhs); Toy_freeLiteral(rhsIdn);
Toy_freeLiteral(idn);
} }
if (TOY_IS_IDENTIFIER(lhs)) { Toy_Literal lhsIdn = lhs;
Toy_Literal idn = lhs; if (TOY_IS_IDENTIFIER(lhs) && Toy_parseIdentifierToValue(interpreter, &lhs)) {
Toy_parseIdentifierToValue(interpreter, &lhs); Toy_freeLiteral(lhsIdn);
Toy_freeLiteral(idn);
} }
if (TOY_IS_TRUTHY(lhs) || TOY_IS_TRUTHY(rhs)) { 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); Toy_Literal arg = Toy_popLiteralArray(arguments);
if (TOY_IS_IDENTIFIER(arg)) { Toy_Literal argIdn = arg;
Toy_Literal idn = arg; if (TOY_IS_IDENTIFIER(arg) && Toy_parseIdentifierToValue(interpreter, &arg)) {
Toy_parseIdentifierToValue(interpreter, &arg); Toy_freeLiteral(argIdn);
Toy_freeLiteral(idn);
} }
if (!Toy_setScopeVariable(inner.scope, paramArray->literals[i], arg, false)) { 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 //get the values of everything on the stack
while (interpreter->stack.count > 0) { while (interpreter->stack.count > 0) {
Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack);
if (TOY_IS_IDENTIFIER(lit)) {
Toy_Literal idn = lit; Toy_Literal litIdn = lit;
Toy_parseIdentifierToValue(interpreter, &lit); if (TOY_IS_IDENTIFIER(lit) && Toy_parseIdentifierToValue(interpreter, &lit)) {
Toy_freeLiteral(idn); Toy_freeLiteral(litIdn);
} }
if (TOY_IS_ARRAY(lit) || TOY_IS_DICTIONARY(lit)) { 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 first = Toy_popLiteralArray(&interpreter->stack);
Toy_Literal compound = Toy_popLiteralArray(&interpreter->stack); Toy_Literal compound = Toy_popLiteralArray(&interpreter->stack);
Toy_Literal idn = compound; Toy_Literal compoundIdn = compound;
bool freeIdn = false; bool freeIdn = false;
if (TOY_IS_IDENTIFIER(compound) && Toy_parseIdentifierToValue(interpreter, &compound)) {
if (TOY_IS_IDENTIFIER(compound)) {
freeIdn = true; 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)) { 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(second);
Toy_freeLiteral(first); Toy_freeLiteral(first);
Toy_freeLiteral(compound); Toy_freeLiteral(compound);
if (freeIdn) { if (freeIdn) {
Toy_freeLiteral(idn); Toy_freeLiteral(compoundIdn);
} }
return false; return false;
} }
@@ -1563,8 +1521,8 @@ static bool execIndex(Toy_Interpreter* interpreter, bool assignIntermediate) {
//leave the idn and compound on the stack //leave the idn and compound on the stack
if (assignIntermediate) { if (assignIntermediate) {
if (TOY_IS_IDENTIFIER(idn)) { if (TOY_IS_IDENTIFIER(compoundIdn)) {
Toy_pushLiteralArray(&interpreter->stack, idn); Toy_pushLiteralArray(&interpreter->stack, compoundIdn);
} }
Toy_pushLiteralArray(&interpreter->stack, compound); Toy_pushLiteralArray(&interpreter->stack, compound);
Toy_pushLiteralArray(&interpreter->stack, first); Toy_pushLiteralArray(&interpreter->stack, first);
@@ -1574,8 +1532,8 @@ static bool execIndex(Toy_Interpreter* interpreter, bool assignIntermediate) {
//call the _index function //call the _index function
if (Toy_private_index(interpreter, &arguments) < 0) { if (Toy_private_index(interpreter, &arguments) < 0) {
interpreter->errorOutput("Something went wrong while indexing: "); interpreter->errorOutput("Something went wrong while indexing (simple index): ");
Toy_printLiteralCustom(idn, interpreter->errorOutput); Toy_printLiteralCustom(compoundIdn, interpreter->errorOutput);
interpreter->errorOutput("\n"); interpreter->errorOutput("\n");
//clean up //clean up
@@ -1584,7 +1542,7 @@ static bool execIndex(Toy_Interpreter* interpreter, bool assignIntermediate) {
Toy_freeLiteral(first); Toy_freeLiteral(first);
Toy_freeLiteral(compound); Toy_freeLiteral(compound);
if (freeIdn) { if (freeIdn) {
Toy_freeLiteral(idn); Toy_freeLiteral(compoundIdn);
} }
Toy_freeLiteralArray(&arguments); Toy_freeLiteralArray(&arguments);
return false; return false;
@@ -1596,7 +1554,7 @@ static bool execIndex(Toy_Interpreter* interpreter, bool assignIntermediate) {
Toy_freeLiteral(first); Toy_freeLiteral(first);
Toy_freeLiteral(compound); Toy_freeLiteral(compound);
if (freeIdn) { if (freeIdn) {
Toy_freeLiteral(idn); Toy_freeLiteral(compoundIdn);
} }
Toy_freeLiteralArray(&arguments); Toy_freeLiteralArray(&arguments);
@@ -1612,20 +1570,15 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) {
Toy_Literal first = Toy_popLiteralArray(&interpreter->stack); Toy_Literal first = Toy_popLiteralArray(&interpreter->stack);
Toy_Literal compound = Toy_popLiteralArray(&interpreter->stack); Toy_Literal compound = Toy_popLiteralArray(&interpreter->stack);
Toy_Literal idn = compound; Toy_Literal assignIdn = assign;
bool freeIdn = false; if (TOY_IS_IDENTIFIER(assign) && Toy_parseIdentifierToValue(interpreter, &assign)) {
Toy_freeLiteral(assignIdn);
if (TOY_IS_IDENTIFIER(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;
} }
Toy_Literal compoundIdn = compound;
bool freeIdn = false;
if (TOY_IS_IDENTIFIER(compound) && Toy_parseIdentifierToValue(interpreter, &compound)) {
freeIdn = true;
} }
if (!TOY_IS_ARRAY(compound) && !TOY_IS_DICTIONARY(compound) && !TOY_IS_STRING(compound)) { 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(first);
Toy_freeLiteral(compound); Toy_freeLiteral(compound);
if (freeIdn) { if (freeIdn) {
Toy_freeLiteral(idn); Toy_freeLiteral(compoundIdn);
} }
return false; return false;
} }
@@ -1672,7 +1625,7 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) {
Toy_freeLiteral(first); Toy_freeLiteral(first);
Toy_freeLiteral(compound); Toy_freeLiteral(compound);
if (freeIdn) { if (freeIdn) {
Toy_freeLiteral(idn); Toy_freeLiteral(compoundIdn);
} }
return false; return false;
} }
@@ -1700,7 +1653,7 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) {
Toy_freeLiteral(first); Toy_freeLiteral(first);
Toy_freeLiteral(compound); Toy_freeLiteral(compound);
if (freeIdn) { if (freeIdn) {
Toy_freeLiteral(idn); Toy_freeLiteral(compoundIdn);
} }
Toy_freeLiteral(op); Toy_freeLiteral(op);
Toy_freeLiteralArray(&arguments); 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) //save the result (assume top of the interpreter stack is the new compound value)
Toy_Literal result = Toy_popLiteralArray(&interpreter->stack); 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) //deep
if (!TOY_IS_IDENTIFIER(idn)) { if (!freeIdn) {
while (interpreter->stack.count > 1) { while (interpreter->stack.count > 1) {
//read the new values //read the new values
Toy_freeLiteral(idn); Toy_freeLiteral(compound);
Toy_freeLiteral(third); Toy_freeLiteral(third);
Toy_freeLiteral(second); Toy_freeLiteral(second);
Toy_freeLiteral(first); Toy_freeLiteral(first);
@@ -1723,17 +1676,18 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) {
Toy_initLiteralArray(&arguments); Toy_initLiteralArray(&arguments);
Toy_freeLiteral(op); Toy_freeLiteral(op);
//reuse these like an idiot
third = Toy_popLiteralArray(&interpreter->stack); third = Toy_popLiteralArray(&interpreter->stack);
second = Toy_popLiteralArray(&interpreter->stack); second = Toy_popLiteralArray(&interpreter->stack);
first = 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 char* opStr = "="; //shadow, but force assignment
int opLength = strlen(opStr); int opLength = strlen(opStr);
op = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(opStr, opLength)); //TODO: static reference optimisation? op = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(opStr, opLength)); //TODO: static reference optimisation?
//assign to the idn / compound - with _index //assign to the idn / compound - with _index
Toy_pushLiteralArray(&arguments, idn); Toy_pushLiteralArray(&arguments, compound); //
Toy_pushLiteralArray(&arguments, first); Toy_pushLiteralArray(&arguments, first);
Toy_pushLiteralArray(&arguments, second); Toy_pushLiteralArray(&arguments, second);
Toy_pushLiteralArray(&arguments, third); Toy_pushLiteralArray(&arguments, third);
@@ -1741,8 +1695,8 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) {
Toy_pushLiteralArray(&arguments, op); Toy_pushLiteralArray(&arguments, op);
if (Toy_private_index(interpreter, &arguments) < 0) { if (Toy_private_index(interpreter, &arguments) < 0) {
interpreter->errorOutput("Something went wrong while indexing: "); interpreter->errorOutput("Something went wrong while indexing (index assign): ");
Toy_printLiteralCustom(idn, interpreter->errorOutput); Toy_printLiteralCustom(compound, interpreter->errorOutput);
interpreter->errorOutput("\n"); interpreter->errorOutput("\n");
//clean up //clean up
@@ -1750,13 +1704,11 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) {
Toy_freeLiteral(third); Toy_freeLiteral(third);
Toy_freeLiteral(second); Toy_freeLiteral(second);
Toy_freeLiteral(first); Toy_freeLiteral(first);
Toy_freeLiteral(compound);
if (freeIdn) { if (freeIdn) {
Toy_freeLiteral(idn); Toy_freeLiteral(compoundIdn);
} }
Toy_freeLiteral(op); Toy_freeLiteral(op);
Toy_freeLiteralArray(&arguments); Toy_freeLiteralArray(&arguments);
Toy_freeLiteral(result);
return false; return false;
} }
@@ -1764,14 +1716,15 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) {
result = Toy_popLiteralArray(&interpreter->stack); result = Toy_popLiteralArray(&interpreter->stack);
} }
Toy_freeLiteral(idn); Toy_freeLiteral(compound);
idn = Toy_popLiteralArray(&interpreter->stack); compound = Toy_popLiteralArray(&interpreter->stack);
compound = idn; 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 "); interpreter->errorOutput("Incorrect type assigned to compound member ");
Toy_printLiteralCustom(idn, interpreter->errorOutput); Toy_printLiteralCustom(compoundIdn, interpreter->errorOutput);
interpreter->errorOutput("\n"); interpreter->errorOutput("\n");
//clean up //clean up
@@ -1781,7 +1734,7 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) {
Toy_freeLiteral(first); Toy_freeLiteral(first);
Toy_freeLiteral(compound); Toy_freeLiteral(compound);
if (freeIdn) { if (freeIdn) {
Toy_freeLiteral(idn); Toy_freeLiteral(compoundIdn);
} }
Toy_freeLiteral(op); Toy_freeLiteral(op);
Toy_freeLiteralArray(&arguments); Toy_freeLiteralArray(&arguments);
@@ -1796,7 +1749,7 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) {
Toy_freeLiteral(first); Toy_freeLiteral(first);
Toy_freeLiteral(compound); Toy_freeLiteral(compound);
if (freeIdn) { if (freeIdn) {
Toy_freeLiteral(idn); Toy_freeLiteral(compoundIdn);
} }
Toy_freeLiteral(op); Toy_freeLiteral(op);
Toy_freeLiteralArray(&arguments); Toy_freeLiteralArray(&arguments);
@@ -2128,6 +2081,7 @@ static void readInterpreterSections(Toy_Interpreter* interpreter) {
} }
break; break;
case TOY_LITERAL_ARRAY_INTERMEDIATE:
case TOY_LITERAL_ARRAY: { case TOY_LITERAL_ARRAY: {
Toy_LiteralArray* array = TOY_ALLOCATE(Toy_LiteralArray, 1); Toy_LiteralArray* array = TOY_ALLOCATE(Toy_LiteralArray, 1);
Toy_initLiteralArray(array); Toy_initLiteralArray(array);
@@ -2158,6 +2112,7 @@ static void readInterpreterSections(Toy_Interpreter* interpreter) {
} }
break; break;
case TOY_LITERAL_DICTIONARY_INTERMEDIATE:
case TOY_LITERAL_DICTIONARY: { case TOY_LITERAL_DICTIONARY: {
Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1); Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
Toy_initLiteralDictionary(dictionary); Toy_initLiteralDictionary(dictionary);

View File

@@ -42,7 +42,7 @@ void Toy_freeLiteral(Toy_Literal literal) {
} }
//compounds //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_freeLiteralArray(TOY_AS_ARRAY(literal));
TOY_FREE(Toy_LiteralArray, TOY_AS_ARRAY(literal)); TOY_FREE(Toy_LiteralArray, TOY_AS_ARRAY(literal));
return; return;
@@ -172,6 +172,22 @@ Toy_Literal Toy_copyLiteral(Toy_Literal original) {
return original; //literally a shallow copy 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: { case TOY_LITERAL_DICTIONARY_INTERMEDIATE: {
Toy_LiteralArray* array = TOY_ALLOCATE(Toy_LiteralArray, 1); Toy_LiteralArray* array = TOY_ALLOCATE(Toy_LiteralArray, 1);
Toy_initLiteralArray(array); 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)); return Toy_equalsRefString(TOY_AS_STRING(lhs), TOY_AS_STRING(rhs));
case TOY_LITERAL_ARRAY: case TOY_LITERAL_ARRAY:
case TOY_LITERAL_ARRAY_INTERMEDIATE:
case TOY_LITERAL_DICTIONARY_INTERMEDIATE: //BUGFIX case TOY_LITERAL_DICTIONARY_INTERMEDIATE: //BUGFIX
case TOY_LITERAL_TYPE_INTERMEDIATE: //BUGFIX: used for storing types as an array case TOY_LITERAL_TYPE_INTERMEDIATE: //BUGFIX: used for storing types as an array
//mismatched sizes //mismatched sizes

View File

@@ -29,6 +29,7 @@ typedef enum {
//these are meta-level types - not for general use //these are meta-level types - not for general use
TOY_LITERAL_TYPE_INTERMEDIATE, //used to process types in the compiler only 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_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_INTERMEDIATE, //used to process functions in the compiler only
TOY_LITERAL_FUNCTION_ARG_REST, //used to process function rest parameters only TOY_LITERAL_FUNCTION_ARG_REST, //used to process function rest parameters only

View File

@@ -30,13 +30,11 @@
//test nested indexing //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": ["bazz": ["fizz": 66]]]], "nested indexing failed";
assert d == ["foo": ["bar": 42]], "nested indexing failed";
} }