diff --git a/src/Unluau/Chunk/IChunk.cs b/src/Unluau/Chunk/IChunk.cs index e38e776..b7fe4ec 100644 --- a/src/Unluau/Chunk/IChunk.cs +++ b/src/Unluau/Chunk/IChunk.cs @@ -22,7 +22,7 @@ public interface IChunk /// /// Translates the current chunk to the IL. /// - /// - public Program Translate(); + /// A block that wraps the IL instructions. + public BasicBlock Translate(); } } diff --git a/src/Unluau/IL/BasicBlock.cs b/src/Unluau/IL/BasicBlock.cs new file mode 100644 index 0000000..880cd8e --- /dev/null +++ b/src/Unluau/IL/BasicBlock.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Unluau.IL.Instructions; + +namespace Unluau.IL +{ + /// + /// Represents a basic block in the program. + /// + /// A list of instructions. + public class BasicBlock(Instruction[] instructions) : Node + { + /// + /// The instructions within the block. + /// + public Instruction[] Instructions { get; set; } = instructions; + + /// + /// Recursive visitor method. + /// + /// The visitor. + public override void Visit(Visitor visitor) + { + if (visitor.Visit(this)) + { + foreach (Instruction instruction in Instructions) + instruction.Visit(visitor); + } + } + } +} diff --git a/src/Unluau/IL/Closure.cs b/src/Unluau/IL/Closure.cs new file mode 100644 index 0000000..a477d30 --- /dev/null +++ b/src/Unluau/IL/Closure.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Unluau.IL +{ + /// + /// Provides information on parameters and contents of a closure. + /// + public struct ClosureContext + { + /// + /// Basic line and instruction information. + /// + public Context Context { get; set; } + } + + /// + /// Represents a function (closure) within the code. + /// + public class Closure(ClosureContext context, BasicBlock[] blocks) : Node(context.Context) + { + /// + /// The children blocks of the closure. Each contain + /// + public BasicBlock[] Blocks { get; set; } = blocks; + + /// + /// Visits the children of the closure. + /// + /// The visitor. + public override void Visit(Visitor visitor) + { + if (visitor.Visit(this)) + { + foreach (var block in Blocks) + block.Visit(visitor); + } + } + } +} diff --git a/src/Unluau/IL/Program.cs b/src/Unluau/IL/Instructions/Instruction.cs similarity index 66% rename from src/Unluau/IL/Program.cs rename to src/Unluau/IL/Instructions/Instruction.cs index f8b2d80..3e2d9f2 100644 --- a/src/Unluau/IL/Program.cs +++ b/src/Unluau/IL/Instructions/Instruction.cs @@ -4,9 +4,9 @@ using System.Text; using System.Threading.Tasks; -namespace Unluau.IL +namespace Unluau.IL.Instructions { - public class Program + public class Instruction : Node { } } diff --git a/src/Unluau/IL/Node.cs b/src/Unluau/IL/Node.cs new file mode 100644 index 0000000..4f37e93 --- /dev/null +++ b/src/Unluau/IL/Node.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Unluau.IL +{ + /// + /// Contains information about location. + /// + public struct Context + { + /// + /// The start and end instruction the node was translated from. + /// + public (int, int) PcScope { get; private set; } + + /// + /// The line number from the original script. + /// + public int? Line { get; private set; } + } + + /// + /// The base node for all IL components. + /// + /// Additional context on the node. + public class Node(Context context) + { + /// + /// Provides additional context on the current node. + /// + public Context Context { get; private set; } = context; + + /// + /// Recursive visitor. + /// + /// The visitor. + public virtual void Visit(Visitor visitor) + { + return; + } + } +} diff --git a/src/Unluau/IL/Variable.cs b/src/Unluau/IL/Variable.cs new file mode 100644 index 0000000..6d7db3b --- /dev/null +++ b/src/Unluau/IL/Variable.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Unluau.IL +{ + public struct Variable + { + /// + /// The name of the variable. + /// + public string? Symbol { get; set; } + + /// + /// The assigned register slot for the variable. + /// + public int Slot { get; set; } + + /// + /// The + /// + public (int, int) PcScope { get; set; } + } +} diff --git a/src/Unluau/IL/Visitor.cs b/src/Unluau/IL/Visitor.cs new file mode 100644 index 0000000..2411769 --- /dev/null +++ b/src/Unluau/IL/Visitor.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Unluau.IL.Instructions; + +namespace Unluau.IL +{ + public class Visitor + { + public virtual bool Visit(Node node) => true; + + public virtual bool Visit(Instruction node) => Visit(node as Node); + } +}