Browse Source

Debugger support started

Xanathar 10 years ago
parent
commit
f5e7c8410d
27 changed files with 312 additions and 57 deletions
  1. 36 0
      src/MoonSharp.Interpreter.Tests/EndToEnd/GotoTests.cs
  2. 1 0
      src/MoonSharp.Interpreter.Tests/MoonSharp.Interpreter.Tests.csproj
  3. 57 0
      src/MoonSharp.Interpreter/DataStructs/MultiDictionary.cs
  4. 13 0
      src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeLabelTracker.cs
  5. 44 0
      src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScopeBlock.cs
  6. 3 0
      src/MoonSharp.Interpreter/MoonSharp.Interpreter.csproj
  7. 8 0
      src/MoonSharp.Interpreter/Script.cs
  8. 9 1
      src/MoonSharp.Interpreter/Tree/Expressions/FunctionCallExpression.cs
  9. 4 3
      src/MoonSharp.Interpreter/Tree/Expressions/FunctionDefinitionExpression.cs
  10. 1 1
      src/MoonSharp.Interpreter/Tree/Lexer/Lexer.cs
  11. 16 2
      src/MoonSharp.Interpreter/Tree/Lexer/Token.cs
  12. 6 3
      src/MoonSharp.Interpreter/Tree/NodeBase.cs
  13. 14 9
      src/MoonSharp.Interpreter/Tree/Statement.cs
  14. 9 2
      src/MoonSharp.Interpreter/Tree/Statements/AssignmentStatement.cs
  15. 4 7
      src/MoonSharp.Interpreter/Tree/Statements/ForEachLoopStatement.cs
  16. 3 6
      src/MoonSharp.Interpreter/Tree/Statements/ForLoopStatement.cs
  17. 8 4
      src/MoonSharp.Interpreter/Tree/Statements/FunctionCallStatement.cs
  18. 7 2
      src/MoonSharp.Interpreter/Tree/Statements/FunctionDefinitionStatement.cs
  19. 39 0
      src/MoonSharp.Interpreter/Tree/Statements/GotoStatement.cs
  20. 4 2
      src/MoonSharp.Interpreter/Tree/Statements/IfStatement.cs
  21. 11 3
      src/MoonSharp.Interpreter/Tree/Statements/LabelStatement.cs
  22. 4 5
      src/MoonSharp.Interpreter/Tree/Statements/RepeatStatement.cs
  23. 2 0
      src/MoonSharp.Interpreter/Tree/Statements/ReturnStatement.cs
  24. 2 2
      src/MoonSharp.Interpreter/Tree/Statements/ScopeBlockStatement.cs
  25. 4 2
      src/MoonSharp.Interpreter/Tree/Statements/WhileStatement.cs
  26. 1 1
      src/MoonSharp.RemoteDebugger/RemoteDebugger.cs
  27. 2 2
      src/MoonSharp/Program.cs

+ 36 - 0
src/MoonSharp.Interpreter.Tests/EndToEnd/GotoTests.cs

@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+
+namespace MoonSharp.Interpreter.Tests.EndToEnd
+{
+	[TestFixture]
+	public class GotoTests
+	{
+		[Test]
+		[Ignore]
+		public void Goto1()
+		{
+			string script = @"
+				function test()
+					x = 3
+					goto skip	
+					x = x + 2;
+					::skip::
+					return x;
+				end				
+
+				return test();
+				";
+
+			DynValue res = Script.RunString(script);
+
+			Assert.AreEqual(DataType.Number, res.Type);
+			Assert.AreEqual(3, res.Number);
+		}
+
+
+	}
+}

+ 1 - 0
src/MoonSharp.Interpreter.Tests/MoonSharp.Interpreter.Tests.csproj

@@ -82,6 +82,7 @@
     <Compile Include="EndToEnd\CoroutineTests.cs" />
     <Compile Include="EndToEnd\CoroutineTests.cs" />
     <Compile Include="EndToEnd\DynamicTests.cs" />
     <Compile Include="EndToEnd\DynamicTests.cs" />
     <Compile Include="EndToEnd\ErrorHandlingTests.cs" />
     <Compile Include="EndToEnd\ErrorHandlingTests.cs" />
+    <Compile Include="EndToEnd\GotoTests.cs" />
     <Compile Include="EndToEnd\LuaTestSuiteExtract.cs" />
     <Compile Include="EndToEnd\LuaTestSuiteExtract.cs" />
     <Compile Include="EndToEnd\MetatableTests.cs">
     <Compile Include="EndToEnd\MetatableTests.cs">
       <SubType>Code</SubType>
       <SubType>Code</SubType>

+ 57 - 0
src/MoonSharp.Interpreter/DataStructs/MultiDictionary.cs

@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MoonSharp.Interpreter.DataStructs
+{
+	public class MultiDictionary<K, V>
+	{
+		Dictionary<K, List<V>> m_Map = new Dictionary<K, List<V>>();
+
+		public void Add(K key, V value)
+		{
+			List<V> list;
+			if (m_Map.TryGetValue(key, out list))
+			{
+				list.Add(value);
+			}
+			else
+			{
+				list = new List<V>();
+				list.Add(value);
+				m_Map.Add(key, list);
+			}
+		}
+
+		public IEnumerable<V> Find(K key)
+		{
+			List<V> list;
+			if (m_Map.TryGetValue(key, out list))
+				return list;
+			else
+				return new V[0];
+		}
+
+		public bool ContainsKey(K key)
+		{
+			return m_Map.ContainsKey(key);
+		}
+
+		public IEnumerable<K> Keys
+		{
+			get { return m_Map.Keys; }
+		}
+
+		public void Clear()
+		{
+			m_Map.Clear();
+		}
+
+		public void Remove(K key)
+		{
+			m_Map.Remove(key);
+		}
+
+	}
+}

