|
@@ -21,6 +21,8 @@ public sealed class LuaCompiler : ISyntaxNodeVisitor<ScopeCompilationContext, bo
|
|
|
{
|
|
{
|
|
|
using var context = FunctionCompilationContext.Create(null);
|
|
using var context = FunctionCompilationContext.Create(null);
|
|
|
context.HasVariableArguments = true;
|
|
context.HasVariableArguments = true;
|
|
|
|
|
+ context.LineDefined = syntaxTree.Position.Line;
|
|
|
|
|
+ context.LastLineDefined = syntaxTree.Position.Line;
|
|
|
// set global enviroment upvalue
|
|
// set global enviroment upvalue
|
|
|
context.AddUpValue(new()
|
|
context.AddUpValue(new()
|
|
|
{
|
|
{
|
|
@@ -586,10 +588,10 @@ public sealed class LuaCompiler : ISyntaxNodeVisitor<ScopeCompilationContext, bo
|
|
|
// function declaration
|
|
// function declaration
|
|
|
public bool VisitFunctionDeclarationExpressionNode(FunctionDeclarationExpressionNode node, ScopeCompilationContext context)
|
|
public bool VisitFunctionDeclarationExpressionNode(FunctionDeclarationExpressionNode node, ScopeCompilationContext context)
|
|
|
{
|
|
{
|
|
|
- var funcIndex = CompileFunctionProto(ReadOnlyMemory<char>.Empty, context, node.ParameterNodes, node.Nodes, node.ParameterNodes.Length, node.HasVariableArguments, false, node.LineDefined, node.LastLineDefined);
|
|
|
|
|
|
|
+ var funcIndex = CompileFunctionProto(ReadOnlyMemory<char>.Empty, context, node.ParameterNodes, node.Nodes, node.ParameterNodes.Length, node.HasVariableArguments, false, node.LineDefined, node.EndPosition.Line);
|
|
|
|
|
|
|
|
// push closure instruction
|
|
// push closure instruction
|
|
|
- context.PushInstruction(Instruction.Closure(context.StackPosition, funcIndex), node.Position, true);
|
|
|
|
|
|
|
+ context.PushInstruction(Instruction.Closure(context.StackPosition, funcIndex), node.EndPosition, true);
|
|
|
|
|
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
@@ -604,23 +606,23 @@ public sealed class LuaCompiler : ISyntaxNodeVisitor<ScopeCompilationContext, bo
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
// compile function
|
|
// compile function
|
|
|
- var funcIndex = CompileFunctionProto(node.Name, context, node.ParameterNodes, node.Nodes, node.ParameterNodes.Length, node.HasVariableArguments, false, node.LineDefined, node.LastLineDefined);
|
|
|
|
|
|
|
+ var funcIndex = CompileFunctionProto(node.Name, context, node.ParameterNodes, node.Nodes, node.ParameterNodes.Length, node.HasVariableArguments, false, node.LineDefined, node.EndPosition.Line);
|
|
|
|
|
|
|
|
// push closure instruction
|
|
// push closure instruction
|
|
|
- context.PushInstruction(Instruction.Closure(context.StackPosition, funcIndex), node.Position, true);
|
|
|
|
|
|
|
+ context.PushInstruction(Instruction.Closure(context.StackPosition, funcIndex), node.EndPosition, true);
|
|
|
|
|
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public bool VisitFunctionDeclarationStatementNode(FunctionDeclarationStatementNode node, ScopeCompilationContext context)
|
|
public bool VisitFunctionDeclarationStatementNode(FunctionDeclarationStatementNode node, ScopeCompilationContext context)
|
|
|
{
|
|
{
|
|
|
- var funcIndex = CompileFunctionProto(node.Name, context, node.ParameterNodes, node.Nodes, node.ParameterNodes.Length, node.HasVariableArguments, false, node.LineDefined, node.LastLineDefined);
|
|
|
|
|
|
|
+ var funcIndex = CompileFunctionProto(node.Name, context, node.ParameterNodes, node.Nodes, node.ParameterNodes.Length, node.HasVariableArguments, false, node.LineDefined, node.EndPosition.Line);
|
|
|
|
|
|
|
|
// add closure
|
|
// add closure
|
|
|
var index = context.Function.GetConstantIndex(node.Name.ToString());
|
|
var index = context.Function.GetConstantIndex(node.Name.ToString());
|
|
|
|
|
|
|
|
// push closure instruction
|
|
// push closure instruction
|
|
|
- context.PushInstruction(Instruction.Closure(context.StackPosition, funcIndex), node.Position, true);
|
|
|
|
|
|
|
+ context.PushInstruction(Instruction.Closure(context.StackPosition, funcIndex), node.EndPosition, true);
|
|
|
|
|
|
|
|
if (context.TryGetLocalVariableInThisScope(node.Name, out var variable))
|
|
if (context.TryGetLocalVariableInThisScope(node.Name, out var variable))
|
|
|
{
|
|
{
|
|
@@ -639,7 +641,7 @@ public sealed class LuaCompiler : ISyntaxNodeVisitor<ScopeCompilationContext, bo
|
|
|
public bool VisitTableMethodDeclarationStatementNode(TableMethodDeclarationStatementNode node, ScopeCompilationContext context)
|
|
public bool VisitTableMethodDeclarationStatementNode(TableMethodDeclarationStatementNode node, ScopeCompilationContext context)
|
|
|
{
|
|
{
|
|
|
var funcIdentifier = node.MemberPath[^1];
|
|
var funcIdentifier = node.MemberPath[^1];
|
|
|
- var funcIndex = CompileFunctionProto(funcIdentifier.Name, context, node.ParameterNodes, node.Nodes, node.ParameterNodes.Length + 1, node.HasVariableArguments, node.HasSelfParameter, node.LineDefined, node.LastLineDefined);
|
|
|
|
|
|
|
+ var funcIndex = CompileFunctionProto(funcIdentifier.Name, context, node.ParameterNodes, node.Nodes, node.ParameterNodes.Length + 1, node.HasVariableArguments, node.HasSelfParameter, node.LineDefined, node.EndPosition.Line);
|
|
|
|
|
|
|
|
// add closure
|
|
// add closure
|
|
|
var index = context.Function.GetConstantIndex(funcIdentifier.Name.ToString());
|
|
var index = context.Function.GetConstantIndex(funcIdentifier.Name.ToString());
|
|
@@ -660,7 +662,7 @@ public sealed class LuaCompiler : ISyntaxNodeVisitor<ScopeCompilationContext, bo
|
|
|
|
|
|
|
|
// push closure instruction
|
|
// push closure instruction
|
|
|
var closureIndex = context.StackPosition;
|
|
var closureIndex = context.StackPosition;
|
|
|
- context.PushInstruction(Instruction.Closure(closureIndex, funcIndex), node.Position, true);
|
|
|
|
|
|
|
+ context.PushInstruction(Instruction.Closure(closureIndex, funcIndex), node.EndPosition, true);
|
|
|
|
|
|
|
|
// set table
|
|
// set table
|
|
|
context.PushInstruction(Instruction.SetTable(tableIndex, (ushort)(index + 256), closureIndex), funcIdentifier.Position);
|
|
context.PushInstruction(Instruction.SetTable(tableIndex, (ushort)(index + 256), closureIndex), funcIdentifier.Position);
|
|
@@ -758,10 +760,10 @@ public sealed class LuaCompiler : ISyntaxNodeVisitor<ScopeCompilationContext, bo
|
|
|
// if
|
|
// if
|
|
|
using (var scopeContext = context.CreateChildScope())
|
|
using (var scopeContext = context.CreateChildScope())
|
|
|
{
|
|
{
|
|
|
- CompileConditionNode(node.IfNode.ConditionNode, scopeContext, true);
|
|
|
|
|
|
|
+ CompileConditionNode(node.IfNode.ConditionNode, scopeContext, true, node.IfNode.Position);
|
|
|
|
|
|
|
|
var ifPosition = scopeContext.Function.Instructions.Length;
|
|
var ifPosition = scopeContext.Function.Instructions.Length;
|
|
|
- scopeContext.PushInstruction(Instruction.Jmp(0, 0), node.Position);
|
|
|
|
|
|
|
+ scopeContext.PushInstruction(Instruction.Jmp(0, 0), node.IfNode.Position);
|
|
|
|
|
|
|
|
foreach (var childNode in node.IfNode.ThenNodes)
|
|
foreach (var childNode in node.IfNode.ThenNodes)
|
|
|
{
|
|
{
|
|
@@ -772,7 +774,7 @@ public sealed class LuaCompiler : ISyntaxNodeVisitor<ScopeCompilationContext, bo
|
|
|
if (hasElse)
|
|
if (hasElse)
|
|
|
{
|
|
{
|
|
|
endJumpIndexList.Add(scopeContext.Function.Instructions.Length);
|
|
endJumpIndexList.Add(scopeContext.Function.Instructions.Length);
|
|
|
- scopeContext.PushInstruction(Instruction.Jmp(stackPositionToClose, 0), node.Position, true);
|
|
|
|
|
|
|
+ scopeContext.PushInstruction(Instruction.Jmp(stackPositionToClose, 0), node.IfNode.ThenNodes[^1].Position, true);
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
@@ -790,7 +792,7 @@ public sealed class LuaCompiler : ISyntaxNodeVisitor<ScopeCompilationContext, bo
|
|
|
CompileConditionNode(elseIf.ConditionNode, scopeContext, true);
|
|
CompileConditionNode(elseIf.ConditionNode, scopeContext, true);
|
|
|
|
|
|
|
|
var elseifPosition = scopeContext.Function.Instructions.Length;
|
|
var elseifPosition = scopeContext.Function.Instructions.Length;
|
|
|
- scopeContext.PushInstruction(Instruction.Jmp(0, 0), node.Position);
|
|
|
|
|
|
|
+ scopeContext.PushInstruction(Instruction.Jmp(0, 0), elseIf.Position);
|
|
|
|
|
|
|
|
foreach (var childNode in elseIf.ThenNodes)
|
|
foreach (var childNode in elseIf.ThenNodes)
|
|
|
{
|
|
{
|
|
@@ -802,11 +804,11 @@ public sealed class LuaCompiler : ISyntaxNodeVisitor<ScopeCompilationContext, bo
|
|
|
if (hasElse)
|
|
if (hasElse)
|
|
|
{
|
|
{
|
|
|
endJumpIndexList.Add(scopeContext.Function.Instructions.Length);
|
|
endJumpIndexList.Add(scopeContext.Function.Instructions.Length);
|
|
|
- scopeContext.PushInstruction(Instruction.Jmp(stackPositionToClose, 0), node.Position);
|
|
|
|
|
|
|
+ scopeContext.PushInstruction(Instruction.Jmp(stackPositionToClose, 0), elseIf.Position);
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
- scopeContext.TryPushCloseUpValue(stackPositionToClose, node.Position);
|
|
|
|
|
|
|
+ scopeContext.TryPushCloseUpValue(stackPositionToClose, elseIf.Position);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
scopeContext.Function.Instructions[elseifPosition].SBx = scopeContext.Function.Instructions.Length - 1 - elseifPosition;
|
|
scopeContext.Function.Instructions[elseifPosition].SBx = scopeContext.Function.Instructions.Length - 1 - elseifPosition;
|
|
@@ -847,8 +849,9 @@ public sealed class LuaCompiler : ISyntaxNodeVisitor<ScopeCompilationContext, bo
|
|
|
|
|
|
|
|
CompileConditionNode(node.ConditionNode, scopeContext, true);
|
|
CompileConditionNode(node.ConditionNode, scopeContext, true);
|
|
|
var a = scopeContext.HasCapturedLocalVariables ? (byte)(stackPosition + 1) : (byte)0;
|
|
var a = scopeContext.HasCapturedLocalVariables ? (byte)(stackPosition + 1) : (byte)0;
|
|
|
- scopeContext.PushInstruction(Instruction.Jmp(a, startIndex - scopeContext.Function.Instructions.Length - 1), node.Position);
|
|
|
|
|
- scopeContext.TryPushCloseUpValue(scopeContext.StackPosition, node.Position);
|
|
|
|
|
|
|
+ var untilPosition = node.ConditionNode.Position;
|
|
|
|
|
+ scopeContext.PushInstruction(Instruction.Jmp(a, startIndex - scopeContext.Function.Instructions.Length - 1), untilPosition);
|
|
|
|
|
+ scopeContext.TryPushCloseUpValue(scopeContext.StackPosition, untilPosition);
|
|
|
|
|
|
|
|
context.Function.LoopLevel--;
|
|
context.Function.LoopLevel--;
|
|
|
|
|
|
|
@@ -1018,7 +1021,7 @@ public sealed class LuaCompiler : ISyntaxNodeVisitor<ScopeCompilationContext, bo
|
|
|
|
|
|
|
|
// push OP_TFORCALL and OP_TFORLOOP
|
|
// push OP_TFORCALL and OP_TFORLOOP
|
|
|
context.PushInstruction(Instruction.TForCall(startPosition, (ushort)node.Names.Length), node.Position);
|
|
context.PushInstruction(Instruction.TForCall(startPosition, (ushort)node.Names.Length), node.Position);
|
|
|
- context.PushInstruction(Instruction.TForLoop((byte)(startPosition + 2), startJumpIndex - context.Function.Instructions.Length), node.EndPosition);
|
|
|
|
|
|
|
+ context.PushInstruction(Instruction.TForLoop((byte)(startPosition + 2), startJumpIndex - context.Function.Instructions.Length), node.Position);
|
|
|
|
|
|
|
|
context.Function.ResolveAllBreaks((byte)(startPosition + 1), context.Function.Instructions.Length - 1, scopeContext);
|
|
context.Function.ResolveAllBreaks((byte)(startPosition + 1), context.Function.Instructions.Length - 1, scopeContext);
|
|
|
context.StackPosition = startPosition;
|
|
context.StackPosition = startPosition;
|
|
@@ -1160,6 +1163,7 @@ public sealed class LuaCompiler : ISyntaxNodeVisitor<ScopeCompilationContext, bo
|
|
|
value = -d1;
|
|
value = -d1;
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
break;
|
|
break;
|
|
|
case UnaryOperator.Not:
|
|
case UnaryOperator.Not:
|
|
|
if (unaryNodeValue.TryRead<bool>(out var b))
|
|
if (unaryNodeValue.TryRead<bool>(out var b))
|
|
@@ -1167,9 +1171,11 @@ public sealed class LuaCompiler : ISyntaxNodeVisitor<ScopeCompilationContext, bo
|
|
|
value = !b;
|
|
value = !b;
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
break;
|
|
break;
|
|
|
case BinaryExpressionNode binaryExpression:
|
|
case BinaryExpressionNode binaryExpression:
|
|
|
if (TryGetConstant(binaryExpression.LeftNode, context, out var leftValue) &&
|
|
if (TryGetConstant(binaryExpression.LeftNode, context, out var leftValue) &&
|
|
@@ -1234,7 +1240,8 @@ public sealed class LuaCompiler : ISyntaxNodeVisitor<ScopeCompilationContext, bo
|
|
|
/// <param name="node">Condition node</param>
|
|
/// <param name="node">Condition node</param>
|
|
|
/// <param name="context">Context</param>
|
|
/// <param name="context">Context</param>
|
|
|
/// <param name="falseIsSkip">If true, generates an instruction sequence that skips the next instruction if the condition is false.</param>
|
|
/// <param name="falseIsSkip">If true, generates an instruction sequence that skips the next instruction if the condition is false.</param>
|
|
|
- void CompileConditionNode(ExpressionNode node, ScopeCompilationContext context, bool falseIsSkip)
|
|
|
|
|
|
|
+ /// <param name="testPosition">Position of the test instruction</param>
|
|
|
|
|
+ void CompileConditionNode(ExpressionNode node, ScopeCompilationContext context, bool falseIsSkip, SourcePosition? testPosition = null)
|
|
|
{
|
|
{
|
|
|
if (node is BinaryExpressionNode binaryExpression)
|
|
if (node is BinaryExpressionNode binaryExpression)
|
|
|
{
|
|
{
|
|
@@ -1286,7 +1293,7 @@ public sealed class LuaCompiler : ISyntaxNodeVisitor<ScopeCompilationContext, bo
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
node.Accept(this, context);
|
|
node.Accept(this, context);
|
|
|
- context.PushInstruction(Instruction.Test((byte)(context.StackPosition - 1), falseIsSkip ? (byte)0 : (byte)1), node.Position);
|
|
|
|
|
|
|
+ context.PushInstruction(Instruction.Test((byte)(context.StackPosition - 1), falseIsSkip ? (byte)0 : (byte)1), testPosition ?? node.Position);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void CompileExpressionList(SyntaxNode rootNode, ExpressionNode[] expressions, int minimumCount, ScopeCompilationContext context)
|
|
void CompileExpressionList(SyntaxNode rootNode, ExpressionNode[] expressions, int minimumCount, ScopeCompilationContext context)
|