Kaynağa Gözat

Found closure bug

Xanathar 11 yıl önce
ebeveyn
işleme
d7cea92ef6
39 değiştirilmiş dosya ile 388 ekleme ve 815 silme
  1. 4 10
      src/MoonSharp.Debugger/MainForm.cs
  2. 4 4
      src/MoonSharp.Debugger/Modules/Test/Builder.lua
  3. 0 60
      src/MoonSharp.Debugger/Modules/Test/Builder/NoOutput.lua
  4. 0 38
      src/MoonSharp.Debugger/Modules/Test/Builder/SocketOutput.lua
  5. 0 140
      src/MoonSharp.Debugger/Modules/Test/Builder/Tester.lua
  6. 0 66
      src/MoonSharp.Debugger/Modules/Test/Builder/Tester/File.lua
  7. 0 12
      src/MoonSharp.Debugger/MoonSharp.Debugger.csproj
  8. 30 0
      src/MoonSharp.Interpreter.Tests/EndToEnd/ClosureTests.cs
  9. 3 2
      src/MoonSharp.Interpreter.Tests/EndToEnd/LuaTestSuiteExtract.cs
  10. 6 20
      src/MoonSharp.Interpreter.Tests/EndToEnd/MetatableTests.cs
  11. 61 12
      src/MoonSharp.Interpreter.Tests/EndToEnd/SimpleTests.cs
  12. 3 15
      src/MoonSharp.Interpreter.Tests/EndToEnd/TableTests.cs
  13. 4 3
      src/MoonSharp.Interpreter.Tests/EndToEnd/TailCallTests.cs
  14. 0 12
      src/MoonSharp.Interpreter.Tests/MoonSharp.Interpreter.Tests.csproj
  15. 4 4
      src/MoonSharp.Interpreter.Tests/TestMore/Modules/Test/Builder.lua
  16. 0 60
      src/MoonSharp.Interpreter.Tests/TestMore/Modules/Test/Builder/NoOutput.lua
  17. 0 38
      src/MoonSharp.Interpreter.Tests/TestMore/Modules/Test/Builder/SocketOutput.lua
  18. 0 140
      src/MoonSharp.Interpreter.Tests/TestMore/Modules/Test/Builder/Tester.lua
  19. 0 66
      src/MoonSharp.Interpreter.Tests/TestMore/Modules/Test/Builder/Tester/File.lua
  20. 5 8
      src/MoonSharp.Interpreter.Tests/TestMore/TapRunner.cs
  21. 17 9
      src/MoonSharp.Interpreter/CoreLib/LoadMethods.cs
  22. 2 2
      src/MoonSharp.Interpreter/CoreLib/Patterns/PatternMatching.cs
  23. 1 1
      src/MoonSharp.Interpreter/CoreLib/StringModule.cs
  24. 70 0
      src/MoonSharp.Interpreter/CoreLib/TableModule.cs
  25. 9 2
      src/MoonSharp.Interpreter/DataTypes/Closure.cs
  26. 11 2
      src/MoonSharp.Interpreter/DataTypes/DynValue.cs
  27. 12 0
      src/MoonSharp.Interpreter/DataTypes/IScriptPrivateResource.cs
  28. 21 6
      src/MoonSharp.Interpreter/DataTypes/Table.cs
  29. 15 3
      src/MoonSharp.Interpreter/Execution/VM/Processor/Processor_InstructionLoop.cs
  30. 6 2
      src/MoonSharp.Interpreter/Grammar/Lua.g4
  31. 7 2
      src/MoonSharp.Interpreter/Modules/CoreModules.cs
  32. 41 7
      src/MoonSharp.Interpreter/Modules/ModuleRegister.cs
  33. 2 0
      src/MoonSharp.Interpreter/MoonSharp.Interpreter.csproj
  34. 6 36
      src/MoonSharp.Interpreter/Script.cs
  35. 24 27
      src/MoonSharp.Interpreter/Tree/Expressions/FunctionDefinitionExpression.cs
  36. 8 0
      src/MoonSharp.Interpreter/Tree/Expressions/SymbolRefExpression.cs
  37. 7 6
      src/MoonSharp.Interpreter/Tree/Loader.cs
  38. 3 0
      src/MoonSharp.Interpreter/Tree/NodeFactory.cs
  39. 2 0
      src/moonsharp.sln

+ 4 - 10
src/MoonSharp.Debugger/MainForm.cs

