diff --git a/src/Unluau.CLI/Program.cs b/src/Unluau.CLI/Program.cs
index fbd5140..d91bbaf 100644
--- a/src/Unluau.CLI/Program.cs
+++ b/src/Unluau.CLI/Program.cs
@@ -7,7 +7,7 @@ internal class Program
{
static void Main(string[] args)
{
- using var stream = File.OpenRead("./test/input.txt");
+ using var stream = File.OpenRead("./test/Unary.luau");
var chunk = LuauChunk.Create(stream);
Console.WriteLine(chunk.ToString());
diff --git a/src/Unluau/Chunk/Luau/Function.cs b/src/Unluau/Chunk/Luau/Function.cs
index b51fa9f..0825571 100644
--- a/src/Unluau/Chunk/Luau/Function.cs
+++ b/src/Unluau/Chunk/Luau/Function.cs
@@ -526,6 +526,35 @@ OpCode.LOADKX or
block.Statements.Add(new Move(context, ra, rb));
break;
}
+ case OpCode.CONCAT:
+ {
+ var values = new Reference[instruction.C - instruction.B + 1];
+
+ for ( var i = instruction.B; i < instruction.C + 1; ++i )
+ {
+ values[i - instruction.B] = new Reference(context, stack.Get(i)!);
+ }
+
+ stack.Set(instruction.A, new Concat(context, values));
+
+ break;
+ }
+ case OpCode.LENGTH:
+ case OpCode.MINUS:
+ case OpCode.NOT:
+ {
+ var type = instruction.Code switch
+ {
+ OpCode.LENGTH => UnaryType.Length,
+ OpCode.MINUS => UnaryType.Minus,
+ OpCode.NOT => UnaryType.Not,
+ _ => throw new NotSupportedException()
+ };
+
+ stack.Set(instruction.A, new Unary(context, type, new Reference(context, stack.Get(instruction.B)!)));
+
+ break;
+ }
case OpCode.JUMPIFEQ:
case OpCode.JUMPIFLE:
case OpCode.JUMPIFLT:
diff --git a/src/Unluau/IL/Values/Concat.cs b/src/Unluau/IL/Values/Concat.cs
new file mode 100644
index 0000000..5051875
--- /dev/null
+++ b/src/Unluau/IL/Values/Concat.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Unluau.Utils;
+
+namespace Unluau.IL.Values
+{
+ ///
+ /// Concatenates values in registers.
+ ///
+ /// Information about the location.
+ /// The registers that are concatenated together.
+ public class Concat(Context context, BasicValue[] registers) : BasicValue(context)
+ {
+ ///
+ /// The registers that are concatenated together.
+ ///
+ public BasicValue[] Registers { get; set; } = registers;
+
+ ///
+ /// Implements the visitor.
+ ///
+ /// The visitor.
+ public override void Visit(Visitor visitor)
+ {
+ if (visitor.Visit(this))
+ {
+ foreach (var reg in Registers)
+ {
+ reg.Visit(visitor);
+ }
+ }
+ }
+
+ ///
+ /// Converts the current to a string.
+ ///
+ /// String representation.
+ public override string ToString() => $"Concat({TypeExtensions.ToString(Registers)})";
+ }
+}
diff --git a/src/Unluau/IL/Values/Unary.cs b/src/Unluau/IL/Values/Unary.cs
new file mode 100644
index 0000000..56263a9
--- /dev/null
+++ b/src/Unluau/IL/Values/Unary.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Unluau.Utils;
+
+namespace Unluau.IL.Values
+{
+ public enum UnaryType
+ {
+ Not,
+ Minus,
+ Length
+ }
+
+ ///
+ /// Applies unary operation to a register.
+ ///
+ /// Information about the location.
+ /// The type of unary operation.
+ /// The register that the unary operation is applied to.
+ public class Unary(Context context, UnaryType type, BasicValue value) : BasicValue(context)
+ {
+ ///
+ /// The type of unary operation.
+ ///
+ public UnaryType Type { get; set; } = type;
+
+ ///
+ /// The register that the unary operation is applied to.
+ ///
+ public BasicValue Value { get; set; } = value;
+
+ ///
+ /// Implements the visitor.
+ ///
+ /// The visitor.
+ public override void Visit(Visitor visitor)
+ {
+ if (visitor.Visit(this))
+ {
+ Value.Visit(visitor);
+ }
+ }
+
+ ///
+ /// Converts the current to a string.
+ ///
+ /// String representation.
+ public override string ToString() => $"{Enum.GetName(typeof(UnaryType), Type)}({TypeExtensions.ToString(Value)})";
+ }
+}
diff --git a/src/Unluau/IL/Visitors/ValueVisitor.cs b/src/Unluau/IL/Visitors/ValueVisitor.cs
index 4a8c953..9b39100 100644
--- a/src/Unluau/IL/Visitors/ValueVisitor.cs
+++ b/src/Unluau/IL/Visitors/ValueVisitor.cs
@@ -167,6 +167,12 @@ private static BasicValue ResolveValue(BasicValue value)
if (value is Table table)
ResolveTable(table);
+ if (value is Concat concat)
+ concat.Registers = ResolveValueList(concat.Registers);
+
+ if (value is Unary unary)
+ unary.Value = ResolveValue(unary.Value);
+
return value;
}