Xanathar 10 年 前
コミット
f04fb3e9cc
34 ファイル変更485 行追加275 行削除
  1. 37 16
      src/MoonSharp.Interpreter.Tests/EndToEnd/SimpleTests.cs
  2. 14 22
      src/MoonSharp.Interpreter.Tests/TestMore/203-lexico.t
  3. 2 2
      src/MoonSharp.Interpreter.Tests/TestMore/214-coroutine.t
  4. 5 1
      src/MoonSharp.Interpreter.Tests/TestMore/304-string.t
  5. 7 2
      src/MoonSharp.Interpreter.Tests/TestMore/305-table.t
  6. 48 49
      src/MoonSharp.Interpreter.Tests/TestMore/TestMoreTests.cs
  7. 1 1
      src/MoonSharp.Interpreter/CoreLib/LoadModule.cs
  8. 12 1
      src/MoonSharp.Interpreter/CoreLib/TableModule.cs
  9. 12 0
      src/MoonSharp.Interpreter/Errors/InterpreterException.cs
  10. 27 3
      src/MoonSharp.Interpreter/Errors/SyntaxErrorException.cs
  11. 0 12
      src/MoonSharp.Interpreter/Execution/ScriptLoadingContext.cs
  12. 0 1
      src/MoonSharp.Interpreter/Execution/VM/ByteCode.cs
  13. 1 1
      src/MoonSharp.Interpreter/Execution/VM/Processor/Processor_BinaryDump.cs
  14. 1 8
      src/MoonSharp.Interpreter/Execution/VM/Processor/Processor_Errors.cs
  15. 10 7
      src/MoonSharp.Interpreter/Tree/Expression_.cs
  16. 4 5
      src/MoonSharp.Interpreter/Tree/Expressions/FunctionCallExpression.cs
  17. 6 6
      src/MoonSharp.Interpreter/Tree/Expressions/FunctionDefinitionExpression.cs
  18. 5 29
      src/MoonSharp.Interpreter/Tree/Expressions/LiteralExpression.cs
  19. 4 2
      src/MoonSharp.Interpreter/Tree/Expressions/SymbolRefExpression.cs
  20. 60 36
      src/MoonSharp.Interpreter/Tree/Fast_Interface/Loader_Fast.cs
  21. 66 20
      src/MoonSharp.Interpreter/Tree/Lexer/Lexer.cs
  22. 1 1
      src/MoonSharp.Interpreter/Tree/Lexer/LexerBackDoor.cs
  23. 115 7
      src/MoonSharp.Interpreter/Tree/Lexer/LexerUtils.cs
  24. 20 11
      src/MoonSharp.Interpreter/Tree/Lexer/Token.cs
  25. 1 0
      src/MoonSharp.Interpreter/Tree/Lexer/TokenType.cs
  26. 12 19
      src/MoonSharp.Interpreter/Tree/NodeBase.cs
  27. 0 1
      src/MoonSharp.Interpreter/Tree/Statement.cs
  28. 1 1
      src/MoonSharp.Interpreter/Tree/Statements/AssignmentStatement.cs
  29. 3 3
      src/MoonSharp.Interpreter/Tree/Statements/BreakStatement.cs
  30. 1 1
      src/MoonSharp.Interpreter/Tree/Statements/ChunkStatement.cs
  31. 1 1
      src/MoonSharp.Interpreter/Tree/Statements/FunctionDefinitionStatement.cs
  32. 1 1
      src/MoonSharpTests/Program.cs
  33. 4 4
      src/PerformanceComparison/HugeFile.cs
  34. 3 1
      src/PerformanceComparison/Program.cs

+ 37 - 16
src/MoonSharp.Interpreter.Tests/EndToEnd/SimpleTests.cs

@@ -155,7 +155,7 @@ namespace MoonSharp.Interpreter.Tests
 			Assert.AreEqual(DataType.String, res.Tuple[0].Type);
 			Assert.AreEqual(DataType.String, res.Tuple[0].Type);
 			Assert.AreEqual(DataType.String, res.Tuple[1].Type);
 			Assert.AreEqual(DataType.String, res.Tuple[1].Type);
 			Assert.AreEqual(DataType.String, res.Tuple[2].Type);
 			Assert.AreEqual(DataType.String, res.Tuple[2].Type);
-			Assert.AreEqual("\t\t\t\t\tciao\r\n\t\t\t\t", res.Tuple[0].String);
+			Assert.AreEqual("\t\t\t\t\tciao\n\t\t\t\t", res.Tuple[0].String);
 			Assert.AreEqual(" [[uh]] ", res.Tuple[1].String);
 			Assert.AreEqual(" [[uh]] ", res.Tuple[1].String);
 			Assert.AreEqual("[==[[=[[[eheh]]=]=]", res.Tuple[2].String);
 			Assert.AreEqual("[==[[=[[[eheh]]=]=]", res.Tuple[2].String);
 		}
 		}
@@ -724,6 +724,17 @@ namespace MoonSharp.Interpreter.Tests
 			Assert.AreEqual(-4, res.Number);
 			Assert.AreEqual(-4, res.Number);
 		}
 		}
 
 
+		[Test]
+		public void OperatorPrecedence7()
+		{
+			string script = @"return -7 / 0.5";
+			Script S = new Script(CoreModules.None);
+
+			DynValue res = S.DoString(script);
+
+			Assert.AreEqual(DataType.Number, res.Type);
+			Assert.AreEqual(-14, res.Number);
+		}
 
 
 		[Test]
 		[Test]
 		public void OperatorPrecedenceAndAssociativity()
 		public void OperatorPrecedenceAndAssociativity()
@@ -1063,21 +1074,6 @@ namespace MoonSharp.Interpreter.Tests
 			Assert.AreEqual(1, res.Number);
 			Assert.AreEqual(1, res.Number);
 		}
 		}
 
 
-		[Test]
-		[ExpectedException(ExpectedException=typeof(SyntaxErrorException))]
-		public void HexFloatsReportError()
-		{
-			string script = @"
-					function x(a, b)
-			
-					end
-
-					x(0x0.1E, 0x1E / 0x100);
-								";
-
-			DynValue res = Script.RunString(script);
-		}
-
 
 
 		[Test]
 		[Test]
 		public void ExpressionReducesTuples2()
 		public void ExpressionReducesTuples2()
@@ -1412,6 +1408,31 @@ namespace MoonSharp.Interpreter.Tests
 			DynValue res = Script.RunString(script);
 			DynValue res = Script.RunString(script);
 		}
 		}
 
 
+		[Test]
+		public void HexFloats_1()
+		{
+			string script = "return 0x0.1E";
+			DynValue result = Script.RunString(script);
+			Assert.AreEqual((double)0x1E / (double)0x100, result.Number);
+		}
+
+		[Test]
+		public void HexFloats_2()
+		{
+			string script = "return 0xA23p-4";
+			DynValue result = Script.RunString(script);
+			Assert.AreEqual((double)0xA23 / 16.0, result.Number);
+		}
+
+		[Test]
+		public void HexFloats_3()
+		{
+			string script = "return 0X1.921FB54442D18P+1";
+			DynValue result = Script.RunString(script);
+			Assert.AreEqual((1 + (double)0x921FB54442D18 / (double)0x10000000000000) * 2, result.Number);
+		}
+
+
 
 
 
 
 	}
 	}

+ 14 - 22
src/MoonSharp.Interpreter.Tests/TestMore/203-lexico.t

@@ -44,7 +44,7 @@ is(string.byte("\t"), 9)
 is(string.byte("\v"), 11)
 is(string.byte("\v"), 11)
 is(string.byte("\\"), 92)
 is(string.byte("\\"), 92)
 
 
-is(string.len("A\0B"), 3, "chk")
+is(string.len("A\0B"), 3)
 
 
 f, msg = load [[a = "A\300"]]
 f, msg = load [[a = "A\300"]]
 like(msg, "^[^:]+:%d+: .- escape .- near")
 like(msg, "^[^:]+:%d+: .- escape .- near")
@@ -55,29 +55,25 @@ like(msg, "^[^:]+:%d+: .- near")
 f, msg = load [[a = "A\Z"]]
 f, msg = load [[a = "A\Z"]]
 like(msg, "^[^:]+:%d+: .- escape .- near")
 like(msg, "^[^:]+:%d+: .- escape .- near")
 
 