@@ -89,17 +89,11 @@ namespace MoonSharp.Debugger
 
 		private void DebugScript(string filename)
 		{
-			Table T = new Table();
-			T["print"] = DynValue.NewCallback(Print);
-			T["assert"] = DynValue.NewCallback(Assert);
-			T["xassert"] = DynValue.NewCallback(XAssert);
+			m_Script = new Script(CoreModules.Preset_Complete);
 
-			T.RegisterModuleType<TableIterators>();
-			T.RegisterModuleType<LoadMethods>();
-			T.RegisterModuleType<MetaTableMethods>();
-			T.RegisterModuleType<StringModule>();
-
-			m_Script = new Script(T);
+			m_Script.Globals["print"] = DynValue.NewCallback(Print);
+			m_Script.Globals["assert"] = DynValue.NewCallback(Assert);
+			m_Script.Globals["xassert"] = DynValue.NewCallback(XAssert);
 
 			var L = new ClassicLuaScriptLoader();
 			L.ModulePaths = L.UnpackStringPaths("Modules/?;Modules/?.lua");

+ 4 - 4
src/MoonSharp.Debugger/Modules/Test/Builder.lua

@@ -3,9 +3,9 @@
 -- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
 --
 
-local debug = require 'debug'
-local io = require 'io'
-local os = require 'os'
+local debug = nil; -- require 'debug'
+local io = nil; -- require 'io'
+local os = nil; -- require 'os'
 local error = error
 local gsub = require 'string'.gsub
 local match = require 'string'.match
@@ -240,7 +240,7 @@ function m:skip_all (reason)
     if self.parent then
         error("skip_all in child", 0)
     end
-    os.exit(0)
+    -- os.exit(0)
 end
 
 local function _check_is_passing_plan (self)

+ 0 - 60
src/MoonSharp.Debugger/Modules/Test/Builder/NoOutput.lua

@@ -1,60 +0,0 @@
-
---
--- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
---
-
-local io = require 'io'
-local pairs = pairs
-local require = require
-
-_ENV = nil
-local m = {}
-
-function m.create ()
-    local tb = require 'Test.Builder'.create()
-    tb:output(io.tmpfile())
-    tb:failure_output(io.tmpfile())
-    tb:todo_output(io.tmpfile())
-
-    function tb:read (stream)
-        if     stream == 'out' then
-            local f = self:output()
-            f:seek 'set'
-            local out = f:read '*a'
-            f:close()
-            self:output(io.tmpfile())
-            return out
-        elseif stream == 'err' then
-            local f = self:failure_output()
-            f:seek 'set'
-            local out = f:read '*a'
-            f:close()
-            self:failure_output(io.tmpfile())
-            return out
-        elseif stream == 'todo' then
-            local f = self:todo_output()
-            f:seek 'set'
-            local out = f:read '*a'
-            f:close()
-            self:todo_output(io.tmpfile())
-            return out
-        else
-            self:output():close()
-            self:output(io.tmpfile())
-            self:failure_output():close()
-            self:failure_output(io.tmpfile())
-            self:todo_output():close()
-            self:todo_output(io.tmpfile())
-        end
-    end
-
-    return tb
-end
-
-return m
---
--- Copyright (c) 2009-2012 Francois Perrad
---
--- This library is licensed under the terms of the MIT/X11 license,
--- like Lua itself.
---

+ 0 - 38
src/MoonSharp.Debugger/Modules/Test/Builder/SocketOutput.lua

@@ -1,38 +0,0 @@
-
---
--- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
---
-
---[[
-    require 'Test.More'
-    require 'socket'
-    local conn = socket.connect(host, port)
-    require 'Test.Builder.SocketOutput'.init(conn)
-    -- now, as usual
-    plan(...)
-    ...
---]]
-
-local assert = assert
-
-local tb = require 'Test.Builder'.new()
-local m = getmetatable(tb)
-_ENV = nil
-
-function m.init (sock)
-    tb:output(sock)
-    tb:failure_output(sock)
-    tb:todo_output(sock)
-end
-
-function m.puts (sock, str)
-    assert(sock:send(str))
-end
-
-return m
---
--- Copyright (c) 2011-2012 Francois Perrad
---
--- This library is licensed under the terms of the MIT/X11 license,
--- like Lua itself.
---

+ 0 - 140
src/MoonSharp.Debugger/Modules/Test/Builder/Tester.lua

@@ -1,140 +0,0 @@
-
---
--- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
---
-
-local error = error
-local pairs = pairs
-local type = type
-local _G = _G
-local debug = require 'debug'
-
-local tb  = require 'Test.Builder'.new()
-local out = require 'Test.Builder.Tester.File'.new 'out'
-local err = require 'Test.Builder.Tester.File'.new 'err'
-
-_ENV = nil
-local m = {}
-
--- for remembering that we're testing and where we're testing at
-local testing = false
-local testing_num
-
--- remembering where the file handles were originally connected
-local original_output_handle
-local original_failure_handle
-local original_todo_handle
-
-local function _start_testing ()
-    -- remember what the handles were set to
-    original_output_handle  = tb:output()
-    original_failure_handle = tb:failure_output()
-    original_todo_handle    = tb:todo_output()
-
-    -- switch out to our own handles
-    tb:output(out)
-    tb:failure_output(err)
-    tb:todo_output(err)
-
-    -- clear the expected list
-    out:reset()
-    err:reset()
-
-    -- remeber that we're testing
-    testing = true
-    testing_num = tb:current_test()
-    tb:current_test(0)
-
-    -- look, we shouldn't do the ending stuff
-    tb.no_ending = true
-end
-
-function m.test_out (...)
-    if not testing then
-        _start_testing()
-    end
-    out:expect(...)
-end
-
-function m.test_err (...)
-    if not testing then
-        _start_testing()
-    end
-    err:expect(...)
-end
-
-function m.test_fail (offset)
-    offset = offset or 0
-    if not testing then
-        _start_testing()
-    end
-    local info = debug.getinfo(2)
-    local prog = info.short_src
-    local line = info.currentline + offset
-    err:expect("#     Failed test (" .. prog .. " at line " .. line .. ")")
-end
-
-function m.test_diag (...)
-    local arg = {...}
-    if not testing then
-        _start_testing()
-    end
-    for i = 1, #arg do
-        err:expect("# " .. arg[i])
-    end
-end
-
-function m.test_test (args)
-    local mess
-    if type(args) == 'table' then
-        mess = args[1]
-    else
-        mess = args
-        args = {}
-    end
-
-    if not testing then
-        error "Not testing.  You must declare output with a test function first."
-    end
-
-    -- okay, reconnect the test suite back to the saved handles
-    tb:output(original_output_handle)
-    tb:failure_output(original_failure_handle)
-    tb:todo_output(original_todo_handle)
-
-    -- restore the test no, etc, back to the original point
-    tb:current_test(testing_num)
-    testing = false
-
-    -- check the output we've stashed
-    local pass = (args.skip_out or out:check())
-             and (args.skip_err or err:check())
-    tb:ok(pass, mess)
-    if not pass then
-        -- print out the diagnostic information about why this
-        -- test failed
-        if not out:check() then
-            tb:diag(out:complaint())
-        end
-        if not err:check() then
-            tb:diag(err:complaint())
-        end
-    end
-end
-
-function m.line_num ()
-    return debug.getinfo(2).currentline
-end
-
-for k, v in pairs(m) do  -- injection
-    _G[k] = v
-end
-
-return m
-
---
--- Copyright (c) 2009-2012 Francois Perrad
---
--- This library is licensed under the terms of the MIT/X11 license,
--- like Lua itself.
---

+ 0 - 66
src/MoonSharp.Debugger/Modules/Test/Builder/Tester/File.lua

@@ -1,66 +0,0 @@
-
---
--- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
---
-
-local tconcat = require 'table'.concat
-local setmetatable = setmetatable
-
-local tb = require 'Test.Builder'.new()
-
-_ENV = nil
-local m = {}
-
-function m.new (_type)
-    local o = setmetatable({ type = _type }, { __index = m })
-    o:reset()
-    return o
-end
-
-function m:write (...)
-    self.got = self.got .. tconcat({...})
-end
-
-function m:reset ()
-    self.got = ''
-    self.wanted = {}
-end
-
-function m:expect (...)
-    local arg = {...}
-    local wanted = self.wanted
-    for i = 1, #arg do
-        wanted[#wanted+1] = arg[i]
-    end
-end
-
-function m:check ()
-    local got = self.got
-    local wanted = tconcat(self.wanted, "\n")
-    if wanted ~= '' then
-        wanted = wanted .. "\n"
-    end
-    return got == wanted
-end
-
-function m:complaint ()
-    local type = self.type
-    local got = self.got
-    local wanted = tconcat(self.wanted, "\n")
-    if wanted ~= '' then
-        wanted = wanted .. "\n"
-    end
-    return type .. " is:"
-     .. "\n" .. got
-     .. "\nnot:"
-     .. "\n" .. wanted
-     .. "\nhas expected"
-end
-
-return m
---
--- Copyright (c) 2009-2012 Francois Perrad
---
--- This library is licensed under the terms of the MIT/X11 license,
--- like Lua itself.
---

+ 0 - 12
src/MoonSharp.Debugger/MoonSharp.Debugger.csproj

@@ -125,18 +125,6 @@
     <None Include="Modules\Test\Builder.lua">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </None>
-    <None Include="Modules\Test\Builder\NoOutput.lua">
-      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
-    </None>
-    <None Include="Modules\Test\Builder\SocketOutput.lua">
-      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
-    </None>
-    <None Include="Modules\Test\Builder\Tester.lua">
-      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
-    </None>
-    <None Include="Modules\Test\Builder\Tester\File.lua">
-      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
-    </None>
     <None Include="Modules\Test\More.lua">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </None>

+ 30 - 0
src/MoonSharp.Interpreter.Tests/EndToEnd/ClosureTests.cs

@@ -193,5 +193,35 @@ namespace MoonSharp.Interpreter.Tests
 			Assert.AreEqual(2000001, res.Tuple[4].Number);
 		}
 
+
+		[Test]
+		public void NestedUpvaluesNotQuiteWorking()
+		{
+			string script = @"
+	local y = y;
+
+	local x = x;
+	local m = { };
+
+	function m:a()
+		self.t = {
+			dojob = function() 
+				if (x == nil) then return 1; else return 0; end
+			end,
+		};
+	end
+
+	m:a();
+
+	return 10 * m.t.dojob();
+								";
+
+			DynValue res = Script.RunString(script);
+
+			Assert.AreEqual(DataType.Number, res.Type);
+			Assert.AreEqual(10, res.Number);
+		}
+
+
 	}
 }

+ 3 - 2
src/MoonSharp.Interpreter.Tests/EndToEnd/LuaTestSuiteExtract.cs

@@ -19,7 +19,9 @@ namespace MoonSharp.Interpreter.Tests
 			HashSet<string> failedTests = new HashSet<string>();
 			int i = 0;
 
-			var globalCtx = new Table();
+			Script S = new Script();
+
+			var globalCtx = S.Globals;
 			globalCtx[DynValue.NewString("xassert")] =  DynValue.NewCallback(new CallbackFunction(
 				(x, a) =>
 				{
@@ -45,7 +47,6 @@ namespace MoonSharp.Interpreter.Tests
 					return DynValue.Nil;
 				}));
 
-			Script S = new Script(globalCtx);
 
 			DynValue res = S.DoString(script);
 

+ 6 - 20
src/MoonSharp.Interpreter.Tests/EndToEnd/MetatableTests.cs

@@ -40,12 +40,7 @@ namespace MoonSharp.Interpreter.Tests.EndToEnd
 
 				return x;";
 
-			Table globalCtx = new Table();
-
-			globalCtx.RegisterModuleType<TableIterators>();
-			globalCtx.RegisterModuleType<MetaTableMethods>();
-
-			DynValue res = (new Script(globalCtx)).DoString(script);
+			DynValue res = (new Script()).DoString(script);
 
 			Assert.AreEqual(DataType.String, res.Type);
 			Assert.AreEqual("321", res.String);