+ 13 - 0
src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeLabelTracker.cs

@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using MoonSharp.Interpreter.Tree.Statements;
+
+namespace MoonSharp.Interpreter.Execution.Scopes
+{
+	class BuildTimeLabelTracker
+	{
+
+	}
+}

+ 44 - 0
src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScopeBlock.cs

@@ -2,6 +2,8 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Text;
 using System.Text;
+using MoonSharp.Interpreter.DataStructs;
+using MoonSharp.Interpreter.Tree.Statements;
 
 
 namespace MoonSharp.Interpreter.Execution.Scopes
 namespace MoonSharp.Interpreter.Execution.Scopes
 {
 {
@@ -14,6 +16,9 @@ namespace MoonSharp.Interpreter.Execution.Scopes
 
 
 		Dictionary<string, SymbolRef> m_DefinedNames = new Dictionary<string, SymbolRef>();
 		Dictionary<string, SymbolRef> m_DefinedNames = new Dictionary<string, SymbolRef>();
 
 
+		MultiDictionary<string, GotoStatement> m_PendingGotos;
+		Dictionary<string, LabelStatement> m_DefineLabels;
+
 		internal BuildTimeScopeBlock(BuildTimeScopeBlock parent)
 		internal BuildTimeScopeBlock(BuildTimeScopeBlock parent)
 		{
 		{
 			Parent = parent;
 			Parent = parent;
@@ -69,5 +74,44 @@ namespace MoonSharp.Interpreter.Execution.Scopes
 
 
 			return lastVal;
 			return lastVal;
 		}
 		}
+
+
+		public void DefineLabel(LabelStatement label)
+		{
+			if (m_DefineLabels.ContainsKey(label.Label))
+			{
+				throw new SyntaxErrorException(null, "label 'label' already defined on line 3");
+			}
+			else
+			{
+				m_DefineLabels.Add(label.Label, label);
+
+				foreach (GotoStatement gotostat in m_PendingGotos.Find(label.Label))
+				{
+					gotostat.ResolveLabel(label);
+				}
+
+				m_PendingGotos.Remove(label.Label);
+			}
+		}
+
+		public void ResolveGotoOrPending(GotoStatement gotostat)
+		{
+			if (m_DefineLabels.ContainsKey(gotostat.Label))
+			{
+				gotostat.ResolveLabel(m_DefineLabels[gotostat.Label]);
+			}
+			else
+			{
+				m_PendingGotos.Add(gotostat.Label, gotostat);
+			}
+		}
+
+
+
+
+
+
+
 	}
 	}
 }
 }

+ 3 - 0
src/MoonSharp.Interpreter/MoonSharp.Interpreter.csproj

@@ -92,6 +92,8 @@
     <Compile Include="CoreLib\OsSystemModule.cs" />
     <Compile Include="CoreLib\OsSystemModule.cs" />
     <Compile Include="CoreLib\OsTimeModule.cs" />
     <Compile Include="CoreLib\OsTimeModule.cs" />
     <Compile Include="CoreLib\StringLib\KopiLua_StrLib.cs" />
     <Compile Include="CoreLib\StringLib\KopiLua_StrLib.cs" />
+    <Compile Include="DataStructs\MultiDictionary.cs" />
+    <Compile Include="Execution\Scopes\BuildTimeLabelTracker.cs" />
     <Compile Include="IO\BinDumpBinaryReader.cs" />
     <Compile Include="IO\BinDumpBinaryReader.cs" />
     <Compile Include="IO\BinDumpBinaryWriter.cs">
     <Compile Include="IO\BinDumpBinaryWriter.cs">
       <SubType>Code</SubType>
       <SubType>Code</SubType>
@@ -244,6 +246,7 @@
     <Compile Include="Tree\Expressions\LiteralExpression.cs" />
     <Compile Include="Tree\Expressions\LiteralExpression.cs" />
     <Compile Include="Tree\Expressions\UnaryOperatorExpression.cs" />
     <Compile Include="Tree\Expressions\UnaryOperatorExpression.cs" />
     <Compile Include="Tree\Fast_Interface\Loader_Fast.cs" />
     <Compile Include="Tree\Fast_Interface\Loader_Fast.cs" />
+    <Compile Include="Tree\Statements\GotoStatement.cs" />
     <Compile Include="Tree\IVariable.cs" />
     <Compile Include="Tree\IVariable.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Tree\Expressions\ExprListExpression.cs" />
     <Compile Include="Tree\Expressions\ExprListExpression.cs" />

+ 8 - 0
src/MoonSharp.Interpreter/Script.cs

@@ -229,7 +229,15 @@ namespace MoonSharp.Interpreter
 		/// <summary>
 		/// <summary>
 		/// Dumps on the specified stream.
 		/// Dumps on the specified stream.
 		/// </summary>
 		/// </summary>
+		/// <param name="function">The function.</param>
 		/// <param name="stream">The stream.</param>
 		/// <param name="stream">The stream.</param>
