Scoping now works

This commit is contained in:
2026-02-28 13:18:40 +11:00
parent 2719017f72
commit 3b3fd447fa
3 changed files with 47 additions and 2 deletions

View File

@@ -22,3 +22,27 @@ SolsVariable* findSolsVariable(SolsScope* scope, const char* name) {
HASH_FIND_STR(scope->variables, name, s); HASH_FIND_STR(scope->variables, name, s);
return s; return s;
} }
SolsScope copySolsScope(SolsScope* scope) {
SolsScope newScope = {
.variables = NULL,
.tmpCounter = scope->tmpCounter
};
SolsVariable *var, *tmp;
HASH_ITER(hh, scope->variables, var, tmp) {
addVariableToScope(&newScope, var->id, var->typeinfo);
}
return newScope;
}
void destroySolsScope(SolsScope* scope) {
SolsVariable *var, *tmp;
HASH_ITER(hh, scope->variables, var, tmp) {
HASH_DEL(scope->variables, var);
free(var);
}
}

View File

@@ -22,4 +22,10 @@ void addVariableToScope(SolsScope* scope, const char* name, SolsType type);
// Finds a variable in the SolsScope. // Finds a variable in the SolsScope.
SolsVariable* findSolsVariable(SolsScope* scope, const char* name); SolsVariable* findSolsVariable(SolsScope* scope, const char* name);
// Deep copies a SolsScope, usually for being inside a code block
SolsScope copySolsScope(SolsScope* scope);
// Destroys everything in the SolsScope
void destroySolsScope(SolsScope* scope);
#endif #endif

View File

@@ -202,6 +202,11 @@ static inline ResultType(GroundProgram, charptr) generatePutsNode(SolsNode* node
} }
GroundInstruction inst = groundCreateInstruction(PRINTLN); GroundInstruction inst = groundCreateInstruction(PRINTLN);
for (size_t i = 0; i < node->children.count; i++) { for (size_t i = 0; i < node->children.count; i++) {
// Validate arg
ResultType(SolsType, charptr) type = getNodeType(&node->children.at[i], scope);
if (type.error) {
return Error(GroundProgram, charptr, type.as.error);
}
groundAddReferenceToInstruction(&inst, node->children.at[i].accessArg); groundAddReferenceToInstruction(&inst, node->children.at[i].accessArg);
} }
GroundProgram program = groundCreateProgram(); GroundProgram program = groundCreateProgram();
@@ -216,7 +221,7 @@ static inline ResultType(GroundProgram, charptr) generateSetNode(SolsNode* node,
if (node->children.at[0].type != SNT_IDENTIFIER) { if (node->children.at[0].type != SNT_IDENTIFIER) {
return Error(GroundProgram, charptr, "set requires an identifier before '='"); return Error(GroundProgram, charptr, "set requires an identifier before '='");
} }
SolsVariable* var = findSolsVariable(scope, node->as.idName); SolsVariable* var = findSolsVariable(scope, node->children.at[0].as.idName);
ResultType(SolsType, charptr) type = getNodeType(&node->children.at[1], scope); ResultType(SolsType, charptr) type = getNodeType(&node->children.at[1], scope);
if (type.error) { if (type.error) {
return Error(GroundProgram, charptr, type.as.error); return Error(GroundProgram, charptr, type.as.error);
@@ -232,7 +237,6 @@ static inline ResultType(GroundProgram, charptr) generateSetNode(SolsNode* node,
return Error(GroundProgram, charptr, "Type of variable cannot be changed"); return Error(GroundProgram, charptr, "Type of variable cannot be changed");
} }
} }
addVariableToScope(scope, node->children.at[0].as.idName, type.as.success);
GroundProgram gp = groundCreateProgram(); GroundProgram gp = groundCreateProgram();
GroundInstruction gi = groundCreateInstruction(SET); GroundInstruction gi = groundCreateInstruction(SET);
@@ -664,7 +668,14 @@ ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope
GroundProgram program = groundCreateProgram(); GroundProgram program = groundCreateProgram();
SolsScope backupScope = {NULL, 0};
if (node->type != SNT_IF && node->type != SNT_WHILE) { if (node->type != SNT_IF && node->type != SNT_WHILE) {
if (node->type == SNT_CODE_BLOCK) {
backupScope = *scope;
SolsScope newScope = copySolsScope(scope);
*scope = newScope;
}
// Generate code for all children before generating this node's code // Generate code for all children before generating this node's code
for (size_t i = 0; i < node->children.count; i++) { for (size_t i = 0; i < node->children.count; i++) {
ResultType(GroundProgram, charptr) generated = generateCode(&node->children.at[i], scope); ResultType(GroundProgram, charptr) generated = generateCode(&node->children.at[i], scope);
@@ -675,6 +686,10 @@ ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope
groundAddInstructionToProgram(&program, generated.as.success.instructions[j]); groundAddInstructionToProgram(&program, generated.as.success.instructions[j]);
} }
} }
if (node->type == SNT_CODE_BLOCK) {
destroySolsScope(scope);
*scope = backupScope;
}
} }
// Now generate code for this node // Now generate code for this node