@@ -73,12 +68,13 @@ namespace MoonSharp.Interpreter.Tests.EndToEnd
 
 				return(v1 + v2);";
 
-			Table globalCtx = new Table();
+			var S = new Script();
+			Table globalCtx = S.Globals;
 
 			globalCtx.RegisterModuleType<TableIterators>();
 			globalCtx.RegisterModuleType<MetaTableMethods>();
 
-			DynValue res = (new Script(globalCtx)).DoString(script);
+			DynValue res = S.DoString(script);
 
 			Assert.AreEqual(DataType.Number, res.Type);
 			Assert.AreEqual(24, res.Number);
@@ -101,12 +97,7 @@ namespace MoonSharp.Interpreter.Tests.EndToEnd
 				return ( t1a == t1b ), ( t1a == t2 ) 
 				";
 
-			Table globalCtx = new Table();
-
-			globalCtx.RegisterModuleType<TableIterators>();
-			globalCtx.RegisterModuleType<MetaTableMethods>();
-
-			DynValue res = (new Script(globalCtx)).DoString(script);
+			DynValue res = (new Script()).DoString(script);
 
 			Assert.AreEqual(DataType.Tuple, res.Type);
 			Assert.AreEqual(true, res.Tuple[0].Boolean);
@@ -134,12 +125,7 @@ namespace MoonSharp.Interpreter.Tests.EndToEnd
 					return x;
 				";
 
-			Table globalCtx = new Table();
-
-			globalCtx.RegisterModuleType<TableIterators>();
-			globalCtx.RegisterModuleType<MetaTableMethods>();
-
-			DynValue res = (new Script(globalCtx)).DoString(script);
+			DynValue res = (new Script()).DoString(script);
 
 
 			Assert.AreEqual(DataType.Number, res.Type);

+ 61 - 12
src/MoonSharp.Interpreter.Tests/EndToEnd/SimpleTests.cs

@@ -17,14 +17,15 @@ namespace MoonSharp.Interpreter.Tests
 
 			string script = "print(\"hello\", \"world\");";
 
-			var globalCtx = new Table();
-			globalCtx["print"] = DynValue.NewCallback(new CallbackFunction((x, a) => 
+			Script S = new Script();
+
+			S.Globals["print"] = DynValue.NewCallback(new CallbackFunction((x, a) => 
 			{
 				args = a.ToArray();
 				return DynValue.NewNumber(1234.0); 
 			}));
 
-			DynValue res = (new Script(globalCtx)).DoString(script);
+			DynValue res = S.DoString(script);
 
 			Assert.AreEqual(DataType.Nil, res.Type);
 			Assert.AreEqual(2, args.Count);
@@ -41,10 +42,10 @@ namespace MoonSharp.Interpreter.Tests
 
 			string script = "local print = print; print(\"hello\", \"world\");";
 
-			var globalCtx = new Table();
-			globalCtx["print"] = DynValue.NewCallback(new CallbackFunction((_x, a) => { args = a.ToArray(); return DynValue.NewNumber(1234.0); }));
+			var S = new Script();
+			S.Globals["print"] = DynValue.NewCallback(new CallbackFunction((_x, a) => { args = a.ToArray(); return DynValue.NewNumber(1234.0); }));
 
-			DynValue res = (new Script(globalCtx)).DoString(script);
+			DynValue res = S.DoString(script);
 
 			Assert.AreEqual(2, args.Count);
 			Assert.AreEqual(DataType.String, args[0].Type);
@@ -61,10 +62,10 @@ namespace MoonSharp.Interpreter.Tests
 
 			string script = "return print(\"hello\", \"world\");";
 
-			var globalCtx = new Table();
-			globalCtx["print"] = DynValue.NewCallback(new CallbackFunction((_x, a) => { args = a.ToArray(); return DynValue.NewNumber(1234.0); }));
+			var S = new Script();
+			S.Globals["print"] = DynValue.NewCallback(new CallbackFunction((_x, a) => { args = a.ToArray(); return DynValue.NewNumber(1234.0); }));
 
-			DynValue res = (new Script(globalCtx)).DoString(script);
+			DynValue res = S.DoString(script);
 
 			Assert.AreEqual(2, args.Count);
 			Assert.AreEqual(DataType.String, args[0].Type);
@@ -120,13 +121,13 @@ namespace MoonSharp.Interpreter.Tests
 				y = false and crash();
 			";
 
-			var globalCtx = new Table();
-			globalCtx["crash"] = DynValue.NewCallback(new CallbackFunction((_x, a) =>
+			Script S = new Script();
+			S.Globals["crash"] = DynValue.NewCallback(new CallbackFunction((_x, a) =>
 			{
 				throw new Exception("FAIL!");
 			}));
 
-			(new Script(globalCtx)).DoString(script);
+			S.DoString(script);
 		}
 
 
@@ -767,5 +768,53 @@ namespace MoonSharp.Interpreter.Tests
 			Assert.AreEqual(2, res.Tuple[2].Number);
 		}
 
+
+		[Test]
+		public void VarArgsNoError()
+		{
+			string script = @"
+					function x(...)
+
+					end
+
+					function y(a, ...)
+
+					end
+
+					return 1;
+								";
+
+			DynValue res = Script.RunString(script);
+
+			Assert.AreEqual(DataType.Number, res.Type);
+			Assert.AreEqual(1, res.Number);
+		}
+
+		[Test]
+		public void VarArgsSum()
+		{
+			string script = @"
+					function x(...)
+						local t = pack(...);
+						local sum = 0;
+
+						for i = 1, #t do
+							sum = sum + t[i];
+						end
+	
+						return sum;
+					end
+
+					return x(1,2,3,4);
+								";
+
+			DynValue res = Script.RunString(script);
+
+			Assert.AreEqual(DataType.Number, res.Type);
+			Assert.AreEqual(10, res.Number);
+		}
+
+
+
 	}
 }

+ 3 - 15
src/MoonSharp.Interpreter.Tests/EndToEnd/TableTests.cs

@@ -247,11 +247,7 @@ namespace MoonSharp.Interpreter.Tests
 
 				return s;";
 
-			Table globalCtx = new Table();
-
-			globalCtx.RegisterModuleType<TableIterators>();
-
-			DynValue res = (new Script(globalCtx)).DoString(script);
+			DynValue res = Script.RunString(script);
 
 			Assert.AreEqual(DataType.String, res.Type);
 			Assert.AreEqual("1|2|3|4|5", res.String);
@@ -281,11 +277,7 @@ namespace MoonSharp.Interpreter.Tests
 
 				return K, V;";
 
-			Table globalCtx = new Table();
-
-			globalCtx.RegisterModuleType<TableIterators>();
-
-			DynValue res = (new Script(globalCtx)).DoString(script);
+			DynValue res = Script.RunString(script);
 
 			Assert.AreEqual(DataType.Tuple, res.Type);
 			Assert.AreEqual(DataType.String, res.Tuple[0].Type);
@@ -314,11 +306,7 @@ namespace MoonSharp.Interpreter.Tests
     
 				return x, y";
 
-			Table globalCtx = new Table();
-
-			globalCtx.RegisterModuleType<TableIterators>();
-
-			DynValue res = (new Script(globalCtx)).DoString(script);
+			DynValue res = Script.RunString(script);
 
 			Assert.AreEqual(DataType.Tuple, res.Type);
 			Assert.AreEqual(2, res.Tuple.Length);

+ 4 - 3
src/MoonSharp.Interpreter.Tests/EndToEnd/TailCallTests.cs

@@ -21,8 +21,9 @@ namespace MoonSharp.Interpreter.Tests.EndToEnd
 				return clrtail(9)";
 
 
