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