Browse Source

Gotos, debugger fixes

Xanathar 10 years ago
parent
commit
22ad9e20c6
28 changed files with 363 additions and 55 deletions
  1. 149 2
      src/MoonSharp.Interpreter.Tests/EndToEnd/GotoTests.cs
  2. 0 1
      src/MoonSharp.Interpreter.Tests/TestMore/TestMoreTests.cs
  3. 1 0
      src/MoonSharp.Interpreter/Execution/InstructionFieldUsage.cs
  4. 11 0
      src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScope.cs
  5. 55 20
      src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScopeBlock.cs
  6. 15 0
      src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScopeFrame.cs
  7. 11 0
      src/MoonSharp.Interpreter/Execution/VM/ByteCode.cs
  8. 3 1
      src/MoonSharp.Interpreter/Execution/VM/OpCode.cs
  9. 3 1
      src/MoonSharp.Interpreter/Execution/VM/Processor/Processor_InstructionLoop.cs
  10. 2 2
      src/MoonSharp.Interpreter/MoonSharp.Interpreter.csproj
  11. 1 1
      src/MoonSharp.Interpreter/Script.cs
  12. 7 7
      src/MoonSharp.Interpreter/Tree/Expressions/FunctionDefinitionExpression.cs
  13. 6 1
      src/MoonSharp.Interpreter/Tree/Lexer/Lexer.cs
  14. 5 3
      src/MoonSharp.Interpreter/Tree/Lexer/Token.cs
  15. 2 0
      src/MoonSharp.Interpreter/Tree/Statement.cs
  16. 4 0
      src/MoonSharp.Interpreter/Tree/Statements/AssignmentStatement.cs
  17. 1 0
      src/MoonSharp.Interpreter/Tree/Statements/BreakStatement.cs
  18. 4 3
      src/MoonSharp.Interpreter/Tree/Statements/ForEachLoopStatement.cs
  19. 3 0
      src/MoonSharp.Interpreter/Tree/Statements/ForLoopStatement.cs
  20. 1 0
      src/MoonSharp.Interpreter/Tree/Statements/FunctionCallStatement.cs
  21. 1 0
      src/MoonSharp.Interpreter/Tree/Statements/FunctionDefinitionStatement.cs
  22. 25 7
      src/MoonSharp.Interpreter/Tree/Statements/GotoStatement.cs
  23. 4 1
      src/MoonSharp.Interpreter/Tree/Statements/IfStatement.cs
  24. 37 3
      src/MoonSharp.Interpreter/Tree/Statements/LabelStatement.cs
  25. 2 0
      src/MoonSharp.Interpreter/Tree/Statements/RepeatStatement.cs
  26. 5 2
      src/MoonSharp.Interpreter/Tree/Statements/ReturnStatement.cs
  27. 2 0
      src/MoonSharp.Interpreter/Tree/Statements/ScopeBlockStatement.cs
  28. 3 0
      src/MoonSharp.Interpreter/Tree/Statements/WhileStatement.cs

+ 149 - 2
src/MoonSharp.Interpreter.Tests/EndToEnd/GotoTests.cs