-			var globalCtx = new Table();
-			globalCtx["clrtail"] = DynValue.NewCallback((xc, a) =>
+			Script S = new Script();
+
+			S.Globals["clrtail"] = DynValue.NewCallback((xc, a) =>
 			{
 				SymbolRef lref = SymbolRef.Global("getResult");
 				DynValue fn = xc.GetVar(lref);
@@ -31,7 +32,7 @@ namespace MoonSharp.Interpreter.Tests.EndToEnd
 				return DynValue.NewTailCallReq(fn, k3);
 			});
 
-			var res = (new Script(globalCtx)).DoString(script);
+			var res = S.DoString(script);
 
 			Assert.AreEqual(DataType.Number, res.Type);
 			Assert.AreEqual(468, res.Number);

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

@@ -212,18 +212,6 @@
     <None Include="TestMore\Modules\Test\Builder.lua">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </None>
-    <None Include="TestMore\Modules\Test\Builder\NoOutput.lua">
-      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
-    </None>
-    <None Include="TestMore\Modules\Test\Builder\SocketOutput.lua">
-      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
-    </None>
-    <None Include="TestMore\Modules\Test\Builder\Tester.lua">
-      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
-    </None>
-    <None Include="TestMore\Modules\Test\Builder\Tester\File.lua">
-      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
-    </None>
     <None Include="TestMore\Modules\Test\More.lua">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </None>

+ 4 - 4
src/MoonSharp.Interpreter.Tests/TestMore/Modules/Test/Builder.lua

@@ -3,9 +3,9 @@
 -- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
 --
 
-local debug = require 'debug'
-local io = require 'io'
-local os = require 'os'
+local debug = nil; -- require 'debug'
+local io = nil; -- require 'io'
+local os = nil; -- require 'os'
 local error = error
 local gsub = require 'string'.gsub
 local match = require 'string'.match
@@ -240,7 +240,7 @@ function m:skip_all (reason)
     if self.parent then
         error("skip_all in child", 0)
     end
-    os.exit(0)
+    -- os.exit(0)
 end
 
 local function _check_is_passing_plan (self)

+ 0 - 60
src/MoonSharp.Interpreter.Tests/TestMore/Modules/Test/Builder/NoOutput.lua

@@ -1,60 +0,0 @@
-
---
--- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
---
-
-local io = require 'io'
-local pairs = pairs
-local require = require
-
-_ENV = nil
-local m = {}
-
-function m.create ()
-    local tb = require 'Test.Builder'.create()
-    tb:output(io.tmpfile())
-    tb:failure_output(io.tmpfile())
-    tb:todo_output(io.tmpfile())
-
-    function tb:read (stream)
-        if     stream == 'out' then
-            local f = self:output()
-            f:seek 'set'
-            local out = f:read '*a'
-            f:close()
-            self:output(io.tmpfile())
-            return out
-        elseif stream == 'err' then
-            local f = self:failure_output()
-            f:seek 'set'
-            local out = f:read '*a'
-            f:close()
-            self:failure_output(io.tmpfile())
-            return out
-        elseif stream == 'todo' then
-            local f = self:todo_output()
-            f:seek 'set'
-            local out = f:read '*a'
-            f:close()
-            self:todo_output(io.tmpfile())
-            return out
-        else
-            self:output():close()
-            self:output(io.tmpfile())
-            self:failure_output():close()
-            self:failure_output(io.tmpfile())
-            self:todo_output():close()
-            self:todo_output(io.tmpfile())
-        end
-    end
-
-    return tb
-end
-
-return m
---
--- Copyright (c) 2009-2012 Francois Perrad
---
--- This library is licensed under the terms of the MIT/X11 license,
--- like Lua itself.
---

+ 0 - 38
src/MoonSharp.Interpreter.Tests/TestMore/Modules/Test/Builder/SocketOutput.lua

@@ -1,38 +0,0 @@
-
---
--- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
---
-
---[[
-    require 'Test.More'
-    require 'socket'
-    local conn = socket.connect(host, port)
-    require 'Test.Builder.SocketOutput'.init(conn)
-    -- now, as usual
-    plan(...)
-    ...
---]]
-
-local assert = assert
-
-local tb = require 'Test.Builder'.new()
-local m = getmetatable(tb)
-_ENV = nil
-
-function m.init (sock)
-    tb:output(sock)
-    tb:failure_output(sock)
-    tb:todo_output(sock)
-end
-
-function m.puts (sock, str)
-    assert(sock:send(str))
-end
-
-return m
---
--- Copyright (c) 2011-2012 Francois Perrad
---
--- This library is licensed under the terms of the MIT/X11 license,
--- like Lua itself.
---

+ 0 - 140
src/MoonSharp.Interpreter.Tests/TestMore/Modules/Test/Builder/Tester.lua

@@ -1,140 +0,0 @@
-
---
--- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
---
-
-local error = error
-local pairs = pairs
-local type = type
-local _G = _G
-local debug = require 'debug'
-
-local tb  = require 'Test.Builder'.new()
-local out = require 'Test.Builder.Tester.File'.new 'out'
-local err = require 'Test.Builder.Tester.File'.new 'err'
-
-_ENV = nil
-local m = {}
-
--- for remembering that we're testing and where we're testing at
-local testing = false
-local testing_num
-
--- remembering where the file handles were originally connected
-local original_output_handle
-local original_failure_handle
-local original_todo_handle
-
-local function _start_testing ()
-    -- remember what the handles were set to
-    original_output_handle  = tb:output()
-    original_failure_handle = tb:failure_output()
-    original_todo_handle    = tb:todo_output()
-
-    -- switch out to our own handles
-    tb:output(out)
-    tb:failure_output(err)
-    tb:todo_output(err)
-
-    -- clear the expected list
-    out:reset()
-    err:reset()
-
-    -- remeber that we're testing
-    testing = true
-    testing_num = tb:current_test()
-    tb:current_test(0)
-
-    -- look, we shouldn't do the ending stuff
-    tb.no_ending = true
-end
-
-function m.test_out (...)
-    if not testing then
-        _start_testing()
-    end
-    out:expect(...)
-end
-
-function m.test_err (...)
-    if not testing then
-        _start_testing()
-    end
-    err:expect(...)
-end
-
-function m.test_fail (offset)
-    offset = offset or 0
-    if not testing then
-        _start_testing()
-    end
-    local info = debug.getinfo(2)
-    local prog = info.short_src
-    local line = info.currentline + offset
-    err:expect("#     Failed test (" .. prog .. " at line " .. line .. ")")
-end
-
-function m.test_diag (...)
-    local arg = {...}
-    if not testing then
-        _start_testing()
-    end
-    for i = 1, #arg do
-        err:expect("# " .. arg[i])
-    end
-end
-
-function m.test_test (args)
-    local mess
-    if type(args) == 'table' then
-        mess = args[1]
-    else
-        mess = args
-        args = {}
-    end
-
-    if not testing then
-        error "Not testing.  You must declare output with a test function first."
-    end
-
-    -- okay, reconnect the test suite back to the saved handles
-    tb:output(original_output_handle)
-    tb:failure_output(original_failure_handle)
-    tb:todo_output(original_todo_handle)
-
-    -- restore the test no, etc, back to the original point
-    tb:current_test(testing_num)
-    testing = false
-
-    -- check the output we've stashed
-    local pass = (args.skip_out or out:check())
-             and (args.skip_err or err:check())
-    tb:ok(pass, mess)
-    if not pass then
-        -- print out the diagnostic information about why this
-        -- test failed
-        if not out:check() then
-            tb:diag(out:complaint())
-        end
-        if not err:check() then
-            tb:diag(err:complaint())
-        end
-    end
-end
-
-function m.line_num ()
-    return debug.getinfo(2).currentline
-end
-
-for k, v in pairs(m) do  -- injection
-    _G[k] = v
-end
-
-return m
-
---
--- Copyright (c) 2009-2012 Francois Perrad
---
--- This library is licensed under the terms of the MIT/X11 license,
--- like Lua itself.
---

+ 0 - 66
src/MoonSharp.Interpreter.Tests/TestMore/Modules/Test/Builder/Tester/File.lua

@@ -1,66 +0,0 @@
-
---
--- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
---
-
-local tconcat = require 'table'.concat
-local setmetatable = setmetatable
-
-local tb = require 'Test.Builder'.new()
-
-_ENV = nil
-local m = {}
-
-function m.new (_type)
-    local o = setmetatable({ type = _type }, { __index = m })
-    o:reset()
-    return o
-end
-
-function m:write (...)
-    self.got = self.got .. tconcat({...})
-end
-
-function m:reset ()
-    self.got = ''
-    self.wanted = {}
-end
-
-function m:expect (...)
-    local arg = {...}
-    local wanted = self.wanted
-    for i = 1, #arg do
-        wanted[#wanted+1] = arg[i]
-    end
-end
-
-function m:check ()
-    local got = self.got
-    local wanted = tconcat(self.wanted, "\n")
-    if wanted ~= '' then
-        wanted = wanted .. "\n"
-    end
-    return got == wanted
-end
-
-function m:complaint ()
-    local type = self.type
-    local got = self.got
-    local wanted = tconcat(self.wanted, "\n")
-    if wanted ~= '' then
-        wanted = wanted .. "\n"
-    end
-    return type .. " is:"
-     .. "\n" .. got
-     .. "\nnot:"
-     .. "\n" .. wanted
-     .. "\nhas expected"
-end
-
-return m
---
--- Copyright (c) 2009-2012 Francois Perrad
---
--- This library is licensed under the terms of the MIT/X11 license,
--- like Lua itself.
---

+ 5 - 8
src/MoonSharp.Interpreter.Tests/TestMore/TapRunner.cs

@@ -28,14 +28,11 @@ namespace MoonSharp.Interpreter.Tests
 
 		public void Run()
 		{
-			var globalCtx = new Table();
-			globalCtx["print"] = DynValue.NewCallback(Print);
-			globalCtx["arg"] = DynValue.NewTable();
-			globalCtx.RegisterModuleType<TableIterators>();
-			globalCtx.RegisterModuleType<LoadMethods>();
-			globalCtx.RegisterModuleType<MetaTableMethods>();
-			globalCtx.RegisterModuleType<StringModule>();
-			var S = new Script(globalCtx);
+			Script S = new Script();
+
+			S.Globals["print"] = DynValue.NewCallback(Print);
+			S.Globals["arg"] = DynValue.NewTable(S);
+
 			var L = new ClassicLuaScriptLoader();
 			L.ModulePaths = L.UnpackStringPaths("TestMore/Modules/?;TestMore/Modules/?.lua");
 			S.ScriptLoader = L;

+ 17 - 9
src/MoonSharp.Interpreter/CoreLib/LoadMethods.cs

@@ -47,27 +47,35 @@ namespace MoonSharp.Interpreter.CoreLib
 		//If there is any error loading or running the module, or if it cannot find any loader for the module, then require 
 		//signals an error. 
 		[MoonSharpMethod]
-		public static DynValue __require_internal(ScriptExecutionContext executionContext, CallbackArguments args)
+		public static DynValue __require_clr_impl(ScriptExecutionContext executionContext, CallbackArguments args)
 		{
 			Script S = executionContext.GetOwnerScript();
-			DynValue v = args.AsType(0, "require", DataType.String, false);
+			DynValue v = args.AsType(0, "__require_clr_impl", DataType.String, false);
 
 			DynValue fn = S.RequireModule(v.String);
 
-			return DynValue.NewTailCallReq(fn); // tail call to dofile
+			return fn; // tail call to dofile
 		}
 
 
 		[MoonSharpMethod]
-		public static string require = @"
-			function(arg)
-				local func, res = __require_internal(arg);
+		public const string require = @"
+			function(modulename)
+				if (package == nil) then package = { }; end
+				if (package.loaded == nil) then package.loaded = { }; end
+
+				local m = package.loaded[modulename];
 
-				if (res == nil) then
-					res = func();
-					_LOADED[arg] = res;
+				if (m ~= nil) then
+					return m;
 				end
 
+				local func = __require_clr_impl(modulename);
+
+				local res = func();
+
+				package.loaded[modulename] = res;
+
 				return res;
 			end
 		";

+ 2 - 2
src/MoonSharp.Interpreter/CoreLib/Patterns/PatternMatching.cs

@@ -509,11 +509,11 @@ namespace MoonSharp.Interpreter.CoreLib.Patterns
 			return DynValue.Nil;
 		}
 
-		public static DynValue GMatch(string src, string pattern)
+		public static DynValue GMatch(Script script, string src, string pattern)
 		{
 			DynValue aux = DynValue.NewCallback(GmatchAux);
 
-			aux.Callback.Closure = new Table();
+			aux.Callback.Closure = new Table(script);
 			aux.Callback.Closure["idx"] = DynValue.NewNumber(0);
 			aux.Callback.Closure["src"] = DynValue.NewString(src);
 			aux.Callback.Closure["pattern"] = DynValue.NewString(pattern);

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

@@ -16,7 +16,7 @@ namespace MoonSharp.Interpreter.CoreLib
 			DynValue s = args.AsType(0, "gmatch", DataType.String, false);
 			DynValue p = args.AsType(1, "gmatch", DataType.String, false);
 
-			return PatternMatching.GMatch(s.String, p.String);
+			return PatternMatching.GMatch(executionContext.GetOwnerScript(), s.String, p.String);
 		}
 
 		[MoonSharpMethod()]

+ 70 - 0
src/MoonSharp.Interpreter/CoreLib/TableModule.cs

@@ -0,0 +1,70 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using MoonSharp.Interpreter.CoreLib.Patterns;
+using MoonSharp.Interpreter.Execution;
+
+namespace MoonSharp.Interpreter.CoreLib
+{
+	[MoonSharpModule(Namespace = "table")]
+	public class TableModule
+	{
+		[MoonSharpMethod()]
+		public static DynValue unpack(ScriptExecutionContext executionContext, CallbackArguments args)
+		{
+			DynValue s = args.AsType(0, "unpack", DataType.Table, false);
+			Table t = s.Table;
+
+			DynValue[] v = new DynValue[(int)t.Length];
+
+			for (int i = 1; i <= v.Length; i++)
+				v[i - 1] = t[i];
+
+			return DynValue.NewTuple(v);
+		}
+
+		[MoonSharpMethod()]
+		public static DynValue pack(ScriptExecutionContext executionContext, CallbackArguments args)
+		{
+			DynValue s = args[0];
+			Table t = new Table(executionContext.GetOwnerScript());
+			DynValue v = DynValue.NewTable(t);
+
+			if (s.IsNil())
+				return v;
+
+			if (s.Type == DataType.Tuple)
+			{
+				for (int i = 0; i < s.Tuple.Length; i++)
+					t[i + 1] = s.Tuple[i];
+			}
+			else
+			{
+				t[1] = s;
+			}
+
+			return v;
+		}
+
+	}
+
+
+	[MoonSharpModule]
+	public class TableModule_Globals
+	{
+		[MoonSharpMethod()]
+		public static DynValue unpack(ScriptExecutionContext executionContext, CallbackArguments args)
+		{
+			return TableModule.unpack(executionContext, args);
+		}
+
+		[MoonSharpMethod()]
+		public static DynValue pack(ScriptExecutionContext executionContext, CallbackArguments args)
+		{
+			return TableModule.pack(executionContext, args);
+		}
+	}
+
+
+}

+ 9 - 2
src/MoonSharp.Interpreter/DataTypes/Closure.cs

@@ -2,11 +2,12 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
+using MoonSharp.Interpreter.DataTypes;
 using MoonSharp.Interpreter.Execution;
 
 namespace MoonSharp.Interpreter
 {
-	public class Closure
+	public class Closure : IScriptPrivateResource
 	{
 		public int ByteCodeLocation { get; private set; }
 
@@ -14,11 +15,16 @@ namespace MoonSharp.Interpreter
 
 		public Table GlobalEnv { get; set; }
 
+		public Script OwnerScript { get; private set; }
+
+
 		private static ClosureContext emptyClosure = new ClosureContext();
 
 
-		internal Closure(int idx, SymbolRef[] symbols, DynValue[] localscope)
+		internal Closure(Script script, int idx, SymbolRef[] symbols, DynValue[] localscope)
 		{
+			OwnerScript = script;
+
 			ByteCodeLocation = idx;
 
 			if (symbols.Length > 0)
@@ -26,5 +32,6 @@ namespace MoonSharp.Interpreter
 			else
 				ClosureContext = emptyClosure;
 		}
+
 	}
 }

+ 11 - 2
src/MoonSharp.Interpreter/DataTypes/DynValue.cs

@@ -173,15 +173,23 @@ namespace MoonSharp.Interpreter
 		/// <summary>
 		/// Creates a new writable value initialized to the specified table.
 		/// </summary>
-		public static DynValue NewTable(Table table = null)
+		public static DynValue NewTable(Table table)
 		{
 			return new DynValue()
 			{
-				Table = table ?? new Table(),
+				Table = table,
 				Type = DataType.Table,
 			};
 		}
 
+		/// <summary>
+		/// Creates a new writable value initialized to an empty table.
+		/// </summary>
+		public static DynValue NewTable(Script script)
+		{
+			return NewTable(new Table(script));
+		}
+
 		/// <summary>
 		/// Creates a new request for a tail call. This is the preferred way to execute Lua/Moon# code from a callback,
 		/// although it's not always possible to use it. When a function (callback or script closure) returns a
@@ -656,6 +664,7 @@ namespace MoonSharp.Interpreter
 
 			this.Number = num;
 		}
+
 	}
 
 