--- MoonSharp - changed tests because of different parser bail out errors
-
 f, msg = load [[a = " unfinished string ]]
 f, msg = load [[a = " unfinished string ]]
-like(msg, ".+")
+like(msg, "^[^:]+:%d+: unfinished string near")
 
 
 f, msg = load [[a = " unfinished string
 f, msg = load [[a = " unfinished string
 ]]
 ]]
-like(msg, ".+")
+like(msg, "^[^:]+:%d+: unfinished string near")
 
 
 f, msg = load [[a = " unfinished string \
 f, msg = load [[a = " unfinished string \
 ]]
 ]]
-like(msg, ".+")
+like(msg, "^[^:]+:%d+: unfinished string near")
 
 
 f, msg = load [[a = " unfinished string \]]
 f, msg = load [[a = " unfinished string \]]
-like(msg, ".+")
+like(msg, "^[^:]+:%d+: unfinished string near")
 
 
 f, msg = load "a = [[ unfinished long string "
 f, msg = load "a = [[ unfinished long string "
-like(msg, ".+")
+like(msg, "^[^:]+:%d+: unfinished long string near")
 
 
 f, msg = load "a = [== invalid long string delimiter "
 f, msg = load "a = [== invalid long string delimiter "
-like(msg, ".+")
-
--- End of MoonSharp changes
+like(msg, "^[^:]+:%d+: invalid long string delimiter near")
 
 
 a = 'alo\n123"'
 a = 'alo\n123"'
 is('alo\n123"', a)
 is('alo\n123"', a)
@@ -89,27 +85,23 @@ is([==[
 alo
 alo
 123"]==], a)
 123"]==], a)
 is("alo\n\z
 is("alo\n\z
-    123\"", a)
+123\"", a)
 
 
 f, msg = load [[a = " escape \z unauthorized
 f, msg = load [[a = " escape \z unauthorized
 new line" ]]
 new line" ]]
-like(msg, "^[^:]+:%d+: .+") -- MoonSharp changed error msg
+like(msg, "^[^:]+:%d+: unfinished string near")
 
 
 is(3.0, 3)
 is(3.0, 3)
 is(314.16e-2, 3.1416)
 is(314.16e-2, 3.1416)
 is(0.31416E1, 3.1416)
 is(0.31416E1, 3.1416)
 is(0xff, 255)
 is(0xff, 255)
 is(0x56, 86)
 is(0x56, 86)
---[[
-MoonSharp : no intention to support hex floats
-
- is(0x0.1E, 0x1E / 0x100, "hexf1")        -- 0.1171875
-is(0xA23p-4, 0xA23 / (2^4), "hexf2")     -- 162.1875
-is(0X1.921FB54442D18P+1, (1 + 0x921FB54442D18/0x10000000000000) * 2, "hexf3")
---]]
+is(0x0.1E, 0x1E / 0x100)        -- 0.1171875
+is(0xA23p-4, 0xA23 / (2^4))     -- 162.1875
+is(0X1.921FB54442D18P+1, (1 + 0x921FB54442D18/0x10000000000000) * 2)
 
 
 f, msg = load [[a = 12e34e56]]
 f, msg = load [[a = 12e34e56]]
-like(msg, ".+") -- MoonSharp changed error msg
+like(msg, "^[^:]+:%d+: malformed number near")
 
 
 --[===[
 --[===[
 --[[
 --[[
@@ -120,7 +112,7 @@ like(msg, ".+") -- MoonSharp changed error msg
 --]===]
 --]===]
 
 
 f, msg = load "  --[[ unfinished long comment "
 f, msg = load "  --[[ unfinished long comment "
-like(msg, ".+")
+like(msg, "^[^:]+:%d+: unfinished long comment near")
 
 
 -- Local Variables:
 -- Local Variables:
 --   mode: lua
 --   mode: lua

+ 2 - 2
src/MoonSharp.Interpreter.Tests/TestMore/214-coroutine.t

@@ -130,7 +130,7 @@ end)
 eq_array({co("Hello")}, {"Hello"})
 eq_array({co("Hello")}, {"Hello"})
 eq_array({co("World")}, {true, "World"})
 eq_array({co("World")}, {true, "World"})
 
 
---[[
+--[[ ]]
 co = coroutine.wrap(function(...)
 co = coroutine.wrap(function(...)
   function backtrace ()
   function backtrace ()
     return 'not a back trace'
     return 'not a back trace'
@@ -141,7 +141,7 @@ co = coroutine.wrap(function(...)
 end)
 end)
 eq_array({co("Hello")}, {"Hello"})
 eq_array({co("Hello")}, {"Hello"})
 eq_array({co("World")}, {true, "World"})
 eq_array({co("World")}, {true, "World"})
-]]
+
 
 
 --[[ ]]
 --[[ ]]
 local output = {}
 local output = {}

+ 5 - 1
src/MoonSharp.Interpreter.Tests/TestMore/304-string.t

@@ -54,7 +54,11 @@ error_like(function () string.char(0, 'bad') end,
            "function char (bad arg)")
            "function char (bad arg)")
 
 
 		   
 		   
---[[		   MoonSharp intentional : string.dump not supported, unicode chars supported!
+--[[		   
+MoonSharp intentional : 
+
+1) unicode chars supported!
+2) plan has upvalues, and by Lua spec it shouldn't be supported!
 		   
 		   
 error_like(function () string.char(0, 9999) end,
 error_like(function () string.char(0, 9999) end,
            "^[^:]+:%d+: bad argument #2 to 'char' %(.-value.-%)",
            "^[^:]+:%d+: bad argument #2 to 'char' %(.-value.-%)",

+ 7 - 2
src/MoonSharp.Interpreter.Tests/TestMore/305-table.t

@@ -171,7 +171,7 @@ for name, line in pairsByKeys(lines, function (a, b) return a < b end) do
 end
 end
 eq_array(output, {'luaH_get', 24, 'luaH_present', 48, 'luaH_set', 10}, "function sort")
 eq_array(output, {'luaH_get', 24, 'luaH_present', 48, 'luaH_set', 10}, "function sort")
 
 
---[[ +++ Commented for coroutines
+
 
 
 function permgen (a, n)
 function permgen (a, n)
     n = n or #a
     n = n or #a
@@ -223,6 +223,11 @@ eq_array(output, {
     'a b c d e f g', 5040,
     'a b c d e f g', 5040,
 }, "function sort (all permutations)")
 }, "function sort (all permutations)")
 
 
+--[[
+
+MoonSharp: Sort callbacks work --]]
+
+
 error_like(function ()
 error_like(function ()
     local t = { 1 }
     local t = { 1 }
     table.sort( { t, t, t, t, }, function (a, b) return a[1] == b[1] end )
     table.sort( { t, t, t, t, }, function (a, b) return a[1] == b[1] end )
@@ -230,6 +235,7 @@ error_like(function ()
            "^[^:]+:%d+: invalid order function for sorting",
            "^[^:]+:%d+: invalid order function for sorting",
            "function sort (bad func)")
            "function sort (bad func)")
 
 
+
 eq_array({table.unpack({})}, {}, "function unpack")
 eq_array({table.unpack({})}, {}, "function unpack")
 eq_array({table.unpack({'a'})}, {'a'})
 eq_array({table.unpack({'a'})}, {'a'})
 eq_array({table.unpack({'a','b','c'})}, {'a','b','c'})
 eq_array({table.unpack({'a','b','c'})}, {'a','b','c'})
@@ -245,4 +251,3 @@ eq_array({table.unpack({'a','b','c'},2,4)}, {'b','c'})
 -- vim: ft=lua expandtab shiftwidth=4:
 -- vim: ft=lua expandtab shiftwidth=4:
 
 
 
 
---]]

+ 48 - 49
src/MoonSharp.Interpreter.Tests/TestMore/TestMoreTests.cs

@@ -13,49 +13,49 @@ namespace MoonSharp.Interpreter.Tests
 		[Test]
 		[Test]
 		public void TestMore_000_sanity()
 		public void TestMore_000_sanity()
 		{
 		{
-			TapRunner.Run(@"TestMore\000-sanity.t");
+			TapRunner.Run(@"TestMore/000-sanity.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_001_if()
 		public void TestMore_001_if()
 		{
 		{
-			TapRunner.Run(@"TestMore\001-if.t");
+			TapRunner.Run(@"TestMore/001-if.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_002_table()
 		public void TestMore_002_table()
 		{
 		{
-			TapRunner.Run(@"TestMore\002-table.t");
+			TapRunner.Run(@"TestMore/002-table.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_011_while()
 		public void TestMore_011_while()
 		{
 		{
-			TapRunner.Run(@"TestMore\011-while.t");
+			TapRunner.Run(@"TestMore/011-while.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_012_repeat()
 		public void TestMore_012_repeat()
 		{
 		{
-			TapRunner.Run(@"TestMore\012-repeat.t");
+			TapRunner.Run(@"TestMore/012-repeat.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_014_fornum()
 		public void TestMore_014_fornum()
 		{
 		{
-			TapRunner.Run(@"TestMore\014-fornum.t");
+			TapRunner.Run(@"TestMore/014-fornum.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_015_forlist()
 		public void TestMore_015_forlist()
 		{
 		{
-			TapRunner.Run(@"TestMore\015-forlist.t");
+			TapRunner.Run(@"TestMore/015-forlist.t");
 		}
 		}
 
 
 
 
@@ -63,49 +63,49 @@ namespace MoonSharp.Interpreter.Tests
 		//[Ignore]
 		//[Ignore]
 		public void TestMore_101_boolean()
 		public void TestMore_101_boolean()
 		{
 		{
-			TapRunner.Run(@"TestMore\101-boolean.t");
+			TapRunner.Run(@"TestMore/101-boolean.t");
 		}
 		}
 
 
 
 
 		[Test] 
 		[Test] 
 		public void TestMore_102_function()
 		public void TestMore_102_function()
 		{
 		{
-			TapRunner.Run(@"TestMore\102-function.t");
+			TapRunner.Run(@"TestMore/102-function.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_103_nil()
 		public void TestMore_103_nil()
 		{
 		{
-			TapRunner.Run(@"TestMore\103-nil.t");
+			TapRunner.Run(@"TestMore/103-nil.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_104_number()
 		public void TestMore_104_number()
 		{
 		{
-			TapRunner.Run(@"TestMore\104-number.t");
+			TapRunner.Run(@"TestMore/104-number.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_105_string()
 		public void TestMore_105_string()
 		{
 		{
-			TapRunner.Run(@"TestMore\105-string.t");
+			TapRunner.Run(@"TestMore/105-string.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_106_table()
 		public void TestMore_106_table()
 		{
 		{
-			TapRunner.Run(@"TestMore\106-table.t");
+			TapRunner.Run(@"TestMore/106-table.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_107_thread()
 		public void TestMore_107_thread()
 		{
 		{
-			TapRunner.Run(@"TestMore\107-thread.t");
+			TapRunner.Run(@"TestMore/107-thread.t");
 		}
 		}
 
 
 
 
@@ -115,137 +115,136 @@ namespace MoonSharp.Interpreter.Tests
 		// end to end tests.
 		// end to end tests.
 		//public void TestMore_108_userdata()
 		//public void TestMore_108_userdata()
 		//{
 		//{
-		//	TapRunner.Run(@"TestMore\108-userdata.t");
+		//	TapRunner.Run(@"TestMore/108-userdata.t");
 		//}
 		//}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_200_examples()
 		public void TestMore_200_examples()
 		{
 		{
-			TapRunner.Run(@"TestMore\200-examples.t");
+			TapRunner.Run(@"TestMore/200-examples.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_201_assign()
 		public void TestMore_201_assign()
 		{
 		{
-			TapRunner.Run(@"TestMore\201-assign.t");
+			TapRunner.Run(@"TestMore/201-assign.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_202_expr()
 		public void TestMore_202_expr()
 		{
 		{
-			TapRunner.Run(@"TestMore\202-expr.t");
+			TapRunner.Run(@"TestMore/202-expr.t");
 		}
 		}
 
 
 
 
-		//[Test]
-		//[Ignore] // Failing because of handling of syntax error messages + goto/labels not implemented
-		//public void TestMore_203_lexico()
-		//{
-		//	TapRunner.Run(@"TestMore\203-lexico.t");
-		//}
+		[Test]
+		public void TestMore_203_lexico()
+		{
+			TapRunner.Run(@"TestMore/203-lexico.t");
+		}
 
 
-		//[Test]
-		//[Ignore] // Failing because of handling of syntax error messages
-		//public void TestMore_204_grammar()
-		//{
-		//	TapRunner.Run(@"TestMore\204-grammar.t");
-		//}
+		[Test]
+		[Ignore] // Failing because of handling of syntax error messages
+		public void TestMore_204_grammar()
+		{
+			TapRunner.Run(@"TestMore/204-grammar.t");
+		}
 
 
 		[Test]
 		[Test]
 		public void TestMore_211_scope()
 		public void TestMore_211_scope()
 		{
 		{
-			TapRunner.Run(@"TestMore\211-scope.t");
+			TapRunner.Run(@"TestMore/211-scope.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_212_function()
 		public void TestMore_212_function()
 		{
 		{
-			TapRunner.Run(@"TestMore\212-function.t");
+			TapRunner.Run(@"TestMore/212-function.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_213_closure()
 		public void TestMore_213_closure()
 		{
 		{
-			TapRunner.Run(@"TestMore\213-closure.t");
+			TapRunner.Run(@"TestMore/213-closure.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_214_coroutine()
 		public void TestMore_214_coroutine()
 		{
 		{
-			TapRunner.Run(@"TestMore\214-coroutine.t");
+			TapRunner.Run(@"TestMore/214-coroutine.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_221_table()
 		public void TestMore_221_table()
 		{
 		{
-			TapRunner.Run(@"TestMore\221-table.t");
+			TapRunner.Run(@"TestMore/221-table.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_222_constructor()
 		public void TestMore_222_constructor()
 		{
 		{
-			TapRunner.Run(@"TestMore\222-constructor.t");
+			TapRunner.Run(@"TestMore/222-constructor.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_223_iterator()
 		public void TestMore_223_iterator()
 		{
 		{
-			TapRunner.Run(@"TestMore\223-iterator.t");
+			TapRunner.Run(@"TestMore/223-iterator.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_231_metatable()
 		public void TestMore_231_metatable()
 		{
 		{
-			TapRunner.Run(@"TestMore\231-metatable.t");
+			TapRunner.Run(@"TestMore/231-metatable.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_232_object()
 		public void TestMore_232_object()
 		{
 		{
-			TapRunner.Run(@"TestMore\232-object.t");
+			TapRunner.Run(@"TestMore/232-object.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_301_basic()
 		public void TestMore_301_basic()
 		{
 		{
-			TapRunner.Run(@"TestMore\301-basic.t");
+			TapRunner.Run(@"TestMore/301-basic.t");
 		}
 		}
 
 
 		[Test]
 		[Test]
 		public void TestMore_304_string()
 		public void TestMore_304_string()
 		{
 		{
-			TapRunner.Run(@"TestMore\304-string.t");
+			TapRunner.Run(@"TestMore/304-string.t");
 		}
 		}
 
 
 		[Test]
 		[Test]
 		public void TestMore_305_table()
 		public void TestMore_305_table()
 		{
 		{
-			TapRunner.Run(@"TestMore\305-table.t");
+			TapRunner.Run(@"TestMore/305-table.t");
 		}
 		}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_306_math()
 		public void TestMore_306_math()
 		{
 		{
-			TapRunner.Run(@"TestMore\306-math.t");
+			TapRunner.Run(@"TestMore/306-math.t");
 		}
 		}
 
 
 		[Test]
 		[Test]
 		public void TestMore_307_bit()
 		public void TestMore_307_bit()
 		{
 		{
-			TapRunner.Run(@"TestMore\307-bit.t");
+			TapRunner.Run(@"TestMore/307-bit.t");
 		}
 		}
 
 
 		[Test]
 		[Test]
@@ -254,7 +253,7 @@ namespace MoonSharp.Interpreter.Tests
 			if (!Platform.Current.AreCoreModulesFullySupported(CoreModules.OS_System | CoreModules.IO))
 			if (!Platform.Current.AreCoreModulesFullySupported(CoreModules.OS_System | CoreModules.IO))
 				throw new SkipThisTestException();
 				throw new SkipThisTestException();
 
 
-			TapRunner.Run(@"TestMore\308-io.t");
+			TapRunner.Run(@"TestMore/308-io.t");
 		}
 		}
 
 
 
 
@@ -264,7 +263,7 @@ namespace MoonSharp.Interpreter.Tests
 			if (!Platform.Current.AreCoreModulesFullySupported(CoreModules.OS_System | CoreModules.IO))
 			if (!Platform.Current.AreCoreModulesFullySupported(CoreModules.OS_System | CoreModules.IO))
 				throw new SkipThisTestException();
 				throw new SkipThisTestException();
 
 
-			TapRunner.Run(@"TestMore\309-os.t");
+			TapRunner.Run(@"TestMore/309-os.t");
 		}
 		}
 
 
 
 
@@ -272,21 +271,21 @@ namespace MoonSharp.Interpreter.Tests
 		//[Ignore]
 		//[Ignore]
 		//public void TestMore_310_debug()
 		//public void TestMore_310_debug()
 		//{
 		//{
-		//	TapRunner.Run(@"TestMore\310-debug.t");
+		//	TapRunner.Run(@"TestMore/310-debug.t");
 		//}
 		//}
 
 
 
 
 		[Test]
 		[Test]
 		public void TestMore_314_regex()
 		public void TestMore_314_regex()
 		{
 		{
-			TapRunner.Run(@"TestMore\314-regex.t");
+			TapRunner.Run(@"TestMore/314-regex.t");
 		}
 		}
 
 
 		//[Test]
 		//[Test]
 		//[Ignore]
 		//[Ignore]
 		//public void TestMore_320_stdin()
 		//public void TestMore_320_stdin()
 		//{
 		//{
-		//	TapRunner.Run(@"TestMore\310-stdin.t");
+		//	TapRunner.Run(@"TestMore/310-stdin.t");
 		//}
 		//}
 
 
 	}
 	}

+ 1 - 1
src/MoonSharp.Interpreter/CoreLib/LoadModule.cs

@@ -101,7 +101,7 @@ namespace MoonSharp.Interpreter.CoreLib
 			}
 			}
 			catch (SyntaxErrorException ex)
 			catch (SyntaxErrorException ex)
 			{
 			{
-				return DynValue.NewTuple(DynValue.Nil, DynValue.NewString(ex.Message));
+				return DynValue.NewTuple(DynValue.Nil, DynValue.NewString(ex.DecoratedMessage ?? ex.Message));
 			}
 			}
 		}
 		}
 
 

+ 12 - 1
src/MoonSharp.Interpreter/CoreLib/TableModule.cs

@@ -61,7 +61,15 @@ namespace MoonSharp.Interpreter.CoreLib
 			for (int i = 1; i <= end; i++)
 			for (int i = 1; i <= end; i++)
 				values.Add(vlist.Table.Get(i));
 				values.Add(vlist.Table.Get(i));
 
 
-			values.Sort((a, b) => SortComparer(executionContext, a, b, lt));
+			try
+			{
+				values.Sort((a, b) => SortComparer(executionContext, a, b, lt));
+			}
+			catch (InvalidOperationException ex)
+			{
+				if (ex.InnerException is ScriptRuntimeException)
+					throw ex.InnerException;
+			}
 
 
 			for (int i = 0; i < values.Count; i++)
 			for (int i = 0; i < values.Count; i++)
 			{
 			{
@@ -111,6 +119,9 @@ namespace MoonSharp.Interpreter.CoreLib
 			if (v2 && !v1)
 			if (v2 && !v1)
 				return 1;
 				return 1;
 
 
+			if (v1 || v2)
+				throw new ScriptRuntimeException("invalid order function for sorting");
+
 			return 0;
 			return 0;
 		}
 		}
 
 

+ 12 - 0
src/MoonSharp.Interpreter/Errors/InterpreterException.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;
 
 
 namespace MoonSharp.Interpreter
 namespace MoonSharp.Interpreter
 {
 {
@@ -31,7 +32,18 @@ namespace MoonSharp.Interpreter
 
 
 		public string DecoratedMessage { get; internal set; }
 		public string DecoratedMessage { get; internal set; }
 
 
+		internal void DecorateMessage(Script script, SourceRef sref, int ip = -1)
+		{
+			if (sref != null)
+			{
+				this.DecoratedMessage = string.Format("{0}: {1}", sref.FormatLocation(script), this.Message);
+			}
+			else
+			{
+				this.DecoratedMessage = string.Format("bytecode:{0}: {1}", ip, this.Message);
+			}
 
 
+		}
 
 
 
 
 	}
 	}

+ 27 - 3
src/MoonSharp.Interpreter/Errors/SyntaxErrorException.cs

@@ -2,23 +2,47 @@
 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.Tree;
 
 
 namespace MoonSharp.Interpreter
 namespace MoonSharp.Interpreter
 {
 {
 	[Serializable]
 	[Serializable]
 	public class SyntaxErrorException : InterpreterException
 	public class SyntaxErrorException : InterpreterException
 	{
 	{
-		internal SyntaxErrorException(string format, params object[] args)
+		internal Token Token { get; private set; }
+
+		internal SyntaxErrorException(Token t, string format, params object[] args)
 			: base(format, args)
 			: base(format, args)
 		{
 		{
-
+			Token = t;
 		}
 		}
 
 
-		internal SyntaxErrorException(string message)
+		internal SyntaxErrorException(Token t, string message)
 			: base(message)
 			: base(message)
 		{
 		{
+			Token = t;
+		}
 
 
+		internal SyntaxErrorException(Script script, SourceRef sref, string format, params object[] args)
+			: base(format, args)
+		{
+			DecorateMessage(script, sref);
 		}
 		}
 
 
+		internal SyntaxErrorException(Script script, SourceRef sref, string message)
+			: base(message)
+		{
+			DecorateMessage(script, sref);
+		}
+
+		internal void DecorateMessage(Script script)
+		{
+			if (Token != null)
+			{
+				DecorateMessage(script, Token.GetSourceRef(false));
+			}
+		}
 	}
 	}
 }
 }

+ 0 - 12
src/MoonSharp.Interpreter/Execution/ScriptLoadingContext.cs

@@ -21,17 +21,5 @@ namespace MoonSharp.Interpreter.Execution
 			Script = s;
 			Script = s;
 		}
 		}
 
 
-		public void EnterLevel()
-		{
-			//if (++ls.L.nCcalls > LUAI_MAXCCALLS)
-			//	LuaXLexError(ls, "chunk has too many syntax levels", 0);
-		}
-
-		public void LeaveLevel()
-		{
-			//ls.L.nCcalls--;
-		}
-
-
 	}
 	}
 }
 }

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

@@ -313,6 +313,5 @@ namespace MoonSharp.Interpreter.Execution.VM
 		{
 		{
 			return AppendInstruction(new Instruction(m_CurrentSourceRef) { OpCode = OpCode.Swap, NumVal = p1, NumVal2 = p2 });
 			return AppendInstruction(new Instruction(m_CurrentSourceRef) { OpCode = OpCode.Swap, NumVal = p1, NumVal2 = p2 });
 		}
 		}
-
 	}
 	}
 }
 }

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

@@ -13,7 +13,7 @@ namespace MoonSharp.Interpreter.Execution.VM
 	sealed partial class Processor
 	sealed partial class Processor
 	{
 	{
 		const ulong DUMP_CHUNK_MAGIC = 0x1A0D234E4F4F4D1D;
 		const ulong DUMP_CHUNK_MAGIC = 0x1A0D234E4F4F4D1D;
-		const int DUMP_CHUNK_VERSION = 0x100;
+		const int DUMP_CHUNK_VERSION = 0x101;
 
 
 		internal static bool IsDumpStream(Stream stream)
 		internal static bool IsDumpStream(Stream stream)
 		{
 		{

+ 1 - 8
src/MoonSharp.Interpreter/Execution/VM/Processor/Processor_Errors.cs

@@ -30,14 +30,7 @@ namespace MoonSharp.Interpreter.Execution.VM
 
 
 			SourceRef sref = GetCurrentSourceRef(ip);
 			SourceRef sref = GetCurrentSourceRef(ip);
 
 
-			if (sref != null)
-			{
-				ex.DecoratedMessage = string.Format("{0}: {1}", sref.FormatLocation(m_Script), ex.Message);
-			}
-			else
-			{
-				ex.DecoratedMessage = string.Format("bytecode:{0}: {1}", ip, ex.Message);
-			}
+			ex.DecorateMessage(m_Script, sref, ip);
 
 
 			ex.CallStack = Debugger_GetCallStack(sref);
 			ex.CallStack = Debugger_GetCallStack(sref);
 		}
 		}

+ 10 - 7
src/MoonSharp.Interpreter/Tree/Expression_.cs

@@ -40,7 +40,7 @@ namespace MoonSharp.Interpreter.Tree
 				lcontext.Lexer.Next();
 				lcontext.Lexer.Next();
 			}
 			}
 
 
-			return exps; //+++
+			return exps; 
 		}
 		}
 
 
 		internal static Expression Expr(ScriptLoadingContext lcontext)
 		internal static Expression Expr(ScriptLoadingContext lcontext)
@@ -127,10 +127,8 @@ namespace MoonSharp.Interpreter.Tree
 				case TokenType.Nil:
 				case TokenType.Nil:
 				case TokenType.True:
 				case TokenType.True:
 				case TokenType.False:
 				case TokenType.False:
-					lcontext.Lexer.Next();
 					return new LiteralExpression(lcontext, t);
 					return new LiteralExpression(lcontext, t);
 				case TokenType.VarArgs:
 				case TokenType.VarArgs:
-					lcontext.Lexer.Next();
 					return new SymbolRefExpression(t, lcontext);
 					return new SymbolRefExpression(t, lcontext);
 				case TokenType.Brk_Open_Curly:
 				case TokenType.Brk_Open_Curly:
 					return new TableConstructor(lcontext);
 					return new TableConstructor(lcontext);
@@ -143,6 +141,11 @@ namespace MoonSharp.Interpreter.Tree
 
 
 		}
 		}
 
 
+		/// <summary>
+		/// Primaries the exp.
+		/// </summary>
+		/// <param name="lcontext">The lcontext.</param>
+		/// <returns></returns>
 		internal static Expression PrimaryExp(ScriptLoadingContext lcontext)
 		internal static Expression PrimaryExp(ScriptLoadingContext lcontext)
 		{
 		{
 			Expression e = PrefixExp(lcontext);
 			Expression e = PrefixExp(lcontext);
@@ -164,9 +167,10 @@ namespace MoonSharp.Interpreter.Tree
 						break;
 						break;
 					case TokenType.Brk_Open_Square:
 					case TokenType.Brk_Open_Square:
 						{
 						{
+							Token openBrk = lcontext.Lexer.Current;
 							lcontext.Lexer.Next(); // skip bracket
 							lcontext.Lexer.Next(); // skip bracket
 							Expression index = Expr(lcontext);
 							Expression index = Expr(lcontext);
-							CheckMatch(lcontext, T.Text, TokenType.Brk_Close_Square);
+							CheckMatch(lcontext, openBrk, TokenType.Brk_Close_Square, "]");
 							e = new IndexExpression(e, index, lcontext);
 							e = new IndexExpression(e, index, lcontext);
 						}
 						}
 						break;
 						break;
@@ -197,13 +201,12 @@ namespace MoonSharp.Interpreter.Tree
 					lcontext.Lexer.Next();
 					lcontext.Lexer.Next();
 					Expression e = Expr(lcontext);
 					Expression e = Expr(lcontext);
 					e = new AdjustmentExpression(lcontext, e);
 					e = new AdjustmentExpression(lcontext, e);
-					CheckMatch(lcontext, T.Text, TokenType.Brk_Close_Round);
+					CheckMatch(lcontext, T, TokenType.Brk_Close_Round, ")");
 					return e;
 					return e;
 				case TokenType.Name:
 				case TokenType.Name:
-					lcontext.Lexer.Next();
 					return new SymbolRefExpression(T, lcontext);
 					return new SymbolRefExpression(T, lcontext);
 				default:
 				default:
-					throw new SyntaxErrorException("unexpected symbol near '{0}'", T.Text);
+					throw new SyntaxErrorException(T, "unexpected symbol near '{0}'", T.Text);
 			}
 			}
 		}
 		}
 
 

+ 4 - 5
src/MoonSharp.Interpreter/Tree/Expressions/FunctionCallExpression.cs

@@ -24,6 +24,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			switch (lcontext.Lexer.Current.Type)
 			switch (lcontext.Lexer.Current.Type)
 			{
 			{
 				case TokenType.Brk_Open_Round:
 				case TokenType.Brk_Open_Round:
+					Token openBrk = lcontext.Lexer.Current;
 					lcontext.Lexer.Next();
 					lcontext.Lexer.Next();
 					Token t = lcontext.Lexer.Current;
 					Token t = lcontext.Lexer.Current;
 					if (t.Type == TokenType.Brk_Close_Round)
 					if (t.Type == TokenType.Brk_Close_Round)
@@ -34,7 +35,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 					else
 					else
 					{
 					{
 						m_Arguments = ExprList(lcontext);
 						m_Arguments = ExprList(lcontext);
-						CheckMatch(lcontext, "(", TokenType.Brk_Close_Round);
+						CheckMatch(lcontext, openBrk, TokenType.Brk_Close_Round, ")");
 					}
 					}
 					break;
 					break;
 				case TokenType.String:
 				case TokenType.String:
@@ -42,7 +43,6 @@ 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);
-						lcontext.Lexer.Next();
 						m_Arguments.Add(le);
 						m_Arguments.Add(le);
 					}
 					}
 					break;
 					break;
@@ -53,7 +53,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 					}
 					}
 					break;
 					break;
 				default:
 				default:
-					throw new SyntaxErrorException("function arguments expected");
+					throw new SyntaxErrorException(lcontext.Lexer.Current, "function arguments expected");
 			}
 			}
 		}
 		}
 
 
@@ -66,8 +66,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			if (!string.IsNullOrEmpty(m_Name))
 			if (!string.IsNullOrEmpty(m_Name))
 			{
 			{
 				bc.Emit_Copy(0);
 				bc.Emit_Copy(0);
-				bc.Emit_Literal(DynValue.NewString(m_Name));
-				bc.Emit_Index();
+				bc.Emit_Index(DynValue.NewString(m_Name));
 				bc.Emit_Swap(0, 1);
 				bc.Emit_Swap(0, 1);
 				++argslen;
 				++argslen;
 			}
 			}

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

@@ -45,9 +45,9 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 				CheckTokenType(lcontext, TokenType.Function);
 				CheckTokenType(lcontext, TokenType.Function);
 
 
 			// here lexer should be at the '('.
 			// here lexer should be at the '('.
-			CheckTokenType(lcontext, TokenType.Brk_Open_Round);
+			Token openRound = CheckTokenType(lcontext, TokenType.Brk_Open_Round);
 
 
-			List<string> paramnames = BuildParamList(lcontext, pushSelfParam);
+			List<string> paramnames = BuildParamList(lcontext, pushSelfParam, openRound);
 			// here lexer is at first token of body
 			// here lexer is at first token of body
 
 
 			// create scope
 			// create scope
@@ -78,13 +78,13 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			Statement s = new CompositeStatement(lcontext);
 			Statement s = new CompositeStatement(lcontext);
 
 
 			if (lcontext.Lexer.Current.Type != TokenType.End)
 			if (lcontext.Lexer.Current.Type != TokenType.End)
-				throw new SyntaxErrorException("'end' expected near '{0}'", lcontext.Lexer.Current.Text);
+				throw new SyntaxErrorException(lcontext.Lexer.Current, "'end' expected near '{0}'", lcontext.Lexer.Current.Text);
 
 
 			lcontext.Lexer.Next();
 			lcontext.Lexer.Next();
 			return s;
 			return s;
 		}
 		}
 
 
-		private List<string> BuildParamList(ScriptLoadingContext lcontext, bool pushSelfParam)
+		private List<string> BuildParamList(ScriptLoadingContext lcontext, bool pushSelfParam, Token openBracketToken)
 		{
 		{
 			List<string> paramnames = new List<string>();
 			List<string> paramnames = new List<string>();
 
 
@@ -106,7 +106,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 					paramnames.Add(WellKnownSymbols.VARARGS);
 					paramnames.Add(WellKnownSymbols.VARARGS);
 				}
 				}
 				else
 				else
-					throw new SyntaxErrorException("unexpected symbol near '{0}'", t.Text);
+					throw new SyntaxErrorException(t, "unexpected symbol near '{0}'", t.Text);
 
 
 				lcontext.Lexer.Next();
 				lcontext.Lexer.Next();
 
 
@@ -118,7 +118,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 				}
 				}
 				else
 				else
 				{
 				{
-					CheckMatch(lcontext, "(", TokenType.Brk_Close_Round);
+					CheckMatch(lcontext, openBracketToken, TokenType.Brk_Close_Round, ")");
 					break;
 					break;
 				}
 				}
 			}
 			}

+ 5 - 29
src/MoonSharp.Interpreter/Tree/Expressions/LiteralExpression.cs

@@ -7,7 +7,7 @@ using MoonSharp.Interpreter.Execution;
 
 
 namespace MoonSharp.Interpreter.Tree.Expressions
 namespace MoonSharp.Interpreter.Tree.Expressions
 {
 {
-	class LiteralExpression: Expression
+	class LiteralExpression : Expression
 	{
 	{
 		DynValue m_Value;
 		DynValue m_Value;
 
 
@@ -16,14 +16,6 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			get { return m_Value; }
 			get { return m_Value; }
 		}
 		}
 
 
-		private string RemoveHexHeader(string s)
-		{
-			s = s.ToUpperInvariant();
-			if (s.StartsWith("0X"))
-				s = s.Substring(2);
-
-			return s;
-		}
 
 
 		public LiteralExpression(ScriptLoadingContext lcontext, DynValue value)
 		public LiteralExpression(ScriptLoadingContext lcontext, DynValue value)
 			: base(lcontext)
 			: base(lcontext)
@@ -38,17 +30,11 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			switch (t.Type)
 			switch (t.Type)
 			{
 			{
 				case TokenType.Number:
 				case TokenType.Number:
-					TryParse(t.Text, s => double.Parse(s, CultureInfo.InvariantCulture));
-					break;
 				case TokenType.Number_Hex:
 				case TokenType.Number_Hex:
-					TryParse(t.Text, s => (double)ulong.Parse(RemoveHexHeader(s), NumberStyles.HexNumber, CultureInfo.InvariantCulture));
-					break;
 				case TokenType.Number_HexFloat:
 				case TokenType.Number_HexFloat:
-					TryParse(t.Text, s => ParseHexFloat(s));
+					m_Value = DynValue.NewNumber(t.GetNumberValue()).AsReadOnly();
 					break;
 					break;
 				case TokenType.String:
 				case TokenType.String:
-					m_Value = DynValue.NewString(t.Text).AsReadOnly();
-					break;
 				case TokenType.String_Long:
 				case TokenType.String_Long:
 					m_Value = DynValue.NewString(t.Text).AsReadOnly();
 					m_Value = DynValue.NewString(t.Text).AsReadOnly();
 					break;
 					break;
@@ -62,30 +48,20 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 					m_Value = DynValue.Nil;
 					m_Value = DynValue.Nil;
 					break;
 					break;
 				default:
 				default:
-					throw new InternalErrorException("Type mismatch");
+					throw new InternalErrorException("type mismatch");
 			}
 			}
 
 
 			if (m_Value == null)
 			if (m_Value == null)
-				throw new SyntaxErrorException("unknown number format near '{0}'", t.Text);
-		}
+				throw new SyntaxErrorException(t, "unknown literal format near '{0}'", t.Text);
 
 
-		private void TryParse(string txt, Func<string, double> parser)
-		{
-			double val = parser(txt);
-			m_Value = DynValue.NewNumber(val).AsReadOnly();
+			lcontext.Lexer.Next();
 		}
 		}
 
 
-
 		public override void Compile(Execution.VM.ByteCode bc)
 		public override void Compile(Execution.VM.ByteCode bc)
 		{
 		{
 			bc.Emit_Literal(m_Value);
 			bc.Emit_Literal(m_Value);
 		}
 		}
 
 
-		private double ParseHexFloat(string s)
-		{
-			throw new SyntaxErrorException("hex floats are not supported: '{0}'", s);
-		}
-
 		public override DynValue Eval(ScriptExecutionContext context)
 		public override DynValue Eval(ScriptExecutionContext context)
 		{
 		{
 			return m_Value;
 			return m_Value;

+ 4 - 2
src/MoonSharp.Interpreter/Tree/Expressions/SymbolRefExpression.cs

@@ -21,16 +21,18 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 				m_Ref = lcontext.Scope.TryDefineLocal(WellKnownSymbols.VARARGS);
 				m_Ref = lcontext.Scope.TryDefineLocal(WellKnownSymbols.VARARGS);
 
 
 				if (!lcontext.Scope.CurrentFunctionHasVarArgs())
 				if (!lcontext.Scope.CurrentFunctionHasVarArgs())
-					throw new SyntaxErrorException("error:0: cannot use '...' outside a vararg function");
+					throw new SyntaxErrorException(T, "cannot use '...' outside a vararg function");
 
 
 				if (lcontext.IsDynamicExpression)
 				if (lcontext.IsDynamicExpression)
-					throw new DynamicExpressionException("Cannot use '...' in a dynamic expression.");
+					throw new DynamicExpressionException("cannot use '...' in a dynamic expression.");
 			}
 			}
 			else
 			else
 			{
 			{
 				if (!lcontext.IsDynamicExpression)
 				if (!lcontext.IsDynamicExpression)
 					m_Ref = lcontext.Scope.Find(m_VarName);
 					m_Ref = lcontext.Scope.Find(m_VarName);
 			}
 			}
+
+			lcontext.Lexer.Next();
 		}
 		}
 
 
 		public SymbolRefExpression(ScriptLoadingContext lcontext, SymbolRef refr)
 		public SymbolRefExpression(ScriptLoadingContext lcontext, SymbolRef refr)

+ 60 - 36
src/MoonSharp.Interpreter/Tree/Fast_Interface/Loader_Fast.cs

@@ -15,14 +15,23 @@ namespace MoonSharp.Interpreter.Tree.Fast_Interface
 		internal static DynamicExprExpression LoadDynamicExpr(Script script, SourceCode source)
 		internal static DynamicExprExpression LoadDynamicExpr(Script script, SourceCode source)
 		{
 		{
 			ScriptLoadingContext lcontext = CreateLoadingContext(script, source);
 			ScriptLoadingContext lcontext = CreateLoadingContext(script, source);
-			lcontext.IsDynamicExpression = true;
-			lcontext.Anonymous = true;
 
 
-			Expression exp;
-			using (script.PerformanceStats.StartStopwatch(Diagnostics.PerformanceCounter.AstCreation))
-				exp = Expression.Expr(lcontext);
+			try
+			{
+				lcontext.IsDynamicExpression = true;
+				lcontext.Anonymous = true;
+
+				Expression exp;
+				using (script.PerformanceStats.StartStopwatch(Diagnostics.PerformanceCounter.AstCreation))
+					exp = Expression.Expr(lcontext);
 
 
-			return new DynamicExprExpression(exp, lcontext);
+				return new DynamicExprExpression(exp, lcontext);
+			}
+			catch (SyntaxErrorException ex)
+			{
+				ex.DecorateMessage(script);
+				throw;
+			}
 		}
 		}
 
 
 		private static ScriptLoadingContext CreateLoadingContext(Script script, SourceCode source)
 		private static ScriptLoadingContext CreateLoadingContext(Script script, SourceCode source)
@@ -31,61 +40,76 @@ namespace MoonSharp.Interpreter.Tree.Fast_Interface
 			{
 			{
 				Scope = new BuildTimeScope(),
 				Scope = new BuildTimeScope(),
 				Source = source,
 				Source = source,
-				Lexer = new Lexer(source.Code, true)
+				Lexer = new Lexer(source.SourceID, source.Code, true)
 			};
 			};
 		}
 		}
 
 
 		internal static int LoadChunk(Script script, SourceCode source, ByteCode bytecode, Table globalContext)
 		internal static int LoadChunk(Script script, SourceCode source, ByteCode bytecode, Table globalContext)
 		{
 		{
 			ScriptLoadingContext lcontext = CreateLoadingContext(script, source);
 			ScriptLoadingContext lcontext = CreateLoadingContext(script, source);
+			try
+			{
+				Statement stat;
 
 
-			Statement stat;
+				using (script.PerformanceStats.StartStopwatch(Diagnostics.PerformanceCounter.AstCreation))
+					stat = new ChunkStatement(lcontext, globalContext);
 
 
-			using (script.PerformanceStats.StartStopwatch(Diagnostics.PerformanceCounter.AstCreation))
-				stat = new ChunkStatement(lcontext, globalContext);
+				int beginIp = -1;
 
 
-			int beginIp = -1;
+				//var srcref = new SourceRef(source.SourceID);
 
 
-			//var srcref = new SourceRef(source.SourceID);
+				using (script.PerformanceStats.StartStopwatch(Diagnostics.PerformanceCounter.Compilation))
+				using (bytecode.EnterSource(null))
+				{
+					bytecode.Emit_Nop(string.Format("Begin chunk {0}", source.Name));
+					beginIp = bytecode.GetJumpPointForLastInstruction();
+					stat.Compile(bytecode);
+					bytecode.Emit_Nop(string.Format("End chunk {0}", source.Name));
+				}
 
 
-			using (script.PerformanceStats.StartStopwatch(Diagnostics.PerformanceCounter.Compilation))
-			using (bytecode.EnterSource(null))
+				//Debug_DumpByteCode(bytecode, source.SourceID);
+
+				return beginIp;
+			}
+			catch (SyntaxErrorException ex)
 			{
 			{
-				bytecode.Emit_Nop(string.Format("Begin chunk {0}", source.Name));
-				beginIp = bytecode.GetJumpPointForLastInstruction();
-				stat.Compile(bytecode);
-				bytecode.Emit_Nop(string.Format("End chunk {0}", source.Name));
+				ex.DecorateMessage(script);
+				throw;
 			}
 			}
-
-			//Debug_DumpByteCode(bytecode, source.SourceID);
-
-			return beginIp;
 		}
 		}
 
 
 		internal static int LoadFunction(Script script, SourceCode source, ByteCode bytecode, Table globalContext)
 		internal static int LoadFunction(Script script, SourceCode source, ByteCode bytecode, Table globalContext)
 		{
 		{
 			ScriptLoadingContext lcontext = CreateLoadingContext(script, source);
 			ScriptLoadingContext lcontext = CreateLoadingContext(script, source);
 
 
-			FunctionDefinitionExpression fnx;
+			try
+			{
+				FunctionDefinitionExpression fnx;
 
 
-			using (script.PerformanceStats.StartStopwatch(Diagnostics.PerformanceCounter.AstCreation))
-				fnx = new FunctionDefinitionExpression(lcontext, globalContext);
+				using (script.PerformanceStats.StartStopwatch(Diagnostics.PerformanceCounter.AstCreation))
+					fnx = new FunctionDefinitionExpression(lcontext, globalContext);
 
 
-			int beginIp = -1;
+				int beginIp = -1;
 
 
-			//var srcref = new SourceRef(source.SourceID);
+				//var srcref = new SourceRef(source.SourceID);
 
 
-			using (script.PerformanceStats.StartStopwatch(Diagnostics.PerformanceCounter.Compilation))
-			using (bytecode.EnterSource(null))
-			{
-				bytecode.Emit_Nop(string.Format("Begin function {0}", source.Name));
-				beginIp = fnx.CompileBody(bytecode, source.Name);
-				bytecode.Emit_Nop(string.Format("End function {0}", source.Name));
-			}
+				using (script.PerformanceStats.StartStopwatch(Diagnostics.PerformanceCounter.Compilation))
+				using (bytecode.EnterSource(null))
+				{
+					bytecode.Emit_Nop(string.Format("Begin function {0}", source.Name));
+					beginIp = fnx.CompileBody(bytecode, source.Name);
+					bytecode.Emit_Nop(string.Format("End function {0}", source.Name));
+				}
 
 
-			//Debug_DumpByteCode(bytecode, source.SourceID);
+				//Debug_DumpByteCode(bytecode, source.SourceID);
 
 
-			return beginIp;
+				return beginIp;
+			}
+			catch (SyntaxErrorException ex)
+			{
+				ex.DecorateMessage(script);
+				throw;
+			}
 
 
 		}
 		}
 
 

+ 66 - 20
src/MoonSharp.Interpreter/Tree/Lexer/Lexer.cs

@@ -10,27 +10,30 @@ namespace MoonSharp.Interpreter.Tree
 		Token m_Current = null;
 		Token m_Current = null;
 		string m_Code;
 		string m_Code;
 		int m_Cursor = 0;
 		int m_Cursor = 0;
-		int m_Line = 0;
+		int m_Line = 1;
 		int m_Col = 0;
 		int m_Col = 0;
+		int m_SourceId;
 		bool m_AutoSkipComments = false;
 		bool m_AutoSkipComments = false;
 
 
-		public Lexer(string scriptContent, bool autoSkipComments)
+		public Lexer(int sourceID, string scriptContent, bool autoSkipComments)
 		{
 		{
 			m_Code = scriptContent;
 			m_Code = scriptContent;
+			m_SourceId = sourceID;
 
 
 			// remove unicode BOM if any
 			// remove unicode BOM if any
 			if (m_Code.Length > 0 && m_Code[0] == 0xFEFF)
 			if (m_Code.Length > 0 && m_Code[0] == 0xFEFF)
 				m_Code = m_Code.Substring(1);
 				m_Code = m_Code.Substring(1);
 
 
 			m_AutoSkipComments = autoSkipComments;
 			m_AutoSkipComments = autoSkipComments;
-
-			Next();
 		}
 		}
 
 
 		public Token Current
 		public Token Current
 		{
 		{
 			get
 			get
 			{
 			{
+				if (m_Current == null)
+					Next();
+
 				return m_Current;
 				return m_Current;
 			}
 			}
 		}
 		}
@@ -40,7 +43,7 @@ namespace MoonSharp.Interpreter.Tree
 			while (true)
 			while (true)
 			{
 			{
 				Token T = ReadToken();
 				Token T = ReadToken();
-	
+
 				//System.Diagnostics.Debug.WriteLine("LEXER : " + T.ToString());
 				//System.Diagnostics.Debug.WriteLine("LEXER : " + T.ToString());
 
 
 				if ((T.Type != TokenType.Comment && T.Type != TokenType.HashBang) || (!m_AutoSkipComments))
 				if ((T.Type != TokenType.Comment && T.Type != TokenType.HashBang) || (!m_AutoSkipComments))
@@ -101,7 +104,7 @@ namespace MoonSharp.Interpreter.Tree
 		private char CursorCharNext()
 		private char CursorCharNext()
 		{
 		{
 			m_Cursor += 1;
 			m_Cursor += 1;
-			return CursorChar();	
+			return CursorChar();
 		}
 		}
 
 
 		private bool CursorMatches(string pattern)
 		private bool CursorMatches(string pattern)
@@ -144,7 +147,7 @@ namespace MoonSharp.Interpreter.Tree
 			int fromCol = m_Col;
 			int fromCol = m_Col;
 
 
 			if (!CursorNotEof())
 			if (!CursorNotEof())
-				return new Token(TokenType.Eof) { Text = "<eof>" };
+				return CreateToken(TokenType.Eof, fromLine, fromCol, "<eof>");
 
 
 			char c = CursorChar();
 			char c = CursorChar();
 
 
@@ -162,7 +165,8 @@ namespace MoonSharp.Interpreter.Tree
 				case '~':
 				case '~':
 				case '!':
 				case '!':
 					if (CursorCharNext() != '=')
 					if (CursorCharNext() != '=')
-						throw new SyntaxErrorException("Expected '=', {0} was found", CursorChar());
+						throw new SyntaxErrorException(CreateToken(TokenType.Invalid, fromLine, fromCol), "unexpected symbol near '{0}'", c);
+
 					CursorCharNext();
 					CursorCharNext();
 					return CreateToken(TokenType.Op_NotEqual, fromLine, fromCol, "~=");
 					return CreateToken(TokenType.Op_NotEqual, fromLine, fromCol, "~=");
 				case '.':
 				case '.':
@@ -202,7 +206,7 @@ namespace MoonSharp.Interpreter.Tree
 						char next = CursorCharNext();
 						char next = CursorCharNext();
 						if (next == '=' || next == '[')
 						if (next == '=' || next == '[')
 						{
 						{
-							string str = ReadLongString(null);
+							string str = ReadLongString(fromLine, fromCol, null, "string");
 							return CreateToken(TokenType.String_Long, fromLine, fromCol, str);
 							return CreateToken(TokenType.String_Long, fromLine, fromCol, str);
 						}
 						}
 						return CreateToken(TokenType.Brk_Open_Square, fromLine, fromCol, "[");
 						return CreateToken(TokenType.Brk_Open_Square, fromLine, fromCol, "[");
@@ -236,14 +240,14 @@ namespace MoonSharp.Interpreter.Tree
 							return ReadNumberToken(fromLine, fromCol);
 							return ReadNumberToken(fromLine, fromCol);
 						}
 						}
 					}
 					}
-					throw new SyntaxErrorException("Fallback to default ?!", CursorChar());
+					throw new SyntaxErrorException(CreateToken(TokenType.Invalid, fromLine, fromCol), "unexpected symbol near '{0}'", CursorChar());
 			}
 			}
 
 
 
 
 
 
 		}
 		}
 
 
-		private string ReadLongString(string startpattern)
+		private string ReadLongString(int fromLine, int fromCol, string startpattern, string subtypeforerrors)
 		{
 		{
 			// here we are at the first '=' or second '['
 			// here we are at the first '=' or second '['
 			StringBuilder text = new StringBuilder(1024);
 			StringBuilder text = new StringBuilder(1024);
@@ -255,7 +259,9 @@ namespace MoonSharp.Interpreter.Tree
 				{
 				{
 					if (c == '\0' || !CursorNotEof())
 					if (c == '\0' || !CursorNotEof())
 					{
 					{
-						throw new SyntaxErrorException("Unterminated long string");
+						throw new SyntaxErrorException(
+							CreateToken(TokenType.Invalid, fromLine, fromCol),
+							"unfinished long {0} near '<eof>'", subtypeforerrors);
 					}
 					}
 					else if (c == '=')
 					else if (c == '=')
 					{
 					{
@@ -268,7 +274,9 @@ namespace MoonSharp.Interpreter.Tree
 					}
 					}
 					else
 					else
 					{
 					{
-						throw new SyntaxErrorException("Unexpected token in long string prefix: {0}", c);
+						throw new SyntaxErrorException(
+							CreateToken(TokenType.Invalid, fromLine, fromCol),
+							"invalid long {0} delimiter near '{1}'", subtypeforerrors, c);
 					}
 					}
 				}
 				}
 			}
 			}
@@ -280,9 +288,14 @@ namespace MoonSharp.Interpreter.Tree
 
 
 			for (char c = CursorCharNext(); ; c = CursorCharNext())
 			for (char c = CursorCharNext(); ; c = CursorCharNext())
 			{
 			{
+				if (c == '\r') // XXI century and we still debate on how a newline is made. throw new DeveloperExtremelyAngryException.
+					continue;
+
 				if (c == '\0' || !CursorNotEof())
 				if (c == '\0' || !CursorNotEof())
 				{
 				{
-					throw new SyntaxErrorException("Unterminated long string or comment");
+					throw new SyntaxErrorException(
+							CreateToken(TokenType.Invalid, fromLine, fromCol),
+							"unfinished long {0} near '{1}'", subtypeforerrors, text.ToString());
 				}
 				}
 				else if (c == ']' && CursorMatches(end_pattern))
 				else if (c == ']' && CursorMatches(end_pattern))
 				{
 				{
@@ -413,7 +426,7 @@ namespace MoonSharp.Interpreter.Tree
 				{
 				{
 					text.Append('[');
 					text.Append('[');
 					CursorCharNext();
 					CursorCharNext();
-					string comment = ReadLongString(text.ToString());
+					string comment = ReadLongString(fromLine, fromCol, text.ToString(), "comment");
 					return CreateToken(TokenType.Comment, fromLine, fromCol, comment);
 					return CreateToken(TokenType.Comment, fromLine, fromCol, comment);
 				}
 				}
 				else if (c == '\n')
 				else if (c == '\n')
@@ -441,15 +454,46 @@ namespace MoonSharp.Interpreter.Tree
 
 
 			for (char c = CursorCharNext(); CursorNotEof(); c = CursorCharNext())
 			for (char c = CursorCharNext(); CursorNotEof(); c = CursorCharNext())
 			{
 			{
+			redo_Loop:
+
 				if (c == '\\')
 				if (c == '\\')
 				{
 				{
 					text.Append(c);
 					text.Append(c);
-					text.Append(CursorCharNext());
+					c = CursorCharNext();
+					text.Append(c);
+
+					if (c == '\r')
+					{
+						c = CursorCharNext();
+						if (c == '\n')
+							text.Append(c);
+						else
+							goto redo_Loop;
+					}
+					else if (c == 'z')
+					{
+						c = CursorCharNext();
+
+						if (char.IsWhiteSpace(c))
+							SkipWhiteSpace();
+
+						c = CursorChar();
+
+						goto redo_Loop;
+					}
+				}
+				else if (c == '\n' || c == '\r')
+				{
+					throw new SyntaxErrorException(
+						CreateToken(TokenType.Invalid, fromLine, fromCol),
+						"unfinished string near '{0}'", text.ToString());
 				}
 				}
 				else if (c == separator)
 				else if (c == separator)
 				{
 				{
 					CursorCharNext();
 					CursorCharNext();
-					return CreateToken(TokenType.String, fromLine, fromCol, LexerUtils.UnescapeLuaString(text.ToString()));
+					Token t = CreateToken(TokenType.String, fromLine, fromCol);
+					t.Text = LexerUtils.UnescapeLuaString(t, text.ToString());
+					return t;
 				}
 				}
 				else
 				else
 				{
 				{
@@ -457,13 +501,15 @@ namespace MoonSharp.Interpreter.Tree
 				}
 				}
 			}
 			}
 
 
-			throw new SyntaxErrorException("Unterminated string");
+			throw new SyntaxErrorException(
+				CreateToken(TokenType.Invalid, fromLine, fromCol),
+				"unfinished string near '{0}'", text.ToString());
 		}
 		}
 
 
 		private Token PotentiallyDoubleCharOperator(char expectedSecondChar, TokenType singleCharToken, TokenType doubleCharToken, int fromLine, int fromCol)
 		private Token PotentiallyDoubleCharOperator(char expectedSecondChar, TokenType singleCharToken, TokenType doubleCharToken, int fromLine, int fromCol)
 		{
 		{
 			string op = CursorChar().ToString();
 			string op = CursorChar().ToString();
-			
+
 			CursorCharNext();
 			CursorCharNext();
 
 
 			if (CursorChar() == expectedSecondChar)
 			if (CursorChar() == expectedSecondChar)
@@ -494,7 +540,7 @@ namespace MoonSharp.Interpreter.Tree
 
 
 		private Token CreateToken(TokenType tokenType, int fromLine, int fromCol, string text = null)
 		private Token CreateToken(TokenType tokenType, int fromLine, int fromCol, string text = null)
 		{
 		{
-			return new Token(tokenType, fromLine, fromCol, m_Line, m_Col)
+			return new Token(tokenType, m_SourceId, fromLine, fromCol, m_Line, m_Col)
 			{
 			{
 				Text = text
 				Text = text
 			};
 			};

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

@@ -13,7 +13,7 @@ namespace MoonSharp.Interpreter.Tree
 			string code = File.ReadAllText(@"c:\temp\test.lua");
 			string code = File.ReadAllText(@"c:\temp\test.lua");
 			List<string> output = new List<string>();
 			List<string> output = new List<string>();
 
 
-			Lexer lexer = new Lexer(code, false);
+			Lexer lexer = new Lexer(0, code, false);
 
 
 			try
 			try
 			{
 			{

+ 115 - 7
src/MoonSharp.Interpreter/Tree/Lexer/LexerUtils.cs

@@ -3,11 +3,119 @@ using System.Collections.Generic;
 using System.Globalization;
 using System.Globalization;
 using System.Linq;
 using System.Linq;
 using System.Text;
 using System.Text;
+using MoonSharp.Interpreter.Execution;
 
 
 namespace MoonSharp.Interpreter.Tree
 namespace MoonSharp.Interpreter.Tree
 {
 {
 	internal static class LexerUtils
 	internal static class LexerUtils
 	{
 	{
+		public static double ParseNumber(Token T)
+		{
+			string txt = T.Text;
+			double res;
+			if (!double.TryParse(txt, NumberStyles.Float, CultureInfo.InvariantCulture, out res))
+				throw new SyntaxErrorException(T, "malformed number near '{0}'", txt);
+
+			return res;
+		}
+
+		public static double ParseHexInteger(Token T)
+		{
+			string txt = T.Text;
+			if ((txt.Length < 2) || (txt[0] != '0' && (char.ToUpper(txt[1]) != 'X')))
+				throw new InternalErrorException("hex numbers must start with '0x' near '{0}'.", txt);
+
+			ulong res;
+
+			if (!ulong.TryParse(txt.Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out res))
+				throw new SyntaxErrorException(T, "malformed number near '{0}'", txt);
+
+			return (double)res;
+		}
+
+		public static string ReadHexProgressive(string s, ref double d, out int digits)
+		{
+			digits = 0;
+
+			for (int i = 0; i < s.Length; i++)
+			{
+				char c = s[i];
+
+				if (LexerUtils.CharIsHexDigit(c))
+				{
+					int v = LexerUtils.HexDigit2Value(c);
+					d *= 16.0;
+					d += v;
+					++digits;
+				}
+				else
+				{
+					return s.Substring(i);
+				}
+			}
+
+			return string.Empty;
+		}
+
+		public static double ParseHexFloat(Token T)
+		{
+			string s = T.Text;
+
+			try
+			{
+				if ((s.Length < 2) || (s[0] != '0' && (char.ToUpper(s[1]) != 'X')))
+					throw new InternalErrorException("hex float must start with '0x' near '{0}'", s);
+
+				s = s.Substring(2);
+
+				double value = 0.0;
+				int dummy, exp = 0;
+
+				s = ReadHexProgressive(s, ref value, out dummy);
+
+				if (s.Length > 0 && s[0] == '.')
+				{
+					s = s.Substring(1);
+					s = ReadHexProgressive(s, ref value, out exp);
+				}
+
+				exp *= -4;
+
+				if (s.Length > 0 && char.ToUpper(s[0]) == 'P')
+				{
+					if (s.Length == 1)
+						throw new SyntaxErrorException(T, "invalid hex float format near '{0}'", s);
+
+					s = s.Substring(s[1] == '+' ? 2 : 1);
+
+					int exp1 = int.Parse(s, CultureInfo.InvariantCulture);
+
+					exp += exp1;
+				}
+
+				double result = value * Math.Pow(2, exp);
+				return result;
+			}
+			catch (FormatException)
+			{
+				throw new SyntaxErrorException(T, "malformed number near '{0}'", s);
+			}
+		}
+
+
+		public static int HexDigit2Value(char c)
+		{
+			if (c >= '0' && c <= '9')
+				return c - '0';
+			else if (c >= 'A' && c <= 'F')
+				return 10 + (c - 'A');
+			else if (c >= 'a' && c <= 'f')
+				return 10 + (c - 'a');
+			else
+				throw new InternalErrorException("invalid hex digit near '{0}'", c);
+		}
+
+
 		public static bool CharIsHexDigit(char c)
 		public static bool CharIsHexDigit(char c)
 		{
 		{
 			return char.IsDigit(c) ||
 			return char.IsDigit(c) ||
@@ -25,7 +133,7 @@ namespace MoonSharp.Interpreter.Tree
 			return str;
 			return str;
 		}
 		}
 
 
-		public static string UnescapeLuaString(string str)
+		public static string UnescapeLuaString(Token token, string str)
 		{
 		{
 			if (!str.Contains('\\'))
 			if (!str.Contains('\\'))
 				return str;
 				return str;
@@ -64,14 +172,14 @@ namespace MoonSharp.Interpreter.Tree
 						else if (c == 'u') { unicode_state = 1; }
 						else if (c == 'u') { unicode_state = 1; }
 						else if (c == 'z') { zmode = true; escape = false; }
 						else if (c == 'z') { zmode = true; escape = false; }
 						else if (char.IsDigit(c)) { val = val + c; }
 						else if (char.IsDigit(c)) { val = val + c; }
-						else throw new SyntaxErrorException("invalid escape sequence near '\\{0}'", c);
+						else throw new SyntaxErrorException(token, "invalid escape sequence near '\\{0}'", c);
 					}
 					}
 					else
 					else
 					{
 					{
 						if (unicode_state == 1)
 						if (unicode_state == 1)
 						{
 						{
 							if (c != '{')
 							if (c != '{')
-								throw new SyntaxErrorException("'{' expected near '\\u'");
+								throw new SyntaxErrorException(token, "'{' expected near '\\u'");
 
 
 							unicode_state = 2;
 							unicode_state = 2;
 						}
 						}
@@ -87,7 +195,7 @@ namespace MoonSharp.Interpreter.Tree
 							}
 							}
 							else if (val.Length >= 8)
 							else if (val.Length >= 8)
 							{
 							{
-								throw new SyntaxErrorException("'}' missing, or unicode code point too large after '\\u'");
+								throw new SyntaxErrorException(token, "'}' missing, or unicode code point too large after '\\u'");
 							}
 							}
 							else
 							else
 							{
 							{
@@ -109,7 +217,7 @@ namespace MoonSharp.Interpreter.Tree
 							}
 							}
 							else
 							else
 							{
 							{
-								throw new SyntaxErrorException("hexadecimal digit expected near '\\{0}{1}{2}'", hexprefix, val, c);
+								throw new SyntaxErrorException(token, "hexadecimal digit expected near '\\{0}{1}{2}'", hexprefix, val, c);
 							}
 							}
 						}
 						}
 						else if (val.Length > 0)
 						else if (val.Length > 0)
@@ -124,7 +232,7 @@ namespace MoonSharp.Interpreter.Tree
 								int i = int.Parse(val, CultureInfo.InvariantCulture);
 								int i = int.Parse(val, CultureInfo.InvariantCulture);
 
 
 								if (i > 255)
 								if (i > 255)
-									throw new SyntaxErrorException("decimal escape too large near '\\{0}'", val);
+									throw new SyntaxErrorException(token, "decimal escape too large near '\\{0}'", val);
 
 
 								sb.Append(char.ConvertFromUtf32(i));
 								sb.Append(char.ConvertFromUtf32(i));
 
 
@@ -165,7 +273,7 @@ namespace MoonSharp.Interpreter.Tree
 
 
 			if (escape)
 			if (escape)
 			{
 			{
-				throw new SyntaxErrorException("unfinished string near '\"{0}\"'", sb.ToString());
+				throw new SyntaxErrorException(token, "unfinished string near '\"{0}\"'", sb.ToString());
 			}
 			}
 
 
 			return sb.ToString();
 			return sb.ToString();

+ 20 - 11
src/MoonSharp.Interpreter/Tree/Lexer/Token.cs

@@ -2,33 +2,29 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Text;
 using System.Text;
+using MoonSharp.Interpreter.Execution;
 
 
 namespace MoonSharp.Interpreter.Tree
 namespace MoonSharp.Interpreter.Tree
 {
 {
 	class Token
 	class Token
 	{
 	{
+		public readonly int SourceId;
 		public readonly int FromCol, ToCol, FromLine, ToLine;
 		public readonly int FromCol, ToCol, FromLine, ToLine;
 		public readonly TokenType Type;
 		public readonly TokenType Type;
 
 
 		public string Text { get; set; }
 		public string Text { get; set; }
 
 
-		public Token(TokenType type, int fromLine, int fromCol, int toLine, int toCol)
+		public Token(TokenType type, int sourceId, int fromLine, int fromCol, int toLine, int toCol)
 		{
 		{
 			Type = type;
 			Type = type;
 
 
+			SourceId = sourceId;
 			FromLine = fromLine;
 			FromLine = fromLine;
 			FromCol = fromCol;
 			FromCol = fromCol;
 			ToCol = toCol;
 			ToCol = toCol;
 			ToLine = toLine;
 			ToLine = toLine;
 		}
 		}
 
 
-		public Token(TokenType type, int line, int col)
-			: this(type, line, col, line, col)
-		{ }
-
-		public Token(TokenType type)
-			: this(type, -1, -1, -1, -1)
-		{ }
 
 
 		public override string ToString()
 		public override string ToString()
 		{
 		{
@@ -36,8 +32,6 @@ namespace MoonSharp.Interpreter.Tree
 			return string.Format("{0}  -  '{1}'", tokenTypeString, this.Text ?? "");
 			return string.Format("{0}  -  '{1}'", tokenTypeString, this.Text ?? "");
 		}
 		}
 
 
-
-
 		public static TokenType? GetReservedTokenType(string reservedWord)
 		public static TokenType? GetReservedTokenType(string reservedWord)
 		{
 		{
 			switch (reservedWord)
 			switch (reservedWord)
@@ -91,7 +85,17 @@ namespace MoonSharp.Interpreter.Tree
 			}
 			}
 		}
 		}
 
 
-
+		public double GetNumberValue()
+		{
+			if (this.Type == TokenType.Number)
+				return LexerUtils.ParseNumber(this);
+			else if (this.Type == TokenType.Number_Hex)
+				return LexerUtils.ParseHexInteger(this);
+			else if (this.Type == TokenType.Number_HexFloat)
+				return LexerUtils.ParseHexFloat(this);
+			else
+				throw new NotSupportedException("GetNumberValue is supported only on numeric tokens");
+		}
 
 
 
 
 		public bool IsEndOfBlock()
 		public bool IsEndOfBlock()
@@ -140,5 +144,10 @@ namespace MoonSharp.Interpreter.Tree
 		}
 		}
 
 
 
 
+
+		internal Debugging.SourceRef GetSourceRef(bool isStepStop = true)
+		{
+			return new Debugging.SourceRef(this.SourceId, this.FromCol, this.ToCol, this.FromLine, this.ToLine, isStepStop);
+		}
 	}
 	}
 }
 }

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

@@ -67,6 +67,7 @@ namespace MoonSharp.Interpreter.Tree
 		Number_HexFloat,
 		Number_HexFloat,
 		Number_Hex,
 		Number_Hex,
 		SemiColon,
 		SemiColon,
+		Invalid,
 	}
 	}
 
 
 
 

+ 12 - 19
src/MoonSharp.Interpreter/Tree/NodeBase.cs

@@ -10,23 +10,14 @@ namespace MoonSharp.Interpreter.Tree
 {
 {
 	abstract class NodeBase
 	abstract class NodeBase
 	{
 	{
-		public NodeBase(ScriptLoadingContext lcontext)
-		{ 
-		
-		}
-
+		public Script Script { get; private set; }
 		protected ScriptLoadingContext LoadingContext { get; private set; }
 		protected ScriptLoadingContext LoadingContext { get; private set; }
 
 
-		public Exception SyntaxError(string format, params object[] args)
+		public NodeBase(ScriptLoadingContext lcontext)
 		{
 		{
-			return new SyntaxErrorException(format, args);
+			Script = lcontext.Script;
 		}
 		}
 
 
-		public void SyntaxAssert(bool condition, string format, params object[] args)
-		{
-			if (!condition)
-				throw  SyntaxError(format, args);
-		}
 
 
 		public abstract void Compile(ByteCode bc);
 		public abstract void Compile(ByteCode bc);
 
 
@@ -57,7 +48,7 @@ namespace MoonSharp.Interpreter.Tree
 		{
 		{
 			Token t = lcontext.Lexer.Current;
 			Token t = lcontext.Lexer.Current;
 			if (t.Type != tokenType)
 			if (t.Type != tokenType)
-				throw new SyntaxErrorException("Unexpected token '{0}'", t.Text);
+				throw new SyntaxErrorException(t, "unexpected symbol near '{0}'", t.Text);
 
 
 			lcontext.Lexer.Next();
 			lcontext.Lexer.Next();
 
 
@@ -68,7 +59,7 @@ namespace MoonSharp.Interpreter.Tree
 		{
 		{
 			Token t = lcontext.Lexer.Current;
 			Token t = lcontext.Lexer.Current;
 			if (t.Type != tokenType1 && t.Type != tokenType2)
 			if (t.Type != tokenType1 && t.Type != tokenType2)
-				throw new SyntaxErrorException("Unexpected token '{0}'", t.Text);
+				throw new SyntaxErrorException(t, "unexpected symbol near '{0}'", t.Text);
 
 
 			lcontext.Lexer.Next();
 			lcontext.Lexer.Next();
 
 
@@ -78,7 +69,7 @@ namespace MoonSharp.Interpreter.Tree
 		{
 		{
 			Token t = lcontext.Lexer.Current;
 			Token t = lcontext.Lexer.Current;
 			if (t.Type != tokenType1 && t.Type != tokenType2 && t.Type != tokenType3)
 			if (t.Type != tokenType1 && t.Type != tokenType2 && t.Type != tokenType3)
-				throw new SyntaxErrorException("Unexpected token '{0}'", t.Text);
+				throw new SyntaxErrorException(t, "unexpected symbol near '{0}'", t.Text);
 
 
 			lcontext.Lexer.Next();
 			lcontext.Lexer.Next();
 
 
@@ -89,13 +80,15 @@ namespace MoonSharp.Interpreter.Tree
 		{
 		{
 			Token t = lcontext.Lexer.Current;
 			Token t = lcontext.Lexer.Current;
 			if (t.Type != tokenType)
 			if (t.Type != tokenType)
-				throw new SyntaxErrorException("Unexpected token '{0}'", t.Text);
+				throw new SyntaxErrorException(t, "unexpected symbol near '{0}'", t.Text);
 		}
 		}
 
 
-		protected static void CheckMatch(ScriptLoadingContext lcontext, string tokenDesc, TokenType tokenType)
+		protected static void CheckMatch(ScriptLoadingContext lcontext, Token originalToken, TokenType expectedTokenType, string expectedTokenText)
 		{
 		{
-			if (lcontext.Lexer.Current.Type != tokenType)
-				throw new SyntaxErrorException("Mismatched '{0}' near '{1}'", tokenDesc, lcontext.Lexer.Current.Text);
+			if (lcontext.Lexer.Current.Type != expectedTokenType)
+				throw new SyntaxErrorException(lcontext.Lexer.Current,
+					"'{0}' expected (to close '{1}' at line {2}) near '{3}'",
+					expectedTokenText, originalToken.Text, originalToken.FromLine, lcontext.Lexer.Current.Text);
 
 
 			lcontext.Lexer.Next();
 			lcontext.Lexer.Next();
 		}
 		}

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

@@ -51,7 +51,6 @@ namespace MoonSharp.Interpreter.Tree
 					forceLast = true;
 					forceLast = true;
 					return new ReturnStatement(lcontext);
 					return new ReturnStatement(lcontext);
 				case TokenType.Break:
 				case TokenType.Break:
-					forceLast = true;
 					return new BreakStatement(lcontext);
 					return new BreakStatement(lcontext);
 				default:
 				default:
 					{
 					{

+ 1 - 1
src/MoonSharp.Interpreter/Tree/Statements/AssignmentStatement.cs

@@ -74,7 +74,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			IVariable v = firstExpression as IVariable;
 			IVariable v = firstExpression as IVariable;
 
 
 			if (v == null)
 			if (v == null)
-				throw new SyntaxErrorException("unexpected symbol near '{0}' - not a l-value", lcontext.Lexer.Current);
+				throw new SyntaxErrorException(lcontext.Lexer.Current, "unexpected symbol near '{0}' - not a l-value", lcontext.Lexer.Current);
 
 
 			return v;
 			return v;
 		}
 		}

+ 3 - 3
src/MoonSharp.Interpreter/Tree/Statements/BreakStatement.cs

@@ -16,7 +16,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 		public BreakStatement(ScriptLoadingContext lcontext)
 		public BreakStatement(ScriptLoadingContext lcontext)
 			: base(lcontext)
 			: base(lcontext)
 		{
 		{
-			CheckTokenType(lcontext, TokenType.Break);
+			m_Ref = CheckTokenType(lcontext, TokenType.Break).GetSourceRef();
 		}
 		}
 
 
 
 
@@ -26,12 +26,12 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			using (bc.EnterSource(m_Ref))
 			using (bc.EnterSource(m_Ref))
 			{
 			{
 				if (bc.LoopTracker.Loops.Count == 0)
 				if (bc.LoopTracker.Loops.Count == 0)
-					throw new SyntaxErrorException("<break> not inside a loop");
+					throw new SyntaxErrorException(this.Script, m_Ref, "<break> at line {0} not inside a loop", m_Ref.FromLine);
 
 
 				ILoop loop = bc.LoopTracker.Loops.Peek();
 				ILoop loop = bc.LoopTracker.Loops.Peek();
 
 
 				if (loop.IsBoundary())
 				if (loop.IsBoundary())
-					throw new SyntaxErrorException("<break> not inside a loop");
+					throw new SyntaxErrorException(this.Script, m_Ref, "<break> at line {0} not inside a loop", m_Ref.FromLine);
 
 
 				loop.CompileBreak(bc);
 				loop.CompileBreak(bc);
 			}
 			}

+ 1 - 1
src/MoonSharp.Interpreter/Tree/Statements/ChunkStatement.cs

@@ -31,7 +31,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			m_Block = new CompositeStatement(lcontext);
 			m_Block = new CompositeStatement(lcontext);
 
 
 			if (lcontext.Lexer.Current.Type != TokenType.Eof)
 			if (lcontext.Lexer.Current.Type != TokenType.Eof)
-				throw new SyntaxErrorException("<eof> expected near '{0}'", lcontext.Lexer.Current.Text);
+				throw new SyntaxErrorException(lcontext.Lexer.Current, "<eof> expected near '{0}'", lcontext.Lexer.Current.Text);
 
 
 			m_StackFrame = lcontext.Scope.PopFunction();
 			m_StackFrame = lcontext.Scope.PopFunction();
 		}
 		}

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

@@ -53,7 +53,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 						Token separator = lcontext.Lexer.Current;
 						Token separator = lcontext.Lexer.Current;
 	
 	
 						if (separator.Type != TokenType.Colon && separator.Type != TokenType.Dot)
 						if (separator.Type != TokenType.Colon && separator.Type != TokenType.Dot)
-							throw new SyntaxErrorException("unexpected symbol near '{0}'", separator.Text);
+							throw new SyntaxErrorException(separator, "unexpected symbol near '{0}'", separator.Text);
 						
 						
 						lcontext.Lexer.Next();
 						lcontext.Lexer.Next();
 
 

+ 1 - 1
src/MoonSharpTests/Program.cs

@@ -16,7 +16,7 @@ namespace MoonSharpTests
 {
 {
 	class Program
 	class Program
 	{
 	{
-		public const string RESTRICT_TEST = "ClosureNoTable";
+		public const string RESTRICT_TEST = null; //"ClosureNoTable";
 
 
 
 
 		static void Main(string[] args)
 		static void Main(string[] args)

+ 4 - 4
src/PerformanceComparison/HugeFile.cs

@@ -10,7 +10,7 @@ namespace PerformanceComparison
 {
 {
 	public class HugeFile
 	public class HugeFile
 	{
 	{
-		static void xxxxMain(string[] args)
+		static void Main(string[] args)
 		{
 		{
 			Console.WriteLine("Started...");
 			Console.WriteLine("Started...");
 			Script.WarmUp();
 			Script.WarmUp();
@@ -23,10 +23,10 @@ namespace PerformanceComparison
 			Stopwatch sw = Stopwatch.StartNew();
 			Stopwatch sw = Stopwatch.StartNew();
 
 
 			//for (int i = 0; i < 10; i++)
 			//for (int i = 0; i < 10; i++)
-			var v = s.LoadFile(@"C:\temp\test3.lua");
+				var v = s.LoadFile(@"C:\temp\test3.lua");
 
 
-			for(int i = 0; i < 1000; i++)
-				s.Call(v);
+			//for(int i = 0; i < 1000; i++)
+			//	s.Call(v);
 
 
 			sw.Stop();
 			sw.Stop();
 
 

+ 3 - 1
src/PerformanceComparison/Program.cs

@@ -123,8 +123,10 @@ end
 		static Lua lua = new Lua();
 		static Lua lua = new Lua();
 		static string testString = "world";
 		static string testString = "world";
 
 
-		static void Main(string[] args)
+		static void xxMain(string[] args)
 		{
 		{
+			Script.WarmUp();
+
 			Stopwatch sw;
 			Stopwatch sw;
 
 
 			sw = Stopwatch.StartNew();
 			sw = Stopwatch.StartNew();