@@ -10,8 +10,7 @@ namespace MoonSharp.Interpreter.Tests.EndToEnd
 	public class GotoTests
 	{
 		[Test]
-		[Ignore]
-		public void Goto1()
+		public void Goto_Simple_Fwd()
 		{
 			string script = @"
 				function test()
@@ -31,6 +30,154 @@ namespace MoonSharp.Interpreter.Tests.EndToEnd
 			Assert.AreEqual(3, res.Number);
 		}
 
+		[Test]
+		public void Goto_Simple_Bwd()
+		{
+			string script = @"
+				function test()
+					x = 5;
+	
+					::jump::
+					if (x == 3) then return x; end
+					
+					x = 3
+					goto jump
+
+					x = 4
+					return x;
+				end				
+
+				return test();
+				";
+
+			DynValue res = Script.RunString(script);
+
+			Assert.AreEqual(DataType.Number, res.Type);
+			Assert.AreEqual(3, res.Number);
+		}
+
+		[Test]
+		[ExpectedException(typeof(SyntaxErrorException))]
+		public void Goto_UndefinedLabel()
+		{
+			string script = @"
+				goto there
+				";
+
+			Script.RunString(script);
+		}
+
+		[Test]
+		[ExpectedException(typeof(SyntaxErrorException))]
+		public void Goto_DoubleDefinedLabel()
+		{
+			string script = @"
+				::label::
+				::label::
+				";
+
+			Script.RunString(script);
+		}
+
+		[Test]
+		public void Goto_RedefinedLabel()
+		{
+			string script = @"
+				::label::
+				do
+					::label::
+				end
+				";
+
+			Script.RunString(script);
+		}
+
+		[Test]
+		public void Goto_RedefinedLabel_Goto()
+		{
+			string script = @"
+				::label::
+				do
+					goto label
+					do return 5 end
+					::label::
+					return 3
+				end
+				";
+
+			DynValue res = Script.RunString(script);
+
+			Assert.AreEqual(DataType.Number, res.Type);
+			Assert.AreEqual(3, res.Number);
+		}
+
+		[Test]
+		[ExpectedException(typeof(SyntaxErrorException))]
+		public void Goto_UndefinedLabel_2()
+		{
+			string script = @"
+				goto label
+				do
+					do return 5 end
+					::label::
+					return 3
+				end
+				";
+
+			DynValue res = Script.RunString(script);
+
+			Assert.AreEqual(DataType.Number, res.Type);
+			Assert.AreEqual(3, res.Number);
+		}
+
+		[Test]
+		[ExpectedException(typeof(SyntaxErrorException))]
+		public void Goto_VarInScope()
+		{
+			string script = @"
+				goto f
+				local x
+				::f::
+				";
+
+			DynValue res = Script.RunString(script);
+
+			Assert.AreEqual(DataType.Number, res.Type);
+			Assert.AreEqual(3, res.Number);
+		}
+
+
+		[Test]
+		public void Goto_JumpOutOfBlocks()
+		{
+			string script = @"
+				local u = 4
+
+				do
+					local x = 5
+	
+					do
+						local y = 6
+		
+						do
+							local z = 7
+						end
+		
+						goto out
+					end
+				end
+
+				do return 5 end
+
+				::out::
+
+				return 3
+			";
+
+			DynValue res = Script.RunString(script);
+			Assert.AreEqual(DataType.Number, res.Type);
+			Assert.AreEqual(3, res.Number);
+		}
 
 	}
 }

+ 0 - 1
src/MoonSharp.Interpreter.Tests/TestMore/TestMoreTests.cs

@@ -147,7 +147,6 @@ namespace MoonSharp.Interpreter.Tests
 		}
 
 		[Test]
-		[Ignore] // Failing because of handling of syntax error messages
 		public void TestMore_204_grammar()
 		{
 			TapRunner.Run(@"TestMore/204-grammar.t");

+ 1 - 0
src/MoonSharp.Interpreter/Execution/InstructionFieldUsage.cs

@@ -65,6 +65,7 @@ namespace MoonSharp.Interpreter.Execution
 				case OpCode.Swap:
 				case OpCode.Enter:
 				case OpCode.Leave:
+				case OpCode.Clean:
 				case OpCode.Exit:
 					return InstructionFieldUsage.NumVal | InstructionFieldUsage.NumVal2;
 				case OpCode.Local:

+ 11 - 0
src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScope.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using MoonSharp.Interpreter.Execution.Scopes;
+using MoonSharp.Interpreter.Tree.Statements;
 
 namespace MoonSharp.Interpreter.Execution
 {
@@ -104,5 +105,15 @@ namespace MoonSharp.Interpreter.Execution
 			return m_Frames.Last().HasVarArgs;
 		}
 
+		internal void DefineLabel(LabelStatement label)
+		{
+			m_Frames.Last().DefineLabel(label);
+		}
+
+		internal void RegisterGoto(GotoStatement gotostat)
+		{
+			m_Frames.Last().RegisterGoto(gotostat);
+		}
+
 	}
 }

+ 55 - 20
src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScopeBlock.cs

@@ -16,8 +16,6 @@ namespace MoonSharp.Interpreter.Execution.Scopes
 
 		Dictionary<string, SymbolRef> m_DefinedNames = new Dictionary<string, SymbolRef>();
 
-		MultiDictionary<string, GotoStatement> m_PendingGotos;
-		Dictionary<string, LabelStatement> m_DefineLabels;
 
 		internal BuildTimeScopeBlock(BuildTimeScopeBlock parent)
 		{
@@ -43,6 +41,7 @@ namespace MoonSharp.Interpreter.Execution.Scopes
 		{
 			SymbolRef l = SymbolRef.Local(name, -1);
 			m_DefinedNames.Add(name, l);
+			m_LastDefinedName = name;
 			return l;
 		}
 
@@ -72,39 +71,73 @@ namespace MoonSharp.Interpreter.Execution.Scopes
 				this.ScopeBlock.ToInclusive = Math.Max(this.ScopeBlock.ToInclusive, child.ResolveLRefs(buildTimeScopeFrame));
 			}
 