+ 12 - 0
src/MoonSharp.Interpreter/DataTypes/IScriptPrivateResource.cs

@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MoonSharp.Interpreter.DataTypes
+{
+	public interface IScriptPrivateResource
+	{
+		Script OwnerScript { get; }
+	}
+}

+ 21 - 6
src/MoonSharp.Interpreter/DataTypes/Table.cs

@@ -3,24 +3,31 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using MoonSharp.Interpreter.DataStructs;
+using MoonSharp.Interpreter.DataTypes;
 
 namespace MoonSharp.Interpreter
 {
-	public class Table
+	public class Table : IScriptPrivateResource
 	{
 		LinkedList<TablePair> m_Values;
 		LinkedListIndex<DynValue, TablePair> m_ValueMap;
 		LinkedListIndex<string, TablePair> m_StringMap;
 		LinkedListIndex<int, TablePair> m_ArrayMap;
+		Script m_Owner;
 
 		int m_CachedLength = -1;
 
-		public Table()
+		public Table(Script owner)
 		{
 			m_Values = new LinkedList<TablePair>();
 			m_StringMap = new LinkedListIndex<string, TablePair>(m_Values);
 			m_ArrayMap = new LinkedListIndex<int, TablePair>(m_Values);
 			m_ValueMap = new LinkedListIndex<DynValue, TablePair>(m_Values);
+			m_Owner = owner;
+		}
+		public Script OwnerScript
+		{
+			get { return m_Owner; }
 		}
 
 		private int GetIntegralKey(double d)
@@ -78,7 +85,9 @@ namespace MoonSharp.Interpreter
 						return;
 					}
 				}
