From 8c6e70b63dcb40c3515daaf48fc2317bf99b81b4 Mon Sep 17 00:00:00 2001 From: suchmememanyskill Date: Mon, 12 Jul 2021 18:04:52 +0200 Subject: [PATCH] add dicts --- source/script/ABadIdeaVersion3.vcxproj | 1 + .../script/ABadIdeaVersion3.vcxproj.filters | 3 ++ source/script/dictionaryClass.c | 50 +++++++++++++++++++ source/script/dictionaryClass.h | 3 ++ source/script/eval.c | 3 ++ source/script/genericClass.c | 29 +++++++++-- source/script/model.h | 2 + source/script/standardLibrary.c | 9 ++++ 8 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 source/script/dictionaryClass.c diff --git a/source/script/ABadIdeaVersion3.vcxproj b/source/script/ABadIdeaVersion3.vcxproj index 2deb8e2..53eb1d3 100644 --- a/source/script/ABadIdeaVersion3.vcxproj +++ b/source/script/ABadIdeaVersion3.vcxproj @@ -145,6 +145,7 @@ + diff --git a/source/script/ABadIdeaVersion3.vcxproj.filters b/source/script/ABadIdeaVersion3.vcxproj.filters index b6dfa81..26caa24 100644 --- a/source/script/ABadIdeaVersion3.vcxproj.filters +++ b/source/script/ABadIdeaVersion3.vcxproj.filters @@ -87,6 +87,9 @@ Source Files\Classes\Elseable + + Source Files\Classes\Dictionary + diff --git a/source/script/dictionaryClass.c b/source/script/dictionaryClass.c new file mode 100644 index 0000000..242b141 --- /dev/null +++ b/source/script/dictionaryClass.c @@ -0,0 +1,50 @@ +#include "dictionaryClass.h" +#include +#include "garbageCollector.h" + +u8 dictOneStrOneAll[] = { StringClass, VARARGCOUNT }; + +Dict_t* getEntry(Vector_t *v, char* name) { + vecForEach(Dict_t*, dict, v) { + if (!strcmp(name, dict->name)) { + return dict; + } + } + return NULL; +} + +ClassFunction(dictSet) { + addPendingReference(args[1]); + char* arg = CpyStr(args[0]->string.value); + Dict_t* possibleEntry = getEntry(&caller->dictionary.vector, arg); + if (possibleEntry == NULL) { + Dict_t a = { .name = arg, .var = args[1] }; + vecAdd(&caller->dictionary.vector, a); + } + else { + possibleEntry->var = args[1]; + free(arg); + } + return &emptyClass; +} + +ClassFunctionTableEntry_t dictFunctions[] = { + {"set", dictSet, 2, dictOneStrOneAll}, +}; + +Variable_t getDictMember(Variable_t* var, char* memberName) { + if (!strcmp(memberName, "set")) + return getGenericFunctionMember(var, memberName, dictFunctions, ARRAY_SIZE(dictFunctions)); + + vecForEach(Dict_t*, dict, (&var->dictionary.vector)) { + if (!strcmp(dict->name, memberName)) { + Variable_t a = { 0 }; + a.variableType = ReferenceType; + a.referenceType = dict->var; + addPendingReference(dict->var); + return a; + } + } + + return (Variable_t) { 0 }; +} \ No newline at end of file diff --git a/source/script/dictionaryClass.h b/source/script/dictionaryClass.h index 665b57c..8cb5361 100644 --- a/source/script/dictionaryClass.h +++ b/source/script/dictionaryClass.h @@ -1,3 +1,6 @@ #pragma once #include "model.h" #include "genericClass.h" +#include "compat.h" + +Variable_t getDictMember(Variable_t* var, char* memberName); \ No newline at end of file diff --git a/source/script/eval.c b/source/script/eval.c index 41a6f46..7de4649 100644 --- a/source/script/eval.c +++ b/source/script/eval.c @@ -187,6 +187,9 @@ void runtimeVariableEdit(Callback_SetVar_t* set, Variable_t* curRes) { callMemberFunctionDirect(set->setVar, "set", args, 2); } + removePendingReference(curRes); + removePendingReference(set->setVar); + // TODO: add non-top level sets } diff --git a/source/script/genericClass.c b/source/script/genericClass.c index 56f082e..7b9b412 100644 --- a/source/script/genericClass.c +++ b/source/script/genericClass.c @@ -13,6 +13,7 @@ #include "saveClass.h" #include "unsolvedArrayClass.h" #include "else.h" +#include "dictionaryClass.h" Variable_t* copyVariableToPtr(Variable_t var) { Variable_t* a = malloc(sizeof(Variable_t)); @@ -31,12 +32,12 @@ MemberGetters_t memberGetters[] = { {SolvedArrayReferenceClass, getArrayReferenceMember}, {UnresolvedArrayClass, getUnsolvedArrayMember}, {ElseClass, getElseMember}, + {DictionaryClass, getDictMember}, #ifndef WIN32 {SaveClass, getSaveMember}, #endif }; - Variable_t* genericGet(Variable_t* var, CallArgs_t* ref) { if (ref->extraAction == ActionExtraMemberName) { for (u32 i = 0; i < ARRAY_SIZE(memberGetters); i++) { @@ -45,6 +46,10 @@ Variable_t* genericGet(Variable_t* var, CallArgs_t* ref) { if (member.variableType == None) return NULL; + if (member.variableType == ReferenceType) { + return member.referenceType; + } + addPendingReference(var); // So caller doesn't fall out of scope. Don't forget to free! return copyVariableToPtr(member); } @@ -186,6 +191,7 @@ Variable_t* genericCall(Variable_t* var, CallArgs_t* ref) { } } +// TODO: add staticStorage Variable_t getGenericFunctionMember(Variable_t* var, char* memberName, ClassFunctionTableEntry_t* entries, u8 len) { Variable_t newVar = {.readOnly = 1, .variableType = FunctionClass}; newVar.function.origin = var; @@ -213,7 +219,12 @@ Variable_t* callMemberFunction(Variable_t* var, char* memberName, CallArgs_t* ar if (funcRef.variableType == None) return NULL; - return genericCall(&funcRef, args); + Variable_t* ptr = &funcRef; + if (funcRef.variableType == ReferenceType) { + ptr = funcRef.referenceType; + } + + return genericCall(ptr, args); } } @@ -228,7 +239,12 @@ Variable_t* callMemberFunctionDirect(Variable_t* var, char* memberName, Variable SCRIPT_FATAL_ERR("Did not find member '%s'", memberName); } - return genericCallDirect(&funcRef, args, argsLen); + Variable_t* ptr = &funcRef; + if (funcRef.variableType == ReferenceType) { + ptr = funcRef.referenceType; + } + + return genericCallDirect(ptr, args, argsLen); } } @@ -251,6 +267,13 @@ void freeVariableInternal(Variable_t* referencedTarget) { case IntArrayClass: vecFree(referencedTarget->solvedArray.vector); break; + case DictionaryClass:; + vecForEach(Dict_t*, dict, (&referencedTarget->dictionary.vector)) { + modReference(dict->var, 0); + free(dict->name); + } + FREE(referencedTarget->dictionary.vector.data); + break; } } diff --git a/source/script/model.h b/source/script/model.h index db004aa..d2596d1 100644 --- a/source/script/model.h +++ b/source/script/model.h @@ -36,6 +36,7 @@ typedef enum { SolvedArrayReferenceClass, SaveClass, ElseClass, + ReferenceType, } VariableType_t; typedef enum { @@ -176,6 +177,7 @@ typedef struct _Variable_t { #ifndef WIN32 SaveClass_t *save; #endif + struct _Variable_t* referenceType; }; union { struct { diff --git a/source/script/standardLibrary.c b/source/script/standardLibrary.c index 084f57d..56d3818 100644 --- a/source/script/standardLibrary.c +++ b/source/script/standardLibrary.c @@ -79,6 +79,13 @@ ClassFunction(stdBreak) { return NULL; } +ClassFunction(stdDict) { + Variable_t a = { 0 }; + a.variableType = DictionaryClass; + a.dictionary.vector = newVec(sizeof(Dict_t), 0); + return copyVariableToPtr(a); +} + #ifndef WIN32 ClassFunction(stdMountSysmmc){ if (connectMMC(MMC_CONN_EMMC)) @@ -121,6 +128,7 @@ enum standardFunctionIndexes { STD_MOUNTSAVE, STD_EXIT, STD_BREAK, + STD_DICT, }; u8 oneIntoneFunction[] = { IntClass, FunctionClass }; @@ -135,6 +143,7 @@ ClassFunctionTableEntry_t standardFunctionDefenitions[] = { [STD_MOUNTSAVE] = {"readsave", stdMountSave, 1, oneStringArgStd}, [STD_EXIT] = {"exit", stdExit, 0, 0}, [STD_BREAK] = {"break", stdBreak, 0, 0}, + [STD_DICT] = {"dict", stdDict, 0, 0}, }; ClassFunctionTableEntry_t* searchStdLib(char* funcName) {