-			return lastVal;
+			if (m_LocalLabels != null)
+				foreach (var label in m_LocalLabels.Values)
+					label.SetScope(this.ScopeBlock);
+
+			return this.ScopeBlock.ToInclusive;
 		}
 
 
-		public void DefineLabel(LabelStatement label)
+		List<GotoStatement> m_PendingGotos;
+		Dictionary<string, LabelStatement> m_LocalLabels;
+		string m_LastDefinedName;
+
+		internal void DefineLabel(LabelStatement label)
 		{
-			if (m_DefineLabels.ContainsKey(label.Label))
+			if (m_LocalLabels == null)
+				m_LocalLabels = new Dictionary<string, LabelStatement>();
+
+			if (m_LocalLabels.ContainsKey(label.Label))
 			{
-				throw new SyntaxErrorException(null, "label 'label' already defined on line 3");
+				throw new SyntaxErrorException(label.NameToken, "label '{0}' already defined on line {1}", label.Label, m_LocalLabels[label.Label].SourceRef.FromLine);
 			}
 			else
 			{
-				m_DefineLabels.Add(label.Label, label);
+				m_LocalLabels.Add(label.Label, label);
+				label.SetDefinedVars(m_DefinedNames.Count, m_LastDefinedName);
+			}
+		}
 
-				foreach (GotoStatement gotostat in m_PendingGotos.Find(label.Label))
-				{
-					gotostat.ResolveLabel(label);
-				}
+		internal void RegisterGoto(GotoStatement gotostat)
+		{
+			if (m_PendingGotos == null)
+				m_PendingGotos = new List<GotoStatement>();
 
-				m_PendingGotos.Remove(label.Label);
-			}
+			m_PendingGotos.Add(gotostat);
+			gotostat.SetDefinedVars(m_DefinedNames.Count, m_LastDefinedName);
 		}
 
-		public void ResolveGotoOrPending(GotoStatement gotostat)
+		internal void ResolveGotos()
 		{
-			if (m_DefineLabels.ContainsKey(gotostat.Label))
-			{
-				gotostat.ResolveLabel(m_DefineLabels[gotostat.Label]);
-			}
-			else
+			if (m_PendingGotos == null)
+				return;
+
+			foreach (GotoStatement gotostat in m_PendingGotos)
 			{
-				m_PendingGotos.Add(gotostat.Label, gotostat);
+				LabelStatement label;
+
+				if (m_LocalLabels != null && m_LocalLabels.TryGetValue(gotostat.Label, out label))
+				{
+					if (label.DefinedVarsCount > gotostat.DefinedVarsCount)
+						throw new SyntaxErrorException(gotostat.GotoToken,
+							"<goto {0}> at line {1} jumps into the scope of local '{2}'", gotostat.Label, 
+							gotostat.GotoToken.FromLine,
+							label.LastDefinedVarName);
+
+					label.RegisterGoto(gotostat);
+				}
+				else
+				{
+					if (Parent == null)
+						throw new SyntaxErrorException(gotostat.GotoToken, "no visible label '{0}' for <goto> at line {1}", gotostat.Label,
+							gotostat.GotoToken.FromLine);
+
+					Parent.RegisterGoto(gotostat);
+				}
 			}
+
+			m_PendingGotos.Clear();
 		}
 
 
@@ -113,5 +146,7 @@ namespace MoonSharp.Interpreter.Execution.Scopes
 
 
 
+
+
 	}
 }

+ 15 - 0
src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScopeFrame.cs