+		/// <exception cref="System.ArgumentException">
+		/// function arg is not a function!
+		/// or
+		/// stream is readonly!
+		/// or
+		/// function arg has upvalues other than _ENV
+		/// </exception>
 		public void Dump(DynValue function, Stream stream)
 		public void Dump(DynValue function, Stream stream)
 		{
 		{
 			if (function.Type != DataType.Function)
 			if (function.Type != DataType.Function)

+ 9 - 1
src/MoonSharp.Interpreter/Tree/Expressions/FunctionCallExpression.cs

@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Text;
 using System.Text;
+using MoonSharp.Interpreter.Debugging;
 using MoonSharp.Interpreter.Execution;
 using MoonSharp.Interpreter.Execution;
 
 
 namespace MoonSharp.Interpreter.Tree.Expressions
 namespace MoonSharp.Interpreter.Tree.Expressions
@@ -13,10 +14,14 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 		string m_Name;
 		string m_Name;
 		string m_DebugErr;
 		string m_DebugErr;
 
 
+		internal SourceRef SourceRef { get; private set; }
+
 
 
 		public FunctionCallExpression(ScriptLoadingContext lcontext, Expression function, Token thisCallName)
 		public FunctionCallExpression(ScriptLoadingContext lcontext, Expression function, Token thisCallName)
 			: base(lcontext)
 			: base(lcontext)
 		{
 		{
+			Token callToken = thisCallName ?? lcontext.Lexer.Current;
+
 			m_Name = thisCallName != null ? thisCallName.Text : null;
 			m_Name = thisCallName != null ? thisCallName.Text : null;
 			m_DebugErr = function.GetFriendlyDebugName();
 			m_DebugErr = function.GetFriendlyDebugName();
 			m_Function = function;
 			m_Function = function;
@@ -30,12 +35,13 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 					if (t.Type == TokenType.Brk_Close_Round)
 					if (t.Type == TokenType.Brk_Close_Round)
 					{
 					{
 						m_Arguments = new List<Expression>();
 						m_Arguments = new List<Expression>();
+						SourceRef = callToken.GetSourceRef(t);
 						lcontext.Lexer.Next();
 						lcontext.Lexer.Next();
 					}
 					}
 					else
 					else
 					{
 					{
 						m_Arguments = ExprList(lcontext);
 						m_Arguments = ExprList(lcontext);
-						CheckMatch(lcontext, openBrk, TokenType.Brk_Close_Round, ")");
+						SourceRef = callToken.GetSourceRef(CheckMatch(lcontext, openBrk, TokenType.Brk_Close_Round, ")"));
 					}
 					}
 					break;
 					break;
 				case TokenType.String:
 				case TokenType.String:
@@ -44,12 +50,14 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 						m_Arguments = new List<Expression>();
 						m_Arguments = new List<Expression>();
 						Expression le = new LiteralExpression(lcontext, lcontext.Lexer.Current);
 						Expression le = new LiteralExpression(lcontext, lcontext.Lexer.Current);
 						m_Arguments.Add(le);
 						m_Arguments.Add(le);
+						SourceRef = callToken.GetSourceRef(lcontext.Lexer.Current);
 					}
 					}
 					break;
 					break;
 				case TokenType.Brk_Open_Curly:
 				case TokenType.Brk_Open_Curly:
 					{
 					{
 						m_Arguments = new List<Expression>();
 						m_Arguments = new List<Expression>();
 						m_Arguments.Add(new TableConstructor(lcontext));
 						m_Arguments.Add(new TableConstructor(lcontext));
+						SourceRef = callToken.GetSourceRefUpTo(lcontext.Lexer.Current);
 					}
 					}
 					break;
 					break;
 				default:
 				default:

+ 4 - 3
src/MoonSharp.Interpreter/Tree/Expressions/FunctionDefinitionExpression.cs

@@ -50,6 +50,8 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			List<string> paramnames = BuildParamList(lcontext, pushSelfParam, openRound);
 			List<string> paramnames = BuildParamList(lcontext, pushSelfParam, openRound);
 			// here lexer is at first token of body
 			// here lexer is at first token of body
 
 
+			m_Begin = openRound.GetSourceRefUpTo(lcontext.Lexer.Current);
+
 			// create scope
 			// create scope
 			lcontext.Scope.PushFunction(this, m_HasVarArgs);
 			lcontext.Scope.PushFunction(this, m_HasVarArgs);
 
 
@@ -68,9 +70,6 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			m_Statement = CreateBody(lcontext);
 			m_Statement = CreateBody(lcontext);
 
 
 			m_StackFrame = lcontext.Scope.PopFunction();
 			m_StackFrame = lcontext.Scope.PopFunction();
-
-			//m_Begin = BuildSourceRef(declarationContext.Start, context.PAREN_CLOSE().Symbol);
-			//m_End = BuildSourceRef(context.Stop, context.END());
 		}
 		}
 
 
 		private Statement CreateBody(ScriptLoadingContext lcontext)
 		private Statement CreateBody(ScriptLoadingContext lcontext)
@@ -80,6 +79,8 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			if (lcontext.Lexer.Current.Type != TokenType.End)
 			if (lcontext.Lexer.Current.Type != TokenType.End)
 				throw new SyntaxErrorException(lcontext.Lexer.Current, "'end' expected near '{0}'", lcontext.Lexer.Current.Text);
 				throw new SyntaxErrorException(lcontext.Lexer.Current, "'end' expected near '{0}'", lcontext.Lexer.Current.Text);
 
 
+			m_End = lcontext.Lexer.Current.GetSourceRef();
+
 			lcontext.Lexer.Next();
 			lcontext.Lexer.Next();
 			return s;
 			return s;
 		}
 		}

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

@@ -103,7 +103,7 @@ namespace MoonSharp.Interpreter.Tree
 
 
 		private char CursorCharNext()
 		private char CursorCharNext()
 		{
 		{
-			m_Cursor += 1;
+			CursorNext();
 			return CursorChar();
 			return CursorChar();
 		}
 		}
 
 

