Add basic defer implementation

This commit is contained in:
nub31
2025-10-16 16:25:02 +02:00
parent a7d5479dab
commit a393699666

View File

@@ -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("}");