mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 23:04:08 +10:00
No segfaults, still failing tests
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
if (shouldFree) {
|
||||
freeLiteral(literal);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
else {
|
||||
int index = pushLiteralArray(literalCache, 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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user