diff --git a/source/script/StringClass.c b/source/script/StringClass.c index 1de459e..c534d46 100644 --- a/source/script/StringClass.c +++ b/source/script/StringClass.c @@ -47,12 +47,23 @@ ClassFunction(getStringLength) { return newIntVariablePtr(strlen(s1)); } +ClassFunction(stringBytes) { + Variable_t v = { 0 }; + v.variableType = ByteArrayClass; + u32 len = strlen(caller->string.value); + v.solvedArray.vector = newVec(1, len); + v.solvedArray.vector.count = len; + memcpy(v.solvedArray.vector.data, caller->string.value, len); + return copyVariableToPtr(v); +} + u8 oneStringArg[] = { StringClass }; ClassFunctionTableEntry_t stringFunctions[] = { {"print", printStringVariable, 0, 0}, {"+", addStringVariables, 1, oneStringArg }, {"len", getStringLength, 0, 0}, + {"bytes", stringBytes, 0, 0}, }; Variable_t getStringMember(Variable_t* var, char* memberName) { diff --git a/source/script/arrayClass.c b/source/script/arrayClass.c index a7b7d28..21e3b3c 100644 --- a/source/script/arrayClass.c +++ b/source/script/arrayClass.c @@ -98,23 +98,28 @@ ClassFunction(arraySlice) { return copyVariableToPtr(refSkip); } +// TODO: arrayForEach does not like the new garbage collector ClassFunction(arrayForEach) { Vector_t* v = &caller->solvedArray.vector; Callback_SetVar_t setVar = { .isTopLevel = 1, .varName = (*args)->string.value }; Variable_t* iter = NULL; iter = copyVariableToPtr(newIntVariable(0)); - + iter->gcDoNotFree = 1; runtimeVariableEdit(&setVar, iter); for (int i = 0; i < v->count; i++) { *iter = arrayClassGetIdx(caller, i); + iter->gcDoNotFree = 1; Variable_t* res = genericCallDirect(args[1], NULL, 0); if (res == NULL) return NULL; } + iter->reference = 1; + free(iter); + return &emptyClass; } diff --git a/source/script/eval.c b/source/script/eval.c index 747a2e2..41a6f46 100644 --- a/source/script/eval.c +++ b/source/script/eval.c @@ -69,6 +69,10 @@ Variable_t* opToVar(Operator_t* op, Callback_SetVar_t *setCallback) { else if (op->variable.staticVariableType == 3) { var = copyVariableToPtr(newFunctionVariable(createFunctionClass((Function_t) { 0 }, op->variable.staticFunction))); var->reference = 1; + + if (!strcmp(var->function.builtInPtr->name,"while")) { + var->function.firstArgAsFunction = 1; + } } } else { diff --git a/source/script/garbageCollector.c b/source/script/garbageCollector.c index a0f51b1..0eaca3b 100644 --- a/source/script/garbageCollector.c +++ b/source/script/garbageCollector.c @@ -24,6 +24,23 @@ void modReference(Variable_t* ref, u8 add) { if (ref == NULL || ref->gcDoNotFree) return; + if (add) { + ref->tagCount++; + } + else { + ref->tagCount--; + if (ref->tagCount <= 0) { + if (ref->variableType == FunctionClass && ref->function.builtIn && ref->function.origin != NULL) + modReference(ref->function.origin, 0); + + if (ref->variableType == SolvedArrayReferenceClass) + modReference(ref->solvedArray.arrayClassReference, 0); + + freeVariable(&ref); + } + } + + /* ReferenceCounter_t* additionalFree = NULL; vecForEach(ReferenceCounter_t*, references, (&storedReferences)) { @@ -59,6 +76,7 @@ void modReference(Variable_t* ref, u8 add) { ReferenceCounter_t r = { .ref = ref, .refCount = 1 }; vecAdd(&storedReferences, r); + */ } /* void addPendingReference(Variable_t* ref) { diff --git a/source/script/genericClass.c b/source/script/genericClass.c index 02334f0..56f082e 100644 --- a/source/script/genericClass.c +++ b/source/script/genericClass.c @@ -17,6 +17,7 @@ Variable_t* copyVariableToPtr(Variable_t var) { Variable_t* a = malloc(sizeof(Variable_t)); *a = var; + a->tagCount = 0; addPendingReference(a); return a; } @@ -201,6 +202,7 @@ Variable_t getGenericFunctionMember(Variable_t* var, char* memberName, ClassFunc } } + printScriptError(SCRIPT_FATAL, "Could not find member of class"); return (Variable_t){ 0 }; } diff --git a/source/script/model.h b/source/script/model.h index 2faaaef..db004aa 100644 --- a/source/script/model.h +++ b/source/script/model.h @@ -185,6 +185,7 @@ typedef struct _Variable_t { u8 gcDoNotFree : 1; }; }; + u8 tagCount; } Variable_t; typedef struct _CallArgs_t {