@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
+using MoonSharp.Interpreter.Tree.Statements;
 
 namespace MoonSharp.Interpreter.Execution.Scopes
 {
@@ -28,6 +29,8 @@ namespace MoonSharp.Interpreter.Execution.Scopes
 		{
 			var tree = m_ScopeTreeHead;
 
+			m_ScopeTreeHead.ResolveGotos();
+
 			m_ScopeTreeHead = m_ScopeTreeHead.Parent;
 
 			if (m_ScopeTreeHead == null)
@@ -71,6 +74,8 @@ namespace MoonSharp.Interpreter.Execution.Scopes
 
 		internal void ResolveLRefs()
 		{
+			m_ScopeTreeRoot.ResolveGotos();
+
 			m_ScopeTreeRoot.ResolveLRefs(this);
 		}
 
@@ -85,5 +90,15 @@ namespace MoonSharp.Interpreter.Execution.Scopes
 		{
 			return m_ScopeFrame.DebugSymbols.Count;
 		}
+
+		internal void DefineLabel(LabelStatement label)
+		{
+			m_ScopeTreeHead.DefineLabel(label);
+		}
+
+		internal void RegisterGoto(GotoStatement gotostat)
+		{
+			m_ScopeTreeHead.RegisterGoto(gotostat);
+		}
 	}
 }

+ 11 - 0
src/MoonSharp.Interpreter/Execution/VM/ByteCode.cs

@@ -15,11 +15,16 @@ namespace MoonSharp.Interpreter.Execution.VM
 	internal class ByteCode : ITrackableReference
 	{
 		public List<Instruction> Code = new List<Instruction>();
+		public Script Script { get; private set; }
 		private List<SourceRef> m_SourceRefStack = new List<SourceRef>();
 		private SourceRef m_CurrentSourceRef = null;
 
 		internal LoopTracker LoopTracker = new LoopTracker();
 
+		public ByteCode(Script script)
+		{
+			Script = script;
+		}
 
 		#region ITrackableReference
 
@@ -175,6 +180,11 @@ namespace MoonSharp.Interpreter.Execution.VM
 			return AppendInstruction(new Instruction(m_CurrentSourceRef) { OpCode = OpCode.Exit, NumVal = runtimeScopeBlock.From, NumVal2 = runtimeScopeBlock.ToInclusive });
 		}
 
+		public Instruction Emit_Clean(RuntimeScopeBlock runtimeScopeBlock)
+		{
+			return AppendInstruction(new Instruction(m_CurrentSourceRef) { OpCode = OpCode.Clean, NumVal = runtimeScopeBlock.To + 1, NumVal2 = runtimeScopeBlock.ToInclusive });
+		}
+
 		public Instruction Emit_Closure(SymbolRef[] symbols, int jmpnum)
 		{
 			return AppendInstruction(new Instruction(m_CurrentSourceRef) { OpCode = OpCode.Closure, SymbolList = symbols, NumVal = jmpnum });
@@ -313,5 +323,6 @@ namespace MoonSharp.Interpreter.Execution.VM
 		{
 			return AppendInstruction(new Instruction(m_CurrentSourceRef) { OpCode = OpCode.Swap, NumVal = p1, NumVal2 = p2 });
 		}
+
 	}
 }

+ 3 - 1
src/MoonSharp.Interpreter/Execution/VM/OpCode.cs