+ 16 - 2
src/MoonSharp.Interpreter/Tree/Lexer/Token.cs

@@ -29,7 +29,12 @@ namespace MoonSharp.Interpreter.Tree
 		public override string ToString()
 		public override string ToString()
 		{
 		{
 			string tokenTypeString = (Type.ToString() + "                                                      ").Substring(0, 16);
 			string tokenTypeString = (Type.ToString() + "                                                      ").Substring(0, 16);
-			return string.Format("{0}  -  '{1}'", tokenTypeString, this.Text ?? "");
+
+			string location = string.Format("{0}:{1}-{2}:{3}", FromLine, FromCol, ToLine, ToCol);
+
+			location = (location + "                                                      ").Substring(0, 10);
+
+			return string.Format("{0}  - {1} - '{2}'", tokenTypeString, location, this.Text ?? "");
 		}
 		}
 
 
 		public static TokenType? GetReservedTokenType(string reservedWord)
 		public static TokenType? GetReservedTokenType(string reservedWord)
@@ -144,10 +149,19 @@ namespace MoonSharp.Interpreter.Tree
 		}
 		}
 
 
 
 
-
 		internal Debugging.SourceRef GetSourceRef(bool isStepStop = true)
 		internal Debugging.SourceRef GetSourceRef(bool isStepStop = true)
 		{
 		{
 			return new Debugging.SourceRef(this.SourceId, this.FromCol, this.ToCol, this.FromLine, this.ToLine, isStepStop);
 			return new Debugging.SourceRef(this.SourceId, this.FromCol, this.ToCol, this.FromLine, this.ToLine, isStepStop);
 		}
 		}
+
+		internal Debugging.SourceRef GetSourceRef(Token to, bool isStepStop = true)
+		{
+			return new Debugging.SourceRef(this.SourceId, this.FromCol, to.ToCol, this.FromLine, to.ToLine, isStepStop);
+		}
+
+		internal Debugging.SourceRef GetSourceRefUpTo(Token to, bool isStepStop = true)
+		{
+			return new Debugging.SourceRef(this.SourceId, this.FromCol, to.FromCol, this.FromLine, to.FromLine, isStepStop);
+		}
 	}
 	}
 }
 }

+ 6 - 3
src/MoonSharp.Interpreter/Tree/NodeBase.cs

@@ -83,14 +83,17 @@ namespace MoonSharp.Interpreter.Tree
 				throw new SyntaxErrorException(t, "unexpected symbol near '{0}'", t.Text);
 				throw new SyntaxErrorException(t, "unexpected symbol near '{0}'", t.Text);
 		}
 		}
 
 
-		protected static void CheckMatch(ScriptLoadingContext lcontext, Token originalToken, TokenType expectedTokenType, string expectedTokenText)
+		protected static Token CheckMatch(ScriptLoadingContext lcontext, Token originalToken, TokenType expectedTokenType, string expectedTokenText)
 		{
 		{
-			if (lcontext.Lexer.Current.Type != expectedTokenType)
+			Token t = lcontext.Lexer.Current;
+			if (t.Type != expectedTokenType)
 				throw new SyntaxErrorException(lcontext.Lexer.Current,
 				throw new SyntaxErrorException(lcontext.Lexer.Current,
 					"'{0}' expected (to close '{1}' at line {2}) near '{3}'",
 					"'{0}' expected (to close '{1}' at line {2}) near '{3}'",
-					expectedTokenText, originalToken.Text, originalToken.FromLine, lcontext.Lexer.Current.Text);
+					expectedTokenText, originalToken.Text, originalToken.FromLine, t.Text);
 
 
 			lcontext.Lexer.Next();
 			lcontext.Lexer.Next();
+
+			return t;
 		}
 		}
 	}
 	}
 }
 }

+ 14 - 9
src/MoonSharp.Interpreter/Tree/Statement.cs

@@ -26,6 +26,8 @@ namespace MoonSharp.Interpreter.Tree
 
 
 			switch (tkn.Type)
 			switch (tkn.Type)
 			{
 			{
+				case TokenType.Goto:
+					return new GotoStatement(lcontext);
 				case TokenType.SemiColon:
 				case TokenType.SemiColon:
 					lcontext.Lexer.Next();
 					lcontext.Lexer.Next();
 					return new EmptyStatement(lcontext);
 					return new EmptyStatement(lcontext);
@@ -40,13 +42,14 @@ namespace MoonSharp.Interpreter.Tree
 				case TokenType.Repeat:
 				case TokenType.Repeat:
 					return new RepeatStatement(lcontext);
 					return new RepeatStatement(lcontext);
 				case TokenType.Function:
 				case TokenType.Function:
-					return new FunctionDefinitionStatement(lcontext, false);
+					return new FunctionDefinitionStatement(lcontext, false, null);
 				case TokenType.Local:
 				case TokenType.Local:
+					Token localToken = lcontext.Lexer.Current;
 					lcontext.Lexer.Next();
 					lcontext.Lexer.Next();
 					if (lcontext.Lexer.Current.Type == TokenType.Function)
 					if (lcontext.Lexer.Current.Type == TokenType.Function)
-						return new FunctionDefinitionStatement(lcontext, true);
+						return new FunctionDefinitionStatement(lcontext, true, localToken);
 					else
 					else
-						return new AssignmentStatement(lcontext);
+						return new AssignmentStatement(lcontext, localToken);
 				case TokenType.Return:
 				case TokenType.Return:
 					forceLast = true;
 					forceLast = true;
 					return new ReturnStatement(lcontext);
 					return new ReturnStatement(lcontext);
@@ -54,12 +57,14 @@ namespace MoonSharp.Interpreter.Tree
 					return new BreakStatement(lcontext);
 					return new BreakStatement(lcontext);
 				default:
 				default:
 					{
 					{
+						Token l = lcontext.Lexer.Current;
 						Expression exp = Expression.PrimaryExp(lcontext);
 						Expression exp = Expression.PrimaryExp(lcontext);
+						FunctionCallExpression fnexp = exp as FunctionCallExpression;
 
 
-						if (exp is FunctionCallExpression)
-							return new FunctionCallStatement(lcontext, exp);
+						if (fnexp != null)
+							return new FunctionCallStatement(lcontext, fnexp);
 						else
 						else
-							return new AssignmentStatement(lcontext, exp);
+							return new AssignmentStatement(lcontext, exp, l);
 					}
 					}
 			}
 			}
 		}
 		}
