Add basic defer implementation
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System.Diagnostics;
|
||||
using NubLang.Ast;
|
||||
|
||||
namespace NubLang.Generation;
|
||||
@@ -7,6 +8,8 @@ public class Generator
|
||||
private readonly List<DefinitionNode> _definitions;
|
||||
private readonly HashSet<NubStructType> _structTypes;
|
||||
private readonly IndentedTextWriter _writer;
|
||||
private readonly Stack<List<DeferNode>> _deferStack = [];
|
||||
private int _tmpIndex;
|
||||
|
||||
public Generator(List<DefinitionNode> definitions, HashSet<NubStructType> structTypes)
|
||||
{
|
||||
@@ -15,6 +18,12 @@ public class Generator
|
||||
_writer = new IndentedTextWriter();
|
||||
}
|
||||
|
||||
// todo(nub31): Handle name collissions
|
||||
private string NewTmp()
|
||||
{
|
||||
return $"_t{++_tmpIndex}";
|
||||
}
|
||||
|
||||
private static string MapType(NubType nubType)
|
||||
{
|
||||
return nubType switch
|
||||
@@ -246,7 +255,7 @@ public class Generator
|
||||
|
||||
private void EmitDefer(DeferNode deferNode)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
_deferStack.Peek().Add(deferNode);
|
||||
}
|
||||
|
||||
private void EmitIf(IfNode ifNode)
|
||||
@@ -273,12 +282,27 @@ public class Generator
|
||||
{
|
||||
if (returnNode.Value == null)
|
||||
{
|
||||
var blockDefers = _deferStack.Peek();
|
||||
for (var i = blockDefers.Count - 1; i >= 0; i--)
|
||||
{
|
||||
EmitStatement(blockDefers[i].Statement);
|
||||
}
|
||||
|
||||
_writer.WriteLine("return;");
|
||||
}
|
||||
else
|
||||
{
|
||||
var returnValue = EmitExpression(returnNode.Value);
|
||||
_writer.WriteLine($"return {returnValue};");
|
||||
var tmp = NewTmp();
|
||||
_writer.WriteLine($"{MapType(returnNode.Value.Type)} {tmp} = {returnValue};");
|
||||
|
||||
var blockDefers = _deferStack.Peek();
|
||||
for (var i = blockDefers.Count - 1; i >= 0; i--)
|
||||
{
|
||||
EmitStatement(blockDefers[i].Statement);
|
||||
}
|
||||
|
||||
_writer.WriteLine($"return {tmp};");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -559,10 +583,18 @@ public class Generator
|
||||
_writer.WriteLine("{");
|
||||
using (_writer.Indent())
|
||||
{
|
||||
_deferStack.Push([]);
|
||||
|
||||
foreach (var statementNode in blockNode.Statements)
|
||||
{
|
||||
EmitStatement(statementNode);
|
||||
}
|
||||
|
||||
var blockDefers = _deferStack.Pop();
|
||||
for (var i = blockDefers.Count - 1; i >= 0; i--)
|
||||
{
|
||||
EmitStatement(blockDefers[i].Statement);
|
||||
}
|
||||
}
|
||||
|
||||
_writer.WriteLine("}");
|
||||
|
||||
Reference in New Issue
Block a user