@@ -5,7 +5,7 @@ using System.Text;
 
 namespace MoonSharp.Interpreter.Execution.VM
 {
-	internal enum OpCode 
+	internal enum OpCode
 	{
 		// Meta-opcodes
 		Nop,		// Does not perform any operation.
@@ -29,6 +29,8 @@ namespace MoonSharp.Interpreter.Execution.VM
 		Enter,		// Enters a new stack frame
 		Leave,		// Leaves a stack frame
 		Exit,		// Leaves every stack frame up and including the topmost function frame, plus it exits the topmost closure
+		Clean,		// Cleansup every stack frame below the specified one
+
 		FuncMeta,	// Injects function metadata used for reflection things (dumping, debugging)
 		BeginFn,	// Adjusts for start of function, taking in parameters and allocating locals
 		Args,		// Takes the arguments passed to a function and sets the appropriate symbols in the local scope

+ 3 - 1
src/MoonSharp.Interpreter/Execution/VM/Processor/Processor_InstructionLoop.cs

@@ -142,6 +142,7 @@ namespace MoonSharp.Interpreter.Execution.VM
 							break;
 						case OpCode.Leave:
 						case OpCode.Exit:
+						case OpCode.Clean:
 							ClearBlockData(i);
 							break;
 						case OpCode.Closure:
@@ -614,7 +615,8 @@ namespace MoonSharp.Interpreter.Execution.VM
 
 
 
-		private int Internal_ExecCall(int argsCount, int instructionPtr, CallbackFunction handler = null, CallbackFunction continuation = null, bool thisCall = false, string debugText = null, DynValue unwindHandler = null)
+		private int Internal_ExecCall(int argsCount, int instructionPtr, CallbackFunction handler = null, CallbackFunction continuation = null, 
+			bool thisCall = false, string debugText = null, DynValue unwindHandler = null)
 		{
 			DynValue fn = m_ValueStack.Peek(argsCount);
 

+ 2 - 2
src/MoonSharp.Interpreter/MoonSharp.Interpreter.csproj

@@ -8,7 +8,7 @@
     <OutputType>Library</OutputType>
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>MoonSharp.Interpreter</RootNamespace>
-    <AssemblyName>MoonSharp.Interpreter</AssemblyName>
+    <AssemblyName>ro</AssemblyName>
     <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <SccProjectName>
@@ -46,7 +46,7 @@
     <NoWarn>3021, 1591</NoWarn>
     <RunCodeAnalysis>false</RunCodeAnalysis>
     <CodeAnalysisRuleSet>ExtendedDesignGuidelineRules.ruleset</CodeAnalysisRuleSet>
-    <DocumentationFile>bin\Release\MoonSharp.Interpreter.XML</DocumentationFile>
+    <DocumentationFile>bin\Release\ro.xml</DocumentationFile>
     <UseVSHostingProcess>false</UseVSHostingProcess>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">

+ 1 - 1
src/MoonSharp.Interpreter/Script.cs

@@ -72,7 +72,7 @@ namespace MoonSharp.Interpreter
 			PerformanceStats = new PerformanceStatistics();
 			Registry = new Table(this);
 
-			m_ByteCode = new ByteCode();
+			m_ByteCode = new ByteCode(this);
 			m_GlobalTable = new Table(this).RegisterCoreModules(coreModules);
 			m_MainProcessor = new Processor(this, m_GlobalTable, m_ByteCode);
 		}

+ 7 - 7
src/MoonSharp.Interpreter/Tree/Expressions/FunctionDefinitionExpression.cs

@@ -27,15 +27,11 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 
 		public FunctionDefinitionExpression(ScriptLoadingContext lcontext, Table globalContext)
 			: this(lcontext, false, globalContext)
-		{
-
-		}
+		{ }
 
 		public FunctionDefinitionExpression(ScriptLoadingContext lcontext, bool pushSelfParam)
 			: this(lcontext, pushSelfParam, null)
-		{
-
-		}
+		{ }
 
 
 		private FunctionDefinitionExpression(ScriptLoadingContext lcontext, bool pushSelfParam, Table globalContext)
@@ -70,6 +66,10 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			m_Statement = CreateBody(lcontext);
 
 			m_StackFrame = lcontext.Scope.PopFunction();
+
+			lcontext.Source.Refs.Add(m_Begin);
+			lcontext.Source.Refs.Add(m_End);
+
 		}
 
 		private Statement CreateBody(ScriptLoadingContext lcontext)
@@ -174,7 +174,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 
 		public int CompileBody(ByteCode bc, string friendlyName)
 		{
-			string funcName = "TODO!"; // friendlyName ?? "<" + this.m_Begin.FormatLocation(this.LoadingContext.Script, true) + ">";
+			string funcName = friendlyName ?? ("<" + this.m_Begin.FormatLocation(bc.Script, true) + ">");
 
 			bc.PushSourceRef(m_Begin);
 

+ 6 - 1
src/MoonSharp.Interpreter/Tree/Lexer/Lexer.cs

@@ -9,6 +9,8 @@ namespace MoonSharp.Interpreter.Tree
 	{
 		Token m_Current = null;
 		string m_Code;
+		int m_PrevLineTo = 0;
+		int m_PrevColTo = 1;
 		int m_Cursor = 0;
 		int m_Line = 1;
 		int m_Col = 0;
@@ -540,10 +542,13 @@ namespace MoonSharp.Interpreter.Tree
 
 		private Token CreateToken(TokenType tokenType, int fromLine, int fromCol, string text = null)
 		{
-			return new Token(tokenType, m_SourceId, fromLine, fromCol, m_Line, m_Col)
+			Token t = new Token(tokenType, m_SourceId, fromLine, fromCol, m_Line, m_Col, m_PrevLineTo, m_PrevColTo)
 			{
 				Text = text
 			};
+			m_PrevLineTo = m_Line;
+			m_PrevColTo = m_Col;
+			return t;
 		}
 
 		private string ReadNameToken()

+ 5 - 3
src/MoonSharp.Interpreter/Tree/Lexer/Token.cs

@@ -9,12 +9,12 @@ namespace MoonSharp.Interpreter.Tree
 	class Token
 	{
 		public readonly int SourceId;
-		public readonly int FromCol, ToCol, FromLine, ToLine;
+		public readonly int FromCol, ToCol, FromLine, ToLine, PrevCol, PrevLine;
 		public readonly TokenType Type;
 
 		public string Text { get; set; }
 
-		public Token(TokenType type, int sourceId, int fromLine, int fromCol, int toLine, int toCol)
+		public Token(TokenType type, int sourceId, int fromLine, int fromCol, int toLine, int toCol, int prevLine, int prevCol)
 		{
 			Type = type;
 
@@ -23,6 +23,8 @@ namespace MoonSharp.Interpreter.Tree
 			FromCol = fromCol;
 			ToCol = toCol;
 			ToLine = toLine;
+			PrevCol = prevCol;
+			PrevLine = prevLine;
 		}
 
 
@@ -161,7 +163,7 @@ namespace MoonSharp.Interpreter.Tree
 
 		internal Debugging.SourceRef GetSourceRefUpTo(Token to, bool isStepStop = true)
 		{
-			return new Debugging.SourceRef(this.SourceId, this.FromCol, to.FromCol, this.FromLine, to.FromLine, isStepStop);
+			return new Debugging.SourceRef(this.SourceId, this.FromCol, to.PrevCol, this.FromLine, to.PrevLine, isStepStop);
 		}
 	}
 }

+ 2 - 0
src/MoonSharp.Interpreter/Tree/Statement.cs

@@ -26,6 +26,8 @@ namespace MoonSharp.Interpreter.Tree
 
 			switch (tkn.Type)
 			{
+				case TokenType.DoubleColon:
+					return new LabelStatement(lcontext);
 				case TokenType.Goto:
 					return new GotoStatement(lcontext);
 				case TokenType.SemiColon:

+ 4 - 0
src/MoonSharp.Interpreter/Tree/Statements/AssignmentStatement.cs

@@ -53,6 +53,8 @@ namespace MoonSharp.Interpreter.Tree.Statements
 
 			Token last = lcontext.Lexer.Current;
 			m_Ref = first.GetSourceRefUpTo(last);
+			lcontext.Source.Refs.Add(m_Ref);
+
 		}
 
 
@@ -74,6 +76,8 @@ namespace MoonSharp.Interpreter.Tree.Statements
 
 			Token last = lcontext.Lexer.Current;
 			m_Ref = first.GetSourceRefUpTo(last);
+			lcontext.Source.Refs.Add(m_Ref);
+
 		}
 
 		private IVariable CheckVar(ScriptLoadingContext lcontext, Expression firstExpression)

+ 1 - 0
src/MoonSharp.Interpreter/Tree/Statements/BreakStatement.cs

@@ -17,6 +17,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			: base(lcontext)
 		{
 			m_Ref = CheckTokenType(lcontext, TokenType.Break).GetSourceRef();
+			lcontext.Source.Refs.Add(m_Ref);
 		}
 
 

+ 4 - 3
src/MoonSharp.Interpreter/Tree/Statements/ForEachLoopStatement.cs

@@ -17,7 +17,6 @@ namespace MoonSharp.Interpreter.Tree.Statements
 		IVariable[] m_NameExps;
 		Expression m_RValues;
 		Statement m_Block;
-		string m_DebugText;
 		SourceRef m_RefFor, m_RefEnd;
 
 		public ForEachLoopStatement(ScriptLoadingContext lcontext, Token firstNameToken, Token forToken)
@@ -57,7 +56,9 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			m_RefEnd = CheckTokenType(lcontext, TokenType.End).GetSourceRef();
 
 			m_StackFrame = lcontext.Scope.PopBlock();
-			m_DebugText = "???";
+
+			lcontext.Source.Refs.Add(m_RefFor);
+			lcontext.Source.Refs.Add(m_RefEnd);
 		}
 
 
