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,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);
} }