-				
+
+				CheckValueOwner(value);
+
 				if (m_ValueMap.Set(key, new TablePair(key, value)))
 					CollectDeadKeys();
 			}
@@ -100,6 +109,8 @@ namespace MoonSharp.Interpreter
 			}
 			set
 			{
+				CheckValueOwner(value);
+
 				if (m_StringMap.Set(key, new TablePair(DynValue.NewString(key), value)))
 					CollectDeadKeys();
 			}
@@ -124,6 +135,8 @@ namespace MoonSharp.Interpreter
 			}
 			set
 			{
+				CheckValueOwner(value);
+
 				if (m_ArrayMap.Set(key, new TablePair(DynValue.NewNumber(key), value)))
 				{
 					CollectDeadKeys();
@@ -132,6 +145,11 @@ namespace MoonSharp.Interpreter
 			}
 		}
 
+		private void CheckValueOwner(DynValue value)
+		{
+			// +++ value.AssertOwner(m_Owner);
+		}
+
 		private void CollectDeadKeys()
 		{
 			for (LinkedListNode<TablePair> node = m_Values.First; node != null; node = node.Next)
@@ -223,8 +241,5 @@ namespace MoonSharp.Interpreter
 				return m_CachedLength; 
 			}
 		}
-
-
-
 	}
 }

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

@@ -122,7 +122,7 @@ namespace MoonSharp.Interpreter.Execution.VM
 						ClearBlockData(i.Block, i.OpCode == OpCode.Exit);
 						break;
 					case OpCode.Closure:
-						m_ValueStack.Push(DynValue.NewClosure(new Closure(i.NumVal, i.SymbolList, m_ExecutionStack.Peek().LocalScope)));
+						m_ValueStack.Push(DynValue.NewClosure(new Closure(this.m_Script, i.NumVal, i.SymbolList, m_ExecutionStack.Peek().LocalScope)));
 						break;
 					case OpCode.BeginFn:
 						ExecBeginFn(i);
@@ -163,7 +163,7 @@ namespace MoonSharp.Interpreter.Execution.VM
 						ExecIndexRef(i, true);
 						break;
 					case OpCode.NewTable:
-						m_ValueStack.Push(DynValue.NewTable(new Table()));
+						m_ValueStack.Push(DynValue.NewTable(this.m_Script));
 						break;
 					case OpCode.IterPrep:
 						ExecIterPrep(i);
@@ -365,6 +365,18 @@ namespace MoonSharp.Interpreter.Execution.VM
 				{
 					this.AssignGenericSymbol(I.SymbolList[i], DynValue.NewNil());
 				}
+				else if ((i == I.SymbolList.Length - 1) && (I.SymbolList[i].i_Name == "..."))
+				{
+					int len = numargs - i;
+					DynValue[] varargs = new DynValue[len];
+
+					for (int ii = 0; ii < len; ii++)
+					{
+						varargs[ii] = m_ValueStack.Peek(numargs - i - ii).CloneAsWritable();
+					}
+
+					this.AssignGenericSymbol(I.SymbolList[i], DynValue.NewTuple(varargs));
+				}
 				else
 				{
 					this.AssignGenericSymbol(I.SymbolList[i], m_ValueStack.Peek(numargs - i).CloneAsWritable());
@@ -418,7 +430,7 @@ namespace MoonSharp.Interpreter.Execution.VM
 					}
 				}
 
-				throw new NotImplementedException("Can't call non function");
+				throw new NotImplementedException("Can't call non function - " + fn.ToString());
 			}
 		}
 

+ 6 - 2
src/MoonSharp.Interpreter/Grammar/Lua.g4

@@ -101,7 +101,7 @@ explist
 
 exp
     : 'nil' | 'false' | 'true' | number | string		
-	| '...'											
+	| vararg
 	| anonfunctiondef								
     | prefixexp										
 	| tableconstructor								
@@ -156,7 +156,7 @@ funcbody
 
 // The list of params in a function def
 parlist
-    : namelist (',' '...')? | '...'
+    : namelist (',' vararg)? | vararg
     ;
 
 
@@ -215,6 +215,10 @@ string
     : NORMALSTRING | CHARSTRING | LONGSTRING
     ;
 
+vararg
+	: '...'
+	;
+
 // LEXER
 
 NAME

+ 7 - 2
src/MoonSharp.Interpreter/Modules/CoreModules.cs

@@ -12,11 +12,16 @@ namespace MoonSharp.Interpreter
 		TableIterators = 0x2,
 		Metatables = 0x4,
 		String = 0x8,
+		LoadMethods = 0x10,
+		Table = 0x20,
 
 
-		Preset_HardSandbox = GlobalConsts | TableIterators | String,
+
+		Preset_HardSandbox = GlobalConsts | TableIterators | String | Table,
 		Preset_SoftSandbox = Preset_HardSandbox | Metatables,
-		Preset_Default = Preset_SoftSandbox,
+		Preset_Default = Preset_SoftSandbox | LoadMethods,
+		Preset_Complete = Preset_Default,
+
 	}
 
 	public static class CoreModules_ExtensionMethods

+ 41 - 7
src/MoonSharp.Interpreter/Modules/ModuleRegister.cs

@@ -16,6 +16,9 @@ namespace MoonSharp.Interpreter
 			if (modules.Has(CoreModules.TableIterators)) RegisterModuleType<TableIterators>(table);
 			if (modules.Has(CoreModules.Metatables)) RegisterModuleType<MetaTableMethods>(table);
 			if (modules.Has(CoreModules.String)) RegisterModuleType<StringModule>(table);
+			if (modules.Has(CoreModules.LoadMethods)) RegisterModuleType<LoadMethods>(table);
+			if (modules.Has(CoreModules.Table)) RegisterModuleType<TableModule>(table);
+			if (modules.Has(CoreModules.Table)) RegisterModuleType<TableModule_Globals>(table);
 
 			return table;
 		}
@@ -58,16 +61,33 @@ namespace MoonSharp.Interpreter
 				table[name] = DynValue.NewCallback(func);
 			}
 