@@ -87,7 +88,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			bc.Emit_ExpTuple(0);
 
 			// calls f(s, var) - stack : iterator-tuple, iteration result
-			bc.Emit_Call(2, m_DebugText);
+			bc.Emit_Call(2, "for..in");
 
 			// perform assignment of iteration result- stack : iterator-tuple, iteration result
 			for (int i = 0; i < m_NameExps.Length; i++)

+ 3 - 0
src/MoonSharp.Interpreter/Tree/Statements/ForLoopStatement.cs

@@ -47,6 +47,9 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			m_InnerBlock = new CompositeStatement(lcontext);
 			m_RefEnd = CheckTokenType(lcontext, TokenType.End).GetSourceRef();
 			m_StackFrame = lcontext.Scope.PopBlock();
+
+			lcontext.Source.Refs.Add(m_RefFor);
+			lcontext.Source.Refs.Add(m_RefEnd);
 		}		
 
 

+ 1 - 0
src/MoonSharp.Interpreter/Tree/Statements/FunctionCallStatement.cs

@@ -16,6 +16,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			: base(lcontext)
 		{
 			m_FunctionCallExpression = functionCallExpression;
+			lcontext.Source.Refs.Add(m_FunctionCallExpression.SourceRef);
 		}
 
 

+ 1 - 0
src/MoonSharp.Interpreter/Tree/Statements/FunctionDefinitionStatement.cs

