Remove scopes from generator
This commit is contained in:
@@ -17,15 +17,12 @@ public class QBEGenerator
|
||||
private readonly List<StringLiteral> _stringLiterals = [];
|
||||
private readonly Stack<string> _breakLabels = [];
|
||||
private readonly Stack<string> _continueLabels = [];
|
||||
private readonly Stack<Scope> _scopes = [];
|
||||
private int _tmpIndex;
|
||||
private int _labelIndex;
|
||||
private int _cStringLiteralIndex;
|
||||
private int _stringLiteralIndex;
|
||||
private bool _codeIsReachable = true;
|
||||
|
||||
private Scope Scope => _scopes.Peek();
|
||||
|
||||
public QBEGenerator(TypedSyntaxTree syntaxTree, TypedDefinitionTable definitionTable)
|
||||
{
|
||||
_syntaxTree = syntaxTree;
|
||||
@@ -39,7 +36,6 @@ public class QBEGenerator
|
||||
_stringLiterals.Clear();
|
||||
_breakLabels.Clear();
|
||||
_continueLabels.Clear();
|
||||
_scopes.Clear();
|
||||
_tmpIndex = 0;
|
||||
_labelIndex = 0;
|
||||
_cStringLiteralIndex = 0;
|
||||
@@ -364,14 +360,7 @@ public class QBEGenerator
|
||||
_writer.WriteLine(") {");
|
||||
_writer.WriteLine("@start");
|
||||
|
||||
var scope = new Scope();
|
||||
|
||||
foreach (var parameter in funcDef.Signature.Parameters)
|
||||
{
|
||||
scope.Declare(parameter.Name, new Val("%" + parameter.Name, parameter.Type, false));
|
||||
}
|
||||
|
||||
EmitBlock(funcDef.Body, scope);
|
||||
EmitBlock(funcDef.Body);
|
||||
|
||||
// Implicit return for void functions if no explicit return has been set
|
||||
if (funcDef.Signature.ReturnType is VoidTypeNode && funcDef.Body.Statements is [.., not ReturnNode])
|
||||
@@ -408,15 +397,7 @@ public class QBEGenerator
|
||||
_writer.WriteLine(") {");
|
||||
_writer.WriteLine("@start");
|
||||
|
||||
var scope = new Scope();
|
||||
|
||||
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);
|
||||
EmitBlock(function.Body);
|
||||
|
||||
// Implicit return for void functions if no explicit return has been set
|
||||
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)
|
||||
{
|
||||
if (_codeIsReachable)
|
||||
@@ -491,8 +470,6 @@ public class QBEGenerator
|
||||
}
|
||||
}
|
||||
|
||||
_scopes.Pop();
|
||||
|
||||
_codeIsReachable = true;
|
||||
}
|
||||
|
||||
@@ -599,8 +576,6 @@ public class QBEGenerator
|
||||
var value = EmitCreateCopyOrInitialize(variableDeclaration.Assignment.Value);
|
||||
EmitStore(variableDeclaration.Assignment.Value.Type, value, name);
|
||||
}
|
||||
|
||||
Scope.Declare(variableDeclaration.Name, new Val(name, variableDeclaration.Type, true));
|
||||
}
|
||||
|
||||
private void EmitWhile(WhileNode whileStatement)
|
||||
@@ -1320,30 +1295,4 @@ public class CStringLiteral(string value, string name)
|
||||
public string Name { get; } = name;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
public record Val(string Name, TypeNode Type, bool IsLValue);
|
||||
Reference in New Issue
Block a user