-			RegisterLuaScripts(table, t);
+			foreach (FieldInfo fi in t.GetFields(BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public | BindingFlags.NonPublic).Where(_mi => _mi.GetCustomAttributes(typeof(MoonSharpMethodAttribute), false).Length > 0))
+			{
+				MoonSharpMethodAttribute attr = (MoonSharpMethodAttribute)fi.GetCustomAttributes(typeof(MoonSharpMethodAttribute), false).First();
+				string name = (!string.IsNullOrEmpty(attr.Name)) ? attr.Name : fi.Name;
+
+				RegisterScriptField(fi, null, table, t, name);
+			}
 
 			return gtable;
 		}
 
-		private static void RegisterLuaScripts(Table table, Type t)
+
+		private static void RegisterScriptField(FieldInfo fi, object o, Table table, Type t, string name)
 		{
-			//throw new NotImplementedException();
+			if (fi.FieldType != typeof(string))
+			{
+				throw new ArgumentException(string.Format("Field {0} does not have the right type - it must be string.", name));
+			}
+
+			string val = fi.GetValue(o) as string;
+
+			DynValue fn = table.OwnerScript.LoadFunction(val, null, name);
+
+			table[name] = fn;
 		}
 
+
 		private static Table CreateModuleNamespace(Table gtable, Type t)
 		{
 			MoonSharpModuleAttribute attr = (MoonSharpModuleAttribute)t.GetCustomAttributes(typeof(MoonSharpModuleAttribute), false).First();
@@ -78,14 +98,22 @@ namespace MoonSharp.Interpreter
 			}
 			else
 			{
-				Table table = new Table();
+				Table table = new Table(gtable.OwnerScript);
 				gtable[attr.Namespace] = DynValue.NewTable(table);
 
-				DynValue loaded = gtable.RawGet("_LOADED");
+				DynValue package = gtable.RawGet("package");
+
+				if (package == null || package.Type != DataType.Table)
+				{
+					gtable["package"] = package = DynValue.NewTable(gtable.OwnerScript);
+				}
+
+
+				DynValue loaded = package.Table.RawGet("loaded");
 
 				if (loaded == null || loaded.Type != DataType.Table)
 				{
-					gtable["_LOADED"] = loaded = DynValue.NewTable();
+					package.Table["loaded"] = loaded = DynValue.NewTable(gtable.OwnerScript);
 				}
 
 				loaded.Table[attr.Namespace] = DynValue.NewTable(table);
@@ -124,7 +152,13 @@ namespace MoonSharp.Interpreter
 				table[name] = DynValue.NewCallback(func);
 			}
 
-			RegisterLuaScripts(table, t);
+			foreach (FieldInfo fi in t.GetFields(BindingFlags.GetField | BindingFlags.Public | BindingFlags.NonPublic).Where(_mi => _mi.GetCustomAttributes(typeof(MoonSharpMethodAttribute), false).Length > 0))
+			{
+				MoonSharpMethodAttribute attr = (MoonSharpMethodAttribute)fi.GetCustomAttributes(typeof(MoonSharpMethodAttribute), false).First();
+				string name = (!string.IsNullOrEmpty(attr.Name)) ? attr.Name : fi.Name;
+
+				RegisterScriptField(fi, o, table, t, name);
+			}
 
 			return gtable;
 		}

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

@@ -91,11 +91,13 @@
     </Compile>
     <Compile Include="CoreLib\StringModule.cs" />
     <Compile Include="CoreLib\TableIterators.cs" />
+    <Compile Include="CoreLib\TableModule.cs" />
     <Compile Include="DataStructs\Extension_Methods.cs" />
     <Compile Include="DataStructs\FastStackDynamic.cs" />
     <Compile Include="DataStructs\ITrackableReference.cs" />
     <Compile Include="DataStructs\LinkedListIndex.cs" />
     <Compile Include="DataStructs\Slice.cs" />
+    <Compile Include="DataTypes\IScriptPrivateResource.cs" />
     <Compile Include="Debugging\DebuggerAction.cs" />
     <Compile Include="Debugging\IDebugger.cs" />
     <Compile Include="Debugging\SourceCodeType.cs" />

+ 6 - 36
src/MoonSharp.Interpreter/Script.cs

@@ -38,7 +38,7 @@ namespace MoonSharp.Interpreter
 		/// Initializes a new instance of the <see cref="Script"/> class.
 		/// </summary>
 		public Script()
-			: this(ModuleRegister.RegisterCoreModules(new Table(), CoreModules.Preset_Default))
+			: this(CoreModules.Preset_Default)
 		{
 		}
 
@@ -47,21 +47,13 @@ namespace MoonSharp.Interpreter
 		/// </summary>
 		/// <param name="coreModules">The core modules to be pre-registered in the default global table.</param>
 		public Script(CoreModules coreModules)
-			: this(ModuleRegister.RegisterCoreModules(new Table(), coreModules))
-		{
-		}
-
-		/// <summary>
-		/// Initializes a new instance of the <see cref="Script"/> class.
-		/// </summary>
-		/// <param name="globalTable">The default global table.</param>
-		public Script(Table globalTable)
 		{
 			m_ByteCode = new ByteCode();
-			m_GlobalTable = globalTable;
+			m_GlobalTable = new Table(this).RegisterCoreModules(coreModules);
 			m_Coroutines.Add(new Processor(this, m_GlobalTable, m_ByteCode));
 		}
 
+
 		/// <summary>
 		/// Gets or sets the script loader to use. A script loader wraps all code loading from files, so that access
 		/// to the filesystem can be completely overridden.
@@ -232,7 +224,7 @@ namespace MoonSharp.Interpreter
 		/// <returns></returns>
 		private DynValue MakeClosure(int address, Table globalContext)
 		{
-			Closure c = new Closure(address, new SymbolRef[0], new DynValue[0]);
+			Closure c = new Closure(this, address, new SymbolRef[0], new DynValue[0]);
 			c.GlobalEnv = globalContext;
 			return DynValue.NewClosure(c);
 		}
@@ -298,38 +290,16 @@ namespace MoonSharp.Interpreter
 		/// </summary>
 		/// <param name="modname">The module name</param>
 		/// <returns></returns>
-		public DynValue RequireModule(string modname, Table globalContext = null, int coroutine = -1)
+		public DynValue RequireModule(string modname, Table globalContext = null)
 		{
 			Table globals = globalContext ?? m_GlobalTable;
-
-			DynValue loaded = globals.RawGet("_LOADED");
-
-			if (loaded == null || loaded.Type != DataType.Table)
-			{
-				globals["_LOADED"] = loaded = DynValue.NewTable();
-			}
-
-			DynValue m = loaded.Table.RawGet(modname);
-
-			if (m != null && !m.IsNil())
-				return m;
-
 			string filename = m_ScriptLoader.ResolveModuleName(modname, globals);
 
 			if (filename == null)
 				throw new ScriptRuntimeException(null, "module '{0}' not found", modname);
 
-			coroutine = FixCoroutineIndex(coroutine);
-
 			DynValue func = LoadResolvedFile(filename, globalContext);
-			m = Call(coroutine, func);
-
-			if (m.IsNilOrNan())
-				m = DynValue.True;
-
-			loaded.Table[modname] = m;
-
-			return m;
+			return func;
 		}
 
 	}

+ 24 - 27
src/MoonSharp.Interpreter/Tree/Expressions/FunctionDefinitionExpression.cs