@@ -87,6 +87,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			}
 
 			m_FuncDef = new FunctionDefinitionExpression(lcontext, m_IsMethodCallingConvention);
+			lcontext.Source.Refs.Add(m_SourceRef);
 		}
 
 		public override void Compile(Execution.VM.ByteCode bc)

+ 25 - 7
src/MoonSharp.Interpreter/Tree/Statements/GotoStatement.cs

@@ -10,30 +10,48 @@ namespace MoonSharp.Interpreter.Tree.Statements
 {
 	class GotoStatement : Statement
 	{
-		SourceRef m_Ref;
+		internal SourceRef SourceRef { get; private set; }
+		internal Token GotoToken { get; private set; }
 		public string Label { get; private set; }
 
+		internal int DefinedVarsCount { get; private set; }
+		internal string LastDefinedVarName { get; private set; }
+
+		Instruction m_Jump;
+		int m_LabelAddress = -1;
+
 		public GotoStatement(ScriptLoadingContext lcontext)
 			: base(lcontext)
 		{
-			m_Ref = CheckTokenType(lcontext, TokenType.Goto).GetSourceRef();
+			GotoToken = CheckTokenType(lcontext, TokenType.Goto);
 			Token name = CheckTokenType(lcontext, TokenType.Name);
 
+			SourceRef = GotoToken.GetSourceRef(name);
+
 			Label = name.Text;
+
+			lcontext.Scope.RegisterGoto(this);
 		}
 
 		public override void Compile(ByteCode bc)
 		{
-			
+			m_Jump = bc.Emit_Jump(OpCode.Jump, m_LabelAddress);
 		}
 
+		internal void SetDefinedVars(int definedVarsCount, string lastDefinedVarsName)
+		{
+			DefinedVarsCount = definedVarsCount;
+			LastDefinedVarName = lastDefinedVarsName;
+		}
 
 
-
-
-		internal void ResolveLabel(LabelStatement labelStatement)
+		internal void SetAddress(int labelAddress)
 		{
-			throw new NotImplementedException();
+			m_LabelAddress = labelAddress;
+
+			if (m_Jump != null)
+				m_Jump.NumVal = labelAddress;
 		}
+
 	}
 }

+ 4 - 1
src/MoonSharp.Interpreter/Tree/Statements/IfStatement.cs

@@ -38,6 +38,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			}
 
 			m_End = CheckTokenType(lcontext, TokenType.End).GetSourceRef();
+			lcontext.Source.Refs.Add(m_End);
 		}
 
 		IfBlock CreateIfBlock(ScriptLoadingContext lcontext)
@@ -52,7 +53,8 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			ifblock.Source = type.GetSourceRef(CheckTokenType(lcontext, TokenType.Then));
 			ifblock.Block = new CompositeStatement(lcontext);
 			ifblock.StackFrame = lcontext.Scope.PopBlock();
-			
+			lcontext.Source.Refs.Add(ifblock.Source);
+
 
 			return ifblock;
 		}
@@ -67,6 +69,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			ifblock.Block = new CompositeStatement(lcontext);
 			ifblock.StackFrame = lcontext.Scope.PopBlock();
 			ifblock.Source = type.GetSourceRef();
+			lcontext.Source.Refs.Add(ifblock.Source);
 			return ifblock;
 		}
 

+ 37 - 3
src/MoonSharp.Interpreter/Tree/Statements/LabelStatement.cs

@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
+using MoonSharp.Interpreter.Debugging;
 using MoonSharp.Interpreter.Execution;
 
 namespace MoonSharp.Interpreter.Tree.Statements
