mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Reduced C callstack size in Toy_Scope
This commit is contained in:
@@ -4,21 +4,19 @@
|
|||||||
|
|
||||||
//run up the ancestor chain, freeing anything with 0 references left
|
//run up the ancestor chain, freeing anything with 0 references left
|
||||||
static void freeAncestorChain(Toy_Scope* scope) {
|
static void freeAncestorChain(Toy_Scope* scope) {
|
||||||
scope->references--;
|
while (scope != NULL) {
|
||||||
|
Toy_Scope* next = scope->ancestor;
|
||||||
|
|
||||||
//free scope chain
|
scope->references--;
|
||||||
if (scope->ancestor != NULL) {
|
|
||||||
freeAncestorChain(scope->ancestor);
|
if (scope->references <= 0) {
|
||||||
|
Toy_freeLiteralDictionary(&scope->variables);
|
||||||
|
Toy_freeLiteralDictionary(&scope->types);
|
||||||
|
TOY_FREE(Toy_Scope, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
scope = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scope->references > 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_freeLiteralDictionary(&scope->variables);
|
|
||||||
Toy_freeLiteralDictionary(&scope->types);
|
|
||||||
|
|
||||||
TOY_FREE(Toy_Scope, scope);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//return false if invalid type
|
//return false if invalid type
|
||||||
@@ -259,74 +257,70 @@ bool Toy_declareScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal typ
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Toy_isDelcaredScopeVariable(Toy_Scope* scope, Toy_Literal key) {
|
bool Toy_isDelcaredScopeVariable(Toy_Scope* scope, Toy_Literal key) {
|
||||||
if (scope == NULL) {
|
while (scope != NULL) {
|
||||||
return false;
|
if (Toy_existsLiteralDictionary(&scope->variables, key)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
scope = scope->ancestor;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if it's not in this scope, keep searching up the chain
|
return false;
|
||||||
if (!Toy_existsLiteralDictionary(&scope->variables, key)) {
|
|
||||||
return Toy_isDelcaredScopeVariable(scope->ancestor, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//return false if undefined, or can't be assigned
|
//return false if undefined, or can't be assigned
|
||||||
bool Toy_setScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal value, bool constCheck) {
|
bool Toy_setScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal value, bool constCheck) {
|
||||||
//dead end
|
while (scope != NULL) {
|
||||||
if (scope == NULL) {
|
//if it's not in this scope, keep searching up the chain
|
||||||
return false;
|
if (!Toy_existsLiteralDictionary(&scope->variables, key)) {
|
||||||
}
|
scope = scope->ancestor;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
//if it's not in this scope, keep searching up the chain
|
//type checking
|
||||||
if (!Toy_existsLiteralDictionary(&scope->variables, key)) {
|
Toy_Literal typeLiteral = Toy_getLiteralDictionary(&scope->types, key);
|
||||||
return Toy_setScopeVariable(scope->ancestor, key, value, constCheck);
|
Toy_Literal original = Toy_getLiteralDictionary(&scope->variables, key);
|
||||||
}
|
|
||||||
|
|
||||||
//type checking
|
if (!checkType(typeLiteral, original, value, constCheck)) {
|
||||||
Toy_Literal typeLiteral = Toy_getLiteralDictionary(&scope->types, key);
|
Toy_freeLiteral(typeLiteral);
|
||||||
Toy_Literal original = Toy_getLiteralDictionary(&scope->variables, key);
|
Toy_freeLiteral(original);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//actually assign
|
||||||
|
Toy_setLiteralDictionary(&scope->variables, key, value); //key & value are copied here
|
||||||
|
|
||||||
if (!checkType(typeLiteral, original, value, constCheck)) {
|
|
||||||
Toy_freeLiteral(typeLiteral);
|
Toy_freeLiteral(typeLiteral);
|
||||||
Toy_freeLiteral(original);
|
Toy_freeLiteral(original);
|
||||||
return false;
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//actually assign
|
return false;
|
||||||
Toy_setLiteralDictionary(&scope->variables, key, value); //key & value are copied here
|
|
||||||
|
|
||||||
Toy_freeLiteral(typeLiteral);
|
|
||||||
Toy_freeLiteral(original);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Toy_getScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal* valueHandle) {
|
bool Toy_getScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal* valueHandle) {
|
||||||
//dead end
|
//optimized to reduce call stack
|
||||||
if (scope == NULL) {
|
while (scope != NULL) {
|
||||||
return false;
|
if (Toy_existsLiteralDictionary(&scope->variables, key)) {
|
||||||
|
*valueHandle = Toy_getLiteralDictionary(&scope->variables, key);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
scope = scope->ancestor;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if it's not in this scope, keep searching up the chain
|
return false;
|
||||||
if (!Toy_existsLiteralDictionary(&scope->variables, key)) {
|
|
||||||
return Toy_getScopeVariable(scope->ancestor, key, valueHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
*valueHandle = Toy_getLiteralDictionary(&scope->variables, key);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Toy_Literal Toy_getScopeType(Toy_Scope* scope, Toy_Literal key) {
|
Toy_Literal Toy_getScopeType(Toy_Scope* scope, Toy_Literal key) {
|
||||||
//dead end
|
while (scope != NULL) {
|
||||||
if (scope == NULL) {
|
if (Toy_existsLiteralDictionary(&scope->types, key)) {
|
||||||
return TOY_TO_NULL_LITERAL;
|
return Toy_getLiteralDictionary(&scope->types, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
scope = scope->ancestor;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if it's not in this scope, keep searching up the chain
|
return TOY_TO_NULL_LITERAL;
|
||||||
if (!Toy_existsLiteralDictionary(&scope->types, key)) {
|
|
||||||
return Toy_getScopeType(scope->ancestor, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Toy_getLiteralDictionary(&scope->types, key);
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user