Remove scopes from generator

This commit is contained in:
nub31
2025-09-08 17:48:29 +02:00
parent 51e7f6da63
commit 2ff77a1f99

View File

@@ -17,15 +17,12 @@ public class QBEGenerator
private readonly List<StringLiteral> _stringLiterals = []; private readonly List<StringLiteral> _stringLiterals = [];
private readonly Stack<string> _breakLabels = []; private readonly Stack<string> _breakLabels = [];
private readonly Stack<string> _continueLabels = []; private readonly Stack<string> _continueLabels = [];
private readonly Stack<Scope> _scopes = [];
private int _tmpIndex; private int _tmpIndex;
private int _labelIndex; private int _labelIndex;
private int _cStringLiteralIndex; private int _cStringLiteralIndex;
private int _stringLiteralIndex; private int _stringLiteralIndex;
private bool _codeIsReachable = true; private bool _codeIsReachable = true;
private Scope Scope => _scopes.Peek();
public QBEGenerator(TypedSyntaxTree syntaxTree, TypedDefinitionTable definitionTable) public QBEGenerator(TypedSyntaxTree syntaxTree, TypedDefinitionTable definitionTable)
{ {
_syntaxTree = syntaxTree; _syntaxTree = syntaxTree;
@@ -39,7 +36,6 @@ public class QBEGenerator
_stringLiterals.Clear(); _stringLiterals.Clear();
_breakLabels.Clear(); _breakLabels.Clear();
_continueLabels.Clear(); _continueLabels.Clear();
_scopes.Clear();
_tmpIndex = 0; _tmpIndex = 0;
_labelIndex = 0; _labelIndex = 0;
_cStringLiteralIndex = 0; _cStringLiteralIndex = 0;
@@ -364,14 +360,7 @@ public class QBEGenerator
_writer.WriteLine(") {"); _writer.WriteLine(") {");
_writer.WriteLine("@start"); _writer.WriteLine("@start");
var scope = new Scope(); EmitBlock(funcDef.Body);
foreach (var parameter in funcDef.Signature.Parameters)
{
scope.Declare(parameter.Name, new Val("%" + parameter.Name, parameter.Type, false));
}
EmitBlock(funcDef.Body, scope);
// Implicit return for void functions if no explicit return has been set // Implicit return for void functions if no explicit return has been set
if (funcDef.Signature.ReturnType is VoidTypeNode && funcDef.Body.Statements is [.., not ReturnNode]) if (funcDef.Signature.ReturnType is VoidTypeNode && funcDef.Body.Statements is [.., not ReturnNode])
@@ -408,15 +397,7 @@ public class QBEGenerator
_writer.WriteLine(") {"); _writer.WriteLine(") {");
_writer.WriteLine("@start"); _writer.WriteLine("@start");
var scope = new Scope(); EmitBlock(function.Body);
scope.Declare("this", new Val("%this", structDef.Type, false));
foreach (var parameter in function.Signature.Parameters)
{
scope.Declare(parameter.Name, new Val("%" + parameter.Name, parameter.Type, false));
}
EmitBlock(function.Body, scope);
// Implicit return for void functions if no explicit return has been set // Implicit return for void functions if no explicit return has been set
if (function.Signature.ReturnType is VoidTypeNode && function.Body.Statements is [.., not ReturnNode]) if (function.Signature.ReturnType is VoidTypeNode && function.Body.Statements is [.., not ReturnNode])
@@ -479,10 +460,8 @@ public class QBEGenerator
} }
} }
private void EmitBlock(BlockNode block, Scope? scope = null) private void EmitBlock(BlockNode block)
{ {
_scopes.Push(scope ?? Scope.SubScope());
foreach (var statement in block.Statements) foreach (var statement in block.Statements)
{ {
if (_codeIsReachable) if (_codeIsReachable)
@@ -491,8 +470,6 @@ public class QBEGenerator
} }
} }
_scopes.Pop();
_codeIsReachable = true; _codeIsReachable = true;
} }
@@ -599,8 +576,6 @@ public class QBEGenerator
var value = EmitCreateCopyOrInitialize(variableDeclaration.Assignment.Value); var value = EmitCreateCopyOrInitialize(variableDeclaration.Assignment.Value);
EmitStore(variableDeclaration.Assignment.Value.Type, value, name); EmitStore(variableDeclaration.Assignment.Value.Type, value, name);
} }
Scope.Declare(variableDeclaration.Name, new Val(name, variableDeclaration.Type, true));
} }
private void EmitWhile(WhileNode whileStatement) private void EmitWhile(WhileNode whileStatement)
@@ -1320,30 +1295,4 @@ public class CStringLiteral(string value, string name)
public string Name { get; } = name; public string Name { get; } = name;
} }
public record Val(string Name, TypeNode Type, bool IsLValue); public record Val(string Name, TypeNode Type, bool IsLValue);
public class Scope(Scope? parent = null)
{
private readonly Dictionary<string, Val> _variables = [];
public Val Lookup(string name)
{
var variable = _variables.GetValueOrDefault(name);
if (variable != null)
{
return variable;
}
return parent?.Lookup(name) ?? throw new UnreachableException($"Variable '{name}' not found");
}
public void Declare(string name, Val value)
{
_variables.Add(name, value);
}
public Scope SubScope()
{
return new Scope(this);
}
}