@@ -10,10 +10,11 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 {
 	class FunctionDefinitionExpression : Expression, IClosureBuilder
 	{
-		SymbolRef[] m_ParamNames;
+		SymbolRef[] m_ParamNames = null;
 		Statement m_Statement;
 		RuntimeScopeFrame m_StackFrame;
 		List<SymbolRef> m_Closure = new List<SymbolRef>();
+		bool m_HasVarArgs = false;
 		public object UpvalueCreationTag { get; set; }
 
 		public FunctionDefinitionExpression(LuaParser.AnonfunctiondefContext context, ScriptLoadingContext lcontext, bool pushSelfParam = false)
@@ -39,36 +40,30 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			: base(context, lcontext)
 		{
 			var parlist = context.parlist();
-			string[] paramnames;
+			List<string> paramnames = new List<string>();
 
-			if (!pushSelfParam)
+			if (pushSelfParam)
 			{
-				if (parlist != null)
-				{
-					paramnames = parlist.namelist().NAME()
-						.Select(t => t.GetText())
-						.ToArray();
-				}
-				else
-				{
-					paramnames = new string[0];
-				}
+				paramnames.Add("self");
 			}
-			else
+
+
+			if (parlist != null)
 			{
-				if (parlist != null)
-				{
-					paramnames = new string[] { "self" }.Union(
-						parlist.namelist().NAME()
-						.Select(t => t.GetText()))
-						.ToArray();
-				}
-				else
+				var namelist = parlist.namelist();
+
+				if (namelist != null)
 				{
-					paramnames = new string[] { "self" };
+					paramnames.AddRange(namelist.NAME()
+						.Select(t => t.GetText()));
 				}
 			}
 
+			m_HasVarArgs = (parlist != null && parlist.vararg() != null);
+
+			if (m_HasVarArgs)
+				paramnames.Add("...");
+
 			lcontext.Scope.EnterClosure(this);
 
 			lcontext.Scope.PushFunction();
@@ -82,11 +77,11 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			lcontext.Scope.LeaveClosure();
 		}
 
-		private SymbolRef[] DefineArguments(string[] paramnames, ScriptLoadingContext lcontext)
+		private SymbolRef[] DefineArguments(List<string> paramnames, ScriptLoadingContext lcontext)
 		{
-			SymbolRef[] ret = new SymbolRef[paramnames.Length];
+			SymbolRef[] ret = new SymbolRef[paramnames.Count];
 
-			for (int i = 0; i < paramnames.Length; i++)
+			for (int i = 0; i < paramnames.Count; i++)
 				ret[i] = lcontext.Scope.DefineLocal(paramnames[i]);
 
 			return ret;
@@ -98,6 +93,8 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 
 			bc.Emit_BeginFn(m_StackFrame, friendlyName ?? "<anonymous>");
 
+			int entryPoint = bc.GetJumpPointForLastInstruction();
+
 			if (m_ParamNames.Length > 0)
 				bc.Emit_Args(m_ParamNames);
 
@@ -107,7 +104,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 
 			I.NumVal = bc.GetJumpPointForNextInstruction();
 
-			return I.NumVal;
+			return entryPoint;
 		}
 
 		public int Compile(ByteCode bc, Action afterDecl, string friendlyName)

+ 8 - 0
src/MoonSharp.Interpreter/Tree/Expressions/SymbolRefExpression.cs

@@ -12,6 +12,14 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 	{
 		SymbolRef m_Ref;
 
+
+		public SymbolRefExpression(LuaParser.VarargContext context, ScriptLoadingContext lcontext)
+			: base(context, lcontext)
+		{
+			m_Ref = lcontext.Scope.TryDefineLocal("...");
+		}
+
+
 		public SymbolRefExpression(ITerminalNode terminalNode, ScriptLoadingContext lcontext)
 			: base(terminalNode, lcontext)
 		{

+ 7 - 6
src/MoonSharp.Interpreter/Tree/Loader.cs

@@ -6,6 +6,7 @@ using System.Diagnostics;
 using System.Linq;
 using System.Text;
 using Antlr4.Runtime;
+using Antlr4.Runtime.Tree;
 using MoonSharp.Interpreter.Diagnostics;
 using MoonSharp.Interpreter.Execution;
 using MoonSharp.Interpreter.Execution.VM;
@@ -19,7 +20,7 @@ namespace MoonSharp.Interpreter.Tree
 	{
 		internal static int LoadChunkFromICharStream(ICharStream charStream, ByteCode bytecode, string sourceName, int sourceIdx)
 		{
-			LuaParser parser = CreateParser(charStream, sourceIdx);
+			LuaParser parser = CreateParser(charStream, sourceIdx, p => p.chunk());
 
 			ScriptLoadingContext lcontext = CreateLoadingContext(sourceName, sourceIdx);
 			ChunkStatement stat = new ChunkStatement(parser.chunk(), lcontext);
@@ -41,7 +42,7 @@ namespace MoonSharp.Interpreter.Tree
 
 		internal static int LoadFunctionFromICharStream(ICharStream charStream, ByteCode bytecode, string sourceName, int sourceIdx)
 		{
-			LuaParser parser = CreateParser(charStream, sourceIdx);
+			LuaParser parser = CreateParser(charStream, sourceIdx, p => p.anonfunctiondef());
 
 			ScriptLoadingContext lcontext = CreateLoadingContext(sourceName, sourceIdx);
 			FunctionDefinitionExpression fndef = new FunctionDefinitionExpression(parser.anonfunctiondef(), lcontext);
@@ -68,10 +69,10 @@ namespace MoonSharp.Interpreter.Tree
 		}
 
 		[Conditional("DEBUG_COMPILER")]
-		private static void Debug_DumpAst(LuaParser parser, int sourceIdx)
+		private static void Debug_DumpAst(LuaParser parser, int sourceIdx, Func<LuaParser, IParseTree> dumper)
 		{
 			AstDump astDump = new AstDump();
-			astDump.DumpTree(parser.chunk(), string.Format(@"c:\temp\treedump_{0:000}.txt", sourceIdx));
+			astDump.DumpTree(dumper(parser), string.Format(@"c:\temp\treedump_{0:000}.txt", sourceIdx));
 			parser.Reset();
 		}
 
@@ -86,7 +87,7 @@ namespace MoonSharp.Interpreter.Tree
 			};
 		}
 
-		private static LuaParser CreateParser(ICharStream charStream, int sourceIdx)
+		private static LuaParser CreateParser(ICharStream charStream, int sourceIdx, Func<LuaParser, IParseTree> dumper)
 		{
 			LuaLexer lexer;
 			LuaParser parser;
@@ -97,7 +98,7 @@ namespace MoonSharp.Interpreter.Tree
 				parser = new LuaParser(new CommonTokenStream(lexer));
 			}
 
-			Debug_DumpAst(parser, sourceIdx);
+			Debug_DumpAst(parser, sourceIdx, dumper);
 
 			return parser;
 		}

+ 3 - 0
src/MoonSharp.Interpreter/Tree/NodeFactory.cs

@@ -154,6 +154,9 @@ namespace MoonSharp.Interpreter.Tree
 			if (tree is LuaParser.TableconstructorContext)
 				return new TableConstructor((LuaParser.TableconstructorContext)tree, lcontext);
 
+			if (tree is LuaParser.VarargContext)
+				return new SymbolRefExpression((LuaParser.VarargContext)tree, lcontext);
+
 			throw new SyntaxErrorException(tree, "Unexpected expression type: {0}", tree.GetType());
 		}
 

+ 2 - 0
src/moonsharp.sln

@@ -47,6 +47,7 @@ Global
 		{91EA9B9D-FE03-4273-BDAF-8AD42EDE1E59}.Release|x86.ActiveCfg = Release|x86
 		{91EA9B9D-FE03-4273-BDAF-8AD42EDE1E59}.Release|x86.Build.0 = Release|x86
 		{4AD350E6-E296-43EF-9FEA-CB70358467E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{4AD350E6-E296-43EF-9FEA-CB70358467E4}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{4AD350E6-E296-43EF-9FEA-CB70358467E4}.Debug|x86.ActiveCfg = Debug|x86
 		{4AD350E6-E296-43EF-9FEA-CB70358467E4}.Debug|x86.Build.0 = Debug|x86
 		{4AD350E6-E296-43EF-9FEA-CB70358467E4}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -68,6 +69,7 @@ Global
 		{470C034F-1F1F-499C-9499-DC00B9EEEDE9}.Release|x86.ActiveCfg = Release|x86
 		{470C034F-1F1F-499C-9499-DC00B9EEEDE9}.Release|x86.Build.0 = Release|x86
 		{F4F82CCE-2E13-441B-939C-63CF2343B1C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F4F82CCE-2E13-441B-939C-63CF2343B1C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{F4F82CCE-2E13-441B-939C-63CF2343B1C9}.Debug|x86.ActiveCfg = Debug|x86
 		{F4F82CCE-2E13-441B-939C-63CF2343B1C9}.Debug|x86.Build.0 = Debug|x86
 		{F4F82CCE-2E13-441B-939C-63CF2343B1C9}.Release|Any CPU.ActiveCfg = Release|Any CPU