@@ -69,14 +74,14 @@ namespace MoonSharp.Interpreter.Tree
 			//	for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end | 
 			//	for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end | 
 			//	for namelist in explist do block end | 		
 			//	for namelist in explist do block end | 		
 
 
-			CheckTokenType(lcontext, TokenType.For);
+			Token forTkn = CheckTokenType(lcontext, TokenType.For);
 
 
 			Token name = CheckTokenType(lcontext, TokenType.Name);
 			Token name = CheckTokenType(lcontext, TokenType.Name);
 
 
 			if (lcontext.Lexer.Current.Type == TokenType.Op_Assignment)
 			if (lcontext.Lexer.Current.Type == TokenType.Op_Assignment)
-				return new ForLoopStatement(lcontext, name);
+				return new ForLoopStatement(lcontext, name, forTkn);
 			else
 			else
-				return new ForEachLoopStatement(lcontext, name);
+				return new ForEachLoopStatement(lcontext, name, forTkn);
 		}
 		}
 
 
 
 

+ 9 - 2
src/MoonSharp.Interpreter/Tree/Statements/AssignmentStatement.cs

@@ -16,11 +16,13 @@ namespace MoonSharp.Interpreter.Tree.Statements
 		SourceRef m_Ref;
 		SourceRef m_Ref;
 
 
 
 
-		public AssignmentStatement(ScriptLoadingContext lcontext)
+		public AssignmentStatement(ScriptLoadingContext lcontext, Token startToken)
 			: base(lcontext)
 			: base(lcontext)
 		{
 		{
 			List<string> names = new List<string>();
 			List<string> names = new List<string>();
 
 
+			Token first = startToken;
+
 			while (true)
 			while (true)
 			{
 			{
 				Token name = CheckTokenType(lcontext, TokenType.Name);
 				Token name = CheckTokenType(lcontext, TokenType.Name);
@@ -49,10 +51,12 @@ namespace MoonSharp.Interpreter.Tree.Statements
 				m_LValues.Add(symbol);
 				m_LValues.Add(symbol);
 			}
 			}
 
 
+			Token last = lcontext.Lexer.Current;
+			m_Ref = first.GetSourceRefUpTo(last);
 		}
 		}
 
 
 
 
-		public AssignmentStatement(ScriptLoadingContext lcontext, Expression firstExpression)
+		public AssignmentStatement(ScriptLoadingContext lcontext, Expression firstExpression, Token first)
 			: base(lcontext)
 			: base(lcontext)
 		{
 		{
 			m_LValues.Add(CheckVar(lcontext, firstExpression));
 			m_LValues.Add(CheckVar(lcontext, firstExpression));
@@ -67,6 +71,9 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			CheckTokenType(lcontext, TokenType.Op_Assignment);
 			CheckTokenType(lcontext, TokenType.Op_Assignment);
 
 
 			m_RValues = Expression.ExprList(lcontext);
 			m_RValues = Expression.ExprList(lcontext);
+
+			Token last = lcontext.Lexer.Current;
+			m_Ref = first.GetSourceRefUpTo(last);
 		}
 		}
 
 
 		private IVariable CheckVar(ScriptLoadingContext lcontext, Expression firstExpression)
 		private IVariable CheckVar(ScriptLoadingContext lcontext, Expression firstExpression)

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

@@ -20,7 +20,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 		string m_DebugText;
 		string m_DebugText;
 		SourceRef m_RefFor, m_RefEnd;
 		SourceRef m_RefFor, m_RefEnd;
 
 
-		public ForEachLoopStatement(ScriptLoadingContext lcontext, Token firstNameToken)
+		public ForEachLoopStatement(ScriptLoadingContext lcontext, Token firstNameToken, Token forToken)
 			: base(lcontext)
 			: base(lcontext)
 		{
 		{
 			//	for namelist in explist do block end | 		
 			//	for namelist in explist do block end | 		
@@ -50,17 +50,14 @@ namespace MoonSharp.Interpreter.Tree.Statements
 				.Cast<IVariable>()
 				.Cast<IVariable>()
 				.ToArray();
 				.ToArray();
 
 
-			CheckTokenType(lcontext, TokenType.Do);
+			m_RefFor = forToken.GetSourceRef(CheckTokenType(lcontext, TokenType.Do));
 
 
 			m_Block = new CompositeStatement(lcontext);
 			m_Block = new CompositeStatement(lcontext);
 
 
-			CheckTokenType(lcontext, TokenType.End);
+			m_RefEnd = CheckTokenType(lcontext, TokenType.End).GetSourceRef();
 
 
 			m_StackFrame = lcontext.Scope.PopBlock();
 			m_StackFrame = lcontext.Scope.PopBlock();
 			m_DebugText = "???";
 			m_DebugText = "???";
-
-			//m_RefFor = BuildSourceRef(context.Start, context.FOR());
-			//m_RefEnd = BuildSourceRef(context.Stop, context.END());
 		}
 		}
 
 
 
 
