Going well tonight - need a break

This commit is contained in:
2022-09-03 00:51:55 +10:00
parent 1f6b3e232d
commit c58c8911fe
3 changed files with 137 additions and 35 deletions

View File

@@ -1,2 +1,8 @@
var a : [any] = [0];
fn foo() {
//
}
foo();

View File

@@ -53,7 +53,7 @@ bool parseIdentifierToValue(Interpreter* interpreter, Literal* literalPtr) {
if (IS_IDENTIFIER(*literalPtr)) { if (IS_IDENTIFIER(*literalPtr)) {
// Literal idn = *literalPtr; // Literal idn = *literalPtr;
if (!getScopeVariable(interpreter->scope, *literalPtr, literalPtr)) { if (!getScopeVariable(interpreter->scope, *literalPtr, literalPtr)) {
printf(ERROR "Error: Undeclared variable \"");; printf(ERROR "ERROR: Undeclared variable \"");;
printLiteral(*literalPtr); printLiteral(*literalPtr);
printf("\"\n" RESET); printf("\"\n" RESET);
return false; return false;
@@ -249,28 +249,32 @@ int _length(Interpreter* interpreter, LiteralArray* arguments) {
Literal obj = arguments->literals[0]; Literal obj = arguments->literals[0];
bool freeObj = false;
if (IS_IDENTIFIER(obj)) {
parseIdentifierToValue(interpreter, &obj); parseIdentifierToValue(interpreter, &obj);
freeObj = true;
}
switch(obj.type) { switch(obj.type) {
case LITERAL_ARRAY: { case LITERAL_ARRAY: {
Literal lit = TO_INTEGER_LITERAL( AS_ARRAY(obj)->count ); Literal lit = TO_INTEGER_LITERAL( AS_ARRAY(obj)->count );
pushLiteralArray(&interpreter->stack, lit); pushLiteralArray(&interpreter->stack, lit);
freeLiteral(lit); freeLiteral(lit);
return 1; break;
} }
case LITERAL_DICTIONARY: { case LITERAL_DICTIONARY: {
Literal lit = TO_INTEGER_LITERAL( AS_DICTIONARY(obj)->count ); Literal lit = TO_INTEGER_LITERAL( AS_DICTIONARY(obj)->count );
pushLiteralArray(&interpreter->stack, lit); pushLiteralArray(&interpreter->stack, lit);
freeLiteral(lit); freeLiteral(lit);
return 1; break;
} }
case LITERAL_STRING: { case LITERAL_STRING: {
Literal lit = TO_INTEGER_LITERAL( strlen(AS_STRING(obj)) ); Literal lit = TO_INTEGER_LITERAL( strlen(AS_STRING(obj)) );
pushLiteralArray(&interpreter->stack, lit); pushLiteralArray(&interpreter->stack, lit);
freeLiteral(lit); freeLiteral(lit);
return 1; break;
} }
default: default:
@@ -278,6 +282,12 @@ int _length(Interpreter* interpreter, LiteralArray* arguments) {
printLiteral(obj); printLiteral(obj);
return -1; return -1;
} }
if (freeObj) {
freeLiteral(obj);
}
return 1;
} }
int _clear(Interpreter* interpreter, LiteralArray* arguments) { int _clear(Interpreter* interpreter, LiteralArray* arguments) {
@@ -339,10 +349,24 @@ void initInterpreter(Interpreter* interpreter) {
} }
void freeInterpreter(Interpreter* interpreter) { void freeInterpreter(Interpreter* interpreter) {
//BUGFIX: handle scopes of functions, which refer to the parent scope (leaking memory)
for (int i = 0; i < interpreter->scope->variables.capacity; i++) {
//handle keys, just in case
if (IS_FUNCTION(interpreter->scope->variables.entries[i].key)) {
popScope(AS_FUNCTION(interpreter->scope->variables.entries[i].key).scope);
AS_FUNCTION(interpreter->scope->variables.entries[i].key).scope = NULL;
}
if (IS_FUNCTION(interpreter->scope->variables.entries[i].value)) {
popScope(AS_FUNCTION(interpreter->scope->variables.entries[i].value).scope);
AS_FUNCTION(interpreter->scope->variables.entries[i].value).scope = NULL;
}
}
popScope(interpreter->scope);
interpreter->scope = NULL;
freeLiteralArray(&interpreter->literalCache); freeLiteralArray(&interpreter->literalCache);
interpreter->scope = popScope(interpreter->scope);
freeLiteralArray(&interpreter->stack); freeLiteralArray(&interpreter->stack);
} }
@@ -537,8 +561,17 @@ static bool execArithmetic(Interpreter* interpreter, Opcode opcode) {
Literal rhs = popLiteralArray(&interpreter->stack); Literal rhs = popLiteralArray(&interpreter->stack);
Literal lhs = popLiteralArray(&interpreter->stack); Literal lhs = popLiteralArray(&interpreter->stack);
if (IS_IDENTIFIER(rhs)) {
Literal idn = rhs;
parseIdentifierToValue(interpreter, &rhs); parseIdentifierToValue(interpreter, &rhs);
freeLiteral(idn);
}
if (IS_IDENTIFIER(lhs)) {
Literal idn = lhs;
parseIdentifierToValue(interpreter, &lhs); parseIdentifierToValue(interpreter, &lhs);
freeLiteral(idn);
}
//special case for string concatenation ONLY //special case for string concatenation ONLY
if (IS_STRING(lhs) && IS_STRING(rhs)) { if (IS_STRING(lhs) && IS_STRING(rhs)) {
@@ -733,7 +766,7 @@ static bool execFnDecl(Interpreter* interpreter, bool lng) {
Literal identifier = interpreter->literalCache.literals[identifierIndex]; Literal identifier = interpreter->literalCache.literals[identifierIndex];
Literal function = interpreter->literalCache.literals[functionIndex]; Literal function = interpreter->literalCache.literals[functionIndex];
function.as.function.scope = pushScope(interpreter->scope); //hacked in AS_FUNCTION(function).scope = pushScope(interpreter->scope); //hacked in (needed for closure persistance)
Literal type = TO_TYPE_LITERAL(LITERAL_FUNCTION, true); Literal type = TO_TYPE_LITERAL(LITERAL_FUNCTION, true);
@@ -744,13 +777,16 @@ static bool execFnDecl(Interpreter* interpreter, bool lng) {
return false; return false;
} }
if (!setScopeVariable(interpreter->scope, identifier, function, false)) { if (!setScopeVariable(interpreter->scope, identifier, function, false)) { //scope gets copied here
printf(ERROR "ERROR: Incorrect type assigned to variable \""); printf(ERROR "ERROR: Incorrect type assigned to variable \"");
printLiteral(identifier); printLiteral(identifier);
printf("\"\n" RESET); printf("\"\n" RESET);
return false; return false;
} }
popScope(AS_FUNCTION(function).scope); //hacked out
AS_FUNCTION(function).scope = NULL;
freeLiteral(type); freeLiteral(type);
return true; return true;
@@ -900,8 +936,17 @@ static bool execCompareEqual(Interpreter* interpreter, bool invert) {
Literal rhs = popLiteralArray(&interpreter->stack); Literal rhs = popLiteralArray(&interpreter->stack);
Literal lhs = popLiteralArray(&interpreter->stack); Literal lhs = popLiteralArray(&interpreter->stack);
if (IS_IDENTIFIER(rhs)) {
Literal idn = rhs;
parseIdentifierToValue(interpreter, &rhs); parseIdentifierToValue(interpreter, &rhs);
freeLiteral(idn);
}
if (IS_IDENTIFIER(lhs)) {
Literal idn = lhs;
parseIdentifierToValue(interpreter, &lhs); parseIdentifierToValue(interpreter, &lhs);
freeLiteral(idn);
}
bool result = literalsAreEqual(lhs, rhs); bool result = literalsAreEqual(lhs, rhs);
@@ -921,8 +966,17 @@ static bool execCompareLess(Interpreter* interpreter, bool invert) {
Literal rhs = popLiteralArray(&interpreter->stack); Literal rhs = popLiteralArray(&interpreter->stack);
Literal lhs = popLiteralArray(&interpreter->stack); Literal lhs = popLiteralArray(&interpreter->stack);
if (IS_IDENTIFIER(rhs)) {
Literal idn = rhs;
parseIdentifierToValue(interpreter, &rhs); parseIdentifierToValue(interpreter, &rhs);
freeLiteral(idn);
}
if (IS_IDENTIFIER(lhs)) {
Literal idn = lhs;
parseIdentifierToValue(interpreter, &lhs); parseIdentifierToValue(interpreter, &lhs);
freeLiteral(idn);
}
//not a number, return falure //not a number, return falure
if (!(IS_INTEGER(lhs) || IS_FLOAT(lhs))) { if (!(IS_INTEGER(lhs) || IS_FLOAT(lhs))) {
@@ -973,8 +1027,17 @@ static bool execCompareLessEqual(Interpreter* interpreter, bool invert) {
Literal rhs = popLiteralArray(&interpreter->stack); Literal rhs = popLiteralArray(&interpreter->stack);
Literal lhs = popLiteralArray(&interpreter->stack); Literal lhs = popLiteralArray(&interpreter->stack);
if (IS_IDENTIFIER(rhs)) {
Literal idn = rhs;
parseIdentifierToValue(interpreter, &rhs); parseIdentifierToValue(interpreter, &rhs);
freeLiteral(idn);
}
if (IS_IDENTIFIER(lhs)) {
Literal idn = lhs;
parseIdentifierToValue(interpreter, &lhs); parseIdentifierToValue(interpreter, &lhs);
freeLiteral(idn);
}
//not a number, return falure //not a number, return falure
if (!(IS_INTEGER(lhs) || IS_FLOAT(lhs))) { if (!(IS_INTEGER(lhs) || IS_FLOAT(lhs))) {
@@ -1025,8 +1088,17 @@ static bool execAnd(Interpreter* interpreter) {
Literal rhs = popLiteralArray(&interpreter->stack); Literal rhs = popLiteralArray(&interpreter->stack);
Literal lhs = popLiteralArray(&interpreter->stack); Literal lhs = popLiteralArray(&interpreter->stack);
if (IS_IDENTIFIER(rhs)) {
Literal idn = rhs;
parseIdentifierToValue(interpreter, &rhs); parseIdentifierToValue(interpreter, &rhs);
freeLiteral(idn);
}
if (IS_IDENTIFIER(lhs)) {
Literal idn = lhs;
parseIdentifierToValue(interpreter, &lhs); parseIdentifierToValue(interpreter, &lhs);
freeLiteral(idn);
}
if (IS_TRUTHY(lhs) && IS_TRUTHY(rhs)) { if (IS_TRUTHY(lhs) && IS_TRUTHY(rhs)) {
pushLiteralArray(&interpreter->stack, TO_BOOLEAN_LITERAL(true)); pushLiteralArray(&interpreter->stack, TO_BOOLEAN_LITERAL(true));
@@ -1045,8 +1117,17 @@ static bool execOr(Interpreter* interpreter) {
Literal rhs = popLiteralArray(&interpreter->stack); Literal rhs = popLiteralArray(&interpreter->stack);
Literal lhs = popLiteralArray(&interpreter->stack); Literal lhs = popLiteralArray(&interpreter->stack);
if (IS_IDENTIFIER(rhs)) {
Literal idn = rhs;
parseIdentifierToValue(interpreter, &rhs); parseIdentifierToValue(interpreter, &rhs);
freeLiteral(idn);
}
if (IS_IDENTIFIER(lhs)) {
Literal idn = lhs;
parseIdentifierToValue(interpreter, &lhs); parseIdentifierToValue(interpreter, &lhs);
freeLiteral(idn);
}
if (IS_TRUTHY(lhs) || IS_TRUTHY(rhs)) { if (IS_TRUTHY(lhs) || IS_TRUTHY(rhs)) {
pushLiteralArray(&interpreter->stack, TO_BOOLEAN_LITERAL(true)); pushLiteralArray(&interpreter->stack, TO_BOOLEAN_LITERAL(true));
@@ -1116,7 +1197,9 @@ static bool execFnCall(Interpreter* interpreter) {
//unpack the stack of arguments //unpack the stack of arguments
for (int i = 0; i < AS_INTEGER(stackSize); i++) { for (int i = 0; i < AS_INTEGER(stackSize); i++) {
pushLiteralArray(&arguments, popLiteralArray(&interpreter->stack)); //NOTE: also reverses the order Literal lit = popLiteralArray(&interpreter->stack);
pushLiteralArray(&arguments, lit); //NOTE: also reverses the order
freeLiteral(lit);
} }
Literal identifier = popLiteralArray(&interpreter->stack); Literal identifier = popLiteralArray(&interpreter->stack);
@@ -1129,6 +1212,8 @@ static bool execFnCall(Interpreter* interpreter) {
return false; return false;
} }
freeLiteral(identifier);
//check for side-loaded native functions //check for side-loaded native functions
if (IS_FUNCTION_NATIVE(func)) { if (IS_FUNCTION_NATIVE(func)) {
//reverse the order to the correct order //reverse the order to the correct order
@@ -1300,7 +1385,10 @@ static bool execFnCall(Interpreter* interpreter) {
//free //free
freeLiteralArray(&returns); freeLiteralArray(&returns);
freeLiteralArray(&arguments); freeLiteralArray(&arguments);
freeInterpreter(&inner); freeLiteralArray(&inner.stack);
freeLiteralArray(&inner.literalCache);
popScope(inner.scope);
freeLiteral(func);
//actual bytecode persists until next call //actual bytecode persists until next call
return true; return true;
@@ -1619,7 +1707,10 @@ static void readInterpreterSections(Interpreter* interpreter) {
//finally, push the array proper //finally, push the array proper
Literal literal = TO_ARRAY_LITERAL(array); Literal literal = TO_ARRAY_LITERAL(array);
pushLiteralArray(&interpreter->literalCache, literal); pushLiteralArray(&interpreter->literalCache, literal); //copied
freeLiteralArray(array);
FREE(LiteralArray, array);
} }
break; break;
@@ -1645,7 +1736,10 @@ static void readInterpreterSections(Interpreter* interpreter) {
//finally, push the dictionary proper //finally, push the dictionary proper
Literal literal = TO_DICTIONARY_LITERAL(dictionary); Literal literal = TO_DICTIONARY_LITERAL(dictionary);
pushLiteralArray(&interpreter->literalCache, literal); pushLiteralArray(&interpreter->literalCache, literal); //copied
freeLiteralDictionary(dictionary);
FREE(LiteralDictionary, dictionary);
} }
break; break;
@@ -1719,12 +1813,12 @@ static void readInterpreterSections(Interpreter* interpreter) {
unsigned short kt = readShort(interpreter->bytecode, &interpreter->count); unsigned short kt = readShort(interpreter->bytecode, &interpreter->count);
unsigned short vt = readShort(interpreter->bytecode, &interpreter->count); unsigned short vt = readShort(interpreter->bytecode, &interpreter->count);
TYPE_PUSH_SUBTYPE(&typeLiteral, interpreter->literalCache.literals[kt]); TYPE_PUSH_SUBTYPE(&typeLiteral, copyLiteral(interpreter->literalCache.literals[kt]));
TYPE_PUSH_SUBTYPE(&typeLiteral, interpreter->literalCache.literals[vt]); TYPE_PUSH_SUBTYPE(&typeLiteral, copyLiteral(interpreter->literalCache.literals[vt]));
} }
//save the type //save the type
pushLiteralArray(&interpreter->literalCache, typeLiteral); pushLiteralArray(&interpreter->literalCache, typeLiteral); //copied
if (command.verbose) { if (command.verbose) {
printf("(type "); printf("(type ");
@@ -1732,7 +1826,7 @@ static void readInterpreterSections(Interpreter* interpreter) {
printf(")\n"); printf(")\n");
} }
// freeLiteral(typeLiteral); freeLiteral(typeLiteral);
} }
break; break;
} }
@@ -1764,6 +1858,7 @@ static void readInterpreterSections(Interpreter* interpreter) {
//change the type to normal //change the type to normal
interpreter->literalCache.literals[i] = TO_FUNCTION_LITERAL(bytes, size); interpreter->literalCache.literals[i] = TO_FUNCTION_LITERAL(bytes, size);
AS_FUNCTION(interpreter->literalCache.literals[i]).scope = pushScope(interpreter->scope); //BUGFIX
} }
} }

View File

@@ -31,7 +31,7 @@ static unsigned int hash(unsigned int x) {
//exposed functions //exposed functions
void freeLiteral(Literal literal) { void freeLiteral(Literal literal) {
if (IS_STRING(literal)) { if (IS_STRING(literal)) {
FREE_ARRAY(char, AS_STRING(literal), literal.as.string.length); FREE_ARRAY(char, AS_STRING(literal), literal.as.string.length + 1);
return; return;
} }
@@ -48,12 +48,13 @@ void freeLiteral(Literal literal) {
} }
if (IS_FUNCTION(literal)) { if (IS_FUNCTION(literal)) {
AS_FUNCTION(literal).scope = popScope(AS_FUNCTION(literal).scope); popScope(AS_FUNCTION(literal).scope);
AS_FUNCTION(literal).scope = NULL;
FREE_ARRAY(unsigned char, AS_FUNCTION(literal).bytecode, AS_FUNCTION(literal).length); FREE_ARRAY(unsigned char, AS_FUNCTION(literal).bytecode, AS_FUNCTION(literal).length);
} }
if (IS_IDENTIFIER(literal)) { if (IS_IDENTIFIER(literal)) {
FREE_ARRAY(char, AS_IDENTIFIER(literal), literal.as.identifier.length); FREE_ARRAY(char, AS_IDENTIFIER(literal), literal.as.identifier.length + 1);
return; return;
} }