No segfaults, still failing tests

This commit is contained in:
2022-09-01 14:00:31 +10:00
parent 3a4017cea5
commit 90b504d3a4
8 changed files with 64 additions and 33 deletions

View File

@@ -336,4 +336,4 @@ var arr: [string] = [
];
print arr;
print arr;

View File

@@ -3,13 +3,15 @@
//test arrays without types
var array = [];
assert _length(array) == 0, "_length failed with array";
_push(array, 1);
_push(array, 2);
_push(array, 3);
_push(array, 4);
_push(array, "foo");
assert _length(array) == 5, "_push or _length failed with array";
assert _length(array) == 5, "_push failed with array";
assert _pop(array) == "foo", "_pop failed with array";
_set(array, 2, "bar");
@@ -43,13 +45,15 @@
//test arrays with types
var array: [int] = [];
assert _length(array) == 0, "_length failed with array (+ types)";
_push(array, 1);
_push(array, 2);
_push(array, 3);
_push(array, 4);
_push(array, 10);
assert _length(array) == 5, "_push or _length failed with array (+ types)";
assert _length(array) == 5, "_push or failed with array (+ types)";
assert _pop(array) == 10, "_pop failed with array (+ types)";
_set(array, 2, 70);

View File

@@ -19,6 +19,8 @@ void initCompiler(Compiler* compiler) {
//separated out, so it can be recursive
static int writeLiteralTypeToCacheOpt(LiteralArray* literalCache, Literal literal, bool skipDuplicationOptimisation) {
bool shouldFree = false;
//if it's a compound type, recurse and store the results
if (AS_TYPE(literal).typeOf == LITERAL_ARRAY || AS_TYPE(literal).typeOf == LITERAL_DICTIONARY) {
//I don't like storing types in an array, but it's the easiest and most straight forward method
@@ -38,6 +40,7 @@ static int writeLiteralTypeToCacheOpt(LiteralArray* literalCache, Literal litera
}
//push the store to the cache, tweaking the type
shouldFree = true;
literal = TO_ARRAY_LITERAL(store);
literal.type = LITERAL_TYPE_INTERMEDIATE; //NOTE: tweaking the type usually isn't a good idea
}
@@ -49,12 +52,16 @@ static int writeLiteralTypeToCacheOpt(LiteralArray* literalCache, Literal litera
index = pushLiteralArray(literalCache, literal);
}
freeLiteral(literal);
if (shouldFree) {
freeLiteral(literal);
}
return index;
}
else {
int index = pushLiteralArray(literalCache, literal);
freeLiteral(literal);
if (shouldFree) {
freeLiteral(literal);
}
return index;
}
}
@@ -411,7 +418,7 @@ static void writeCompilerWithJumps(Compiler* compiler, Node* node, void* breakAd
//embed these in the bytecode...
int index = writeNodeCollectionToCache(compiler, node);
compiler->bytecode[compiler->count] = (unsigned short)index; //2 bytes
AS_USHORT(compiler->bytecode[compiler->count]) = (unsigned short)index; //2 bytes
compiler->count += sizeof(unsigned short);
}
break;

View File