@@ -87,7 +84,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			bc.Emit_Enter(m_StackFrame);
 			bc.Emit_Enter(m_StackFrame);
 
 
 			// expand the tuple - stack : iterator-tuple, f, var, s
 			// expand the tuple - stack : iterator-tuple, f, var, s
-			bc.Emit_ExpTuple(0);  
+			bc.Emit_ExpTuple(0);
 
 
 			// calls f(s, var) - stack : iterator-tuple, iteration result
 			// calls f(s, var) - stack : iterator-tuple, iteration result
 			bc.Emit_Call(2, m_DebugText);
 			bc.Emit_Call(2, m_DebugText);

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

@@ -19,7 +19,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 		Expression m_Start, m_End, m_Step;
 		Expression m_Start, m_End, m_Step;
 		SourceRef m_RefFor, m_RefEnd;
 		SourceRef m_RefFor, m_RefEnd;
 
 
-		public ForLoopStatement(ScriptLoadingContext lcontext, Token nameToken)
+		public ForLoopStatement(ScriptLoadingContext lcontext, Token nameToken, Token forToken)
 			: base(lcontext)
 			: base(lcontext)
 		{
 		{
 			//	for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end | 
 			//	for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end | 
@@ -43,13 +43,10 @@ namespace MoonSharp.Interpreter.Tree.Statements
 
 
 			lcontext.Scope.PushBlock();
 			lcontext.Scope.PushBlock();
 			m_VarName = lcontext.Scope.DefineLocal(nameToken.Text);
 			m_VarName = lcontext.Scope.DefineLocal(nameToken.Text);
-			CheckTokenType(lcontext, TokenType.Do);
+			m_RefFor = forToken.GetSourceRef(CheckTokenType(lcontext, TokenType.Do));
 			m_InnerBlock = new CompositeStatement(lcontext);
 			m_InnerBlock = new CompositeStatement(lcontext);
-			CheckTokenType(lcontext, TokenType.End);
+			m_RefEnd = CheckTokenType(lcontext, TokenType.End).GetSourceRef();
 			m_StackFrame = lcontext.Scope.PopBlock();
 			m_StackFrame = lcontext.Scope.PopBlock();
-
-			//m_RefFor = BuildSourceRef(context.Start, context.FOR());
-			//m_RefEnd = BuildSourceRef(context.Stop, context.END());
 		}		
 		}		
 
 
 
 

+ 8 - 4
src/MoonSharp.Interpreter/Tree/Statements/FunctionCallStatement.cs

@@ -4,14 +4,15 @@ using System.Linq;
 using System.Text;
 using System.Text;
 using MoonSharp.Interpreter.Execution;
 using MoonSharp.Interpreter.Execution;
 using MoonSharp.Interpreter.Execution.VM;
 using MoonSharp.Interpreter.Execution.VM;
