Remove scopes from generator
This commit is contained in:
@@ -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)
|
||||||
@@ -1321,29 +1296,3 @@ public class CStringLiteral(string value, string 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user