@@ -75,6 +75,7 @@ int _set(Interpreter* interpreter, LiteralArray* arguments) {
Literal val = arguments->literals[2];
parseIdentifierToValue(interpreter, &obj);
parseIdentifierToValue(interpreter, &key);
switch(obj.type) {
case LITERAL_ARRAY: {
@@ -99,17 +100,8 @@ int _set(Interpreter* interpreter, LiteralArray* arguments) {
return -1;
}
parseIdentifierToValue(interpreter, &val);
//if it's a string or an identifier, make a local copy
if (IS_STRING(val)) {
val = TO_STRING_LITERAL(copyString(AS_STRING(val), strlen(AS_STRING(val)) ), strlen(AS_STRING(val)));
}
if (IS_IDENTIFIER(val)) {
val = TO_IDENTIFIER_LITERAL(copyString(AS_IDENTIFIER(val), strlen(AS_IDENTIFIER(val)) ), strlen(AS_STRING(val)));
}
//TODO: proper copy function for literals
//don't use pushLiteralArray, since we're setting
val = copyLiteral(val);
AS_ARRAY(obj)->literals[AS_INTEGER(key)] = val;
return 0;
@@ -197,6 +189,7 @@ int _push(Interpreter* interpreter, LiteralArray* arguments) {
Literal val = arguments->literals[1];
parseIdentifierToValue(interpreter, &obj);
parseIdentifierToValue(interpreter, &val);
switch(obj.type) {
case LITERAL_ARRAY: {
@@ -211,8 +204,6 @@ int _push(Interpreter* interpreter, LiteralArray* arguments) {
}
}
parseIdentifierToValue(interpreter, &val);
pushLiteralArray(AS_ARRAY(obj), val);
return 0;
}
@@ -261,17 +252,25 @@ int _length(Interpreter* interpreter, LiteralArray* arguments) {
switch(obj.type) {
case LITERAL_ARRAY: {
pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( AS_ARRAY(obj)->count ));
Literal lit = TO_INTEGER_LITERAL( AS_ARRAY(obj)->count );
pushLiteralArray(&interpreter->stack, lit);
freeLiteral(lit);
return 1;
}
case LITERAL_DICTIONARY:
pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( AS_DICTIONARY(obj)->count ));
case LITERAL_DICTIONARY: {
Literal lit = TO_INTEGER_LITERAL( AS_DICTIONARY(obj)->count );
pushLiteralArray(&interpreter->stack, lit);
freeLiteral(lit);
return 1;
}
case LITERAL_STRING:
pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( strlen(AS_STRING(obj)) ));
case LITERAL_STRING: {
Literal lit = TO_INTEGER_LITERAL( strlen(AS_STRING(obj)) );
pushLiteralArray(&interpreter->stack, lit);
freeLiteral(lit);
return 1;
}
default:
(interpreter->printOutput)("Incorrect compound type in _length");
@@ -703,7 +702,6 @@ static bool execVarDecl(Interpreter* interpreter, bool lng) {
return false;
}
freeLiteral(type);
freeLiteral(val);
return true;
@@ -727,7 +725,7 @@ static bool execFnDecl(Interpreter* interpreter, bool lng) {
Literal identifier = interpreter->literalCache.literals[identifierIndex];
Literal function = interpreter->literalCache.literals[functionIndex];
function.as.function.scope = scope; //hacked in
function.as.function.scope = pushScope(scope); //hacked in
Literal type = TO_TYPE_LITERAL(LITERAL_FUNCTION, true);
@@ -1153,6 +1151,7 @@ static bool execFnCall(Interpreter* interpreter) {
inner.bytecode = AS_FUNCTION(func).bytecode;
inner.length = func.as.function.length;
inner.count = 0;
inner.panic = false;
initLiteralArray(&inner.stack);
setInterpreterPrint(&inner, interpreter->printOutput);
setInterpreterAssert(&inner, interpreter->assertOutput);
@@ -1178,6 +1177,7 @@ static bool execFnCall(Interpreter* interpreter) {
//free, and skip out
freeLiteralArray(&arguments);
popScope(inner.scope);
freeInterpreter(&inner);
return false;
@@ -1190,6 +1190,7 @@ static bool execFnCall(Interpreter* interpreter) {
printf(ERROR "[internal] Could not re-declare parameter\n" RESET);
//free, and skip out
freeLiteralArray(&arguments);
popScope(inner.scope);
freeInterpreter(&inner);
return false;
}
@@ -1198,6 +1199,7 @@ static bool execFnCall(Interpreter* interpreter) {
printf(ERROR "[internal] Could not define parameter (bad type?)\n" RESET);
//free, and skip out
freeLiteralArray(&arguments);
popScope(inner.scope);
freeInterpreter(&inner);
return false;
}
@@ -1222,6 +1224,7 @@ static bool execFnCall(Interpreter* interpreter) {
freeLiteral(restType);
freeLiteralArray(&rest);
freeLiteralArray(&arguments);
popScope(inner.scope);
freeInterpreter(&inner);
return false;
}
@@ -1232,6 +1235,7 @@ static bool execFnCall(Interpreter* interpreter) {
freeLiteral(restType);
freeLiteralArray(&rest);
freeLiteralArray(&arguments);
popScope(inner.scope);
freeInterpreter(&inner);
return false;
}
@@ -1249,7 +1253,9 @@ static bool execFnCall(Interpreter* interpreter) {
//unpack the results
while (inner.stack.count > 0) {
pushLiteralArray(&returns, popLiteralArray(&inner.stack)); //NOTE: also reverses the order
Literal lit = popLiteralArray(&inner.stack);
pushLiteralArray(&returns, lit); //NOTE: also reverses the order
freeLiteral(lit);
}
//TODO: remove this when multiple assignment is enabled - note the BUGFIX that balances the stack
@@ -1281,6 +1287,7 @@ static bool execFnCall(Interpreter* interpreter) {
}
pushLiteralArray(&interpreter->stack, ret); //NOTE: reverses again
freeLiteral(ret);
}
//free
@@ -1306,7 +1313,9 @@ static bool execFnReturn(Interpreter* interpreter) {
//and back again
while (returns.count > 0) {
pushLiteralArray(&interpreter->stack, popLiteralArray(&returns));
Literal lit = popLiteralArray(&returns);
pushLiteralArray(&interpreter->stack, lit);
freeLiteral(lit);
}
freeLiteralArray(&returns);
@@ -1700,7 +1709,7 @@ static void readInterpreterSections(Interpreter* interpreter) {
if (AS_TYPE(typeLiteral).typeOf == LITERAL_ARRAY) {
unsigned short vt = readShort(interpreter->bytecode, &interpreter->count);
TYPE_PUSH_SUBTYPE(&typeLiteral, interpreter->literalCache.literals[vt]);
TYPE_PUSH_SUBTYPE(&typeLiteral, copyLiteral(interpreter->literalCache.literals[vt]));
}
if (AS_TYPE(typeLiteral).typeOf == LITERAL_DICTIONARY) {
@@ -1720,7 +1729,7 @@ static void readInterpreterSections(Interpreter* interpreter) {
printf(")\n");
}
freeLiteral(typeLiteral);
// freeLiteral(typeLiteral);
}
break;
}

View File

@@ -78,7 +78,9 @@ Literal copyLiteral(Literal original) {
//copy each element
for (int i = 0; i < AS_ARRAY(original)->count; i++) {
pushLiteralArray(array, copyLiteral(AS_ARRAY(original)->literals[i]));
Literal literal = copyLiteral(AS_ARRAY(original)->literals[i]);
pushLiteralArray(array, literal);
freeLiteral(literal);
}
Literal ret = TO_ARRAY_LITERAL(array);
@@ -93,7 +95,7 @@ Literal copyLiteral(Literal original) {
//copy each element
for (int i = 0; i < AS_ARRAY(original)->count; i++) {
Literal literal = copyLiteral(AS_ARRAY(original)->literals[i]);
pushLiteralArray(array, literal );
pushLiteralArray(array, literal);
freeLiteral(literal);
}

View File

@@ -6,6 +6,11 @@
#include <stdlib.h>
void* reallocate(void* pointer, size_t oldSize, size_t newSize) {
if (newSize == 0 && oldSize == 0) {
//causes issues, so just skip out with a NO-OP
return NULL;
}
if (newSize == 0) {
free(pointer);

View File

@@ -121,6 +121,10 @@ Scope* pushScope(Scope* ancestor) {
}
Scope* popScope(Scope* scope) {
if (scope == NULL) { //CAN pop a null
return NULL;
}
Scope* ret = scope->ancestor;
freeAncestorChain(scope);

View File

@@ -16,7 +16,7 @@ all: $(OBJ) $(TESTS:%.c=../$(OUTDIR)/%.exe)
../$(OUTDIR)/%.exe: $(ODIR)/%.o
@$(CC) -o $@ $< $(TARGETS:../source/%.c=$(ODIR)/%.o) $(CFLAGS) $(LIBS)
ifeq ($(shell uname),Linux)
valgrind --leak-check=full $@
valgrind --leak-check=full --track-origins=yes $@
else
@echo please run these tests with valgrind on linux
endif