@@ -9,22 +10,55 @@ namespace MoonSharp.Interpreter.Tree.Statements
 	class LabelStatement : Statement
 	{
 		public string Label { get; private set; }
+		public int Address { get; private set; }
+		public SourceRef SourceRef { get; private set; }
+		public Token NameToken { get; private set; }
+
+		internal int DefinedVarsCount { get; private set; }
+		internal string LastDefinedVarName { get; private set; }
+
+		List<GotoStatement> m_Gotos = new List<GotoStatement>();
+		RuntimeScopeBlock m_StackFrame;
 
 
 		public LabelStatement(ScriptLoadingContext lcontext)
 			: base(lcontext)
 		{
 			CheckTokenType(lcontext, TokenType.DoubleColon);
-			Token name = CheckTokenType(lcontext, TokenType.Name);
+			NameToken = CheckTokenType(lcontext, TokenType.Name);
 			CheckTokenType(lcontext, TokenType.DoubleColon);
 
-			Label = name.Text;
+			SourceRef = NameToken.GetSourceRef();
+			Label = NameToken.Text;
+
+			lcontext.Scope.DefineLabel(this);
+		}
+
+		internal void SetDefinedVars(int definedVarsCount, string lastDefinedVarsName)
+		{
+			DefinedVarsCount = definedVarsCount;
+			LastDefinedVarName = lastDefinedVarsName;
+		}
+
+		internal void RegisterGoto(GotoStatement gotostat)
+		{
+			m_Gotos.Add(gotostat);
 		}
 
 
 		public override void Compile(Execution.VM.ByteCode bc)
 		{
-			throw new NotImplementedException();
+			bc.Emit_Clean(m_StackFrame);
+
+			Address = bc.GetJumpPointForLastInstruction();
+
+			foreach (var gotostat in m_Gotos)
+				gotostat.SetAddress(this.Address);
+		}
+
+		internal void SetScope(RuntimeScopeBlock runtimeScopeBlock)
+		{
+			m_StackFrame = runtimeScopeBlock;
 		}
 	}
 }

+ 2 - 0
src/MoonSharp.Interpreter/Tree/Statements/RepeatStatement.cs

@@ -31,6 +31,8 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			m_Until = until.GetSourceRefUpTo(lcontext.Lexer.Current);
 
 			m_StackFrame = lcontext.Scope.PopBlock();
+			lcontext.Source.Refs.Add(m_Repeat);
+			lcontext.Source.Refs.Add(m_Until);
 		}
 
 		public override void Compile(ByteCode bc)

+ 5 - 2
src/MoonSharp.Interpreter/Tree/Statements/ReturnStatement.cs

@@ -17,6 +17,8 @@ namespace MoonSharp.Interpreter.Tree.Statements
 		public ReturnStatement(ScriptLoadingContext lcontext)
 			: base(lcontext)
 		{
+			Token ret = lcontext.Lexer.Current;
+
 			lcontext.Lexer.Next();
 
 			Token cur = lcontext.Lexer.Current;
@@ -24,13 +26,14 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			if (cur.IsEndOfBlock() || cur.Type == TokenType.SemiColon)
 			{
 				m_Expression = null;
-				m_Ref = cur.GetSourceRef();
+				m_Ref = ret.GetSourceRef();
 			}
 			else
 			{
 				m_Expression = new ExprListExpression(Expression.ExprList(lcontext), lcontext);
-				m_Ref = cur.GetSourceRefUpTo(lcontext.Lexer.Current);
+				m_Ref = ret.GetSourceRefUpTo(lcontext.Lexer.Current);
 			}
+			lcontext.Source.Refs.Add(m_Ref);
 		}
 
 

+ 2 - 0
src/MoonSharp.Interpreter/Tree/Statements/ScopeBlockStatement.cs

@@ -25,6 +25,8 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			m_End = CheckTokenType(lcontext, TokenType.End).GetSourceRef();
 
 			m_StackFrame = lcontext.Scope.PopBlock();
+			lcontext.Source.Refs.Add(m_Do);
+			lcontext.Source.Refs.Add(m_End);
 		}
 
 

+ 3 - 0
src/MoonSharp.Interpreter/Tree/Statements/WhileStatement.cs

@@ -33,6 +33,9 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			m_Block = new CompositeStatement(lcontext);
 			m_End = CheckTokenType(lcontext, TokenType.End).GetSourceRef();
 			m_StackFrame = lcontext.Scope.PopBlock();
+
+			lcontext.Source.Refs.Add(m_Start);
+			lcontext.Source.Refs.Add(m_End);
 		}