Reduced C callstack size in Toy_Scope

This commit is contained in:
2023-02-26 22:31:37 +11:00
parent 624a0c80ba
commit 9b673f23ad

View File

@@ -4,23 +4,21 @@
//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) {
while (scope != NULL) {
Toy_Scope* next = scope->ancestor;
scope->references--; scope->references--;
//free scope chain if (scope->references <= 0) {
if (scope->ancestor != NULL) {
freeAncestorChain(scope->ancestor);
}
if (scope->references > 0) {
return;
}
Toy_freeLiteralDictionary(&scope->variables); Toy_freeLiteralDictionary(&scope->variables);
Toy_freeLiteralDictionary(&scope->types); Toy_freeLiteralDictionary(&scope->types);
TOY_FREE(Toy_Scope, scope); TOY_FREE(Toy_Scope, scope);
} }
scope = next;
}
}
//return false if invalid type //return false if invalid type
static bool checkType(Toy_Literal typeLiteral, Toy_Literal original, Toy_Literal value, bool constCheck) { static bool checkType(Toy_Literal typeLiteral, Toy_Literal original, Toy_Literal value, bool constCheck) {
//for constants, fail if original != value //for constants, fail if original != value
@@ -259,28 +257,24 @@ 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)) {
}
//if it's not in this scope, keep searching up the chain
if (!Toy_existsLiteralDictionary(&scope->variables, key)) {
return Toy_isDelcaredScopeVariable(scope->ancestor, key);
}
return true; return true;
} }
scope = scope->ancestor;
}
return false;
}
//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) {
return false;
}
//if it's not in this scope, keep searching up the chain //if it's not in this scope, keep searching up the chain
if (!Toy_existsLiteralDictionary(&scope->variables, key)) { if (!Toy_existsLiteralDictionary(&scope->variables, key)) {
return Toy_setScopeVariable(scope->ancestor, key, value, constCheck); scope = scope->ancestor;
continue;
} }
//type checking //type checking
@@ -302,31 +296,31 @@ bool Toy_setScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal value,
return true; return true;
} }
bool Toy_getScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal* valueHandle) {
//dead end
if (scope == NULL) {
return false; return false;
} }
//if it's not in this scope, keep searching up the chain bool Toy_getScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal* valueHandle) {
if (!Toy_existsLiteralDictionary(&scope->variables, key)) { //optimized to reduce call stack
return Toy_getScopeVariable(scope->ancestor, key, valueHandle); while (scope != NULL) {
} if (Toy_existsLiteralDictionary(&scope->variables, key)) {
*valueHandle = Toy_getLiteralDictionary(&scope->variables, key); *valueHandle = Toy_getLiteralDictionary(&scope->variables, key);
return true; return true;
} }
scope = scope->ancestor;
}
return false;
}
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;
}
//if it's not in this scope, keep searching up the chain
if (!Toy_existsLiteralDictionary(&scope->types, key)) {
return Toy_getScopeType(scope->ancestor, key);
}
return Toy_getLiteralDictionary(&scope->types, key); return Toy_getLiteralDictionary(&scope->types, key);
} }
scope = scope->ancestor;
}
return TOY_TO_NULL_LITERAL;
}