+using MoonSharp.Interpreter.Tree.Expressions;
 
 
 namespace MoonSharp.Interpreter.Tree.Statements
 namespace MoonSharp.Interpreter.Tree.Statements
 {
 {
 	class FunctionCallStatement : Statement
 	class FunctionCallStatement : Statement
 	{
 	{
-		Expression m_FunctionCallExpression;
+		FunctionCallExpression m_FunctionCallExpression;
 
 
-		public FunctionCallStatement(ScriptLoadingContext lcontext, Expression functionCallExpression)
+		public FunctionCallStatement(ScriptLoadingContext lcontext, FunctionCallExpression functionCallExpression)
 			: base(lcontext)
 			: base(lcontext)
 		{
 		{
 			m_FunctionCallExpression = functionCallExpression;
 			m_FunctionCallExpression = functionCallExpression;
@@ -20,8 +21,11 @@ namespace MoonSharp.Interpreter.Tree.Statements
 
 
 		public override void Compile(ByteCode bc)
 		public override void Compile(ByteCode bc)
 		{
 		{
-			m_FunctionCallExpression.Compile(bc);
-			bc.Emit_Pop();
+			using (bc.EnterSource(m_FunctionCallExpression.SourceRef))
+			{
+				m_FunctionCallExpression.Compile(bc);
+				bc.Emit_Pop();
+			}
 		}
 		}
 	}
 	}
 }
 }

+ 7 - 2
src/MoonSharp.Interpreter/Tree/Statements/FunctionDefinitionStatement.cs

@@ -22,11 +22,12 @@ namespace MoonSharp.Interpreter.Tree.Statements
 		List<string> m_TableAccessors;
 		List<string> m_TableAccessors;
 		FunctionDefinitionExpression m_FuncDef;
 		FunctionDefinitionExpression m_FuncDef;
 
 
-		public FunctionDefinitionStatement(ScriptLoadingContext lcontext, bool local)
+		public FunctionDefinitionStatement(ScriptLoadingContext lcontext, bool local, Token localToken)
 			: base(lcontext)
 			: base(lcontext)
 		{
 		{
 			// here lexer must be at the 'function' keyword
 			// here lexer must be at the 'function' keyword
-			CheckTokenType(lcontext, TokenType.Function);
+			Token funcKeyword = CheckTokenType(lcontext, TokenType.Function);
+			funcKeyword = localToken ?? funcKeyword; // for debugger purposes
 			
 			
 			m_Local = local;
 			m_Local = local;
 
 
@@ -35,12 +36,15 @@ namespace MoonSharp.Interpreter.Tree.Statements
 				Token name = CheckTokenType(lcontext, TokenType.Name);
 				Token name = CheckTokenType(lcontext, TokenType.Name);
 				m_FuncSymbol = lcontext.Scope.TryDefineLocal(name.Text);
 				m_FuncSymbol = lcontext.Scope.TryDefineLocal(name.Text);
 				m_FriendlyName = string.Format("{0} (local)", name.Text);
 				m_FriendlyName = string.Format("{0} (local)", name.Text);
+				m_SourceRef = funcKeyword.GetSourceRef(name);
 			}
 			}
 			else
 			else
 			{
 			{
 				Token name = CheckTokenType(lcontext, TokenType.Name);
 				Token name = CheckTokenType(lcontext, TokenType.Name);
 				string firstName = name.Text;
 				string firstName = name.Text;
 
 
+				m_SourceRef = funcKeyword.GetSourceRef(name);
+
 				m_FuncSymbol = lcontext.Scope.Find(firstName);
 				m_FuncSymbol = lcontext.Scope.Find(firstName);
 				m_FriendlyName = firstName;
 				m_FriendlyName = firstName;
 
 
@@ -60,6 +64,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 						Token field = CheckTokenType(lcontext, TokenType.Name);
 						Token field = CheckTokenType(lcontext, TokenType.Name);
 
 
 						m_FriendlyName += separator.Text + field.Text;
 						m_FriendlyName += separator.Text + field.Text;
+						m_SourceRef = funcKeyword.GetSourceRef(field);
 
 
 						if (separator.Type == TokenType.Colon)
 						if (separator.Type == TokenType.Colon)
 						{
 						{

+ 39 - 0
src/MoonSharp.Interpreter/Tree/Statements/GotoStatement.cs

@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using MoonSharp.Interpreter.Debugging;
+using MoonSharp.Interpreter.Execution;
+using MoonSharp.Interpreter.Execution.VM;
+
+namespace MoonSharp.Interpreter.Tree.Statements
+{
+	class GotoStatement : Statement
+	{
+		SourceRef m_Ref;
+		public string Label { get; private set; }
+
+		public GotoStatement(ScriptLoadingContext lcontext)
+			: base(lcontext)
+		{
+			m_Ref = CheckTokenType(lcontext, TokenType.Goto).GetSourceRef();
+			Token name = CheckTokenType(lcontext, TokenType.Name);
+
+			Label = name.Text;
+		}
+
+		public override void Compile(ByteCode bc)
+		{
+			
+		}
+
+
+
+
+
+		internal void ResolveLabel(LabelStatement labelStatement)
+		{
+			throw new NotImplementedException();
+		}
+	}
+}

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

@@ -37,7 +37,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 				m_Else = CreateElseBlock(lcontext);
 				m_Else = CreateElseBlock(lcontext);
 			}
 			}
 
 
-			CheckTokenType(lcontext, TokenType.End);
+			m_End = CheckTokenType(lcontext, TokenType.End).GetSourceRef();
 		}
 		}
 
 
 		IfBlock CreateIfBlock(ScriptLoadingContext lcontext)
 		IfBlock CreateIfBlock(ScriptLoadingContext lcontext)
@@ -49,9 +49,10 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			var ifblock = new IfBlock();
 			var ifblock = new IfBlock();
 
 
 			ifblock.Exp = Expression.Expr(lcontext);
 			ifblock.Exp = Expression.Expr(lcontext);
-			CheckTokenType(lcontext, TokenType.Then);
+			ifblock.Source = type.GetSourceRef(CheckTokenType(lcontext, TokenType.Then));
 			ifblock.Block = new CompositeStatement(lcontext);
 			ifblock.Block = new CompositeStatement(lcontext);
 			ifblock.StackFrame = lcontext.Scope.PopBlock();
 			ifblock.StackFrame = lcontext.Scope.PopBlock();
+			
 
 
 			return ifblock;
 			return ifblock;
 		}
 		}
@@ -65,6 +66,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			var ifblock = new IfBlock();
 			var ifblock = new IfBlock();
 			ifblock.Block = new CompositeStatement(lcontext);
 			ifblock.Block = new CompositeStatement(lcontext);
 			ifblock.StackFrame = lcontext.Scope.PopBlock();
 			ifblock.StackFrame = lcontext.Scope.PopBlock();
+			ifblock.Source = type.GetSourceRef();
 			return ifblock;
 			return ifblock;
 		}
 		}
 
 

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

@@ -1,5 +1,4 @@
-#if false
-using System;
+using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Text;
 using System.Text;
@@ -12,6 +11,16 @@ namespace MoonSharp.Interpreter.Tree.Statements
 		public string Label { get; private set; }
 		public string Label { get; private set; }
 
 
 
 
+		public LabelStatement(ScriptLoadingContext lcontext)
+			: base(lcontext)
+		{
+			CheckTokenType(lcontext, TokenType.DoubleColon);
+			Token name = CheckTokenType(lcontext, TokenType.Name);
+			CheckTokenType(lcontext, TokenType.DoubleColon);
+
+			Label = name.Text;
+		}
+
 
 
 		public override void Compile(Execution.VM.ByteCode bc)
 		public override void Compile(Execution.VM.ByteCode bc)
 		{
 		{
@@ -20,4 +29,3 @@ namespace MoonSharp.Interpreter.Tree.Statements
 	}
 	}
 }
 }
 
 
-#endif

+ 4 - 5
src/MoonSharp.Interpreter/Tree/Statements/RepeatStatement.cs

@@ -19,19 +19,18 @@ namespace MoonSharp.Interpreter.Tree.Statements
 		public RepeatStatement(ScriptLoadingContext lcontext)
 		public RepeatStatement(ScriptLoadingContext lcontext)
 			: base(lcontext)
 			: base(lcontext)
 		{
 		{
-			CheckTokenType(lcontext, TokenType.Repeat);
+			m_Repeat = CheckTokenType(lcontext, TokenType.Repeat).GetSourceRef();
 
 
 			lcontext.Scope.PushBlock();
 			lcontext.Scope.PushBlock();
 			m_Block = new CompositeStatement(lcontext);
 			m_Block = new CompositeStatement(lcontext);
 
 
-			CheckTokenType(lcontext, TokenType.Until);
+			Token until = CheckTokenType(lcontext, TokenType.Until);
 
 
 			m_Condition = Expression.Expr(lcontext);
 			m_Condition = Expression.Expr(lcontext);
 
 
-			m_StackFrame = lcontext.Scope.PopBlock();
+			m_Until = until.GetSourceRefUpTo(lcontext.Lexer.Current);
 
 
-			//m_Repeat = BuildSourceRef(context.Start, context.REPEAT());
-			//m_Until = BuildSourceRef(exp.Start, exp.Stop);
+			m_StackFrame = lcontext.Scope.PopBlock();
 		}
 		}
 
 
 		public override void Compile(ByteCode bc)
 		public override void Compile(ByteCode bc)

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

@@ -24,10 +24,12 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			if (cur.IsEndOfBlock() || cur.Type == TokenType.SemiColon)
 			if (cur.IsEndOfBlock() || cur.Type == TokenType.SemiColon)
 			{
 			{
 				m_Expression = null;
 				m_Expression = null;
+				m_Ref = cur.GetSourceRef();
 			}
 			}
 			else
 			else
 			{
 			{
 				m_Expression = new ExprListExpression(Expression.ExprList(lcontext), lcontext);
 				m_Expression = new ExprListExpression(Expression.ExprList(lcontext), lcontext);
+				m_Ref = cur.GetSourceRefUpTo(lcontext.Lexer.Current);
 			}
 			}
 		}
 		}
 
 

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

@@ -18,11 +18,11 @@ namespace MoonSharp.Interpreter.Tree.Statements
 		{
 		{
 			lcontext.Scope.PushBlock();
 			lcontext.Scope.PushBlock();
 
 
-			CheckTokenType(lcontext, TokenType.Do);
+			m_Do = CheckTokenType(lcontext, TokenType.Do).GetSourceRef();
 
 
 			m_Block = new CompositeStatement(lcontext);
 			m_Block = new CompositeStatement(lcontext);
 
 
-			CheckTokenType(lcontext, TokenType.End);
+			m_End = CheckTokenType(lcontext, TokenType.End).GetSourceRef();
 
 
 			m_StackFrame = lcontext.Scope.PopBlock();
 			m_StackFrame = lcontext.Scope.PopBlock();
 		}
 		}

+ 4 - 2
src/MoonSharp.Interpreter/Tree/Statements/WhileStatement.cs

@@ -19,17 +19,19 @@ namespace MoonSharp.Interpreter.Tree.Statements
 		public WhileStatement(ScriptLoadingContext lcontext)
 		public WhileStatement(ScriptLoadingContext lcontext)
 			: base(lcontext)
 			: base(lcontext)
 		{
 		{
-			CheckTokenType(lcontext, TokenType.While);
+			Token whileTk = CheckTokenType(lcontext, TokenType.While);
 
 
 			m_Condition = Expression.Expr(lcontext);
 			m_Condition = Expression.Expr(lcontext);
 
 
+			m_Start = whileTk.GetSourceRefUpTo(lcontext.Lexer.Current);
+
 			//m_Start = BuildSourceRef(context.Start, exp.Stop);
 			//m_Start = BuildSourceRef(context.Start, exp.Stop);
 			//m_End = BuildSourceRef(context.Stop, context.END());
 			//m_End = BuildSourceRef(context.Stop, context.END());
 
 
 			lcontext.Scope.PushBlock();
 			lcontext.Scope.PushBlock();
 			CheckTokenType(lcontext, TokenType.Do);
 			CheckTokenType(lcontext, TokenType.Do);
 			m_Block = new CompositeStatement(lcontext);
 			m_Block = new CompositeStatement(lcontext);
-			CheckTokenType(lcontext, TokenType.End);
+			m_End = CheckTokenType(lcontext, TokenType.End).GetSourceRef();
 			m_StackFrame = lcontext.Scope.PopBlock();
 			m_StackFrame = lcontext.Scope.PopBlock();
 		}
 		}
 
 

+ 1 - 1
src/MoonSharp.RemoteDebugger/RemoteDebugger.cs

@@ -88,7 +88,7 @@ namespace MoonSharp.RemoteDebugger
 			{
 			{
 				if (m_HttpServer != null)
 				if (m_HttpServer != null)
 				{
 				{
-					return string.Format("http://localhost:{0}/", m_Options.HttpPort.Value);
+					return string.Format("http://127.0.0.1:{0}/", m_Options.HttpPort.Value);
 				}
 				}
 				return null;
 				return null;
 			}
 			}

+ 2 - 2
src/MoonSharp/Program.cs

@@ -129,8 +129,8 @@ namespace MoonSharp
 			}
 			}
 			if (p == "!")
 			if (p == "!")
 			{
 			{
-				//ParseCommand(S, "debug");
-				//ParseCommand(S, @"run c:\temp\test.lua");
+				ParseCommand(S, "debug");
+				ParseCommand(S, @"run c:\temp\test.lua");
 			}
 			}
 			if (p == "wb")
 			if (p == "wb")
 			{
 			{