Pārlūkot izejas kodu

Integrated TestMore - 38 fails

Xanathar 11 gadi atpakaļ
vecāks
revīzija
2400874d1e
50 mainītis faili ar 7626 papildinājumiem un 3 dzēšanām
  1. 137 0
      src/MoonSharp.Interpreter.Tests/MoonSharp.Interpreter.Tests.csproj
  2. 44 0
      src/MoonSharp.Interpreter.Tests/TapRunner.cs
  3. 54 0
      src/MoonSharp.Interpreter.Tests/TestMore/000-sanity.t
  4. 87 0
      src/MoonSharp.Interpreter.Tests/TestMore/001-if.t
  5. 67 0
      src/MoonSharp.Interpreter.Tests/TestMore/002-table.t
  6. 80 0
      src/MoonSharp.Interpreter.Tests/TestMore/011-while.t
  7. 78 0
      src/MoonSharp.Interpreter.Tests/TestMore/012-repeat.t
  8. 136 0
      src/MoonSharp.Interpreter.Tests/TestMore/014-fornum.t
  9. 99 0
      src/MoonSharp.Interpreter.Tests/TestMore/015-forlist.t
  10. 120 0
      src/MoonSharp.Interpreter.Tests/TestMore/101-boolean.t
  11. 199 0
      src/MoonSharp.Interpreter.Tests/TestMore/102-function.t
  12. 120 0
      src/MoonSharp.Interpreter.Tests/TestMore/103-nil.t
  13. 190 0
      src/MoonSharp.Interpreter.Tests/TestMore/104-number.t
  14. 183 0
      src/MoonSharp.Interpreter.Tests/TestMore/105-string.t
  15. 125 0
      src/MoonSharp.Interpreter.Tests/TestMore/106-table.t
  16. 128 0
      src/MoonSharp.Interpreter.Tests/TestMore/107-thread.t
  17. 125 0
      src/MoonSharp.Interpreter.Tests/TestMore/108-userdata.t
  18. 104 0
      src/MoonSharp.Interpreter.Tests/TestMore/200-examples.t
  19. 123 0
      src/MoonSharp.Interpreter.Tests/TestMore/201-assign.t
  20. 111 0
      src/MoonSharp.Interpreter.Tests/TestMore/202-expr.t
  21. 122 0
      src/MoonSharp.Interpreter.Tests/TestMore/203-lexico.t
  22. 106 0
      src/MoonSharp.Interpreter.Tests/TestMore/204-grammar.t
  23. 83 0
      src/MoonSharp.Interpreter.Tests/TestMore/211-scope.t
  24. 268 0
      src/MoonSharp.Interpreter.Tests/TestMore/212-function.t
  25. 98 0
      src/MoonSharp.Interpreter.Tests/TestMore/213-closure.t
  26. 191 0
      src/MoonSharp.Interpreter.Tests/TestMore/214-coroutine.t
  27. 112 0
      src/MoonSharp.Interpreter.Tests/TestMore/221-table.t
  28. 85 0
      src/MoonSharp.Interpreter.Tests/TestMore/222-constructor.t
  29. 196 0
      src/MoonSharp.Interpreter.Tests/TestMore/223-iterator.t
  30. 533 0
      src/MoonSharp.Interpreter.Tests/TestMore/231-metatable.t
  31. 307 0
      src/MoonSharp.Interpreter.Tests/TestMore/232-object.t
  32. 187 0
      src/MoonSharp.Interpreter.Tests/TestMore/241-standalone.t
  33. 133 0
      src/MoonSharp.Interpreter.Tests/TestMore/242-luac.t
  34. 482 0
      src/MoonSharp.Interpreter.Tests/TestMore/301-basic.t
  35. 217 0
      src/MoonSharp.Interpreter.Tests/TestMore/303-package.t
  36. 285 0
      src/MoonSharp.Interpreter.Tests/TestMore/304-string.t
  37. 231 0
      src/MoonSharp.Interpreter.Tests/TestMore/305-table.t
  38. 150 0
      src/MoonSharp.Interpreter.Tests/TestMore/306-math.t
  39. 94 0
      src/MoonSharp.Interpreter.Tests/TestMore/307-bit.t
  40. 241 0
      src/MoonSharp.Interpreter.Tests/TestMore/308-io.t
  41. 184 0
      src/MoonSharp.Interpreter.Tests/TestMore/309-os.t
  42. 183 0
      src/MoonSharp.Interpreter.Tests/TestMore/310-debug.t
  43. 207 0
      src/MoonSharp.Interpreter.Tests/TestMore/314-regex.t
  44. 124 0
      src/MoonSharp.Interpreter.Tests/TestMore/320-stdin.t
  45. 13 0
      src/MoonSharp.Interpreter.Tests/TestMore/rx_captures
  46. 38 0
      src/MoonSharp.Interpreter.Tests/TestMore/rx_charclass
  47. 117 0
      src/MoonSharp.Interpreter.Tests/TestMore/rx_metachars
  48. 305 0
      src/MoonSharp.Interpreter.Tests/TestMoreTests.cs
  49. 10 3
      src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScopeFrame.cs
  50. 14 0
      src/MoonSharp.Interpreter/Execution/VM/Processor/Processor_InstructionLoop.cs

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

@@ -77,6 +77,8 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="SimpleTests.cs" />
     <Compile Include="TableTests.cs" />
+    <Compile Include="TapRunner.cs" />
+    <Compile Include="TestMoreTests.cs" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\MoonSharp.Interpreter\MoonSharp.Interpreter.csproj">
@@ -86,6 +88,141 @@
   </ItemGroup>
   <ItemGroup>
     <None Include="packages.config" />
+    <Content Include="TestMore\000-sanity.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\001-if.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\002-table.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\011-while.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\012-repeat.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\014-fornum.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\015-forlist.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\101-boolean.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\102-function.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\103-nil.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\104-number.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\105-string.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\106-table.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\107-thread.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\108-userdata.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\200-examples.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\201-assign.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\202-expr.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\203-lexico.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\204-grammar.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\211-scope.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\212-function.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\213-closure.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\214-coroutine.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\221-table.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\222-constructor.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\223-iterator.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\231-metatable.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\232-object.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\241-standalone.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\242-luac.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\301-basic.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\303-package.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\304-string.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\305-table.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\306-math.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\307-bit.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\308-io.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\309-os.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\310-debug.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\314-regex.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\320-stdin.t">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\rx_captures">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\rx_charclass">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="TestMore\rx_metachars">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
   </ItemGroup>
   <Choose>
     <When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">

+ 44 - 0
src/MoonSharp.Interpreter.Tests/TapRunner.cs

@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using MoonSharp.Interpreter.Execution;
+using NUnit.Framework;
+
+namespace MoonSharp.Interpreter.Tests
+{
+	public class TapRunner
+	{
+		string m_File;
+
+		public RValue Print(IList<RValue> values)
+		{
+			string str = string.Join(" ", values.Select(s => s.AsString()).ToArray());
+			Assert.IsFalse(str.Trim().StartsWith("not ok"), string.Format("TAP fail ({0}) : {1}", m_File, str));
+			return RValue.Nil;
+		}
+
+		public TapRunner(string filename)
+		{
+			m_File = filename;
+		}
+
+		public void Run()
+		{
+			string script = File.ReadAllText(m_File);
+			var globalCtx = new Table();
+			globalCtx[new RValue("print")] = new RValue(new CallbackFunction(Print));
+			MoonSharpInterpreter.LoadFromString(script).Execute(globalCtx);
+		}
+
+		public static void Run(string filename)
+		{
+			TapRunner t = new TapRunner(filename);
+			t.Run();
+		}
+
+
+
+	}
+}

+ 54 - 0
src/MoonSharp.Interpreter.Tests/TestMore/000-sanity.t

@@ -0,0 +1,54 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua test suite
+
+=head2 Synopsis
+
+    % prove 000-sanity.t
+
+=head2 Description
+
+=cut
+
+]]
+
+function f (n)
+    return n + 1
+end
+
+function g (m, p)
+    return m + p
+end
+
+print('1..9')
+print("ok 1 -")
+print('ok', 2, "- list")
+print("ok " .. 3 .. " - concatenation")
+i = 4
+print("ok " .. i .. " - var")
+i = i + 1
+print("ok " .. i .. " - var incr")
+print("ok " .. i+1 .. " - expr")
+j = f(i + 1)
+print("ok " .. j .. " - call f")
+k = g(i, 3)
+print("ok " .. k .. " - call g")
+local print = print
+print("ok 9 - local")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 87 - 0
src/MoonSharp.Interpreter.Tests/TestMore/001-if.t

@@ -0,0 +1,87 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2010, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua if statement
+
+=head2 Synopsis
+
+    % prove 001-if.t
+
+=head2 Description
+
+See "Lua 5.2 Reference Manual", section 3.3.4 "Control Structures",
+L<http://www.lua.org/manual/5.2/manual.html#3.3.4>.
+
+See "Programming in Lua", section 4.3 "Control Structures".
+
+=cut
+
+]]
+
+print("1..6")
+
+if true then
+    print("ok 1")
+else
+    print("not ok 1")
+end
+
+if not true then
+    print("not ok 2")
+else
+    print("ok 2")
+end
+
+a = 12
+b = 34
+if a < b then
+    print("ok 3")
+else
+    print("not ok 3")
+end
+
+a = 0
+b = 4
+if a < b then
+    print("ok 4")
+elseif a == b then
+    print("not ok 4")
+else
+    print("not ok 4")
+end
+
+a = 5
+b = 5
+if a < b then
+    print("not ok 5")
+elseif a == b then
+    print("ok 5")
+else
+    print("not ok 5")
+end
+
+a = 10
+b = 6
+if a < b then
+    print("not ok 6")
+elseif a == b then
+    print("not ok 6")
+else
+    print("ok 6")
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 67 - 0
src/MoonSharp.Interpreter.Tests/TestMore/002-table.t

@@ -0,0 +1,67 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua table
+
+=head2 Synopsis
+
+    % prove 002-table.t
+
+=head2 Description
+
+See "Programming in Lua", section 2.5 "Tables".
+
+=cut
+
+]]
+
+print("1..8")
+
+a = {"ok 1", "ok 2", "ok 3"}
+print(a[1])
+i = 2
+print(a[i])
+print(a[i+1])
+if #a == 3 then
+    print("ok 4 - len")
+else
+    print("not ok 4")
+end
+if a[7] == nil then
+    print("ok 5")
+else
+    print("not ok 5")
+end
+
+t = {a=10, b=100}
+if t['a'] == 10 then
+    print("ok 6")
+else
+    print("not ok 6")
+end
+if t.b == 100 then
+    print("ok 7")
+else
+    print("not ok 7")
+end
+if t.z == nil then
+    print("ok 8")
+else
+    print("not ok 8")
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 80 - 0
src/MoonSharp.Interpreter.Tests/TestMore/011-while.t

@@ -0,0 +1,80 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2010, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua while statement
+
+=head2 Synopsis
+
+    % prove 011-while.t
+
+=head2 Description
+
+See "Lua 5.2 Reference Manual", section 3.3.4 "Control Structures",
+L<http://www.lua.org/manual/5.2/manual.html#3.3.4>.
+
+See "Programming in Lua", section 4.3 "Control Structures".
+
+=cut
+
+]]
+
+print("1..11")
+
+a = {}
+local i = 1
+while a[i] do
+    i = i + 1
+end
+if i == 1 then
+    print("ok 1 - while empty")
+else
+    print("not ok 1 - " .. i)
+end
+
+a = {"ok 2 - while ", "ok 3", "ok 4"}
+local i = 1
+while a[i] do
+    print(a[i])
+    i = i + 1
+end
+
+a = {"ok 5 - with break", "ok 6", "stop", "more"}
+local i = 1
+while a[i] do
+    if a[i] == 'stop' then break end
+    print(a[i])
+    i = i + 1
+end
+if i == 3 then
+    print("ok 7 - break")
+else
+    print("not ok 7 - " .. i)
+end
+
+x = 3
+local i = 1
+while i<=x do
+    print("ok " .. 7+i)
+    i = i + 1
+end
+if i == 4 then
+    print("ok 11")
+else
+    print("not ok 11 - " .. i)
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 78 - 0
src/MoonSharp.Interpreter.Tests/TestMore/012-repeat.t

@@ -0,0 +1,78 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2010, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua repeat statement
+
+=head2 Synopsis
+
+    % prove 012-repeat.t
+
+=head2 Description
+
+See "Lua 5.2 Reference Manual", section 3.3.4 "Control Structures",
+L<http://www.lua.org/manual/5.2/manual.html#3.3.4>.
+
+See "Programming in Lua", section 4.3 "Control Structures".
+
+=cut
+
+]]
+
+print("1..8")
+
+a = {"ok 1 - repeat", "ok 2", "ok 3"}
+local i = 0
+repeat
+    i = i + 1
+    if a[i] then
+        print(a[i])
+    end
+until not a[i]
+if i == 4 then
+    print("ok 4")
+else
+    print("not ok 4 - " .. i)
+end
+
+a = {"ok 5 - with break", "ok 6", 'stop', 'more'}
+local i = 0
+repeat
+    i = i + 1
+    if a[i] == 'stop' then break end
+    print(a[i])
+until not a[i]
+if a[i] == 'stop' then
+    print("ok 7 - break")
+else
+    print("not ok 7 - " .. a[i])
+end
+
+function f () return true end
+
+local i = 1
+repeat
+    local v = f()
+    if i == 1 then
+        print("ok 8 - scope")
+    else
+        print("not ok")
+        break
+    end
+    i = i + 1
+until v
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 136 - 0
src/MoonSharp.Interpreter.Tests/TestMore/014-fornum.t

@@ -0,0 +1,136 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2010, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua for statement
+
+=head2 Synopsis
+
+    % prove 014-fornum.t
+
+=head2 Description
+
+See "Lua 5.2 Reference Manual", section 3.3.5 "For Statement",
+L<http://www.lua.org/manual/5.2/manual.html#3.3.5>.
+
+See "Programming in Lua", section 4.3 "Control Structures".
+
+=cut
+
+--]]
+
+print("1..36")
+
+for i = 1, 10, 2 do
+    print("ok " .. (i+1)/2 .. " - for 1, 10, 2")
+end
+
+for i = 1, 10, 2 do
+    function f ()
+        print("ok " .. (i+11)/2 .. " - for 1, 10, 2 lex")
+    end
+    f()
+end
+
+function f (i)
+    print("ok " .. (i+21)/2 .. " - for 1, 10, 2 !lex")
+end
+for i = 1, 10, 2 do
+    f(i)
+end
+
+for i = 3, 5 do
+    print("ok " .. 13+i .. " - for 3, 5")
+    i = i + 1
+end
+
+for i = 5, 1, -1 do
+    print("ok " .. 24-i .. " - for 5, 1, -1")
+end
+
+for i = 5, 5 do
+    print("ok " .. 19+i .. " - for 5, 5")
+end
+
+for i = 5, 5, -1 do
+    print("ok " .. 20+i .. " - for 5, 5, -1")
+end
+
+v = false
+for i = 5, 3 do
+    v = true
+end
+if v then
+    print("not ok 26 - for 5, 3")
+else
+    print("ok 26 - for 5, 3")
+end
+
+v = false
+for i = 5, 7, -1 do
+    v = true
+end
+if v then
+    print("not ok 27 - for 5, 7, -1")
+else
+    print("ok 27 - for 5, 7, -1")
+end
+
+v = false
+for i = 5, 7, 0 do
+    v = true
+    break -- avoid infinite loop with luajit
+end
+if arg[-1] == 'luajit' then
+    print("not ok 28 - for 5, 7, 0 # TODO # LuaJIT intentional.")
+elseif v then
+    print("not ok 28 - for 5, 7, 0")
+else
+    print("ok 28 - for 5, 7, 0")
+end
+
+v = nil
+for i = 1, 10, 2 do
+    if i > 4 then break end
+    print("ok " .. (i+57)/2 .. " - for break")
+    v = i
+end
+if v == 3 then
+    print("ok 31 - break")
+else
+    print("not ok 31 - " .. v)
+end
+
+local function first() return 1 end
+local function limit() return 8 end
+local function step()  return 2 end
+for i = first(), limit(), step() do
+    print("ok " .. (i+63)/2 .. " - with functions")
+end
+
+local a = {}
+for i = 1, 10 do
+    a[i] = function () return i end
+end
+local v = a[5]()
+if v == 5 then
+    print("ok 36 - for & upval")
+else
+    print("not ok 36 - for & upval")
+    print("#", v)
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 99 - 0
src/MoonSharp.Interpreter.Tests/TestMore/015-forlist.t

@@ -0,0 +1,99 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2010, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua for statement
+
+=head2 Synopsis
+
+    % prove 015-forlist.t
+
+=head2 Description
+
+See "Lua 5.2 Reference Manual", section 3.3.5 "For Statement",
+L<http://www.lua.org/manual/5.2/manual.html#3.3.5>.
+
+See "Programming in Lua", section 4.3 "Control Structures".
+
+=cut
+
+--]]
+
+print("1..18")
+
+a = {"ok 1 - for ipairs", "ok 2 - for ipairs", "ok 3 - for ipairs"}
+for _, v in ipairs(a) do
+    print(v)
+end
+for i, v in ipairs(a) do
+    print("ok " .. 3+i .. " - for ipairs")
+end
+
+r = false
+t = {a=10, b=100}
+for i, v in ipairs(t) do
+    print(i, v)
+    r = true
+end
+if r then
+    print("not ok 7 - for ipairs (hash)")
+else
+    print("ok 7 - for ipairs (hash)")
+end
+
+for k in pairs(a) do
+    print("ok " .. 7+k .. " - for pairs")
+end
+
+local i = 1
+for k in pairs(t) do
+    if k == 'a' or k == 'b' then
+        print("ok " .. 10+i .. " - for pairs (hash)")
+    else
+        print("not ok " .. 10+i .. " - " .. k)
+    end
+    i = i + 1
+end
+
+a = {"ok 13 - for break", "ok 14 - for break", "stop", "more"}
+local i
+for _, v in ipairs(a) do
+    if v == "stop" then break end
+    print(v)
+    i = _
+end
+if i == 2 then
+    print("ok 15 - break")
+else
+    print("not ok 15 - " .. i)
+end
+
+local a = {"ok 16 - for & upval", "ok 17 - for & upval", "ok 18 - for & upval"}
+local b = {}
+for i, v in ipairs(a) do
+    b[i] = function () return v end
+end
+for i, v in ipairs(a) do
+    local r = b[i]()
+    if r == a[i] then
+        print(r)
+    else
+        print("not " .. a[i])
+        print("#", r)
+    end
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 120 - 0
src/MoonSharp.Interpreter.Tests/TestMore/101-boolean.t

@@ -0,0 +1,120 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1  Lua boolean & coercion
+
+=head2 Synopsis
+
+    % prove 101-boolean.t
+
+=head2 Description
+
+=cut
+
+]]
+
+require 'Test.More'
+
+plan(24)
+
+error_like(function () return -true end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a %w+ value",
+           "-true")
+
+error_like(function () return #true end,
+           "^[^:]+:%d+: attempt to get length of a boolean value",
+           "#true")
+
+is(not false, true, "not false")
+
+error_like(function () return true + 10 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "true + 10")
+
+error_like(function () return true - 2 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "true - 2")
+
+error_like(function () return true * 3.14 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "true * 3.14")
+
+error_like(function () return true / -7 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "true / -7")
+
+error_like(function () return true % 4 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "true % 4")
+
+error_like(function () return true ^ 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "true ^ 3")
+
+error_like(function () return true .. 'end' end,
+           "^[^:]+:%d+: attempt to concatenate a boolean value",
+           "true .. 'end'")
+
+is(true == true, true, "true == true")
+
+is(true ~= false, true, "true ~= false")
+
+is(true == 1, false, "true == 1")
+
+is(true ~= 1, true, "true ~= 1")
+
+error_like(function () return true < false end,
+           "^[^:]+:%d+: attempt to compare two boolean values",
+           "true < false")
+
+error_like(function () return true <= false end,
+           "^[^:]+:%d+: attempt to compare two boolean values",
+           "true <= false")
+
+error_like(function () return true > false end,
+           "^[^:]+:%d+: attempt to compare two boolean values",
+           "true > false")
+
+error_like(function () return true >= false end,
+           "^[^:]+:%d+: attempt to compare two boolean values",
+           "true >= false")
+
+error_like(function () return true < 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "true < 0")
+
+error_like(function () return true <= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "true <= 0")
+
+error_like(function () return true > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "true > 0")
+
+error_like(function () return true >= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "true >= 0")
+
+error_like(function () a = true; b = a[1]; end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+error_like(function () a = true; a[1] = 1; end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 199 - 0
src/MoonSharp.Interpreter.Tests/TestMore/102-function.t

@@ -0,0 +1,199 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2011, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua function & coercion
+
+=head2 Synopsis
+
+    % prove 102-function.t
+
+=head2 Description
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(51)
+
+f = function () return 1 end
+
+error_like(function () return -f end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "-f")
+
+error_like(function () f = print; return -f end,
+           "^[^:]+:%d+: attempt to perform arithmetic on")
+
+error_like(function () return #f end,
+           "^[^:]+:%d+: attempt to get length of",
+           "#f")
+
+error_like(function () f = print; return #f end,
+           "^[^:]+:%d+: attempt to get length of")
+
+is(not f, false, "not f")
+
+is(not print, false)
+
+error_like(function () return f + 10 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "f + 10")
+
+error_like(function () f = print; return f + 10 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on")
+
+error_like(function () return f - 2 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "f - 2")
+
+error_like(function () f = print; return f - 2 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on")
+
+error_like(function () return f * 3.14 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "f * 3.14")
+
+error_like(function () f = print; return f * 3.14 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on")
+
+error_like(function () return f / -7 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "f / -7")
+
+error_like(function () f = print; return f / -7 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on")
+
+error_like(function () return f % 4 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "f % 4")
+
+error_like(function () f = print; return f % 4 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on")
+
+error_like(function () return f ^ 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "f ^ 3")
+
+error_like(function () f = print; return f ^ 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on")
+
+error_like(function () return f .. 'end' end,
+           "^[^:]+:%d+: attempt to concatenate",
+           "f .. 'end'")
+
+error_like(function () f = print; return f .. 'end' end,
+           "^[^:]+:%d+: attempt to concatenate")
+
+g = f
+is(f == g, true, "f == f")
+
+g = print
+is(g == print, true)
+
+g = function () return 2 end
+is(f ~= g, true, "f ~= g")
+h = type
+is(f ~= h, true)
+
+is(print ~= g, true)
+is(print ~= h, true)
+
+is(f == 1, false, "f == 1")
+
+is(print == 1, false)
+
+is(f ~= 1, true, "f ~= 1")
+
+is(print ~= 1, true)
+
+error_like(function () return f < g end,
+           "^[^:]+:%d+: attempt to compare two function values",
+           "f < g")
+
+error_like(function () f = print; g = type; return f < g end,
+           "^[^:]+:%d+: attempt to compare two function values")
+
+error_like(function () return f <= g end,
+           "^[^:]+:%d+: attempt to compare two function values",
+           "f <= g")
+
+error_like(function () f = print; g = type; return f <= g end,
+           "^[^:]+:%d+: attempt to compare two function values")
+
+error_like(function () return f > g end,
+           "^[^:]+:%d+: attempt to compare two function values",
+           "f > g")
+
+error_like(function () f = print; g = type; return f > g end,
+           "^[^:]+:%d+: attempt to compare two function values")
+
+error_like(function () return f >= g end,
+           "^[^:]+:%d+: attempt to compare two function values",
+           "f >= g")
+
+error_like(function () f = print; g = type; return f >= g end,
+           "^[^:]+:%d+: attempt to compare two function values")
+
+error_like(function () return f < 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "f < 0")
+
+error_like(function () f = print; return f < 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+")
+
+error_like(function () return f <= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "f <= 0")
+
+error_like(function () f = print; return f <= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+")
+
+error_like(function () return f > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "f > 0")
+
+error_like(function () f = print; return f > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+")
+
+error_like(function () return f > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "f >= 0")
+
+error_like(function () f = print; return f >= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+")
+
+error_like(function () a = f; b = a[1]; end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+error_like(function () a = print; b = a[1]; end,
+           "^[^:]+:%d+: attempt to index")
+
+error_like(function () a = f; a[1] = 1; end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+error_like(function () a = print; a[1] = 1; end,
+           "^[^:]+:%d+: attempt to index")
+
+t = {}
+t[print] = true
+ok(t[print])
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 120 - 0
src/MoonSharp.Interpreter.Tests/TestMore/103-nil.t

@@ -0,0 +1,120 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua nil & coercion
+
+=head2 Synopsis
+
+    % prove 103-nil.t
+
+=head2 Description
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(24)
+
+error_like(function () return -nil end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a nil value",
+           "-nil")
+
+error_like(function () return #nil end,
+           "^[^:]+:%d+: attempt to get length of a nil value",
+           "#nil")
+
+is(not nil, true, "not nil")
+
+error_like(function () return nil + 10 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a nil value",
+           "nil + 10")
+
+error_like(function () return nil - 2 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a nil value",
+           "nil - 2")
+
+error_like(function () return nil * 3.14 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a nil value",
+           "nil * 3.14")
+
+error_like(function () return nil / -7 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a nil value",
+           "nil / -7")
+
+error_like(function () return nil % 4 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a nil value",
+           "nil % 4")
+
+error_like(function () return nil ^ 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a nil value",
+           "nil ^ 3")
+
+error_like(function () return nil .. 'end' end,
+           "^[^:]+:%d+: attempt to concatenate a nil value",
+           "nil .. 'end'")
+
+is(nil == nil, true, "nil == nil")
+
+is(nil ~= nil, false, "nil ~= nil")
+
+is(nil == 1, false, "nil == 1")
+
+is(nil ~= 1, true, "nil ~= 1")
+
+error_like(function () return nil < nil end,
+           "^[^:]+:%d+: attempt to compare two nil values",
+           "nil < nil")
+
+error_like(function () return nil <= nil end,
+           "^[^:]+:%d+: attempt to compare two nil values",
+           "nil <= nil")
+
+error_like(function () return nil > nil end,
+           "^[^:]+:%d+: attempt to compare two nil values",
+           "nil > nil")
+
+error_like(function () return nil > nil end,
+           "^[^:]+:%d+: attempt to compare two nil values",
+           "nil >= nil")
+
+error_like(function () return nil < 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "nil < 0")
+
+error_like(function () return nil <= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "nil <= 0")
+
+error_like(function () return nil > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "nil > 0")
+
+error_like(function () return nil >= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "nil >= 0")
+
+error_like(function () a = nil; b = a[1]; end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+error_like(function () a = nil; a[1] = 1; end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 190 - 0
src/MoonSharp.Interpreter.Tests/TestMore/104-number.t

@@ -0,0 +1,190 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua number & coercion
+
+=head2 Synopsis
+
+    % prove 104-number.t
+
+=head2 Description
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(54)
+
+is(-1, -(1), "-1")
+
+error_like(function () return #1 end,
+           "^[^:]+:%d+: attempt to get length of a number value",
+           "#1")
+
+is(not 1, false, "not 1")
+
+is(10 + 2, 12, "10 + 2")
+
+is(2 - 10, -8, "2 - 10")
+
+is(3.14 * 1, 3.14, "3.14 * 1")
+
+is(-7 / 0.5, -14, "-7 / 0.5")
+
+type_ok(1 / 0, 'number', "1 / 0")
+
+is(-25 % 3, 2, "-25 % 3")
+
+type_ok(1 % 0, 'number', "1 % 0")
+
+error_like(function () return 10 + true end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "10 + true")
+
+error_like(function () return 2 - nil end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a nil value",
+           "2 - nil")
+
+error_like(function () return 3.14 * false end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "3.14 * false")
+
+error_like(function () return -7 / {} end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a table value",
+           "-7 / {}")
+
+error_like(function () return 3 ^ true end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "3 ^ true")
+
+error_like(function () return -25 % false end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "-25 % false")
+
+error_like(function () return 10 + 'text' end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a string value",
+           "10 + 'text'")
+
+error_like(function () return 2 - 'text' end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a string value",
+           "2 - 'text'")
+
+error_like(function () return 3.14 * 'text' end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a string value",
+           "3.14 * 'text'")
+
+error_like(function () return -7 / 'text' end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a string value",
+           "-7 / 'text'")
+
+error_like(function () return 25 % 'text' end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a string value",
+           "25 % 'text'")
+
+error_like(function () return 3 ^ 'text' end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a string value",
+           "3 ^ 'text'")
+
+is(10 + '2', 12, "10 + '2'")
+
+is(2 - '10', -8, "2 - '10'")
+
+is(3.14 * '1', 3.14, "3.14 * '1'")
+
+is(-7 / '0.5', -14, "-7 / '0.5'")
+
+is(-25 % '3', 2, "-25 % '3'")
+
+is(3 ^ '3', 27, "3 ^ '3'")
+
+is(1 .. 'end', '1end', "1 .. 'end'")
+
+is(1 .. 2, '12', "1 .. 2")
+
+error_like(function () return 1 .. true end,
+           "^[^:]+:%d+: attempt to concatenate a %w+ value",
+           "1 .. true")
+
+is(1.0 == 1, true, "1.0 == 1")
+
+is(1 ~= 2, true, "1 ~= 2")
+
+is(1 == true, false, "1 == true")
+
+is(1 ~= nil, true, "1 ~= nil")
+
+is(1 == '1', false, "1 == '1'")
+
+is(1 ~= '1', true, "1 ~= '1'")
+
+is(1 < 0, false, "1 < 0")
+
+is(1 <= 0, false, "1 <= 0")
+
+is(1 > 0, true, "1 > 0")
+
+is(1 >= 0, true, "1 >= 0")
+
+error_like(function () return 1 < false end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "1 < false")
+
+error_like(function () return 1 <= nil end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "1 <= nil")
+
+error_like(function () return 1 > true end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "1 > true")
+
+error_like(function () return 1 >= {} end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "1 >= {}")
+
+error_like(function () return 1 < '0' end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "1 < '0'")
+
+error_like(function () return 1 <= '0' end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "1 <= '0'")
+
+error_like(function () return 1 > '0' end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "1 > '0'")
+
+error_like(function () return 1 >= '0' end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "1 >= '0'")
+
+is(tostring(1000000000), '1000000000', "number 1000000000")
+
+is(tostring(1e9), '1000000000', "number 1e9")
+
+is(tostring(1.0e+9), '1000000000', "number 1.0e+9")
+
+error_like(function () a= 3.14; b = a[1]; end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+error_like(function () a = 3.14; a[1] = 1; end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 183 - 0
src/MoonSharp.Interpreter.Tests/TestMore/105-string.t

@@ -0,0 +1,183 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2011, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua string & coercion
+
+=head2 Synopsis
+
+    % prove 105-string.t
+
+=head2 Description
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(51)
+
+is(- '1', -1, "-'1'")
+
+error_like(function () return - 'text' end,
+           "^[^:]+:%d+: attempt to perform arithmetic on .- string value",
+           "-'text'")
+
+is(# 'text', 4, "#'text'")
+
+is(not 'text', false, "not 'text'")
+
+is('10' + 2, 12, "'10' + 2")
+
+is('2' - 10, -8, "'2' - 10")
+
+is('3.14' * 1, 3.14, "'3.14' * 1")
+
+is('-7' / 0.5, -14, "'-7' / 0.5")
+
+is('-25' % 3, 2, "'-25' % 3")
+
+is('3' ^ 3, 27, "'3' ^ 3")
+
+error_like(function () return '10' + true end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "'10' + true")
+
+error_like(function () return '2' - nil end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a nil value",
+           "'2' - nil")
+
+error_like(function () return '3.14' * false end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "'3.14' * false")
+
+error_like(function () return '-7' / {} end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a table value",
+           "'-7' / {}")
+
+error_like(function () return '-25' % false end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "'-25' % false")
+
+error_like(function () return '3' ^ true end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "'3' ^ true")
+
+error_like(function () return '10' + 'text' end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a string value",
+           "'10' + 'text'")
+
+error_like(function () return '2' - 'text' end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a string value",
+           "'2' - 'text'")
+
+error_like(function () return '3.14' * 'text' end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a string value",
+           "'3.14' * 'text'")
+
+error_like(function () return '-7' / 'text' end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a string value",
+           "'-7' / 'text'")
+
+error_like(function () return '-25' % 'text' end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a string value",
+           "'-25' % 'text'")
+
+error_like(function () return '3' ^ 'text' end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a string value",
+           "'3' ^ 'text'")
+
+is('10' + '2', 12, "'10' + '2'")
+
+is('2' - '10', -8, "'2' - '10'")
+
+is('3.14' * '1', 3.14, "'3.14' * '1'")
+
+is('-7' / '0.5', -14, "'-7' / '0.5'")
+
+is('-25' % '3', 2, "'-25' % '3'")
+
+is('3' ^ '3', 27, "'3' ^ '3'")
+
+is('1' .. 'end', '1end', "'1' .. 'end'")
+
+is('1' .. 2, '12', "'1' .. 2")
+
+error_like(function () return '1' .. true end,
+           "^[^:]+:%d+: attempt to concatenate a boolean value",
+           "'1' .. true")
+
+is('1.0' == '1', false, "'1.0' == '1'")
+
+is('1' ~= '2', true, "'1' ~= '2'")
+
+is('1' == true, false, "'1' == true")
+
+is('1' ~= nil, true, "'1' ~= nil")
+
+is('1' == 1, false, "'1' == 1")
+
+is('1' ~= 1, true, "'1' ~= 1")
+
+is('1' < '0', false, "'1' < '0'")
+
+is('1' <= '0', false, "'1' <= '0'")
+
+is('1' > '0', true, "'1' > '0'")
+
+is('1' >= '0', true, "'1' >= '0'")
+
+error_like(function () return '1' < false end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "'1' < false")
+
+error_like(function () return '1' <= nil end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "'1' <= nil")
+
+error_like(function () return '1' > true end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "'1' > true")
+
+error_like(function () return '1' >= {} end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "'1' >= {}")
+
+error_like(function () return '1' < 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "'1' < 0")
+
+error_like(function () return '1' <= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "'1' <= 0")
+
+error_like(function () return '1' > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "'1' > 0")
+
+error_like(function () return '1' > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "'1' >== 0")
+
+a = 'text'
+is(a[1], nil, "index")
+
+error_like(function () a = 'text'; a[1] = 1; end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 125 - 0
src/MoonSharp.Interpreter.Tests/TestMore/106-table.t

@@ -0,0 +1,125 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2011, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua table & coercion
+
+=head2 Synopsis
+
+    % prove 106-table.t
+
+=head2 Description
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(28)
+
+error_like(function () return -{} end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "-{}")
+
+is(# {}, 0, "#{}")
+is(# {4,5,6}, 3)
+
+is(not {}, false, "not {}")
+
+error_like(function () return {} + 10 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "{} + 10")
+
+error_like(function () return {} - 2 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "{} - 2")
+
+error_like(function () return {} * 3.14 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "{} * 3.14")
+
+error_like(function () return {} / 7 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "{} / 7")
+
+error_like(function () return {} % 4 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "{} % 4")
+
+error_like(function () return {} ^ 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "{} ^ 3")
+
+error_like(function () return {} .. 'end' end,
+           "^[^:]+:%d+: attempt to concatenate",
+           "{} .. 'end'")
+
+is({} == {}, false, "{} == {}")
+
+t1 = {}
+t2 = {}
+is(t1 == t1, true, "t1 == t1")
+is(t1 == t2, false, "t1 == t2")
+is(t1 ~= t2, true, "t1 ~= t2")
+
+is({} == 1, false, "{} == 1")
+
+is({} ~= 1, true, "{} ~= 1")
+
+error_like(function () return t1 < t2 end,
+           "^[^:]+:%d+: attempt to compare two table values",
+           "t1 < t2")
+
+error_like(function () return t1 <= t2 end,
+           "^[^:]+:%d+: attempt to compare two table values",
+           "t1 <= t2")
+
+error_like(function () return t1 > t2 end,
+           "^[^:]+:%d+: attempt to compare two table values",
+           "t1 > t2")
+
+error_like(function () return t1 >= t2 end,
+           "^[^:]+:%d+: attempt to compare two table values",
+           "t1 >= t2")
+
+error_like(function () return {} < 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "{} < 0")
+
+error_like(function () return {} <= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "{} <= 0")
+
+error_like(function () return {} > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "{} > 0")
+
+error_like(function () return {} >= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "{} >= 0")
+
+t = {}
+is( t[1], nil, "index" )
+t[1] = 42
+is( t[1], 42, "index" )
+
+error_like(function () t = {}; t[nil] = 42 end,
+           "^[^:]+:%d+: table index is nil",
+           "table index is nil")
+
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 128 - 0
src/MoonSharp.Interpreter.Tests/TestMore/107-thread.t

@@ -0,0 +1,128 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2011, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua thread & coercion
+
+=head2 Synopsis
+
+    % prove 107-thread.t
+
+=head2 Description
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(25)
+
+co = coroutine.create(function () return 1 end)
+
+error_like(function () return -co end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "-co")
+
+error_like(function () return #co end,
+           "^[^:]+:%d+: attempt to get length of",
+           "#co")
+
+is(not co, false, "not co")
+
+error_like(function () return co + 10 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "co + 10")
+
+error_like(function () return co - 2 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "co - 2")
+
+error_like(function () return co * 3.14 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "co * 3.14")
+
+error_like(function () return co / 7 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "co / 7")
+
+error_like(function () return co % 4 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "co % 4")
+
+error_like(function () return co ^ 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "co ^ 3")
+
+error_like(function () return co .. 'end' end,
+           "^[^:]+:%d+: attempt to concatenate",
+           "co .. 'end'")
+
+is(co == co, true, "co == co")
+
+co1 = coroutine.create(function () return 1 end)
+co2 = coroutine.create(function () return 2 end)
+is(co1 ~= co2, true, "co1 ~= co2")
+
+is(co == 1, false, "co == 1")
+
+is(co ~= 1, true, "co ~= 1")
+
+error_like(function () return co1 < co2 end,
+           "^[^:]+:%d+: attempt to compare two thread values",
+           "co1 < co2")
+
+error_like(function () return co1 <= co2 end,
+           "^[^:]+:%d+: attempt to compare two thread values",
+           "co1 <= co2")
+
+error_like(function () return co1 > co2 end,
+           "^[^:]+:%d+: attempt to compare two thread values",
+           "co1 > co2")
+
+error_like(function () return co1 >= co2 end,
+           "^[^:]+:%d+: attempt to compare two thread values",
+           "co1 >= co2")
+
+error_like(function () return co < 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "co < 0")
+
+error_like(function () return co <= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "co <= 0")
+
+error_like(function () return co > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "co > 0")
+
+error_like(function () return co > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "co >= 0")
+
+error_like(function () a = co[1] end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+error_like(function () co[1] = 1 end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+t = {}
+t[co] = true
+ok(t[co])
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 125 - 0
src/MoonSharp.Interpreter.Tests/TestMore/108-userdata.t

@@ -0,0 +1,125 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2011, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua userdata & coercion
+
+=head2 Synopsis
+
+    % prove 108-userdata.t
+
+=head2 Description
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(25)
+
+u = io.stdin
+
+error_like(function () return -u end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "-u")
+
+error_like(function () return #u end,
+           "^[^:]+:%d+: attempt to get length of",
+           "#u")
+
+is(not u, false, "not u")
+
+error_like(function () return u + 10 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "u + 10")
+
+error_like(function () return u - 2 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "u - 2")
+
+error_like(function () return u * 3.14 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "u * 3.14")
+
+error_like(function () return u / 7 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "u / 7")
+
+error_like(function () return u % 4 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "u % 4")
+
+error_like(function () return u ^ 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "u ^ 3")
+
+error_like(function () return u .. 'end' end,
+           "^[^:]+:%d+: attempt to concatenate",
+           "u .. 'end'")
+
+is(u == u, true, "u == u")
+
+v = io.stdout
+is(u ~= v, true, "u ~= v")
+
+is(u == 1, false, "u == 1")
+
+is(u ~= 1, true, "u ~= 1")
+
+error_like(function () return u < v end,
+           "^[^:]+:%d+: attempt to compare two userdata values",
+           "u < v")
+
+error_like(function () return u <= v end,
+           "^[^:]+:%d+: attempt to compare two userdata values",
+           "u <= v")
+
+error_like(function () return u > v end,
+           "^[^:]+:%d+: attempt to compare two userdata values",
+           "u > v")
+
+error_like(function () return u >= v end,
+           "^[^:]+:%d+: attempt to compare two userdata values",
+           "u >= v")
+
+error_like(function () return u < 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "u < 0")
+
+error_like(function () return u <= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "u <= 0")
+
+error_like(function () return u > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "u > 0")
+
+error_like(function () return u > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "u >= 0")
+
+is(u[1], nil, "index")
+
+error_like(function () u[1] = 1 end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+t = {}
+t[u] = true
+ok(t[u])
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 104 - 0
src/MoonSharp.Interpreter.Tests/TestMore/200-examples.t

@@ -0,0 +1,104 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2011, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 some Lua code examples
+
+=head2 Synopsis
+
+    % prove 200-examples.t
+
+=head2 Description
+
+First tests in order to check infrastructure.
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(5)
+
+function factorial (n)
+    if n == 0 then
+        return 1
+    else
+        return n * factorial(n-1)
+    end
+end
+is(factorial(7), 5040, "factorial (recursive)")
+
+local function local_factorial (n)
+    if n == 0 then
+        return 1
+    else
+        return n * local_factorial(n-1)
+    end
+end
+is(local_factorial(7), 5040, "factorial (recursive)")
+
+function loop_factorial (n)
+    local a = 1
+    for i = 1, n, 1 do
+        a = a*i
+    end
+    return a
+end
+is(loop_factorial(7), 5040, "factorial (loop)")
+
+function iter_factorial (n)
+    local function iter (product, counter)
+        if counter > n then
+            return product
+        else
+            return iter(counter*product, counter+1)
+        end
+    end
+    return iter(1, 1)
+end
+is(iter_factorial(7), 5040, "factorial (iter)")
+
+--[[
+
+  Knuth's "man or boy" test.
+  See http://en.wikipedia.org/wiki/Man_or_boy_test
+
+]]
+
+local function A (k, x1, x2, x3, x4, x5)
+    local function B ()
+        k = k - 1
+        return A(k, B, x1, x2, x3, x4)
+    end
+    if k <= 0 then
+        return x4() + x5()
+    else
+        return B()
+    end
+end
+
+is(A(10,
+        function () return 1 end,
+        function () return -1 end,
+        function () return -1 end,
+        function () return 1 end,
+        function () return 0 end),
+   -67,
+   "man or boy"
+)
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 123 - 0
src/MoonSharp.Interpreter.Tests/TestMore/201-assign.t

@@ -0,0 +1,123 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2010, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua assignment
+
+=head2 Synopsis
+
+    % prove 201-assign.t
+
+=head2 Description
+
+See "Lua 5.2 Reference Manual", section 3.3.3 "Assignment",
+L<http://www.lua.org/manual/5.2/manual.html#3.3.3>.
+
+See "Programming in Lua", section 4.1 "Assignment".
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(38)
+
+is(b, nil, "global variable")
+b = 10
+is(b, 10)
+if arg[-1] == 'luajit' then
+    skip("LuaJIT intentional. _ENV.", 3)
+else
+    is(_ENV.b, 10, "_ENV")
+    is(_G, _ENV, "_G")
+    error_like([[ _ENV = nil; b = 20 ]],
+               "^[^:]+:%d+: attempt to index upvalue '_ENV' %(a nil value%)")
+end
+b = nil
+is(b, nil)
+
+a = {}
+i = 3
+i, a[i] = i+1, 20
+is(i, 4, "check eval")
+is(a[3], 20)
+
+x = 1.
+y = 2.
+x, y = y, x -- swap
+is(x, 2, "check swap")
+is(y, 1)
+
+a, b, c = 0, 1
+is(a, 0, "check padding")
+is(b, 1)
+is(c, nil)
+a, b = a+1, b+1, a+b
+is(a, 1)
+is(b, 2)
+a, b, c = 0
+is(a, 0)
+is(b, nil)
+is(c, nil)
+
+function f() return 1, 2 end
+a, b, c, d = f()
+is(a, 1, "adjust with function")
+is(b, 2)
+is(c, nil)
+is(d, nil)
+
+function f() print('# f') end
+a = 2
+a, b, c = f(), 3
+is(a, nil, "padding with function")
+is(b, 3)
+is(c, nil)
+
+local my_i = 1
+is(my_i, 1, "local variable")
+local my_i = 2
+is(my_i, 2)
+
+local i = 1
+local j = i
+is(i, 1, "local variable")
+is(j, 1)
+j = 2
+is(i, 1)
+is(j, 2)
+
+local function f(x) return 2*x end
+is(f(2), 4, "param & result of function")
+a = 2
+a = f(a)
+is(a, 4)
+local b = 2
+b = f(b)
+is(b, 4)
+
+local n1 = 1
+local n2 = 2
+local n3 = 3
+local n4 = 4
+n1,n2,n3,n4 = n4,n3,n2,n1
+is(n1, 4, "assignment list swap values")
+is(n2, 3)
+is(n3, 2)
+is(n4, 1)
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 111 - 0
src/MoonSharp.Interpreter.Tests/TestMore/202-expr.t

@@ -0,0 +1,111 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2010, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua expression
+
+=head2 Synopsis
+
+    % prove 202-expr.t
+
+=head2 Description
+
+See "Lua 5.2 Reference Manual", section 3.4 "Expressions",
+L<http://www.lua.org/manual/5.2/manual.html#3.4>.
+
+See "Programming in Lua", section 3 "Expressions".
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(39)
+
+x = math.pi
+is(x - x%0.01, 3.14, "modulo")
+
+a = {}; a.x = 1; a.y = 0;
+b = {}; b.x = 1; b.y = 0;
+c = a
+is(a == c, true, "relational op (by reference)")
+is(a ~= b, true)
+
+is('0' == 0, false, "relational op")
+is(2 < 15, true)
+is('2' < '15', false)
+
+error_like(function () return 2 < '15' end,
+           "compare",
+           "relational op")
+
+error_like(function () return '2' < 15 end,
+           "compare",
+           "relational op")
+
+is(4 and 5, 5, "logical op")
+is(nil and 13, nil)
+is(false and 13, false)
+is(4 or 5, 4)
+is(false or 5, 5)
+is(false or 'text', 'text')
+
+is(10 or 20, 10, "logical op")
+is(10 or error(), 10)
+is(nil or 'a', 'a')
+is(nil and 10, nil)
+is(false and error(), false)
+is(false and nil, false)
+is(false or nil, nil)
+is(10 and 20, 20)
+
+is(not nil, true, "logical not")
+is(not false, true)
+is(not 0, false)
+is(not not nil, false)
+is(not 'text', false)
+a = {}
+is(not a, false)
+
+is("Hello " .. "World", "Hello World", "concatenation")
+is(0 .. 1, '01')
+a = "Hello"
+is(a .. " World", "Hello World")
+is(a, "Hello")
+
+is('10' + 1, 11, "coercion")
+is('-5.3' * '2', -10.6)
+is(10 .. 20, '1020')
+is(tostring(10), '10')
+is(10 .. '', '10')
+
+error_like(function () return 'hello' + 1 end,
+           "perform arithmetic",
+           "no coercion")
+
+error_like(function ()
+                local function first() return 1 end
+                local function limit() return end
+                local function step()  return 2 end
+                for i = first(), limit(), step() do
+                    print(i)
+                end
+           end,
+           "^[^:]+:%d+: 'for' limit must be a number",
+           "for tonumber")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 122 - 0
src/MoonSharp.Interpreter.Tests/TestMore/203-lexico.t

@@ -0,0 +1,122 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2010, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Lexicography
+
+=head2 Synopsis
+
+    % prove 203-lexico.t
+
+=head2 Description
+
+See "Lua 5.2 Reference Manual", section 3.1 "Lexical Conventions",
+L<http://www.lua.org/manual/5.2/manual.html#3.1>.
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(40)
+
+is("\65", "A")
+is("\065", "A")
+is("\x41", "A")
+is("\x3d", "=")
+is("\x3D", "=")
+
+is(string.byte("\a"), 7)
+is(string.byte("\b"), 8)
+is(string.byte("\f"), 12)
+is(string.byte("\n"), 10)
+is(string.byte("\r"), 13)
+is(string.byte("\t"), 9)
+is(string.byte("\v"), 11)
+is(string.byte("\\"), 92)
+
+is(string.len("A\0B"), 3)
+
+f, msg = load [[a = "A\300"]]
+like(msg, "^[^:]+:%d+: .- escape .- near")
+
+f, msg = load [[a = "A\xyz"]]
+like(msg, "^[^:]+:%d+: .- near")
+
+f, msg = load [[a = "A\Z"]]
+like(msg, "^[^:]+:%d+: .- escape .- near")
+
+f, msg = load [[a = " unfinished string ]]
+like(msg, "^[^:]+:%d+: unfinished string near")
+
+f, msg = load [[a = " unfinished string
+]]
+like(msg, "^[^:]+:%d+: unfinished string near")
+
+f, msg = load [[a = " unfinished string \
+]]
+like(msg, "^[^:]+:%d+: unfinished string near")
+
+f, msg = load [[a = " unfinished string \]]
+like(msg, "^[^:]+:%d+: unfinished string near")
+
+f, msg = load "a = [[ unfinished long string "
+like(msg, "^[^:]+:%d+: unfinished long string near")
+
+f, msg = load "a = [== invalid long string delimiter "
+like(msg, "^[^:]+:%d+: invalid long string delimiter near")
+
+a = 'alo\n123"'
+is('alo\n123"', a)
+is("alo\n123\"", a)
+is('\97lo\10\04923"', a)
+is([[alo
+123"]], a)
+is([==[
+alo
+123"]==], a)
+is("alo\n\z
+123\"", a)
+
+f, msg = load [[a = " escape \z unauthorized
+new line" ]]
+like(msg, "^[^:]+:%d+: unfinished string near")
+
+is(3.0, 3)
+is(314.16e-2, 3.1416)
+is(0.31416E1, 3.1416)
+is(0xff, 255)
+is(0x56, 86)
+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]]
+like(msg, "^[^:]+:%d+: malformed number near")
+
+--[===[
+--[[
+--[=[
+    nested long comments
+--]=]
+--]]
+--]===]
+
+f, msg = load "  --[[ unfinished long comment "
+like(msg, "^[^:]+:%d+: unfinished long comment near")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 106 - 0
src/MoonSharp.Interpreter.Tests/TestMore/204-grammar.t

@@ -0,0 +1,106 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2010-2012, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Grammar
+
+=head2 Synopsis
+
+    % prove 204-grammar.t
+
+=head2 Description
+
+See "Lua 5.2 Reference Manual", section 9 "The Complete Syntax of Lua",
+L<http://www.lua.org/manual/5.2/manual.html#9>.
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(6)
+
+--[[ empty statement ]]
+f, msg = load [[; a = 1]]
+type_ok(f, 'function', "empty statement")
+
+--[[ orphan break ]]
+f, msg = load [[
+function f()
+    print "before"
+    do
+        print "inner"
+        break
+    end
+    print "after"
+end
+]]
+if arg[-1] == 'luajit' then
+    like(msg, "^[^:]+:%d+: no loop to break", "orphan break")
+else
+    like(msg, "^[^:]+:%d+: <break> at line 5 not inside a loop", "orphan break")
+end
+
+--[[ break anywhere ]]
+lives_ok( [[
+function f()
+    print "before"
+    while true do
+        print "inner"
+        break
+        print "break"
+    end
+    print "after"
+end
+]], "break anywhere")
+
+--[[ goto ]]
+f, msg = load [[
+::label::
+goto unknown
+]]
+if arg[-1] == 'luajit' then
+    like(msg, ":%d+: undefined label 'unknown'", "unknown goto")
+else
+    like(msg, ":%d+: no visible label 'unknown' for <goto> at line %d+", "unknown goto")
+end
+
+f, msg = load [[
+::label::
+goto label
+::label::
+]]
+if arg[-1] == 'luajit' then
+    like(msg, ":%d+: duplicate label 'label'", "duplicate label")
+else
+    like(msg, ":%d+: label 'label' already defined on line %d+", "duplicate label")
+end
+
+f, msg = load [[
+::e::
+goto f
+local x
+::f::
+goto e
+]]
+if arg[-1] == 'luajit' then
+    like(msg, ":%d+: <goto f> jumps into the scope of local 'x'", "bad goto")
+else
+    like(msg, ":%d+: <goto f> at line %d+ jumps into the scope of local 'x'", "bad goto")
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 83 - 0
src/MoonSharp.Interpreter.Tests/TestMore/211-scope.t

@@ -0,0 +1,83 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2010, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua scope
+
+=head2 Synopsis
+
+    % prove 211-scope.t
+
+=head2 Description
+
+See "Lua 5.2 Reference Manual", section 3.5 "Visibility Rules",
+L<http://www.lua.org/manual/5.2/manual.html#3.5>.
+
+See "Programming in Lua", section 4.2 "Local Variables and Blocks".
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(10)
+
+--[[ scope ]]
+x = 10
+do
+    local x = x
+    is(x, 10, "scope")
+    x = x + 1
+    do
+        local x = x + 1
+        is(x, 12)
+    end
+    is(x, 11)
+end
+is(x, 10)
+
+--[[ scope ]]
+x = 10
+local i = 1
+
+while i<=x do
+    local x = i*2
+--    print(x)
+    i = i + 1
+end
+
+if i > 20 then
+    local x
+    x = 20
+    nok("scope")
+else
+    is(x, 10, "scope")
+end
+
+is(x, 10)
+
+--[[ scope ]]
+local a, b = 1, 10
+if a < b then
+    is(a, 1, "scope")
+    local a
+    is(a, nil)
+end
+is(a, 1)
+is(b, 10)
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 268 - 0
src/MoonSharp.Interpreter.Tests/TestMore/212-function.t

@@ -0,0 +1,268 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2010, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua functions
+
+=head2 Synopsis
+
+    % prove 212-function.t
+
+=head2 Description
+
+See "Lua 5.2 Reference Manual", section 3.4.10 "Function Definitions",
+L<http://www.lua.org/manual/5.2/manual.html#3.4.10>.
+
+See "Programming in Lua", section 5 "Functions".
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(63)
+
+--[[ add ]]
+function add (a)
+    local sum = 0
+    for i,v in ipairs(a) do
+        sum = sum + v
+    end
+    return sum
+end
+
+t = { 10, 20, 30, 40 }
+is(add(t), 100, "add")
+
+--[[ f ]]
+function f(a, b) return a or b end
+
+is(f(3), 3, "f")
+is(f(3, 4), 3)
+is(f(3, 4, 5), 3)
+
+--[[ incCount ]]
+count = 0
+
+function incCount (n)
+    n = n or 1
+    count = count + n
+end
+
+is(count, 0, "inCount")
+incCount()
+is(count, 1)
+incCount(2)
+is(count, 3)
+incCount(1)
+is(count, 4)
+
+--[[ maximum ]]
+function maximum (a)
+    local mi = 1                -- maximum index
+    local m = a[mi]             -- maximum value
+    for i,val in ipairs(a) do
+        if val > m then
+            mi = i
+            m = val
+        end
+    end
+    return m, mi
+end
+
+local m, mi = maximum({8,10,23,12,5})
+is(m, 23, "maximum")
+is(mi, 3)
+
+--[[ call by value ]]
+function f (n)
+    n = n - 1
+    return n
+end
+
+a = 12
+is(a, 12, "call by value")
+b = f(a)
+is(b, 11)
+is(a, 12)
+c = f(12)
+is(c, 11)
+is(a, 12)
+
+--[[ call by ref ]]
+function f (t)
+    t[#t+1] = 'end'
+    return t
+end
+
+a = { 'a', 'b', 'c' }
+is(table.concat(a, ','), 'a,b,c', "call by ref")
+b = f(a)
+is(table.concat(b, ','), 'a,b,c,end')
+is(table.concat(a, ','), 'a,b,c,end')
+
+--[[ var args ]]
+local function g(a, b, ...)
+    local arg = {...}
+    is(a, 3, "vararg")
+    is(b, nil)
+    is(#arg, 0)
+    is(arg[1], nil)
+end
+g(3)
+
+local function g(a, b, ...)
+    local arg = {...}
+    is(a, 3)
+    is(b, 4)
+    is(#arg, 0)
+    is(arg[1], nil)
+end
+g(3, 4)
+
+local function g(a, b, ...)
+    local arg = {...}
+    is(a, 3)
+    is(b, 4)
+    is(#arg, 2)
+    is(arg[1], 5)
+    is(arg[2], 8)
+end
+g(3, 4, 5, 8)
+
+--[[ var args ]]
+local function g(a, b, ...)
+    local c, d, e = ...
+    is(a, 3, "var args")
+    is(b, nil)
+    is(c, nil)
+    is(d, nil)
+    is(e, nil)
+end
+g(3)
+
+local function g(a, b, ...)
+    local c, d, e = ...
+    is(a, 3)
+    is(b, 4)
+    is(c, nil)
+    is(d, nil)
+    is(e, nil)
+end
+g(3, 4)
+
+local function g(a, b, ...)
+    local c, d, e = ...
+    is(a, 3)
+    is(b, 4)
+    is(c, 5)
+    is(d, 8)
+    is(e, nil)
+end
+
+--[[ var args ]]
+local function g(a, b, ...)
+    is(#{a, b, ...}, 1, "varargs")
+end
+g(3)
+
+local function g(a, b, ...)
+    is(#{a, b, ...}, 2)
+end
+g(3, 4)
+
+local function g(a, b, ...)
+    is(#{a, b, ...}, 4)
+end
+g(3, 4, 5, 8)
+
+--[[ var args ]]
+function f() return 1, 2 end
+function g() return 'a', f() end
+function h() return f(), 'b' end
+function k() return 'c', (f()) end
+
+x, y = f()
+is(x, 1, "var args")
+is(y, 2)
+x, y, z = g()
+is(x, 'a')
+is(y, 1)
+is(z, 2)
+x, y = h()
+is(x, 1)
+is(y, 'b')
+x, y, z = k()
+is(x, 'c')
+is(y, 1)
+is(z, nil)
+
+
+--[[ invalid var args ]]
+f, msg = load [[
+function f ()
+    print(...)
+end
+]]
+like(msg, "^[^:]+:%d+: cannot use '...' outside a vararg function", "invalid var args")
+
+--[[ tail call ]]
+output = {}
+local function foo (n)
+    output[#output+1] = n
+    if n > 0 then
+        return foo(n -1)
+    end
+    return 'end', 0
+end
+
+eq_array({foo(3)}, {'end', 0}, "tail call")
+eq_array(output, {3, 2, 1, 0})
+
+--[[ no tail call ]]
+output = {}
+local function foo (n)
+    output[#output+1] = n
+    if n > 0 then
+        return (foo(n -1))
+    end
+    return 'end', 0
+end
+
+is(foo(3), 'end', "no tail call")
+eq_array(output, {3, 2, 1, 0})
+
+--[[ no tail call ]]
+output = {}
+local function foo (n)
+    output[#output+1] = n
+    if n > 0 then
+        foo(n -1)
+    end
+end
+
+is(foo(3), nil, "no tail call")
+eq_array(output, {3, 2, 1, 0})
+
+--[[ sub name ]]
+local function f () return 1 end
+is(f(), 1, "sub name")
+
+local function f () return 2 end
+is(f(), 2)
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 98 - 0
src/MoonSharp.Interpreter.Tests/TestMore/213-closure.t

@@ -0,0 +1,98 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2010, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua closures
+
+=head2 Synopsis
+
+    % prove 213-closure.t
+
+=head2 Description
+
+See "Lua 5.2 Reference Manual", section 3.5 "Visibility Rules",
+L<http://www.lua.org/manual/5.2/manual.html#3.5>.
+
+See "Programming in Lua", section 6.1 "Closures".
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(15)
+
+--[[ inc ]]
+local counter = 0
+
+function inc (x)
+    counter = counter + x
+    return counter
+end
+
+is(inc(1), 1, "inc")
+is(inc(2), 3)
+
+--[[ newCounter ]]
+function newCounter ()
+    local i = 0
+    return function ()  -- anonymous function
+               i = i + 1
+               return i
+           end
+end
+
+c1 = newCounter()
+is(c1(), 1, "newCounter")
+is(c1(), 2)
+
+c2 = newCounter()
+is(c2(), 1)
+is(c1(), 3)
+is(c2(), 2)
+
+--[[
+The loop creates ten closures (that is, ten instances of the anonymous
+function). Each of these closures uses a different y variable, while all
+of them share the same x.
+]]
+a = {}
+local x = 20
+for i=1,10 do
+    local y = 0
+    a[i] = function () y=y+1; return x+y end
+end
+
+is(a[1](), 21, "ten closures")
+is(a[1](), 22)
+is(a[2](), 21)
+
+
+--[[ add ]]
+function add(x)
+    return function (y) return (x + y) end
+end
+
+f = add(2)
+type_ok(f, 'function', "add")
+is(f(10), 12)
+g = add(5)
+is(g(1), 6)
+is(g(10), 15)
+is(f(1), 3)
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

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

@@ -0,0 +1,191 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2011, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua coroutines
+
+=head2 Synopsis
+
+    % prove 214-coroutine.t
+
+=head2 Description
+
+See "Lua 5.2 Reference Manual", section 2.6 "Coroutines",
+L<http://www.lua.org/manual/5.2/manual.html#2.6>.
+
+See "Programming in Lua", section 9 "Coroutines".
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(30)
+
+--[[ ]]
+output = {}
+
+function foo1 (a)
+    output[#output+1] = "foo " .. a
+    return coroutine.yield(2*a)
+end
+
+co = coroutine.create(function (a,b)
+        output[#output+1] = "co-body " .. a .." " .. b
+        local r = foo1(a+1)
+        output[#output+1] = "co-body " .. r
+        local r, s = coroutine.yield(a+b, a-b)
+        output[#output+1] = "co-body " .. r .. " " .. s
+        return b, 'end'
+    end)
+
+eq_array({coroutine.resume(co, 1, 10)}, {true, 4}, "foo1")
+eq_array({coroutine.resume(co, 'r')}, {true, 11, -9})
+eq_array({coroutine.resume(co, "x", "y")}, {true, 10, 'end'})
+eq_array({coroutine.resume(co, "x", "y")}, {false, "cannot resume dead coroutine"})
+eq_array(output, {
+    'co-body 1 10',
+    'foo 2',
+    'co-body r',
+    'co-body x y',
+})
+
+--[[ ]]
+co = coroutine.create(function ()
+        output = 'hi'
+    end)
+like(co, '^thread: 0?[Xx]?%x+$', "basics")
+
+is(coroutine.status(co), 'suspended')
+output = ''
+coroutine.resume(co)
+is(output, 'hi')
+is(coroutine.status(co), 'dead')
+
+error_like(function () coroutine.create(true) end,
+           "^[^:]+:%d+: bad argument #1 to 'create' %(function expected, got boolean%)")
+
+error_like(function () coroutine.resume(true) end,
+           "^[^:]+:%d+: bad argument #1 to 'resume' %(coroutine expected%)")
+
+error_like(function () coroutine.status(true) end,
+           "^[^:]+:%d+: bad argument #1 to 'status' %(coroutine expected%)")
+
+--[[ ]]
+output = {}
+co = coroutine.create(function ()
+        for i=1,10 do
+            output[#output+1] = i
+            coroutine.yield()
+        end
+    end)
+
+coroutine.resume(co)
+thr, ismain = coroutine.running(co)
+type_ok(thr, 'thread', "running")
+is(ismain, true, "running")
+is(coroutine.status(co), 'suspended', "basics")
+coroutine.resume(co)
+coroutine.resume(co)
+coroutine.resume(co)
+coroutine.resume(co)
+coroutine.resume(co)
+coroutine.resume(co)
+coroutine.resume(co)
+coroutine.resume(co)
+coroutine.resume(co)
+coroutine.resume(co)
+eq_array({coroutine.resume(co)}, {false, 'cannot resume dead coroutine'})
+eq_array(output, {1,2,3,4,5,6,7,8,9,10})
+
+--[[ ]]
+co = coroutine.create(function (a,b)
+        coroutine.yield(a + b, a - b)
+    end)
+
+eq_array({coroutine.resume(co, 20, 10)}, {true, 30, 10}, "basics")
+
+--[[ ]]
+co = coroutine.create(function ()
+        return 6, 7
+    end)
+
+eq_array({coroutine.resume(co)}, {true, 6, 7}, "basics")
+
+--[[ ]]
+co = coroutine.wrap(function(...)
+  return pcall(function(...)
+    return coroutine.yield(...)
+  end, ...)
+end)
+eq_array({co("Hello")}, {"Hello"})
+eq_array({co("World")}, {true, "World"})
+
+co = coroutine.wrap(function(...)
+  function backtrace ()
+    return 'not a back trace'
+  end
+  return xpcall(function(...)
+    return coroutine.yield(...)
+  end, backtrace, ...)
+end)
+eq_array({co("Hello")}, {"Hello"})
+eq_array({co("World")}, {true, "World"})
+
+--[[ ]]
+local output = {}
+co = coroutine.wrap(function()
+  while true do
+    local t = setmetatable({}, {
+      __eq = function(...)
+        return coroutine.yield(...)
+      end}
+    )
+    local t2 = setmetatable({}, getmetatable(t))
+    output[#output+1] = t == t2
+  end
+end)
+co()
+co(true)
+co(false)
+eq_array(output, {true, false})
+
+--[[ ]]
+co = coroutine.wrap(print)
+type_ok(co, 'function')
+
+error_like(function () coroutine.wrap(true) end,
+           "^[^:]+:%d+: bad argument #1 to 'wrap' %(function expected, got boolean%)")
+
+co = coroutine.wrap(function () error"in coro" end)
+error_like(function () co() end,
+           "^[^:]+:%d+: [^:]+:%d+: in coro$")
+
+--[[ ]]
+co = coroutine.create(function ()
+        error "in coro"
+    end)
+r, msg = coroutine.resume(co)
+is(r, false)
+like(msg, "^[^:]+:%d+: in coro$")
+
+--[[ ]]
+error_like(function () coroutine.yield() end,
+           "attempt to yield")
+
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 112 - 0
src/MoonSharp.Interpreter.Tests/TestMore/221-table.t

@@ -0,0 +1,112 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua tables
+
+=head2 Synopsis
+
+    % prove 221-table.t
+
+=head2 Description
+
+See "Programming in Lua", section 2.5 "Tables".
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(25)
+
+--[[ ]]
+a = {}
+k = 'x'
+a[k] = 10
+a[20] = 'great'
+is(a['x'], 10)
+k = 20
+is(a[k], 'great')
+a['x'] = a ['x'] + 1
+is(a['x'], 11)
+
+--[[ ]]
+a = {}
+a['x'] = 10
+b = a
+is(b['x'], 10)
+b['x'] = 20
+is(a['x'], 20)
+a = nil
+b = nil
+
+--[[ ]]
+a = {}
+for i=1,1000 do a[i] = i*2 end
+is(a[9], 18)
+a['x'] = 10
+is(a['x'], 10)
+is(a['y'], nil)
+
+--[[ ]]
+a = {}
+x = 'y'
+a[x] = 10
+is(a[x], 10)
+is(a.x, nil)
+is(a.y, 10)
+
+--[[ ]]
+i = 10; j = '10'; k = '+10'
+a = {}
+a[i] = "one value"
+a[j] = "another value"
+a[k] = "yet another value"
+is(a[j], "another value")
+is(a[k], "yet another value")
+is(a[tonumber(j)], "one value")
+is(a[tonumber(k)], "one value")
+
+t = { {'a','b','c'}, 10 }
+is(t[2], 10)
+is(t[1][3], 'c')
+t[1][1] = 'A'
+is(table.concat(t[1],','), 'A,b,c')
+
+--[[ ]]
+local tt
+tt = { {'a','b','c'}, 10 }
+is(tt[2], 10)
+is(tt[1][3], 'c')
+tt[1][1] = 'A'
+is(table.concat(tt[1],','), 'A,b,c')
+
+--[[ ]]
+a = {}
+error_like(function () a() end,
+           "^[^:]+:%d+: attempt to call")
+
+--[[ ]]
+local tt
+tt = { {'a','b','c'}, 10 }
+is((tt)[2], 10)
+is((tt[1])[3], 'c');
+(tt)[1][2] = 'B'
+(tt[1])[3] = 'C'
+is(table.concat(tt[1],','), 'a,B,C')
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 85 - 0
src/MoonSharp.Interpreter.Tests/TestMore/222-constructor.t

@@ -0,0 +1,85 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2010, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Table Constructors
+
+=head2 Synopsis
+
+    % prove 222-constructor.t
+
+=head2 Description
+
+See "Lua 5.2 Reference Manual", section 3.4.8 "Table Constructors",
+L<http://www.lua.org/manual/5.2/manual.html#3.4.8>.
+
+See "Programming in Lua", section 3.6 "Table Constructors".
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(14)
+
+--[[ list-style init ]]
+days = {'Sunday', 'Monday', 'Tuesday', 'Wednesday',
+        'Thursday', 'Friday', 'Saturday'}
+is(days[4], 'Wednesday', "list-style init")
+is(#days, 7)
+
+--[[ record-style init ]]
+a = {x=0, y=0}
+is(a.x, 0, "record-style init")
+is(a.y, 0)
+
+--[[ ]]
+w = {x=0, y=0, label='console'}
+x = {0, 1, 2}
+w[1] = "another field"
+x.f = w
+is(w['x'], 0, "ctor")
+is(w[1], "another field")
+is(x.f[1], "another field")
+w.x = nil
+
+--[[ mix record-style and list-style init ]]
+polyline = {color='blue', thickness=2, npoints=4,
+             {x=0,   y=0},
+             {x=-10, y=0},
+             {x=-10, y=1},
+             {x=0,   y=1}
+           }
+is(polyline[2].x, -10, "mix record-style and list-style init")
+
+--[[ ]]
+opnames = {['+'] = 'add', ['-'] = 'sub',
+           ['*'] = 'mul', ['/'] = 'div'}
+i = 20; s = '-'
+a = {[i+0] = s, [i+1] = s..s, [i+2] = s..s..s}
+is(opnames[s], 'sub', "ctor")
+is(a[22], '---')
+
+--[[ ]]
+local function f() return 10, 20 end
+
+eq_array({f()}, {10, 20}, "ctor")
+eq_array({'a', f()}, {'a', 10, 20})
+eq_array({f(), 'b'}, {10, 'b'})
+eq_array({'c', (f())}, {'c', 10})
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 196 - 0
src/MoonSharp.Interpreter.Tests/TestMore/223-iterator.t

@@ -0,0 +1,196 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2010, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua iterators
+
+=head2 Synopsis
+
+    % prove 223-iterator.t
+
+=head2 Description
+
+See "Programming in Lua", section 7 "Iterators and the Generic for" and
+section 9.3 "Coroutines as Iterators".
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(8)
+
+--[[ list_iter ]]
+function list_iter (t)
+    local i = 0
+    local n = #t
+    return function ()
+               i = i + 1
+               if i <= n then
+                   return t[i]
+               else
+                   return nil
+               end
+           end
+end
+
+t = {10, 20, 30}
+output = {}
+for element in list_iter(t) do
+    output[#output+1] = element
+end
+eq_array(output, t, "list_iter")
+
+--[[ values ]]
+function values (t)
+    local i = 0
+    return function ()
+               i = i + 1
+               return t[i]
+           end
+end
+
+t = {10, 20, 30}
+output = {}
+for element in values(t) do
+    output[#output+1] = element
+end
+eq_array(output, t, "values")
+
+--[[ emul ipairs ]]
+local function iter (a, i)
+    i = i + 1
+    local v = a[i]
+    if v then
+        return i, v
+    end
+end
+
+local function my_ipairs (a)
+    return iter, a, 0
+end
+
+a = {'one', 'two', 'three'}
+output = {}
+for i, v in my_ipairs(a) do
+    output[#output+1] = i
+    output[#output+1] = v
+end
+eq_array(output, {1, 'one', 2, 'two', 3, 'three'}, "emul ipairs")
+
+--[[ emul pairs ]]
+local function my_pairs (t)
+    return next, t, nil
+end
+
+a = {'one', 'two', 'three'}
+output = {}
+for k, v in my_pairs(a) do
+    output[#output+1] = k
+    output[#output+1] = v
+end
+eq_array(output, {1, 'one', 2, 'two', 3, 'three'}, "emul ipairs")
+
+--[[ with next ]]
+t = {'one', 'two', 'three'}
+output = {}
+for k, v in next, t do
+    output[#output+1] = k
+    output[#output+1] = v
+end
+eq_array(output, {1, 'one', 2, 'two', 3, 'three'}, "with next")
+
+--[[ permutations ]]
+function permgen (a, n)
+    n = n or #a         -- default for 'n' is size of 'a'
+    if n <= 1 then      -- nothing to change?
+        coroutine.yield(a)
+    else
+        for i=1,n do
+            -- put i-th element as the last one
+            a[n], a[i] = a[i], a[n]
+            -- generate all permutations of the other elements
+            permgen(a, n - 1)
+            -- restore i-th element
+            a[n], a[i] = a[i], a[n]
+        end
+    end
+end
+
+function permutations (a)
+    local co = coroutine.create(function () permgen(a) end)
+    return function ()  -- iterator
+               local code, res = coroutine.resume(co)
+               return res
+           end
+end
+
+output = {}
+for p in permutations{'a', 'b', 'c'} do
+    output[#output+1] = table.concat(p, ' ')
+end
+eq_array(output, {'b c a','c b a','c a b','a c b','b a c','a b c'}, "permutations")
+
+
+--[[ permutations with wrap ]]
+function permgen (a, n)
+    n = n or #a         -- default for 'n' is size of 'a'
+    if n <= 1 then      -- nothing to change?
+        coroutine.yield(a)
+    else
+        for i=1,n do
+            -- put i-th element as the last one
+            a[n], a[i] = a[i], a[n]
+            -- generate all permutations of the other elements
+            permgen(a, n - 1)
+            -- restore i-th element
+            a[n], a[i] = a[i], a[n]
+        end
+    end
+end
+
+function permutations (a)
+    return coroutine.wrap(function () permgen(a) end)
+end
+
+output = {}
+for p in permutations{'a', 'b', 'c'} do
+    output[#output+1] = table.concat(p, ' ')
+end
+eq_array(output, {'b c a','c b a','c a b','a c b','b a c','a b c'}, "permutations with wrap")
+
+--[[ fibo ]]
+function fibogen ()
+    local x, y = 0, 1
+    while true do
+        coroutine.yield(x)
+        x, y = y, x + y
+    end
+end
+
+function fibo ()
+    return coroutine.wrap(function () fibogen() end)
+end
+
+output = {}
+for n in fibo() do
+    output[#output+1] = n
+    if n > 30 then break end
+end
+eq_array(output, {0, 1, 1, 2, 3, 5, 8, 13, 21, 34}, "fibo")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 533 - 0
src/MoonSharp.Interpreter.Tests/TestMore/231-metatable.t

@@ -0,0 +1,533 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2012, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua metatables
+
+=head2 Synopsis
+
+    % prove 231-metatable.t
+
+=head2 Description
+
+See "Lua 5.2 Reference Manual", section 2.4 "Metatables and Metamethods",
+L<http://www.lua.org/manual/5.2/manual.html#2.4>.
+
+See "Programming in Lua", section 13 "Metatables and Metamethods".
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(96)
+
+t = {}
+is(getmetatable(t), nil, "metatable")
+t1 = {}
+is(setmetatable(t, t1), t)
+is(getmetatable(t), t1)
+is(setmetatable(t, nil), t)
+error_like(function () setmetatable(t, true) end,
+           "^[^:]+:%d+: bad argument #2 to 'setmetatable' %(nil or table expected%)")
+
+mt = {}
+mt.__metatable = "not your business"
+setmetatable(t, mt)
+is(getmetatable(t), "not your business", "protected metatable")
+error_like(function () setmetatable(t, {}) end,
+           "^[^:]+:%d+: cannot change a protected metatable")
+
+is(getmetatable('').__index, string, "metatable for string")
+
+is(getmetatable(nil), nil, "metatable for nil")
+is(getmetatable(false), nil, "metatable for boolean")
+is(getmetatable(2), nil, "metatable for number")
+is(getmetatable(print), nil, "metatable for function")
+
+t = {}
+mt = { __tostring=function () return '__TABLE__' end }
+setmetatable(t, mt)
+is(tostring(t), '__TABLE__', "__tostring")
+
+mt = {}
+a = nil
+function mt.__tostring () a = "return nothing" end
+setmetatable(t, mt)
+is(tostring(t), nil, "__tostring no-output")
+is(a, "return nothing")
+error_like(function () print(t) end,
+           "^[^:]+:%d+: 'tostring' must return a string to 'print'")
+
+mt.__tostring = function () return '__FIRST__', 2 end
+setmetatable(t, mt)
+is(tostring(t), '__FIRST__', "__tostring too-many-output")
+
+t = {}
+t.mt = {}
+setmetatable(t, t.mt)
+t.mt.__tostring = "not a function"
+error_like(function () tostring(t) end,
+           "attempt to call",
+           "__tostring invalid")
+
+t = {}
+mt = { __len=function () return 42 end }
+setmetatable(t, mt)
+is(#t, 42, "__len")
+
+t = {}
+mt = { __len=function () return nil end }
+setmetatable(t, mt)
+if arg[-1] == 'luajit' then
+    todo("LuaJIT TODO. __len.", 1)
+end
+error_like(function () print(table.concat(t)) end,
+           "object length is not a number",
+           "__len invalid")
+
+t = {}
+mt = {
+  __tostring=function () return 't' end,
+  __concat=function (op1, op2)
+        return tostring(op1) .. '|' .. tostring(op2)
+  end,
+}
+setmetatable(t, mt)
+is(t .. t .. t .. 4 ..'end', "t|t|t|4end", "__concat")
+
+
+--[[ Cplx ]]
+Cplx = {}
+Cplx.mt = {}
+
+function Cplx.new (re, im)
+    local c = {}
+    setmetatable(c, Cplx.mt)
+    c.re = tonumber(re)
+    if im == nil then
+        c.im = 0.0
+    else
+        c.im = tonumber(im)
+    end
+    return c
+end
+
+function Cplx.mt.__tostring (c)
+    return '(' .. c.re .. ',' .. c.im .. ')'
+end
+
+function Cplx.mt.__add (a, b)
+    if type(a) ~= 'table' then
+        a = Cplx.new(a, 0)
+    end
+    if type(b) ~= 'table' then
+        b = Cplx.new(b, 0)
+    end
+    local r = Cplx.new(a.re + b.re, a.im + b.im)
+    return r
+end
+
+c1 = Cplx.new(1, 3)
+c2 = Cplx.new(2, -1)
+
+is(tostring(c1 + c2), '(3,2)', "cplx __add")
+is(tostring(c1 + 3), '(4,3)')
+is(tostring(-2 + c1), '(-1,3)')
+is(tostring(c1 + '3'), '(4,3)')
+is(tostring('-2' + c1), '(-1,3)')
+
+function Cplx.mt.__sub (a, b)
+    if type(a) ~= 'table' then
+        a = Cplx.new(a, 0)
+    end
+    if type(b) ~= 'table' then
+        b = Cplx.new(b, 0)
+    end
+    local r = Cplx.new(a.re - b.re, a.im - b.im)
+    return r
+end
+
+is(tostring(c1 - c2), '(-1,4)', "cplx __sub")
+is(tostring(c1 - 3), '(-2,3)')
+is(tostring(-2 - c1), '(-3,-3)')
+is(tostring(c1 - '3'), '(-2,3)')
+is(tostring('-2' - c1), '(-3,-3)')
+
+function Cplx.mt.__mul (a, b)
+    if type(a) ~= 'table' then
+        a = Cplx.new(a, 0)
+    end
+    if type(b) ~= 'table' then
+        b = Cplx.new(b, 0)
+    end
+    local r = Cplx.new(a.re*b.re - a.im*b.im,
+        a.re*b.im + a.im*b.re)
+    return r
+end
+
+is(tostring(c1 * c2), '(5,5)', "cplx __mul")
+is(tostring(c1 * 3), '(3,9)')
+is(tostring(-2 * c1), '(-2,-6)')
+is(tostring(c1 * '3'), '(3,9)')
+is(tostring('-2' * c1), '(-2,-6)')
+
+function Cplx.mt.__div (a, b)
+    if type(a) ~= 'table' then
+        a = Cplx.new(a, 0)
+    end
+    if type(b) ~= 'table' then
+        b = Cplx.new(b, 0)
+    end
+    local n = b.re*b.re + b.im*b.im
+    local inv = Cplx.new(b.re/n, b.im/n)
+    local r = Cplx.new(a.re*inv.re - a.im*inv.im,
+        a.re*inv.im + a.im*inv.re)
+    return r
+end
+
+c1 = Cplx.new(2, 6)
+c2 = Cplx.new(2, 0)
+
+is(tostring(c1 / c2), '(1,3)', "cplx __div")
+is(tostring(c1 / 2), '(1,3)')
+is(tostring(-4 / c2), '(-2,0)')
+is(tostring(c1 / '2'), '(1,3)')
+is(tostring('-4' / c2), '(-2,0)')
+
+function Cplx.mt.__unm (a)
+    if type(a) ~= 'table' then
+        a = Cplx.new(a, 0)
+    end
+    local r = Cplx.new(-a.re, -a.im)
+    return r
+end
+
+c1 = Cplx.new(1, 3)
+is(tostring(- c1), '(-1,-3)', "cplx __unm")
+
+function Cplx.mt.__len (a)
+    return math.sqrt(a.re*a.re + a.im*a.im)
+end
+
+c1 = Cplx.new(3, 4)
+is( #c1, 5, "cplx __len")
+
+function Cplx.mt.__eq (a, b)
+    if type(a) ~= 'table' then
+        a = Cplx.new(a, 0)
+    end
+    if type(b) ~= 'table' then
+        b = Cplx.new(b, 0)
+    end
+    return (a.re == b.re) and (b.im == b.im)
+end
+
+c1 = Cplx.new(2, 0)
+c2 = Cplx.new(1, 3)
+c3 = Cplx.new(2, 0)
+
+is(c1 ~= c2, true, "cplx __eq")
+is(c1 == c3, true)
+is(c1 == 2, false)
+is(Cplx.mt.__eq(c1, 2), true)
+
+function Cplx.mt.__lt (a, b)
+    if type(a) ~= 'table' then
+        a = Cplx.new(a, 0)
+    end
+    if type(b) ~= 'table' then
+        b = Cplx.new(b, 0)
+    end
+    local ra = a.re*a.re + a.im*a.im
+    local rb = b.re*b.re + b.im*b.im
+    return ra < rb
+end
+
+is(c1 < c2, true, "cplx __lt")
+is(c1 < c3, false)
+is(c1 <= c3, true)
+is(c1 < 1, false)
+is(c1 < 4, true)
+
+function Cplx.mt.__le (a, b)
+    if type(a) ~= 'table' then
+        a = Cplx.new(a, 0)
+    end
+    if type(b) ~= 'table' then
+        b = Cplx.new(b, 0)
+    end
+    local ra = a.re*a.re + a.im*a.im
+    local rb = b.re*b.re + b.im*b.im
+    return ra <= rb
+end
+
+is(c1 < c2, true, "cplx __lt __le")
+is(c1 < c3, false)
+is(c1 <= c3, true)
+
+function Cplx.mt.__call (obj)
+    a = "Cplx.__call " .. tostring(obj)
+    return true
+end
+
+c1 = Cplx.new(2, 0)
+a = nil
+r = c1()
+is(r, true, "cplx __call (without args)")
+is(a, "Cplx.__call (2,0)")
+
+function Cplx.mt.__call (obj, ...)
+    a = "Cplx.__call " .. tostring(obj) .. ", " .. table.concat({...}, ", ")
+    return true
+end
+
+is(c1(), true, "cplx __call (with args)")
+is(a, "Cplx.__call (2,0), ")
+is(c1('a'), true)
+is(a, "Cplx.__call (2,0), a")
+is(c1('a', 'b', 'c'), true)
+is(a, "Cplx.__call (2,0), a, b, c")
+
+--[[ delegate ]]
+
+local t = {
+    _VALUES = {
+        a = 1,
+        b = 'text',
+        c = true,
+    }
+}
+local mt = {
+    __pairs = function (op)
+        return next, op._VALUES
+    end
+}
+setmetatable(t, mt)
+
+r = {}
+for k in pairs(t) do
+    r[#r+1] = k
+end
+table.sort(r)
+is( table.concat(r, ','), 'a,b,c', "__pairs" )
+
+local t = {
+    _VALUES = { 'a', 'b', 'c' }
+}
+local mt = {
+    __ipairs = function (op)
+        return ipairs(op._VALUES)
+    end
+}
+setmetatable(t, mt)
+
+r = ''
+for i, v in ipairs(t) do
+    r = r .. v
+end
+is( r, 'abc', "__ipairs" )
+
+--[[ Window ]]
+
+-- create a namespace
+Window = {}
+-- create a prototype with default values
+Window.prototype = {x=0, y=0, width=100, heigth=100, }
+-- create a metatable
+Window.mt = {}
+-- declare the constructor function
+function Window.new (o)
+    setmetatable(o, Window.mt)
+    return o
+end
+
+Window.mt.__index = function (table, key)
+    return Window.prototype[key]
+end
+
+w = Window.new{x=10, y=20}
+is(w.x, 10, "table-access")
+is(w.width, 100)
+is(rawget(w, 'x'), 10)
+is(rawget(w, 'width'), nil)
+
+Window.mt.__index = Window.prototype  -- just a table
+w = Window.new{x=10, y=20}
+is(w.x, 10, "table-access")
+is(w.width, 100)
+is(rawget(w, 'x'), 10)
+is(rawget(w, 'width'), nil)
+
+--[[ tables with default values ]]
+function setDefault_1 (t, d)
+    local mt = {__index = function () return d end}
+    setmetatable (t, mt)
+end
+
+tab = {x=10, y=20}
+is(tab.x, 10, "tables with default values")
+is(tab.z, nil)
+setDefault_1(tab, 0)
+is(tab.x, 10)
+is(tab.z, 0)
+
+--[[ tables with default values ]]
+local mt = {__index = function (t) return t.___ end}
+function setDefault_2 (t, d)
+    t.___ = d
+    setmetatable (t, mt)
+end
+
+tab = {x=10, y=20}
+is(tab.x, 10, "tables with default values")
+is(tab.z, nil)
+setDefault_2(tab, 0)
+is(tab.x, 10)
+is(tab.z, 0)
+
+--[[ tables with default values ]]
+local key = {}
+local mt = {__index = function (t) return t[key] end}
+function setDefault_3 (t, d)
+    t[key] = d
+    setmetatable (t, mt)
+end
+
+tab = {x=10, y=20}
+is(tab.x, 10, "tables with default values")
+is(tab.z, nil)
+setDefault_3(tab, 0)
+is(tab.x, 10)
+is(tab.z, 0)
+
+--[[ private access ]]
+t = {}  -- original table
+-- keep a private access to original table
+local _t = t
+-- create proxy
+t = {}
+-- create metatable
+local mt = {
+    __index = function (t,k)
+        r = "*access to element " .. tostring(k)
+        return _t[k]  -- access the original table
+    end,
+
+    __newindex = function (t,k,v)
+        w = "*update of element " .. tostring(k) ..
+                           " to " .. tostring(v)
+        _t[k] = v  -- update original table
+    end
+}
+setmetatable(t, mt)
+
+w = nil
+r = nil
+t[2] = 'hello'
+is(t[2], 'hello', "tracking table accesses")
+is(w, "*update of element 2 to hello")
+is(r, "*access to element 2")
+
+--[[ private access ]]
+-- create private index
+local index = {}
+-- create metatable
+local mt = {
+    __index = function (t,k)
+        r = "*access to element " .. tostring(k)
+        return t[index][k]  -- access the original table
+    end,
+
+    __newindex = function (t,k,v)
+        w = "*update of element " .. tostring(k) ..
+                           " to " .. tostring(v)
+        t[index][k] = v  -- update original table
+    end
+}
+function track (t)
+    local proxy = {}
+    proxy[index] = t
+    setmetatable(proxy, mt)
+    return proxy
+end
+
+t = {}
+t = track(t)
+
+w = nil
+r = nil
+t[2] = 'hello'
+is(t[2], 'hello', "tracking table accesses")
+is(w, "*update of element 2 to hello")
+is(r, "*access to element 2")
+
+--[[ read-only table ]]
+function readOnly (t)
+    local proxy = {}
+    local mt = {
+        __index = t,
+        __newindex = function (t,k,v)
+            error("attempt to update a read-only table", 2)
+        end
+    }
+    setmetatable(proxy, mt)
+    return proxy
+end
+
+days = readOnly{'Sunday', 'Monday', 'Tuesday', 'Wednesday',
+        'Thurday', 'Friday', 'Saturday'}
+
+is(days[1], 'Sunday', "read-only tables")
+
+error_like(function () days[2] = 'Noday' end,
+           "^[^:]+:%d+: attempt to update a read%-only table")
+
+--[[ declare global ]]
+function declare (name, initval)
+    rawset(_G, name, initval or false)
+end
+
+setmetatable(_G, {
+    __newindex = function (_, n)
+        error("attempt to write to undeclared variable " .. n, 2)
+    end,
+    __index = function (_, n)
+        error("attempt to read undeclared variable" .. n, 2)
+    end,
+})
+
+error_like(function () new_a = 1 end,
+           "^[^:]+:%d+: attempt to write to undeclared variable new_a",
+           "declaring global variables")
+
+declare 'new_a'
+new_a = 1
+is(new_a, 1)
+
+--[[ ]]
+local newindex = {}
+-- create metatable
+local mt = {
+    __newindex = newindex
+}
+local t = setmetatable({}, mt)
+t[1] = 42
+is(newindex[1], 42, "__newindex")
+
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 307 - 0
src/MoonSharp.Interpreter.Tests/TestMore/232-object.t

@@ -0,0 +1,307 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua object
+
+=head2 Synopsis
+
+    % prove 232-object.t
+
+=head2 Description
+
+See "Programming in Lua", section 16 "Object-Oriented Programming".
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(18)
+
+--[[ object ]]
+Account = {balance = 0}
+
+function Account.withdraw (self, v)
+    self.balance = self.balance - v
+end
+
+a1 = Account; Account = nil
+a1.withdraw(a1, 100.00)
+is(a1.balance, -100, "object")
+
+a2 = {balance = 0, withdraw = a1.withdraw}
+a2.withdraw(a2, 260.00)
+is(a2.balance, -260)
+
+--[[ object ]]
+Account = {balance = 0}
+
+function Account:withdraw (v)
+    self.balance = self.balance - v
+end
+
+a = Account
+a:withdraw(100.00)
+is(a.balance, -100, "object")
+
+Account = { balance = 0,
+            withdraw = function (self, v)
+                           self.balance = self.balance -v
+                       end
+          }
+function Account:deposit (v)
+    self.balance = self.balance + v
+end
+
+Account.deposit(Account, 200.00)
+is(Account.balance, 200, "object")
+Account:withdraw(100.00)
+is(Account.balance, 100)
+
+--[[ classe ]]
+Account = {balance = 0}
+
+function Account:new (o)
+    o = o or {}
+    setmetatable(o, self)
+    self.__index = self
+    return o
+end
+
+function Account:deposit (v)
+    self.balance = self.balance + v
+end
+
+function Account:withdraw (v)
+    self.balance = self.balance - v
+end
+
+a = Account:new{balance = 0}
+a:deposit(100.00)
+is(a.balance, 100, "classe")
+
+b = Account:new()
+is(b.balance, 0)
+b:deposit(200.00)
+is(b.balance, 200)
+
+--[[ inheritance ]]
+Account = {balance = 0}
+
+function Account:new (o)
+--    print "Account:new"
+    o = o or {}
+    setmetatable(o, self)
+    self.__index = self
+    return o
+end
+
+function Account:deposit (v)
+--    print "Account:deposit"
+    self.balance = self.balance + v
+end
+
+function Account:withdraw (v)
+--    print "Account:withdraw"
+    if v > self.balance then error"insuficient funds" end
+    self.balance = self.balance - v
+end
+
+a = Account:new()
+is(a.balance, 0, "inheritance")
+-- r, msg = pcall(Account.withdraw, a, 100)
+-- print(msg)
+
+SpecialAccount = Account:new()
+
+function SpecialAccount:withdraw (v)
+--    print "SpecialAccount:withdraw"
+    if self.balance - v <= -self:getLimit() then
+        error"insuficient funds"
+    end
+    self.balance = self.balance - v
+end
+
+function SpecialAccount:getLimit ()
+--    print "SpecialAccount:getLimit"
+    return self.limit or 0
+end
+
+s = SpecialAccount:new{limit=1000.00}
+
+s:deposit(100.00)
+is(s.balance, 100)
+
+s:withdraw(200.00)
+is(s.balance, -100)
+
+--[[ multiple inheritance ]]
+-- look up for 'k' in list of tables 'plist'
+local function search (k, plist)
+    for i=1, #plist do
+        local v = plist[i][k]  -- try 'i'-th superclass
+        if v then return v end
+    end
+end
+
+function createClass (...)
+    local c = {}  -- new class
+    local arg = {...}
+
+    -- class will search for each method in the list of its
+    -- parents ('arg' is the list of parents)
+    setmetatable(c, {__index = function (t, k)
+        return search(k, arg)
+    end})
+
+    -- prepare 'c' to be the metatable of its instance
+    c.__index = c
+
+    -- define a new constructor for this new class
+    function c:new (o)
+        o = o or {}
+        setmetatable(o, c)
+        return o
+    end
+
+    -- return new class
+    return c
+end
+
+Account = {balance = 0}
+function Account:deposit (v)
+    self.balance = self.balance + v
+end
+function Account:withdraw (v)
+    self.balance = self.balance - v
+end
+
+Named = {}
+function Named:getname ()
+    return self.name
+end
+function Named:setname (n)
+    self.name = n
+end
+
+NamedAccount = createClass(Account, Named)
+
+account = NamedAccount:new{name = "Paul"}
+is(account:getname(), 'Paul', "multiple inheritance")
+account:deposit(100.00)
+is(account.balance, 100)
+
+
+--[[ multiple inheritance (patched) ]]
+-- look up for 'k' in list of tables 'plist'
+local function search (k, plist)
+    for i=1, #plist do
+        local v = plist[i][k]  -- try 'i'-th superclass
+        if v then return v end
+    end
+end
+
+function createClass (...)
+    local c = {}  -- new class
+    local arg = {...}
+
+    -- class will search for each method in the list of its
+    -- parents ('arg' is the list of parents)
+    setmetatable(c, {__index = function (t, k)
+        -- return search(k, arg)
+        return (search(k, arg))
+    end})
+
+    -- prepare 'c' to be the metatable of its instance
+    c.__index = c
+
+    -- define a new constructor for this new class
+    function c:new (o)
+        o = o or {}
+        setmetatable(o, c)
+        return o
+    end
+
+    -- return new class
+    return c
+end
+
+Account = {balance = 0}
+function Account:deposit (v)
+    self.balance = self.balance + v
+end
+function Account:withdraw (v)
+    self.balance = self.balance - v
+end
+
+Named = {}
+function Named:getname ()
+    return self.name
+end
+function Named:setname (n)
+    self.name = n
+end
+
+NamedAccount = createClass(Account, Named)
+
+account = NamedAccount:new{name = "Paul"}
+is(account:getname(), 'Paul', "multiple inheritance (patched)")
+account:deposit(100.00)
+is(account.balance, 100)
+
+--[[ privacy ]]
+function newAccount (initialBalance)
+    local self = {balance = initialBalance}
+
+    local withdraw = function (v)
+                         self.balance = self.balance - v
+                     end
+
+    local deposit = function (v)
+                        self.balance = self.balance + v
+                    end
+
+    local getBalance = function () return self.balance end
+
+    return {
+        withdraw = withdraw,
+        deposit = deposit,
+        getBalance = getBalance
+    }
+end
+
+acc1 = newAccount(100.00)
+acc1.withdraw(40.00)
+is(acc1.getBalance(), 60, "privacy")
+
+--[[ single-method approach ]]
+function newObject (value)
+    return function (action, v)
+        if action == 'get' then return value
+        elseif action == 'set' then value = v
+        else error("invalid action")
+        end
+    end
+end
+
+d = newObject(0)
+is(d('get'), 0, "single-method approach")
+d('set', 10)
+is(d('get'), 10)
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 187 - 0
src/MoonSharp.Interpreter.Tests/TestMore/241-standalone.t

@@ -0,0 +1,187 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2012, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Stand-alone
+
+=head2 Synopsis
+
+    % prove 241-standalone.t
+
+=head2 Description
+
+See "Lua 5.2 Reference Manual", section 7 "Lua Stand-alone",
+L<http://www.lua.org/manual/5.2/manual.html#7>.
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+local lua = (platform and platform.lua) or arg[-1]
+local luac = (platform and platform.luac) or lua .. 'c'
+
+if not pcall(io.popen, lua .. [[ -e "a=1"]]) then
+    skip_all "io.popen not supported"
+end
+
+plan(28)
+diag(lua)
+
+f = io.open('hello.lua', 'w')
+f:write([[
+print 'Hello World'
+]])
+f:close()
+
+cmd = lua .. " hello.lua"
+f = io.popen(cmd)
+is(f:read'*l', 'Hello World', "file")
+f:close()
+
+cmd = lua .. " no_file.lua 2>&1"
+f = io.popen(cmd)
+like(f:read'*l', "^[^:]+: cannot open no_file.lua", "no file")
+f:close()
+
+if arg[-1] == 'luajit' then
+    os.execute(lua .. " -b hello.lua hello.luac")
+else
+    os.execute(luac .. " -s -o hello.luac hello.lua")
+end
+cmd = lua .. " hello.luac"
+f = io.popen(cmd)
+is(f:read'*l', 'Hello World', "bytecode")
+f:close()
+os.remove('hello.luac') -- clean up
+
+if arg[-1] == 'luajit' then
+    skip("LuaJIT intentional. cannot combine sources", 2)
+else
+    os.execute(luac .. " -s -o hello2.luac hello.lua hello.lua")
+    cmd = lua .. " hello2.luac"
+    f = io.popen(cmd)
+    is(f:read'*l', 'Hello World', "combine 1")
+    is(f:read'*l', 'Hello World', "combine 2")
+    f:close()
+    os.remove('hello2.luac') -- clean up
+end
+
+cmd = lua .. " < hello.lua"
+f = io.popen(cmd)
+is(f:read'*l', 'Hello World', "redirect")
+f:close()
+
+cmd = lua .. [[ -e"a=1" -e "print(a)"]]
+f = io.popen(cmd)
+is(f:read'*l', '1', "-e")
+f:close()
+
+cmd = lua .. [[ -e "error('msg')"  2>&1]]
+f = io.popen(cmd)
+is(f:read'*l', lua .. [[: (command line):1: msg]], "error")
+is(f:read'*l', "stack traceback:", "backtrace")
+f:close()
+
+cmd = lua .. [[ -e "error(setmetatable({}, {__tostring=function() return 'MSG' end}))"  2>&1]]
+f = io.popen(cmd)
+is(f:read'*l', lua .. [[: MSG]], "error with object")
+if arg[-1] == 'luajit' then
+    todo("LuaJIT intentional.", 1)
+end
+is(f:read'*l', nil, "not backtrace")
+f:close()
+
+cmd = lua .. [[ -e "error{}"  2>&1]]
+f = io.popen(cmd)
+if arg[-1] == 'luajit' then
+    todo("LuaJIT TODO.", 1)
+end
+is(f:read'*l', lua .. [[: (no error message)]], "error")
+is(f:read'*l', nil, "not backtrace")
+f:close()
+
+cmd = lua .. [[ -e"a=1" -e "print(a)" hello.lua]]
+f = io.popen(cmd)
+is(f:read'*l', '1', "-e & script")
+is(f:read'*l', 'Hello World')
+f:close()
+
+cmd = lua .. [[ -e "?syntax error?" 2>&1]]
+f = io.popen(cmd)
+like(f:read'*l', "lua", "-e bad")
+f:close()
+
+cmd = lua .. [[ -e 2>&1]]
+f = io.popen(cmd)
+if arg[-1] == 'luajit' then
+    skip("LuaJIT.", 1)
+else
+    like(f:read'*l', "^[^:]+: '%-e' needs argument", "no file")
+end
+like(f:read'*l', "^usage: ", "no file")
+f:close()
+
+cmd = lua .. [[ -v 2>&1]]
+f = io.popen(cmd)
+like(f:read'*l', '^Lua', "-v")
+f:close()
+
+cmd = lua .. [[ -v hello.lua 2>&1]]
+f = io.popen(cmd)
+like(f:read'*l', '^Lua', "-v & script")
+is(f:read'*l', 'Hello World')
+f:close()
+
+cmd = lua .. [[ -E hello.lua 2>&1]]
+f = io.popen(cmd)
+is(f:read'*l', 'Hello World')
+f:close()
+
+cmd = lua .. [[ -u 2>&1]]
+f = io.popen(cmd)
+if arg[-1] == 'luajit' then
+    skip("LuaJIT.", 1)
+else
+    like(f:read'*l', "^[^:]+: unrecognized option '%-u'", "unknown option")
+end
+like(f:read'*l', "^usage: ", "no file")
+f:close()
+
+cmd = lua .. [[ -lTest.More -e "print(type(ok))"]]
+f = io.popen(cmd)
+is(f:read'*l', 'function', "-lTest.More")
+f:close()
+
+cmd = lua .. [[ -l Test.More -e "print(type(ok))"]]
+f = io.popen(cmd)
+is(f:read'*l', 'function', "-l Test.More")
+f:close()
+
+cmd = lua .. [[ -l socket -e "print(1)" 2>&1]]
+f = io.popen(cmd)
+isnt(f:read'*l', nil, "-l socket")
+f:close()
+
+cmd = lua .. [[ -l no_lib hello.lua 2>&1]]
+f = io.popen(cmd)
+like(f:read'*l', "^[^:]+: module 'no_lib' not found:", "-l no lib")
+f:close()
+
+os.remove('hello.lua') -- clean up
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 133 - 0
src/MoonSharp.Interpreter.Tests/TestMore/242-luac.t

@@ -0,0 +1,133 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2010-2012, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Stand-alone
+
+=head2 Synopsis
+
+    % prove t/242-luac.t
+
+=head2 Description
+
+See "Lua 5.2 Reference Manual", section 7 "Lua Stand-alone",
+L<http://www.lua.org/manual/5.2/manual.html#7>.
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+if arg[-1] == 'luajit' then
+    skip_all("LuaJIT. no bytecode")
+end
+
+local lua = (platform and platform.lua) or arg[-1]
+local luac = (platform and platform.luac) or lua .. 'c'
+
+if not pcall(io.popen, lua .. [[ -e "a=1"]]) then
+    skip_all "io.popen not supported"
+end
+
+plan(14)
+diag(luac)
+
+f = io.open('hello.lua', 'w')
+f:write([[
+local a = false
+b = a + 1
+pi = 3.14
+s = "all escaped \1\a\b\f\n\r\t\v\\\""
+local t = { "a", "b", "c", "d" }
+local f = table.concat
+local function f () while true do print(a) end end
+s = nil
+
+print 'Hello World'
+]])
+f:close()
+
+cmd = luac .. [[ -v 2>&1]]
+f = io.popen(cmd)
+like(f:read'*l', '^Lua', "-v")
+f:close()
+
+cmd = luac .. [[ -u 2>&1]]
+f = io.popen(cmd)
+like(f:read'*l', "^[^:]+: unrecognized option '%-u'", "unknown option")
+like(f:read'*l', "^usage:")
+f:close()
+
+cmd = luac .. [[ -p hello.lua 2>&1]]
+f = io.popen(cmd)
+is(f:read'*l', nil)
+f:close()
+
+cmd = luac .. [[ -p no_file.lua 2>&1]]
+f = io.popen(cmd)
+like(f:read'*l', "^[^:]+: cannot open no_file.lua", "no file")
+f:close()
+
+cmd = luac .. [[ -v -l -l hello.lua]]
+f = io.popen(cmd)
+like(f:read'*l', '^Lua', "-v")
+is(f:read'*l', '')
+like(f:read'*l', "^main")
+f:close()
+
+cmd = luac .. [[ -l luac.out]]
+f = io.popen(cmd)
+is(f:read'*l', '')
+like(f:read'*l', "^main")
+f:close()
+
+f = io.open('luac.out', 'w')
+f:write "\x1bLua\x52\x00"
+f:close()
+cmd = luac .. [[ luac.out 2>&1]]
+f = io.popen(cmd)
+like(f:read'*l', "truncated precompiled chunk")
+f:close()
+
+f = io.open('luac.out', 'w')
+f:write "\x1bFoo\x52\x00\xde\xad\xbe\xef\x00\x19\x93\r\n\x1a\nCode"
+f:close()
+cmd = luac .. [[ luac.out 2>&1]]
+f = io.popen(cmd)
+like(f:read'*l', "not a precompiled chunk")
+f:close()
+
+f = io.open('luac.out', 'w')
+f:write "\x1bLua\x51\x00\xde\xad\xbe\xef\x00\x19\x93\r\n\x1a\nCode"
+f:close()
+cmd = luac .. [[ luac.out 2>&1]]
+f = io.popen(cmd)
+like(f:read'*l', "version mismatch in precompiled chunk")
+f:close()
+
+f = io.open('luac.out', 'w')
+f:write "\x1bLua\x52\x00\xde\xad\xbe\xef\x00\x19\x93\r\n\x1a\nCode"
+f:close()
+cmd = luac .. [[ luac.out 2>&1]]
+f = io.popen(cmd)
+like(f:read'*l', "incompatible precompiled chunk")
+f:close()
+
+os.remove('hello.lua') -- clean up
+os.remove('luac.out') -- clean up
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 482 - 0
src/MoonSharp.Interpreter.Tests/TestMore/301-basic.t

@@ -0,0 +1,482 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2012, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Basic Library
+
+=head2 Synopsis
+
+    % prove 301-basic.t
+
+=head2 Description
+
+Tests Lua Basic Library
+
+See "Lua 5.2 Reference Manual", section 6.1 "Basic Functions",
+L<http://www.lua.org/manual/5.2/manual.html#6.1>.
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(168)
+
+if arg[-1] == 'luajit' then
+    like(_VERSION, '^Lua 5%.1', "variable _VERSION")
+else
+    like(_VERSION, '^Lua 5%.2', "variable _VERSION")
+end
+
+v, msg = assert('text', "assert string")
+is(v, 'text', "function assert")
+is(msg, "assert string")
+v, msg = assert({}, "assert table")
+is(msg, "assert table")
+
+error_like(function () assert(false, "ASSERTION TEST") end,
+           "^[^:]+:%d+: ASSERTION TEST",
+           "function assert(false, msg)")
+
+error_like(function () assert(false) end,
+           "^[^:]+:%d+: assertion failed!",
+           "function assert(false)")
+
+error_like(function () assert(false, nil) end,
+           "^[^:]+:%d+: assertion failed!",
+           "function assert(false, nil)")
+
+is(collectgarbage('stop'), 0, "function collectgarbage 'stop/restart/collect'")
+if arg[-1] == 'luajit' then
+    skip("LuaJIT. gc isrunning", 1)
+else
+    is(collectgarbage('isrunning'), false)
+end
+is(collectgarbage('step'), false)
+is(collectgarbage('restart'), 0)
+if arg[-1] == 'luajit' then
+    skip("LuaJIT. gc isrunning", 1)
+else
+    is(collectgarbage('isrunning'), true)
+end
+is(collectgarbage('step'), false)
+is(collectgarbage('collect'), 0)
+is(collectgarbage('setpause', 10), 200)
+is(collectgarbage('setstepmul', 200), 200)
+is(collectgarbage(), 0)
+if arg[-1] == 'luajit' then
+    skip("LuaJIT. gc mode gen/inc", 4)
+else
+    is(collectgarbage('generational'), 0)
+    is(collectgarbage('step'), false)
+    is(collectgarbage('incremental'), 0)
+    is(collectgarbage('setmajorinc'), 200)
+end
+
+type_ok(collectgarbage('count'), 'number', "function collectgarbage 'count'")
+
+error_like(function () collectgarbage('unknown') end,
+           "^[^:]+:%d+: bad argument #1 to 'collectgarbage' %(invalid option 'unknown'%)",
+           "function collectgarbage (invalid)")
+
+f = io.open('lib1.lua', 'w')
+f:write[[
+function norm (x, y)
+    return (x^2 + y^2)^0.5
+end
+
+function twice (x)
+    return 2*x
+end
+]]
+f:close()
+dofile('lib1.lua')
+n = norm(3.4, 1.0)
+like(twice(n), '^7%.088', "function dofile")
+
+os.remove('lib1.lua') -- clean up
+
+error_like(function () dofile('no_file.lua') end,
+           "cannot open no_file.lua: No such file or directory",
+           "function dofile (no file)")
+
+f = io.open('foo.lua', 'w')
+f:write[[?syntax error?]]
+f:close()
+error_like(function () dofile('foo.lua') end,
+           "^foo%.lua:%d+:",
+           "function dofile (syntax error)")
+os.remove('foo.lua') -- clean up
+
+a = {'a','b','c'}
+local f, v, s = ipairs(a)
+type_ok(f, 'function', "function ipairs")
+type_ok(v, 'table')
+is(s, 0)
+s, v = f(a, s)
+is(s, 1)
+is(v, 'a')
+s, v = f(a, s)
+is(s, 2)
+is(v, 'b')
+s, v = f(a, s)
+is(s, 3)
+is(v, 'c')
+s, v = f(a, s)
+is(s, nil)
+is(v, nil)
+
+t = { [[
+function bar (x)
+    return x
+end
+]] }
+i = 0
+function reader ()
+    i = i + 1
+    return t[i]
+end
+f, msg = load(reader)
+if msg then
+    diag(msg)
+end
+type_ok(f, 'function', "function load(reader)")
+is(bar, nil)
+f()
+is(bar('ok'), 'ok')
+bar = nil
+
+t = { [[
+function baz (x)
+    return x
+end
+]] }
+i = -1
+function reader ()
+    i = i + 1
+    return t[i]
+end
+f, msg = load(reader)
+if msg then
+    diag(msg)
+end
+type_ok(f, 'function', "function load(pathological reader)")
+f()
+is(baz, nil)
+
+t = { [[?syntax error?]] }
+i = 0
+f, msg = load(reader, "errorchunk")
+is(f, nil, "function load(syntax error)")
+like(msg, "^%[string \"errorchunk\"%]:%d+:")
+
+f = load(function () return nil end)
+type_ok(f, 'function', "when reader returns nothing")
+
+f, msg = load(function () return {} end)
+is(f, nil, "reader function must return a string")
+like(msg, "reader function must return a string")
+
+f = load([[
+function bar (x)
+    return x
+end
+]])
+is(bar, nil, "function load(str)")
+f()
+is(bar('ok'), 'ok')
+bar = nil
+
+env = {}
+f = load([[
+function bar (x)
+    return x
+end
+]], "from string", 't', env)
+is(env.bar, nil, "function load(str)")
+f()
+is(env.bar('ok'), 'ok')
+
+f, msg = load([[?syntax error?]], "errorchunk")
+is(f, nil, "function load(syntax error)")
+like(msg, "^%[string \"errorchunk\"%]:%d+:")
+
+f, msg = load([[print 'ok']], "chunk txt", 'b')
+like(msg, "attempt to load")
+is(f, nil, "mode")
+
+f, msg = load("\x1bLua", "chunk bin", 't')
+like(msg, "attempt to load")
+is(f, nil, "mode")
+
+f = io.open('foo.lua', 'w')
+f:write'\xEF\xBB\xBF' -- BOM
+f:write[[
+function foo (x)
+    return x
+end
+]]
+f:close()
+f = loadfile('foo.lua')
+is(foo, nil, "function loadfile")
+f()
+is(foo('ok'), 'ok')
+
+f, msg = loadfile('foo.lua', 'b')
+like(msg, "attempt to load")
+is(f, nil, "mode")
+
+env = {}
+f = loadfile('foo.lua', 't', env)
+is(env.foo, nil, "function loadfile")
+f()
+is(env.foo('ok'), 'ok')
+
+os.remove('foo.lua') -- clean up
+
+f, msg = loadfile('no_file.lua')
+is(f, nil, "function loadfile (no file)")
+is(msg, "cannot open no_file.lua: No such file or directory")
+
+f = io.open('foo.lua', 'w')
+f:write[[?syntax error?]]
+f:close()
+f, msg = loadfile('foo.lua')
+is(f, nil, "function loadfile (syntax error)")
+like(msg, '^foo%.lua:%d+:')
+os.remove('foo.lua') -- clean up
+
+if (platform and platform.compat)
+or (arg[-1] == 'luajit') then
+    ok(loadstring[[i = i + 1]], "function loadstring")
+else
+    is(loadstring, nil, "function loadstring (removed)")
+    loadstring = load
+end
+
+f = loadstring([[i = i + 1]])
+i = 0
+f()
+is(i, 1, "function loadstring")
+f()
+is(i, 2)
+
+i = 32
+local i = 0
+f = loadstring([[i = i + 1; return i]])
+g = function () i = i + 1; return i end
+is(f(), 33, "function loadstring")
+is(g(), 1)
+
+f, msg = loadstring([[?syntax error?]])
+is(f, nil, "function loadstring (syntax error)")
+like(msg, '^%[string "%?syntax error%?"%]:%d+:')
+
+t = {'a','b','c'}
+a = next(t, nil)
+is(a, 1, "function next (array)")
+a = next(t, 1)
+is(a, 2)
+a = next(t, 2)
+is(a, 3)
+a = next(t, 3)
+is(a, nil)
+
+error_like(function () a = next() end,
+           "^[^:]+:%d+: bad argument #1 to 'next' %(table expected, got no value%)",
+           "function next (no arg)")
+
+error_like(function () a = next(t, 6) end,
+           "invalid key to 'next'",
+           "function next (invalid key)")
+
+t = {'a','b','c'}
+a = next(t, 2)
+is(a, 3, "function next (unorderer)")
+a = next(t, 1)
+is(a, 2)
+a = next(t, 3)
+is(a, nil)
+
+t = {}
+a = next(t, nil)
+is(a, nil, "function next (empty table)")
+
+a = {'a','b','c'}
+local f, v, s = pairs(a)
+type_ok(f, 'function', "function pairs")
+type_ok(v, 'table')
+is(s, nil)
+s = f(v, s)
+is(s, 1)
+s = f(v, s)
+is(s, 2)
+s = f(v, s)
+is(s, 3)
+s = f(v, s)
+is(s, nil)
+
+r = pcall(assert, true)
+is(r, true, "function pcall")
+r, msg = pcall(assert, false, 'catched')
+is(r, false)
+is(msg, 'catched')
+r = pcall(assert)
+is(r, false)
+
+t = {}
+a = t
+is(rawequal(nil, nil), true, "function rawequal -> true")
+is(rawequal(false, false), true)
+is(rawequal(3, 3), true)
+is(rawequal('text', 'text'), true)
+is(rawequal(t, a), true)
+is(rawequal(print, print), true)
+
+is(rawequal(nil, 2), false, "function rawequal -> false")
+is(rawequal(false, true), false)
+is(rawequal(false, 2), false)
+is(rawequal(3, 2), false)
+is(rawequal(3, '2'), false)
+is(rawequal('text', '2'), false)
+is(rawequal('text', 2), false)
+is(rawequal(t, {}), false)
+is(rawequal(t, 2), false)
+is(rawequal(print, format), false)
+is(rawequal(print, 2), false)
+
+is(rawlen("text"), 4, "function rawlen (string)")
+is(rawlen({ 'a', 'b', 'c'}), 3, "function rawlen (table)")
+error_like(function () a = rawlen(true) end,
+           "^[^:]+:%d+: bad argument #1 to 'rawlen' %(table ",
+           "function rawlen (bad arg)")
+
+t = {a = 'letter a', b = 'letter b'}
+is(rawget(t, 'a'), 'letter a', "function rawget")
+
+t = {}
+is(rawset(t, 'a', 'letter a'), t, "function rawset")
+is(t.a, 'letter a')
+
+error_like(function () t = {}; rawset(t, nil, 42) end,
+           "^table index is nil",
+           "function rawset (table index is nil)")
+
+is(select('#'), 0, "function select")
+is(select('#','a','b','c'), 3)
+eq_array({select(1,'a','b','c')}, {'a','b','c'})
+eq_array({select(3,'a','b','c')}, {'c'})
+eq_array({select(5,'a','b','c')}, {})
+eq_array({select(-1,'a','b','c')}, {'c'})
+eq_array({select(-2,'a','b','c')}, {'b', 'c'})
+eq_array({select(-3,'a','b','c')}, {'a', 'b', 'c'})
+
+error_like(function () select(0,'a','b','c') end,
+           "^[^:]+:%d+: bad argument #1 to 'select' %(index out of range%)",
+           "function select (out of range)")
+
+error_like(function () select(-4,'a','b','c') end,
+           "^[^:]+:%d+: bad argument #1 to 'select' %(index out of range%)",
+           "function select (out of range)")
+
+is(type("Hello world"), 'string', "function type")
+is(type(10.4*3), 'number')
+is(type(print), 'function')
+is(type(type), 'function')
+is(type(true), 'boolean')
+is(type(nil), 'nil')
+is(type(io.stdin), 'userdata')
+is(type(type(X)), 'string')
+
+a = nil
+is(type(a), 'nil', "function type")
+a = 10
+is(type(a), 'number')
+a = "a string!!"
+is(type(a), 'string')
+a = print
+is(type(a), 'function')
+is(type(function () end), 'function')
+
+error_like(function () type() end,
+           "^[^:]+:%d+: bad argument #1 to 'type' %(value expected%)",
+           "function type (no arg)")
+
+is(tonumber('text12'), nil, "function tonumber")
+is(tonumber('12text'), nil)
+is(tonumber(3.14), 3.14)
+is(tonumber('3.14'), 3.14)
+is(tonumber('  3.14  '), 3.14)
+is(tonumber(111, 2), 7)
+is(tonumber('111', 2), 7)
+is(tonumber('  111  ', 2), 7)
+a = {}
+is(tonumber(a), nil)
+
+error_like(function () tonumber() end,
+           "^[^:]+:%d+: bad argument #1 to 'tonumber' %(value expected%)",
+           "function tonumber (no arg)")
+
+error_like(function () tonumber('111', 200) end,
+           "^[^:]+:%d+: bad argument #2 to 'tonumber' %(base out of range%)",
+           "function tonumber (bad base)")
+
+is(tostring('text'), 'text', "function tostring")
+is(tostring(3.14), '3.14')
+is(tostring(nil), 'nil')
+is(tostring(true), 'true')
+is(tostring(false), 'false')
+like(tostring({}), '^table: 0?[Xx]?%x+$')
+like(tostring(print), '^function: 0?[Xx]?[builtin]*#?%x+$')
+
+error_like(function () tostring() end,
+           "^[^:]+:%d+: bad argument #1 to 'tostring' %(value expected%)",
+           "function tostring (no arg)")
+
+if (platform and platform.compat)
+or (arg[-1] == 'luajit') then
+    type_ok(unpack, 'function', "function unpack")
+else
+    is(unpack, nil, "function unpack (removed)")
+end
+
+if arg[-1] == 'luajit' then
+    error_like(function () xpcall(assert, nil) end,
+               "bad argument #2 to 'xpcall' %(function expected, got nil%)",
+               "function xpcall")
+    error_like(function () xpcall(assert) end,
+               "bad argument #2 to 'xpcall' %(function expected, got no value%)",
+               "function xpcall")
+    diag("LuaJIT intentional. xpcall")
+else
+    is(xpcall(assert, nil), false, "function xpcall")
+    error_like(function () xpcall(assert) end,
+               "^[^:]+:%d+: bad argument #2 to 'xpcall' %(value expected%)",
+               "function xpcall (no arg)")
+end
+
+function backtrace ()
+    return 'not a back trace'
+end
+r, msg = xpcall(assert, backtrace)
+is(r, false, "function xpcall (backtrace)")
+is(msg, 'not a back trace')
+
+r = xpcall(assert, backtrace, true)
+is(r, true, "function xpcall")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 217 - 0
src/MoonSharp.Interpreter.Tests/TestMore/303-package.t

@@ -0,0 +1,217 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2011, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Package Library
+
+=head2 Synopsis
+
+    % prove 303-package.t
+
+=head2 Description
+
+Tests Lua Package Library
+
+See "Lua 5.2 Reference Manual", section 6.3 "Modules",
+L<http://www.lua.org/manual/5.2/manual.html#6.3>.
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(33)
+
+ok(package.loaded._G, "table package.loaded")
+ok(package.loaded.coroutine)
+ok(package.loaded.io)
+ok(package.loaded.math)
+ok(package.loaded.os)
+ok(package.loaded.package)
+ok(package.loaded.string)
+ok(package.loaded.table)
+
+type_ok(package.path, 'string')
+
+type_ok(package.preload, 'table', "table package.preload")
+is(# package.preload, 0)
+
+if (platform and platform.compat)
+or (arg[-1] == 'luajit') then
+    type_ok(package.loaders, 'table', "table package.loaders")
+    if arg[-1] == 'luajit' then
+        todo("LuaJIT TODO. package.searchers", 1)
+    end
+    is(package.searchers, package.loaders, "alias")
+else
+    type_ok(package.searchers, 'table', "table package.searchers")
+    is(package.loaders, nil)
+end
+
+m = {}
+if (platform and platform.compat)
+or (arg[-1] == 'luajit') then
+    package.seeall(m)
+    m.pass("function package.seeall")
+else
+    is(package.seeall, nil, "package.seeall (removed)")
+end
+
+local m = require 'Test.More'
+m.ok(true, "function require")
+is(m, package.loaded['Test.More'])
+
+p = package.searchpath('Test.More', package.path)
+type_ok(p, 'string', "searchpath")
+p = package.searchpath('Test.More', 'bad path')
+is(p, nil)
+
+f = io.open('complex.lua', 'w')
+f:write [[
+complex = {}
+
+function complex.new (r, i) return {r=r, i=i} end
+
+--defines a constant 'i'
+complex.i = complex.new(0, 1)
+
+function complex.add (c1, c2)
+    return complex.new(c1.r + c2.r, c1.i + c2.i)
+end
+
+function complex.sub (c1, c2)
+    return complex.new(c1.r - c2.r, c1.i - c2.i)
+end
+
+function complex.mul (c1, c2)
+    return complex.new(c1.r*c2.r - c1.i*c2.i,
+                       c1.r*c2.i + c1.i*c2.r)
+end
+
+local function inv (c)
+    local n = c.r^2 + c.i^2
+    return complex.new(c.r/n, -c.i/n)
+end
+
+function complex.div (c1, c2)
+    return complex.mul(c1, inv(c2))
+end
+
+return complex
+]]
+f:close()
+m = require 'complex'
+is(m, complex, "function require")
+is(complex.i.r, 0)
+is(complex.i.i, 1)
+os.remove('complex.lua') -- clean up
+
+error_like(function () require('no_module') end,
+           "^[^:]+:%d+: module 'no_module' not found:",
+           "function require (no module)")
+
+f = io.open('foo.lua', 'w')
+f:write [[?syntax error?]]
+f:close()
+error_like(function () require('foo') end,
+           "^error loading module 'foo' from file '%.[/\\]foo%.lua':",
+           "function require (syntax error)")
+os.remove('foo.lua') -- clean up
+
+foo = {}
+foo.bar = 1234
+function foo_loader ()
+    return foo
+end
+package.preload.foo = foo_loader
+m = require 'foo'
+assert(m == foo)
+is(m.bar, 1234, "function require & package.preload")
+
+f = io.open('bar.lua', 'w')
+f:write [[
+    print("    in bar.lua", ...)
+    a = ...
+]]
+f:close()
+a = nil
+require 'bar'
+is(a, 'bar', "function require (arg)")
+os.remove('bar.lua') -- clean up
+
+f = io.open('cplx.lua', 'w')
+f:write [[
+-- print('cplx.lua', ...)
+local _G = _G
+_ENV = nil
+local cplx = {}
+
+local function new (r, i) return {r=r, i=i} end
+cplx.new = new
+
+--defines a constant 'i'
+cplx.i = new(0, 1)
+
+function cplx.add (c1, c2)
+    return new(c1.r + c2.r, c1.i + c2.i)
+end
+
+function cplx.sub (c1, c2)
+    return new(c1.r - c2.r, c1.i - c2.i)
+end
+
+function cplx.mul (c1, c2)
+    return new(c1.r*c2.r - c1.i*c2.i,
+               c1.r*c2.i + c1.i*c2.r)
+end
+
+local function inv (c)
+    local n = c.r^2 + c.i^2
+    return new(c.r/n, -c.i/n)
+end
+
+function cplx.div (c1, c2)
+    return mul(c1, inv(c2))
+end
+
+_G.cplx = cplx
+return cplx
+]]
+f:close()
+require 'cplx'
+is(cplx.i.r, 0, "function require & module")
+is(cplx.i.i, 1)
+os.remove('cplx.lua') -- clean up
+
+if (platform and platform.compat)
+or (arg[-1] == 'luajit') then
+    is(mod, nil, "function module & seeall")
+    module('mod', package.seeall)
+    type_ok(mod, 'table')
+    is(mod, package.loaded.mod)
+
+    is(modz, nil, "function module")
+    local _G = _G
+    module('modz')
+    _G.type_ok(_G.modz, 'table')
+    _G.is(_G.modz, _G.package.loaded.modz)
+else
+    is(module, nil, "module (removed)")
+    skip("module (removed)", 5)
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 285 - 0
src/MoonSharp.Interpreter.Tests/TestMore/304-string.t

@@ -0,0 +1,285 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2012, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua String Library
+
+=head2 Synopsis
+
+    % prove 304-string.t
+
+=head2 Description
+
+Tests Lua String Library
+
+See "Lua 5.2 Reference Manual", section 6.4 "String Manipulation",
+L<http://www.lua.org/manual/5.2/manual.html#6.4>.
+
+See "Programming in Lua", section 20 "The String Library".
+
+=cut
+
+]]
+
+require 'Test.More'
+
+plan(111)
+
+is(string.byte('ABC'), 65, "function byte")
+is(string.byte('ABC', 2), 66)
+is(string.byte('ABC', -1), 67)
+is(string.byte('ABC', 4), nil)
+is(string.byte('ABC', 0), nil)
+eq_array({string.byte('ABC', 1, 3)}, {65, 66, 67})
+eq_array({string.byte('ABC', 1, 4)}, {65, 66, 67})
+
+type_ok(getmetatable('ABC'), 'table', "literal string has metatable")
+
+s = "ABC"
+is(s:byte(2), 66, "method s:byte")
+
+is(string.char(65, 66, 67), 'ABC', "function char")
+is(string.char(), '')
+
+error_like(function () string.char(0, 'bad') end,
+           "^[^:]+:%d+: bad argument #2 to 'char' %(number expected, got string%)",
+           "function char (bad arg)")
+
+error_like(function () string.char(0, 9999) end,
+           "^[^:]+:%d+: bad argument #2 to 'char' %(.-value.-%)",
+           "function char (invalid)")
+
+d = string.dump(plan)
+type_ok(d, 'string', "function dump")
+
+error_like(function () string.dump(print) end,
+           "^[^:]+:%d+: unable to dump given function",
+           "function dump (C function)")
+
+s = "hello world"
+eq_array({string.find(s, "hello")}, {1, 5}, "function find (mode plain)")
+eq_array({string.find(s, "hello", 1, true)}, {1, 5})
+eq_array({string.find(s, "hello", 1)}, {1, 5})
+is(string.sub(s, 1, 5), "hello")
+eq_array({string.find(s, "world")}, {7, 11})
+eq_array({string.find(s, "l")}, {3, 3})
+is(string.find(s, "lll"), nil)
+is(string.find(s, "hello", 2, true), nil)
+eq_array({string.find(s, "world", 2, true)}, {7, 11})
+is(string.find(s, "hello", 20), nil)
+
+s = "hello world"
+eq_array({string.find(s, "^h.ll.")}, {1, 5}, "function find (with regex & captures)")
+eq_array({string.find(s, "w.rld", 2)}, {7, 11})
+is(string.find(s, "W.rld"), nil)
+eq_array({string.find(s, "^(h.ll.)")}, {1, 5, 'hello'})
+eq_array({string.find(s, "^(h.)l(l.)")}, {1, 5, 'he', 'lo'})
+s = "Deadline is 30/05/1999, firm"
+date = "%d%d/%d%d/%d%d%d%d"
+is(string.sub(s, string.find(s, date)), "30/05/1999")
+date = "%f[%S]%d%d/%d%d/%d%d%d%d"
+is(string.sub(s, string.find(s, date)), "30/05/1999")
+
+error_like(function () string.find(s, '%f') end,
+           "^[^:]+:%d+: missing '%[' after '%%f' in pattern",
+           "function find (invalid frontier)")
+
+is(string.format("pi = %.4f", math.pi), 'pi = 3.1416', "function format")
+d = 5; m = 11; y = 1990
+is(string.format("%02d/%02d/%04d", d, m, y), "05/11/1990")
+tag, title = "h1", "a title"
+is(string.format("<%s>%s</%s>", tag, title, tag), "<h1>a title</h1>")
+
+is(string.format('%q', 'a string with "quotes" and \n new line'), [["a string with \"quotes\" and \
+ new line"]], "function format %q")
+
+is(string.format('%q', 'a string with \b and \b2'), [["a string with \8 and \0082"]], "function format %q")
+
+is(string.format("%s %s", 1, 2, 3), '1 2', "function format (too many arg)")
+
+is(string.format("%% %c %%", 65), '% A %', "function format (%%)")
+
+r = string.rep("ab", 100)
+is(string.format("%s %d", r, r:len()), r .. " 200")
+
+error_like(function () string.format("%s %s", 1) end,
+           "^[^:]+:%d+: bad argument #3 to 'format' %(.-no value%)",
+           "function format (too few arg)")
+
+error_like(function () string.format('%d', 'toto') end,
+           "^[^:]+:%d+: bad argument #2 to 'format' %(number expected, got string%)",
+           "function format (bad arg)")
+
+error_like(function () string.format('%k', 'toto') end,
+           "^[^:]+:%d+: invalid option '%%k' to 'format'",
+           "function format (invalid option)")
+
+error_like(function () string.format('%------s', 'toto') end,
+           "^[^:]+:%d+: invalid format %(repeated flags%)",
+           "function format (invalid format)")
+
+error_like(function () string.format('pi = %.123f', math.pi) end,
+           "^[^:]+:%d+: invalid format %(width or precision too long%)",
+           "function format (invalid format)")
+
+error_like(function () string.format('% 123s', 'toto') end,
+           "^[^:]+:%d+: invalid format %(width or precision too long%)",
+           "function format (invalid format)")
+
+s = "hello"
+output = {}
+for c in string.gmatch(s, '..') do
+    table.insert(output, c)
+end
+eq_array(output, {'he', 'll'}, "function gmatch")
+output = {}
+for c1, c2 in string.gmatch(s, '(.)(.)') do
+    table.insert(output, c1)
+    table.insert(output, c2)
+end
+eq_array(output, {'h', 'e', 'l', 'l'})
+s = "hello world from Lua"
+output = {}
+for w in string.gmatch(s, '%a+') do
+    table.insert(output, w)
+end
+eq_array(output, {'hello', 'world', 'from', 'Lua'})
+s = "from=world, to=Lua"
+output = {}
+for k, v in string.gmatch(s, '(%w+)=(%w+)') do
+    table.insert(output, k)
+    table.insert(output, v)
+end
+eq_array(output, {'from', 'world', 'to', 'Lua'})
+
+is(string.gsub("hello world", "(%w+)", "%1 %1"), "hello hello world world", "function gsub")
+is(string.gsub("hello world", "%w+", "%0 %0", 1), "hello hello world")
+is(string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1"), "world hello Lua from")
+is(string.gsub("home = $HOME, user = $USER", "%$(%w+)", string.reverse), "home = EMOH, user = RESU")
+is(string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s) return load(s)() end), "4+5 = 9")
+local t = {name='lua', version='5.1'}
+is(string.gsub("$name-$version.tar.gz", "%$(%w+)", t), "lua-5.1.tar.gz")
+
+is(string.gsub("Lua is cute", 'cute', 'great'), "Lua is great")
+is(string.gsub("all lii", 'l', 'x'), "axx xii")
+is(string.gsub("Lua is great", '^Sol', 'Sun'), "Lua is great")
+is(string.gsub("all lii", 'l', 'x', 1), "axl lii")
+is(string.gsub("all lii", 'l', 'x', 2), "axx lii")
+is(select(2, string.gsub("string with 3 spaces", ' ', ' ')), 3)
+
+eq_array({string.gsub("hello, up-down!", '%A', '.')}, {"hello..up.down.", 4})
+text = "hello world"
+nvow = select(2, string.gsub(text, '[AEIOUaeiou]', ''))
+is(nvow, 3)
+eq_array({string.gsub("one, and two; and three", '%a+', 'word')}, {"word, word word; word word", 5})
+test = "int x; /* x */  int y; /* y */"
+eq_array({string.gsub(test, "/%*.*%*/", '<COMMENT>')}, {"int x; <COMMENT>", 1})
+eq_array({string.gsub(test, "/%*.-%*/", '<COMMENT>')}, {"int x; <COMMENT>  int y; <COMMENT>", 2})
+s = "a (enclosed (in) parentheses) line"
+eq_array({string.gsub(s, '%b()', '')}, {"a  line", 1})
+
+error_like(function () string.gsub(s, '%b(', '') end,
+           "^[^:]+:%d+: .- pattern",
+           "function gsub (malformed pattern)")
+
+eq_array({string.gsub("hello Lua!", "%a", "%0-%0")}, {"h-he-el-ll-lo-o L-Lu-ua-a!", 8})
+eq_array({string.gsub("hello Lua", "(.)(.)", "%2%1")}, {"ehll ouLa", 4})
+
+function expand (s)
+    return (string.gsub(s, '$(%w+)', _G))
+end
+name = 'Lua'; status= 'great'
+is(expand("$name is $status, isn't it?"), "Lua is great, isn't it?")
+is(expand("$othername is $status, isn't it?"), "$othername is great, isn't it?")
+
+function expand (s)
+    return (string.gsub(s, '$(%w+)', function (n)
+                                          return tostring(_G[n]), 1
+                                     end))
+end
+like(expand("print = $print; a = $a"), "^print = function: [0]?[Xx]?[builtin]*#?%x+; a = nil")
+
+error_like(function () string.gsub("hello world", '(%w+)', '%2 %2') end,
+           "^[^:]+:%d+: invalid capture index",
+           "function gsub (invalid index)")
+
+error_like(function () string.gsub("hello world", '(%w+)', true) end,
+           "^[^:]+:%d+: bad argument #3 to 'gsub' %(string/function/table expected%)",
+           "function gsub (bad type)")
+
+error_like(function ()
+    function expand (s)
+        return (string.gsub(s, '$(%w+)', _G))
+    end
+
+    name = 'Lua'; status= true
+    expand("$name is $status, isn't it?")
+           end,
+           "^[^:]+:%d+: invalid replacement value %(a boolean%)",
+           "function gsub (invalid value)")
+
+is(string.len(''), 0, "function len")
+is(string.len('test'), 4)
+is(string.len("a\000b\000c"), 5)
+is(string.len('"'), 1)
+
+is(string.lower('Test'), 'test', "function lower")
+is(string.lower('TeSt'), 'test')
+
+s = "hello world"
+is(string.match(s, '^hello'), 'hello', "function match")
+is(string.match(s, 'world', 2), 'world')
+is(string.match(s, 'World'), nil)
+eq_array({string.match(s, '^(h.ll.)')}, {'hello'})
+eq_array({string.match(s, '^(h.)l(l.)')}, {'he', 'lo'})
+date = "Today is 17/7/1990"
+is(string.match(date, '%d+/%d+/%d+'), '17/7/1990')
+eq_array({string.match(date, '(%d+)/(%d+)/(%d+)')}, {'17', '7', '1990'})
+is(string.match("The number 1298 is even", '%d+'), '1298')
+pair = "name = Anna"
+eq_array({string.match(pair, '(%a+)%s*=%s*(%a+)')}, {'name', 'Anna'})
+
+s = [[then he said: "it's all right"!]]
+eq_array({string.match(s, "([\"'])(.-)%1")}, {'"', "it's all right"}, "function match (back ref)")
+p = "%[(=*)%[(.-)%]%1%]"
+s = "a = [=[[[ something ]] ]==]x]=]; print(a)"
+eq_array({string.match(s, p)}, {'=', '[[ something ]] ]==]x'})
+
+is(string.match(s, "%g"), "a", "match graphic char")
+
+error_like(function () string.match("hello world", "%1") end,
+           "^[^:]+:%d+: invalid capture index",
+           "function match invalid capture")
+
+is(string.rep('ab', 3), 'ababab', "function rep")
+is(string.rep('ab', 0), '')
+is(string.rep('ab', -1), '')
+is(string.rep('', 5), '')
+is(string.rep('ab', 3, ','), 'ab,ab,ab', "with sep")
+
+is(string.reverse('abcde'), 'edcba', "function reverse")
+is(string.reverse('abcd'), 'dcba')
+is(string.reverse(''), '')
+
+is(string.sub('abcde', 1, 2), 'ab', "function sub")
+is(string.sub('abcde', 3, 4), 'cd')
+is(string.sub('abcde', -2), 'de')
+is(string.sub('abcde', 3, 2), '')
+
+is(string.upper('Test'), 'TEST', "function upper")
+is(string.upper('TeSt'), 'TEST')
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 231 - 0
src/MoonSharp.Interpreter.Tests/TestMore/305-table.t

@@ -0,0 +1,231 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2012, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Table Library
+
+=head2 Synopsis
+
+    % prove 305-table.t
+
+=head2 Description
+
+Tests Lua Table Library
+
+See "Lua 5.2 Reference Manual", section 6.5 "Table Manipulation",
+L<http://www.lua.org/manual/5.2/manual.html#6.5>.
+
+See "Programming in Lua", section 19 "The Table Library".
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(44)
+
+t = {'a','b','c','d','e'}
+is(table.concat(t), 'abcde', "function concat")
+is(table.concat(t, ','), 'a,b,c,d,e')
+is(table.concat(t, ',',2), 'b,c,d,e')
+is(table.concat(t, ',', 2, 4), 'b,c,d')
+is(table.concat(t, ',', 4, 2), '')
+
+t = {'a','b',3,'d','e'}
+is(table.concat(t,','), 'a,b,3,d,e', "function concat (number)")
+
+t = {'a','b','c','d','e'}
+error_like(function () table.concat(t, ',', 2, 7) end,
+           "^[^:]+:%d+: invalid value %(nil%) at index 6 in table for 'concat'",
+           "function concat (out of range)")
+
+t = {'a','b',true,'d','e'}
+error_like(function () table.concat(t, ',') end,
+           "^[^:]+:%d+: invalid value %(boolean%) at index 3 in table for 'concat'",
+           "function concat (non-string)")
+
+a = {10, 20, 30}
+table.insert(a, 1, 15)
+is(table.concat(a,','), '15,10,20,30', "function insert")
+t = {}
+table.insert(t, 'a')
+is(table.concat(t, ','), 'a')
+table.insert(t, 'b')
+is(table.concat(t, ','), 'a,b')
+table.insert(t, 1, 'c')
+is(table.concat(t, ','), 'c,a,b')
+table.insert(t, 2, 'd')
+is(table.concat(t, ','), 'c,d,a,b')
+table.insert(t, 7, 'e')
+is(t[7], 'e')
+table.insert(t, -9, 'f')
+is(t[-9], 'f')
+
+error_like(function () table.insert(t, 2, 'g', 'h')  end,
+           "^[^:]+:%d+: wrong number of arguments to 'insert'",
+           "function insert (too many arg)")
+
+if (platform and platform.compat)
+or (arg[-1] == 'luajit') then
+    t = {}
+    is(table.maxn(t), 0, "function maxn")
+    t[1] = 'a'
+    t[2] = 'b'
+    is(table.maxn(t), 2)
+    t[6] = 'g'
+    is(table.maxn(t), 6)
+    a = {}
+    a[10000] = 1
+    is(table.maxn(a), 10000)
+else
+    is(table.maxn, nil, "maxn (removed)")
+    skip("maxn (removed)", 3)
+end
+
+t = table.pack("abc", "def", "ghi")
+eq_array(t, {
+    "abc",
+    "def",
+    "ghi"
+}, "function pack")
+is(t.n, 3)
+
+t = table.pack()
+eq_array(t, {}, "function pack (no element)")
+is(t.n, 0)
+
+t = {}
+a = table.remove(t)
+is(a, nil, "function remove")
+t = {'a','b','c','d','e'}
+a = table.remove(t)
+is(a, 'e')
+is(table.concat(t, ','), 'a,b,c,d')
+a = table.remove(t,3)
+is(a, 'c')
+is(table.concat(t, ','), 'a,b,d')
+a = table.remove(t,1)
+is(a, 'a')
+is(table.concat(t, ','), 'b,d')
+a = table.remove(t,7)
+is(a, nil)
+is(table.concat(t, ','), 'b,d')
+
+lines = {
+    luaH_set = 10,
+    luaH_get = 24,
+    luaH_present = 48,
+}
+a = {}
+for n in pairs(lines) do a[#a + 1] = n end
+table.sort(a)
+output = {}
+for _, n in ipairs(a) do
+    table.insert(output, n)
+end
+eq_array(output, {'luaH_get', 'luaH_present', 'luaH_set'}, "function sort")
+
+function pairsByKeys (t, f)
+    local a = {}
+    for n in pairs(t) do a[#a + 1] = n end
+    table.sort(a, f)
+    local i = 0     -- iterator variable
+    return function ()  -- iterator function
+        i = i + 1
+        return a[i], t[a[i]]
+    end
+end
+
+output = {}
+for name, line in pairsByKeys(lines) do
+    table.insert(output, name)
+    table.insert(output, line)
+end
+eq_array(output, {'luaH_get', 24, 'luaH_present', 48, 'luaH_set', 10}, "function sort")
+
+output = {}
+for name, line in pairsByKeys(lines, function (a, b) return a < b end) do
+    table.insert(output, name)
+    table.insert(output, line)
+end
+eq_array(output, {'luaH_get', 24, 'luaH_present', 48, 'luaH_set', 10}, "function sort")
+
+function permgen (a, n)
+    n = n or #a
+    if n <= 1 then
+        coroutine.yield(a)
+    else
+        for i=1,n do
+            a[n], a[i] = a[i], a[n]
+            permgen(a, n - 1)
+            a[n], a[i] = a[i], a[n]
+        end
+    end
+end
+
+function permutations (a)
+    local co = coroutine.create(function () permgen(a) end)
+    return function ()
+               local code, res = coroutine.resume(co)
+               return res
+           end
+end
+
+local t = {}
+output = {}
+for _, v in ipairs{'a', 'b', 'c', 'd', 'e', 'f', 'g'} do
+    table.insert(t, v)
+    local ref = table.concat(t, ' ')
+    table.insert(output, ref)
+    local n = 0
+    for p in permutations(t) do
+        local c = {}
+        for i, v in ipairs(p) do
+            c[i] = v
+        end
+        table.sort(c)
+        assert(ref == table.concat(c, ' '), table.concat(p, ' '))
+        n = n + 1
+    end
+    table.insert(output, n)
+end
+
+eq_array(output, {
+    'a', 1,
+    'a b', 2,
+    'a b c', 6,
+    'a b c d', 24,
+    'a b c d e', 120,
+    'a b c d e f', 720,
+    'a b c d e f g', 5040,
+}, "function sort (all permutations)")
+
+error_like(function ()
+    local t = { 1 }
+    table.sort( { t, t, t, t, }, function (a, b) return a[1] == b[1] end )
+           end,
+           "^[^:]+:%d+: invalid order function for sorting",
+           "function sort (bad func)")
+
+eq_array({table.unpack({})}, {}, "function unpack")
+eq_array({table.unpack({'a'})}, {'a'})
+eq_array({table.unpack({'a','b','c'})}, {'a','b','c'})
+eq_array({(table.unpack({'a','b','c'}))}, {'a'})
+eq_array({table.unpack({'a','b','c','d','e'},2,4)}, {'b','c','d'})
+eq_array({table.unpack({'a','b','c'},2,4)}, {'b','c'})
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 150 - 0
src/MoonSharp.Interpreter.Tests/TestMore/306-math.t

@@ -0,0 +1,150 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2012, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Mathematic Library
+
+=head2 Synopsis
+
+    % prove 306-math.t
+
+=head2 Description
+
+Tests Lua Mathematic Library
+
+See "Lua 5.2 Reference Manual", section 6.6 "Mathematical Functions",
+L<http://www.lua.org/manual/5.2/manual.html#6.6>.
+
+See "Programming in Lua", section 18 "The Mathematical Library".
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(47)
+
+like(tostring(math.pi), '^3%.14', "variable pi")
+
+type_ok(math.huge, 'number', "variable huge")
+
+is(math.abs(-12.34), 12.34, "function abs")
+is(math.abs(12.34), 12.34)
+
+like(math.acos(0.5), '^1%.047', "function acos")
+
+like(math.asin(0.5), '^0%.523', "function asin")
+
+like(math.atan(0.5), '^0%.463', "function atan")
+
+like(math.atan2(1, 2), '^0%.463', "function atan2")
+
+is(math.ceil(12.34), 13, "function ceil")
+is(math.ceil(-12.34), -12)
+
+like(math.cos(0), '^1$', "function cos")
+
+like(math.cosh(0), '^1$', "function cosh")
+
+is(math.deg(math.pi), 180, "function deg")
+
+like(math.exp(1.0), '^2%.718', "function exp")
+
+is(math.floor(12.34), 12, "function floor")
+is(math.floor(-12.34), -13)
+
+is(math.fmod(7, 3), 1, "function fmod")
+is(math.fmod(-7, 3), -1)
+
+eq_array({math.frexp(1.5)}, {0.75, 1}, "function frexp")
+
+is(math.ldexp(1.2, 3), 9.6, "function ldexp")
+
+like(math.log(47), '^3%.85', "function log")
+like(math.log(47, 2), '^5%.554', "function log (base 2)")
+like(math.log(47, 10), '^1%.672', "function log (base 10)")
+
+if (platform and platform.compat)
+or (arg[-1] == 'luajit') then
+    like(math.log10(47), '^1%.672', "function log10")
+else
+    is(math.log10, nil, "function log10 (removed)")
+end
+
+error_like(function () math.max() end,
+           "^[^:]+:%d+: bad argument #1 to 'max' %(number expected, got no value%)",
+           "function max 0")
+
+is(math.max(1), 1, "function max")
+is(math.max(1, 2), 2)
+is(math.max(1, 2, 3, -4), 3)
+
+error_like(function () math.min() end,
+           "^[^:]+:%d+: bad argument #1 to 'min' %(number expected, got no value%)",
+           "function min 0")
+
+is(math.min(1), 1, "function min")
+is(math.min(1, 2), 1)
+is(math.min(1, 2, 3, -4), -4)
+
+eq_array({math.modf(2.25)}, {2, 0.25}, "function modf")
+
+is(math.pow(-2, 3), -8, "function pow")
+
+like(math.rad(180), '^3%.14', "function rad")
+
+like(math.random(), '^%d%.%d+', "function random no arg")
+
+like(math.random(9), '^%d$', "function random 1 arg")
+
+like(math.random(10, 19), '^1%d$', "function random 2 arg")
+
+if arg[-1] == 'luajit' then
+    todo("LuaJIT intentional. Don't check empty interval.", 2)
+end
+error_like(function () math.random(0) end,
+           "^[^:]+:%d+: bad argument #1 to 'random' %(interval is empty%)",
+           "function random empty interval")
+
+error_like(function () math.random(19, 10) end,
+           "^[^:]+:%d+: bad argument #2 to 'random' %(interval is empty%)",
+           "function random empty interval")
+
+if arg[-1] == 'luajit' then
+    todo("LuaJIT intentional. Don't care about extra arguments.")
+end
+error_like(function () math.random(1, 2, 3) end,
+           "^[^:]+:%d+: wrong number of arguments",
+           "function random too many arg")
+
+math.randomseed(12)
+a = math.random()
+math.randomseed(12)
+b = math.random()
+is(a, b, "function randomseed")
+
+like(math.sin(math.pi/2), '^1$', "function sin")
+
+like(math.sinh(1), '^1%.175', "function sinh")
+
+like(math.sqrt(2), '^1%.414', "function sqrt")
+
+like(math.tan(math.pi/3), '^1%.732', "function tan")
+
+like(math.tanh(1), '^0%.761', "function sinh")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 94 - 0
src/MoonSharp.Interpreter.Tests/TestMore/307-bit.t

@@ -0,0 +1,94 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2010-2011, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Bitwise Library
+
+=head2 Synopsis
+
+    % prove 307-bit.t
+
+=head2 Description
+
+Tests Lua Bitwise Library
+
+See "Lua 5.2 Reference Manual", section 6.7 "Bitwise operations",
+L<http://www.lua.org/manual/5.2/manual.html#6.7>.
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+if arg[-1] == 'luajit' then
+    skip_all("LuaJIT. bit32")
+end
+
+plan(20)
+
+is(bit32.band(0x01, 0x03, 0x07), 0x01, "function band")
+
+is(bit32.bnot(0x03), (-1 - 0x03) % 2^32, "function bnot")
+
+is(bit32.bor(0x01, 0x03, 0x07), 0x07, "function bor")
+
+is(bit32.btest(0x01), true, "function btest")
+is(bit32.btest(0x00), false, "function btest")
+
+is(bit32.bxor(0x01, 0x03, 0x07), 0x05, "function bxor")
+
+is(bit32.lrotate(0x03, 2), 0x0C, "function lrotate")
+
+is(bit32.rrotate(0x06, 1), 0x03, "function rrotate")
+
+is(bit32.arshift(0x06, 1), 0x03, "function arshift")
+
+is(bit32.arshift(-3, 1), bit32.arshift(-6, 2), "function arshift")
+
+is(bit32.lshift(0x03, 2), 0x0C, "function lshift")
+
+is(bit32.rshift(0x06, 1), 0x03, "function rshift")
+
+is(bit32.extract(0xFFFF, 3, 3), 0x07, "function extract")
+
+error_like(function () bit32.extract(0xFFFF, 99) end,
+           "^[^:]+:%d+: trying to access non%-existent bits",
+           "function extract (non-existent bits)")
+
+error_like(function () bit32.extract(0xFFFF, -3) end,
+           "^[^:]+:%d+: bad argument #2 to 'extract' %(field cannot be negative%)",
+           "function extract (negatif field)")
+
+error_like(function () bit32.extract(0xFFFF, 3, -3) end,
+           "^[^:]+:%d+: bad argument #3 to 'extract' %(width must be positive%)",
+           "function extract (negative width)")
+
+is(bit32.replace(0x0000, 0xFFFF, 3, 3), 0x38, "function replace")
+
+error_like(function () bit32.replace(0x0000, 0xFFFF, 99) end,
+           "^[^:]+:%d+: trying to access non%-existent bits",
+           "function replace (non-existent bits)")
+
+error_like(function () bit32.replace(0x0000, 0xFFFF, -3) end,
+           "^[^:]+:%d+: bad argument #3 to 'replace' %(field cannot be negative%)",
+           "function replace (negatif field)")
+
+error_like(function () bit32.replace(0x0000, 0xFFFF, 3, -3) end,
+           "^[^:]+:%d+: bad argument #4 to 'replace' %(width must be positive%)",
+           "function replace (negative width)")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 241 - 0
src/MoonSharp.Interpreter.Tests/TestMore/308-io.t

@@ -0,0 +1,241 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2012, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Input/Output Library
+
+=head2 Synopsis
+
+    % prove 308-io.t
+
+=head2 Description
+
+Tests Lua Input/Output Library
+
+See "Lua 5.2 Reference Manual", section 6.8 "Input and Output Facilities",
+L<http://www.lua.org/manual/5.2/manual.html#6.8>.
+
+See "Programming in Lua", section 21 "The I/O Library".
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+local lua = (platform and platform.lua) or arg[-1]
+
+plan(65)
+
+like(io.stdin, '^file %(0?[Xx]?%x+%)$', "variable stdin")
+
+like(io.stdout, '^file %(0?[Xx]?%x+%)$', "variable stdout")
+
+like(io.stderr, '^file %(0?[Xx]?%x+%)$', "variable stderr")
+
+r, msg = io.close(io.stderr)
+is(r, nil, "close (std)")
+is(msg, "cannot close standard file")
+
+is(io.flush(), true, "function flush")
+
+os.remove('file.no')
+f, msg = io.open("file.no")
+is(f, nil, "function open")
+is(msg, "file.no: No such file or directory")
+
+os.remove('file.txt')
+f = io.open('file.txt', 'w')
+f:write("file with text\n")
+f:close()
+f = io.open('file.txt')
+like(f, '^file %(0?[Xx]?%x+%)$', "function open")
+
+is(io.close(f), true, "function close")
+
+error_like(function () io.close(f) end,
+           "^[^:]+:%d+: attempt to use a closed file",
+           "function close (closed)")
+
+if arg[-1] == 'luajit' then
+    todo("LuaJIT TODO. open mode")
+end
+error_like(function () io.open('file.txt', 'baz') end,
+           "^[^:]+:%d+: invalid mode 'baz' %(should match '%[rwa%]%%%+%?b%?'%)",
+           "function open (bad mode)")
+
+is(io.type("not a file"), nil, "function type")
+f = io.open('file.txt')
+is(io.type(f), 'file')
+like(tostring(f), '^file %(0?[Xx]?%x+%)$')
+io.close(f)
+is(io.type(f), 'closed file')
+is(tostring(f), 'file (closed)')
+
+is(io.stdin, io.input(), "function input")
+is(io.stdin, io.input(nil))
+f = io.stdin
+like(io.input('file.txt'), '^file %(0?[Xx]?%x+%)$')
+is(f, io.input(f))
+
+is(io.output(), io.stdout, "function output")
+is(io.output(nil), io.stdout)
+f = io.stdout
+like(io.output('output.new'), '^file %(0?[Xx]?%x+%)$')
+is(f, io.output(f))
+os.remove('output.new')
+
+r, f = pcall(io.popen, lua .. [[ -e "print 'standard output'"]])
+if r then
+    is(io.type(f), 'file', "popen (read)")
+    is(f:read(), "standard output")
+    is(io.close(f), true)
+else
+    skip("io.popen not supported", 3)
+end
+
+r, f = pcall(io.popen, lua .. [[ -e "for line in io.lines() do print((line:gsub('e', 'a'))) end"]], 'w')
+if r then
+    is(io.type(f), 'file', "popen (write)")
+    f:write("# hello\n") -- not tested : hallo
+    is(io.close(f), true)
+else
+    skip("io.popen not supported", 2)
+end
+
+for line in io.lines('file.txt') do
+    is(line, "file with text", "function lines(filename)")
+end
+
+f = io.tmpfile()
+is(io.type(f), 'file', "function tmpfile")
+f:write("some text")
+f:close()
+
+io.write() -- not tested
+io.write('# text', 12, "\n") -- not tested :  # text12
+
+r, msg = io.stderr:close()
+is(r, nil, "method close (std)")
+is(msg, "cannot close standard file")
+
+f = io.open('file.txt')
+is(f:close(), true, "method close")
+
+is(io.stderr:flush(), true, "method flush")
+
+error_like(function () f:flush() end,
+           "^[^:]+:%d+: attempt to use a closed file",
+           "method flush (closed)")
+
+error_like(function () f:read() end,
+           "^[^:]+:%d+: attempt to use a closed file",
+           "method read (closed)")
+
+f = io.open('file.txt')
+s = f:read()
+is(s:len(), 14, "method read")
+is(s, "file with text")
+s = f:read()
+is(s, nil)
+f:close()
+
+f = io.open('file.txt')
+error_like(function () f:read('*z') end,
+           "^[^:]+:%d+: bad argument #1 to 'read' %(invalid %w+%)",
+           "method read (invalid)")
+f:close()
+
+f = io.open('file.txt')
+s1, s2 = f:read('*l', '*l')
+is(s1:len(), 14, "method read *l")
+is(s1, "file with text")
+is(s2, nil)
+f:close()
+
+f = io.open('file.txt')
+s1, s2 = f:read('*L', '*L')
+is(s1:len(), 15, "method read *L")
+is(s1, "file with text\n")
+is(s2, nil)
+f:close()
+
+f = io.open('file.txt')
+n1, n2 = f:read('*n', '*n')
+is(n1, nil, "method read *n")
+is(n2, nil)
+f:close()
+
+f = io.open('file.txt')
+s = f:read('*a')
+is(s:len(), 15, "method read *a")
+is(s, "file with text\n")
+f:close()
+
+f = io.open('file.txt')
+is(f:read(0), '', "method read number")
+eq_array({f:read(5, 5, 15)}, {'file ', 'with ', "text\n"})
+-- print(f:read(0))
+f:close()
+
+f = io.open('file.txt')
+for line in f:lines() do
+    is(line, "file with text", "method lines")
+end
+is(io.type(f), 'file')
+f:close()
+is(io.type(f), 'closed file')
+
+error_like(function () f:seek('end', 0) end,
+           "^[^:]+:%d+: attempt to use a closed file",
+           "method seek (closed)")
+
+f = io.open('file.txt')
+error_like(function () f:seek('bad', 0) end,
+           "^[^:]+:%d+: bad argument #1 to 'seek' %(invalid option 'bad'%)",
+           "method seek (invalid)")
+
+f = io.open('file.txt')
+if platform and platform.osname == 'MSWin32' then
+    is(f:seek('end', 0), 16, "method seek")
+else
+    is(f:seek('end', 0), 15, "method seek")
+end
+f:close()
+
+f = io.open('file.txt')
+is(f:setvbuf('no'), true, "method setvbuf 'no'")
+
+is(f:setvbuf('full', 4096), true, "method setvbuf 'full'")
+
+is(f:setvbuf('line', 132), true, "method setvbuf 'line'")
+f:close()
+
+os.remove('file.txt') -- clean up
+
+f = io.open('file.out', 'w')
+f:close()
+error_like(function () f:write('end') end,
+           "^[^:]+:%d+: attempt to use a closed file",
+           "method write (closed)")
+
+f = io.open('file.out', 'w')
+is(f:write('end'), f, "method write")
+f:close()
+
+os.remove('file.out') --clean up
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 184 - 0
src/MoonSharp.Interpreter.Tests/TestMore/309-os.t

@@ -0,0 +1,184 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2012, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Operating System Library
+
+=head2 Synopsis
+
+    % prove 309-os.t
+
+=head2 Description
+
+Tests Lua Operating System Library
+
+See "Lua 5.2 Reference Manual", section 6.9 "Operating System Facilities",
+L<http://www.lua.org/manual/5.2/manual.html#6.9>.
+
+See "Programming in Lua", section 22 "The Operating System Library".
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(51)
+
+local lua = (platform and platform.lua) or arg[-1]
+
+clk = os.clock()
+type_ok(clk, 'number', "function clock")
+ok(clk <= os.clock())
+
+d = os.date('!*t', 0)
+is(d.year, 1970, "function date")
+is(d.month, 1)
+is(d.day, 1)
+is(d.hour, 0)
+is(d.min, 0)
+is(d.sec, 0)
+is(d.wday, 5)
+is(d.yday, 1)
+is(d.isdst, false)
+
+is(os.date('!%d/%m/%y %H:%M:%S', 0), '01/01/70 00:00:00', "function date")
+
+like(os.date('%H:%M:%S'), '^%d%d:%d%d:%d%d', "function date")
+
+if arg[-1] == 'luajit' then
+    todo("LuaJIT TODO. invalid strftime.", 2)
+end
+is(os.date('%Oy', 0), '70')
+error_like(function () os.date('%Ja', 0) end,
+           "^[^:]+:%d+: bad argument #1 to 'date' %(invalid conversion specifier '%%Ja'%)",
+           "function date (invalid)")
+
+is(os.difftime(1234, 1200), 34, "function difftime")
+is(os.difftime(1234), 1234)
+
+r = os.execute()
+is(r, true, "function execute")
+
+cmd = lua .. [[ -e "print '# hello from external Lua'; os.exit(2)"]]
+r, s, n = os.execute(cmd)
+is(r, nil)
+is(s, 'exit', "function execute & exit")
+is(n, 2, "exit value")
+
+cmd = lua .. [[ -e "print '# hello from external Lua'; os.exit(false)"]]
+r, s, n = os.execute(cmd)
+is(r, nil)
+is(s, 'exit', "function execute & exit")
+is(n, 1, "exit value")
+
+cmd = lua .. [[ -e "print '# hello from external Lua'; os.exit(true, true)"]]
+is(os.execute(cmd), true, "function execute & exit")
+
+cmd = lua .. [[ -e "print 'reached'; os.exit(); print 'not reached';"]]
+r, f = pcall(io.popen, cmd)
+if r then
+    is(f:read'*l', 'reached', "function exit")
+    is(f:read'*l', nil)
+    code = f:close()
+    is(code, true, "exit code")
+else
+    skip("io.popen not supported", 3)
+end
+
+cmd = lua .. [[ -e "print 'reached'; os.exit(3); print 'not reached';"]]
+r, f = pcall(io.popen, cmd)
+if r then
+    is(f:read'*l', 'reached', "function exit")
+    is(f:read'*l', nil)
+    r, s, n = f:close()
+    is(r, nil)
+    is(s, 'exit', "exit code")
+    is(n, 3, "exit value")
+else
+    skip("io.popen not supported", 5)
+end
+
+is(os.getenv('__IMPROBABLE__'), nil, "function getenv")
+
+user = os.getenv('LOGNAME') or os.getenv('USERNAME')
+type_ok(user, 'string', "function getenv")
+
+local f = io.open('file.rm', 'w')
+f:write("file to remove")
+f:close()
+r = os.remove("file.rm")
+is(r, true, "function remove")
+
+r, msg = os.remove('file.rm')
+is(r, nil, "function remove")
+like(msg, '^file.rm: No such file or directory')
+
+local f = io.open('file.old', 'w')
+f:write("file to rename")
+f:close()
+os.remove('file.new')
+r = os.rename('file.old', 'file.new')
+is(r, true, "function rename")
+os.remove('file.new') -- clean up
+
+r, msg = os.rename('file.old', 'file.new')
+is(r, nil, "function rename")
+like(msg, '^file.old: No such file or directory')
+
+is(os.setlocale('C', 'all'), 'C', "function setlocale")
+is(os.setlocale(), 'C')
+
+is(os.setlocale('unk_loc', 'all'), nil, "function setlocale (unknown locale)")
+
+like(os.time(), '^%d+%.?%d*$', "function time")
+
+like(os.time(nil), '^%d+%.?%d*$', "function time")
+
+like(os.time({
+    sec = 0,
+    min = 0,
+    hour = 0,
+    day = 1,
+    month = 1,
+    year = 2000,
+    isdst = 0,
+}), '^946%d+$', "function time")
+
+if platform and platform.intsize == 8 then
+    todo("pb on 64bit platforms")
+    -- os.time returns nil when C mktime returns < 0
+    -- this test needs a out of range value on any platform
+end
+is(os.time({
+    sec = 0,
+    min = 0,
+    hour = 0,
+    day = 1,
+    month = 1,
+    year = 1000,
+    isdst = 0,
+}), nil, "function time -> nil")
+
+error_like(function () os.time{} end,
+           "^[^:]+:%d+: field 'day' missing in date table",
+           "function time (missing field)")
+
+fname = os.tmpname()
+type_ok(fname, 'string', "function tmpname")
+ok(fname ~= os.tmpname())
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 183 - 0
src/MoonSharp.Interpreter.Tests/TestMore/310-debug.t

@@ -0,0 +1,183 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2012, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Debug Library
+
+=head2 Synopsis
+
+    % prove 310-debug.t
+
+=head2 Description
+
+Tests Lua Debug Library
+
+See "Lua 5.2 Reference Manual", section 6.10 "The Debug Library",
+L<http://www.lua.org/manual/5.2/manual.html#6.10>.
+
+See "Programming in Lua", section 23 "The Debug Library".
+
+=cut
+
+]]
+
+require 'Test.More'
+
+plan(51)
+
+debug = require 'debug'
+
+info = debug.getinfo(is)
+type_ok(info, 'table', "function getinfo (function)")
+is(info.func, is, " .func")
+
+info = debug.getinfo(is, 'L')
+type_ok(info, 'table', "function getinfo (function, opt)")
+type_ok(info.activelines, 'table')
+
+info = debug.getinfo(1)
+type_ok(info, 'table', "function getinfo (level)")
+like(info.func, "^function: [0]?[Xx]?%x+", " .func")
+
+is(debug.getinfo(12), nil, "function getinfo (too depth)")
+
+error_like(function () debug.getinfo('bad') end,
+           "bad argument #1 to 'getinfo' %(function or level expected%)",
+           "function getinfo (bad arg)")
+
+error_like(function () debug.getinfo(is, 'X') end,
+           "bad argument #2 to 'getinfo' %(invalid option%)",
+           "function getinfo (bad opt)")
+
+local name, value = debug.getlocal(0, 1)
+type_ok(name, 'string', "function getlocal (level)")
+is(value, 0)
+
+error_like(function () debug.getlocal(42, 1) end,
+           "bad argument #1 to 'getlocal' %(level out of range%)",
+           "function getlocal (out of range)")
+
+local name, value = debug.getlocal(like, 1)
+type_ok(name, 'string', "function getlocal (func)")
+is(value, nil)
+
+t = {}
+is(debug.getmetatable(t), nil, "function getmetatable")
+t1 = {}
+debug.setmetatable(t, t1)
+is(debug.getmetatable(t), t1)
+
+a = true
+is(debug.getmetatable(a), nil)
+debug.setmetatable(a, t1)
+is(debug.getmetatable(t), t1)
+
+a = 3.14
+is(debug.getmetatable(a), nil)
+debug.setmetatable(a, t1)
+is(debug.getmetatable(t), t1)
+
+local reg = debug.getregistry()
+type_ok(reg, 'table', "function getregistry")
+type_ok(reg._LOADED, 'table')
+
+local name = debug.getupvalue(plan, 1)
+type_ok(name, 'string', "function getupvalue")
+
+debug.sethook()
+hook, mask, count = debug.gethook()
+is(hook, nil, "function gethook")
+is(mask, '')
+is(count, 0)
+local function f () end
+debug.sethook(f, 'c', 42)
+hook , mask, count = debug.gethook()
+is(hook, f, "function gethook")
+is(mask, 'c')
+is(count, 42)
+
+co = coroutine.create(function () print "thread" end)
+hook = debug.gethook(co)
+if arg[-1] == 'luajit' then
+    todo("LuaJIT TODO. debug.gethook(thread)", 1)
+end
+is(hook, nil, "function gethook(thread)")
+
+local name = debug.setlocal(0, 1, 0)
+type_ok(name, 'string', "function setlocal (level)")
+
+local name = debug.setlocal(0, 42, 0)
+is(name, nil, "function setlocal (level)")
+
+error_like(function () debug.setlocal(42, 1, true) end,
+           "bad argument #1 to 'setlocal' %(level out of range%)",
+           "function getlocal (out of range)")
+
+t = {}
+t1 = {}
+is(debug.setmetatable(t, t1), t, "function setmetatable")
+is(getmetatable(t), t1)
+
+error_like(function () debug.setmetatable(t, true) end,
+           "^[^:]+:%d+: bad argument #2 to 'setmetatable' %(nil or table expected%)")
+
+local name = debug.setupvalue(plan, 1, require 'Test.Builder':new())
+type_ok(name, 'string', "function setupvalue")
+
+local name = debug.setupvalue(plan, 42, true)
+is(name, nil)
+
+local u = io.tmpfile()
+local old = debug.getuservalue(u)
+if arg[-1] == 'luajit' then
+    type_ok(old, 'table', "function getuservalue")
+else
+    is(old, nil, "function getuservalue")
+end
+is(debug.getuservalue(true), nil)
+local data = {}
+r = debug.setuservalue(u, data)
+is(r, u, "function setuservalue")
+is(debug.getuservalue(u), data)
+r = debug.setuservalue(u, old)
+is(debug.getuservalue(u), old)
+
+error_like(function () debug.setuservalue({}, data) end,
+           "^[^:]+:%d+: bad argument #1 to 'setuservalue' %(userdata expected, got table%)")
+
+error_like(function () debug.setuservalue(u, true) end,
+           "^[^:]+:%d+: bad argument #2 to 'setuservalue' %(table expected, got boolean%)")
+
+like(debug.traceback(), "^stack traceback:\n", "function traceback")
+
+like(debug.traceback("message\n"), "^message\n\nstack traceback:\n", "function traceback with message")
+
+like(debug.traceback(false), "false", "function traceback")
+
+local id = debug.upvalueid(plan, 1)
+type_ok(id, 'userdata', "function upvalueid")
+
+debug.upvaluejoin (pass, 1, fail, 1)
+
+error_like(function () debug.upvaluejoin(true, 1, nil, 1) end,
+           "bad argument #1 to 'upvaluejoin' %(function expected, got boolean%)",
+           "function upvaluejoin (bad arg)")
+
+error_like(function () debug.upvaluejoin(pass, 1, true, 1) end,
+           "bad argument #3 to 'upvaluejoin' %(function expected, got boolean%)",
+           "function upvaluejoin (bad arg)")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 207 - 0
src/MoonSharp.Interpreter.Tests/TestMore/314-regex.t

@@ -0,0 +1,207 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2011, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Regex Compiler
+
+=head2 Synopsis
+
+    % prove 314-regex.t
+
+=head2 Description
+
+Tests Lua Regex
+
+Individual tests are stored in the C<rx_*> files in the same directory;
+There is one test per line: each test consists of the following
+columns (separated by one *or more* tabs):
+
+=over 4
+
+=item pattern
+
+The Lua regex to test.
+
+=item target
+
+The string that will be matched against the pattern. Use '' to indicate
+an empty string.
+
+=item result
+
+The expected result of the match.
+
+=item description
+
+Description of the test.
+
+=back
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+plan(162)
+
+local test_files = {
+    'rx_captures',
+    'rx_charclass',
+    'rx_metachars',
+}
+
+local todo_info = {
+}
+
+if arg[-1] == 'luajit' then
+    todo_info[147] = "LuaJIT TODO. \\0"
+    todo_info[149] = "LuaJIT TODO. \\0"
+    todo_info[151] = "LuaJIT TODO. [^\\0]"
+    todo_info[153] = "LuaJIT TODO. [^\\0]"
+end
+
+local function split (line)
+    local pattern, target, result, desc = '', '', '', ''
+    local idx = 1
+    local c = line:sub(idx, idx)
+    while (c ~= '' and c ~= "\t") do
+        if (c == '"') then
+            pattern = pattern .. "\\\""
+        else
+            pattern = pattern .. c
+        end
+        idx = idx + 1
+        c = line:sub(idx, idx)
+    end
+    if pattern == "''" then
+        pattern = ''
+    end
+    while (c ~= '' and c == "\t") do
+        idx = idx + 1
+        c = line:sub(idx, idx)
+    end
+    while (c ~= '' and c ~= "\t") do
+        if (c == '"') then
+            target = target .. "\\\""
+        else
+            target = target .. c
+        end
+        idx = idx + 1
+        c = line:sub(idx, idx)
+    end
+    if target == "''" then
+        target = ''
+    end
+    while (c ~= '' and c == "\t") do
+        idx = idx + 1
+        c = line:sub(idx, idx)
+    end
+    while (c ~= '' and c ~= "\t") do
+        if c == "\\" then
+            idx = idx + 1
+            c = line:sub(idx, idx)
+            if     c == 'f' then
+                result = result .. "\f"
+            elseif c == 'n' then
+                result = result .. "\n"
+            elseif c == 'r' then
+                result = result .. "\r"
+            elseif c == 't' then
+                result = result .. "\t"
+            elseif c == '0' then
+                idx = idx + 1
+                c = line:sub(idx, idx)
+                if     c == '1' then
+                    result = result .. "\01"
+                elseif c == '2' then
+                    result = result .. "\02"
+                elseif c == '3' then
+                    result = result .. "\03"
+                elseif c == '4' then
+                    result = result .. "\04"
+                else
+                    result = result .. "\0" .. c
+                end
+            elseif c == "\t" then
+                result = result .. "\\"
+            else
+                result = result .. "\\" .. c
+            end
+        else
+            result = result .. c
+        end
+        idx = idx + 1
+        c = line:sub(idx, idx)
+    end
+    if result == "''" then
+        result = ''
+    end
+    while (c ~= '' and c == "\t") do
+        idx = idx + 1
+        c = line:sub(idx, idx)
+    end
+    while (c ~= '' and c ~= "\t") do
+        desc = desc .. c
+        idx = idx + 1
+        c = line:sub(idx, idx)
+    end
+    return pattern, target, result, desc
+end
+
+local test_number = 0
+local dirname = arg[0]:sub(1, arg[0]:find'314' -1)
+for _, filename in ipairs(test_files) do
+    local f, msg = io.open(dirname .. filename, 'r')
+    if f == nil then
+        diag(msg)
+        break
+    else
+        for line in f:lines() do
+            if line:len() == 0 then
+                break
+            end
+            local pattern, target, result, desc = split(line)
+            test_number = test_number + 1
+            if todo_info[test_number] then
+                todo(todo_info[test_number])
+            end
+            local code = [[
+                    local t = {string.match("]] .. target .. [[", "]] .. pattern .. [[")}
+                    if #t== 0 then
+                        return 'nil'
+                    else
+                        return table.concat(t, "\t")
+                    end
+            ]]
+            local compiled, msg = load(code)
+            if not compiled then
+                error("can't compile : " .. code .. "\n" .. msg)
+            end
+            if result:sub(1, 1) == '/' then
+                local pattern = result:sub(2, result:len() - 1)
+                error_like(compiled, pattern, desc)
+            else
+                local out
+                pcall(function () out = compiled() end)
+                is(out, result, desc)
+            end
+        end
+        f:close()
+    end
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 124 - 0
src/MoonSharp.Interpreter.Tests/TestMore/320-stdin.t

@@ -0,0 +1,124 @@
+#! /usr/bin/lua
+--
+-- lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
+--
+-- Copyright (C) 2009-2011, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Library
+
+=head2 Synopsis
+
+    % prove 320-stdin.t
+
+=head2 Description
+
+Tests Lua Basic & IO Libraries with stdin
+
+=cut
+
+--]]
+
+require 'Test.More'
+
+local lua = (platform and platform.lua) or arg[-1]
+
+if not pcall(io.popen, lua .. [[ -e "a=1"]]) then
+    skip_all "io.popen not supported"
+end
+
+plan(12)
+
+f = io.open('lib1.lua', 'w')
+f:write[[
+function norm (x, y)
+    return (x^2 + y^2)^0.5
+end
+
+function twice (x)
+    return 2*x
+end
+]]
+f:close()
+
+cmd = lua .. [[ -e "dofile(); n = norm(3.4, 1.0); print(twice(n))" < lib1.lua]]
+f = io.popen(cmd)
+like(f:read'*l', '^7%.088', "function dofile (stdin)")
+f:close()
+
+os.remove('lib1.lua') -- clean up
+
+f = io.open('foo.lua', 'w')
+f:write[[
+function foo (x)
+    return x
+end
+]]
+f:close()
+
+cmd = lua .. [[ -e "f = loadfile(); print(foo); f(); print(foo('ok'))" < foo.lua]]
+f = io.popen(cmd)
+is(f:read'*l', 'nil', "function loadfile (stdin)")
+is(f:read'*l', 'ok')
+f:close()
+
+os.remove('foo.lua') -- clean up
+
+f = io.open('file.txt', 'w')
+f:write("file with text\n")
+f:close()
+
+cmd = lua .. [[ -e "print(io.read'*l'); print(io.read'*l'); print(io.type(io.stdin))" < file.txt]]
+f = io.popen(cmd)
+is(f:read'*l', 'file with text', "function io.read *l")
+is(f:read'*l', 'nil')
+is(f:read'*l', 'file')
+f:close()
+
+f = io.open('number.txt', 'w')
+f:write("6.0     -3.23   15e12\n")
+f:write("4.3     234     1000001\n")
+f:close()
+
+cmd = lua .. [[ -e "while true do local n1, n2, n3 = io.read('*number', '*number', '*number'); if not n1 then break end; print(math.max(n1, n2, n3)) end" < number.txt]]
+f = io.popen(cmd)
+is(f:read'*l', '15000000000000', "function io:read *number")
+is(f:read'*l', '1000001')
+f:close()
+
+os.remove('number.txt') -- clean up
+
+cmd = lua .. [[ -e "for line in io.lines() do print(line) end" < file.txt]]
+f = io.popen(cmd)
+is(f:read'*l', 'file with text', "function io.lines")
+is(f:read'*l', nil)
+f:close()
+
+os.remove('file.txt') -- clean up
+
+f = io.open('dbg.txt', 'w')
+f:write("print 'ok'\n")
+f:write("error 'dbg'\n")
+f:write("cont\n")
+f:close()
+
+cmd = lua .. [[ -e "debug.debug()" < dbg.txt]]
+f = io.popen(cmd)
+is(f:read'*l', 'ok', "function debug.debug")
+is(f:read'*l', nil)
+f:close()
+
+os.remove('dbg.txt') -- clean up
+
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:

+ 13 - 0
src/MoonSharp.Interpreter.Tests/TestMore/rx_captures

@@ -0,0 +1,13 @@
+(a.)..(..)		zzzabcdefzzz	ab\tef			basic match
+(a(b(c))(d))		abcd		abcd\tbc\tc\td		nested match
+((%w+))			abcd		abcd\tabcd		nested match
+(a*(.)%w(%s*))		aa!b c		aa!b \t!\t 		nested match
+(a?)..			abcd		a			opt
+(A?)..			abcd		''			opt
+()aa()			flaaap		3\t5			empty capture
+(.)%1			bookkeeper	o			backreference
+(%w+)%s+%1		hello hello	hello			backreference
+(.*)x			123x		123			repeated dot capture
+$(%w+)			$abc=		abc			not escaped
+
+## vim: noexpandtab tabstop=4 shiftwidth=4

+ 38 - 0
src/MoonSharp.Interpreter.Tests/TestMore/rx_charclass

@@ -0,0 +1,38 @@
+[c]			abcdef		c		character class
+^[a]			abcdef		a		anchored character class
+[^e]			abcdef		a		negated character class
+^[a]?			abcdef		a		anchored optional character class
+[^e]?			abcdef		a		negated optional character class
+^[^e]			abcdef		a		anchored negated character class
+^[^a]			abcdef		nil		anchored negated character class
+[b-d]			abcdef		b		character range
+[b-d]			abxxef		b		character range
+[b-d]			axcxef		c		character range
+[b-d]			axxdef		d		character range
+[b-d]			axxxef		nil		character range
+[^b-d]			abcdef		a		negated character range
+[^b-d]			bbccdd		nil		negated character range
+[-]			ab-def		-		unescaped hyphen
+[%-]			ab-def		-		escaped hyphen
+[%-]			abcdef		nil		escaped hyphen
+[^%-]			---x--		x		negated escaped hyphen
+[^%-]			------		nil		negated escaped hyphen
+[%-+]			ab-def		-		escaped hyphen in range
+[%-+]			ab+def		+		escaped hyphen in range
+[%-+]			abcdef		nil		escaped hyphen in range
+[+%-]			ab-def		-		escaped hyphen in range
+[+%-]			ab+def		+		escaped hyphen in range
+[+%-]			abcdef		nil		escaped hyphen in range
+[^%-+]			---x--		x		negated escaped hyphen in range
+[^%-+]			------		nil		negated escaped hyphen in range
+[^+%-]			---x--		x		negated escaped hyphen in range
+[^+%-]			------		nil		negated escaped hyphen in range
+["\\]			\\		\		escaped backslash
+[%]]			]		]		escaped close bracket
+[%]			\\]]		/malformed pattern %(missing ']'%)/	unescaped backslash (or no closing brace)
+ab\\cd			ab\092cd	ab\cd		literal match with backslash
+%?			ab<?		?		literal match with question mark
+[A-Z0-9]		abcdef		nil		two enumerated ranges
+[A-Z0-9]		abcDef		D		two enumerated ranges
+
+## vim: noexpandtab tabstop=4 shiftwidth=4

+ 117 - 0
src/MoonSharp.Interpreter.Tests/TestMore/rx_metachars

@@ -0,0 +1,117 @@
+.			a		a		dot (.)
+.			\n		\n		dot (.)
+.			''		nil		dot (.)
+a%s+f			abcdef		nil		whitespace (%s)
+ab%s+cdef		ab  cdef	ab  cdef	whitespace (%s)
+a%S+f			abcdef		abcdef		not whitespace (%S)
+a%S+f			ab cdef		nil		not whitespace (%S)
+^abc			abcdef		abc		start and end of string (^)
+^abc			abc\ndef	abc		start and end of string (^)
+^abc			def\nabc	nil		start and end of string (^)
+def\n^abc		def\nabc	nil		start and end of string (^)
+def$			abcdef		def		start and end of string ($)
+def$			abc\ndef	def		start and end of string ($)
+def$			def\nabc	nil		start and end of string ($)
+def$\nabc		def\nabc	nil		start and end of string (^)
+abc\n$			abc\n		abc\n		end of string ($)
+abc$			abc\n		nil		end of string ($)
+c\nd			abc\ndef	c\nd		newline (\n)
+c\nd			abc\010def	c\nd		newline (\n)
+c\n+d			abc\n\ndef	c\n\nd		newline (\n)
+a\n+f			abcdef		nil		newline (\n)
+b\nc			abc\ndef	nil		newline (\n)
+c\td			abc\tdef	c\td		horizontal tab (\t)
+c\td			abc\09def	c\td		horizontal tab (\t)
+c\t+d			abc\t\tdef	c\t\td		horizontal tab (\t)
+a\t+f			abcdef		nil		horizontal tab (\t)
+b\tc			abc\tdef	nil		horizontal tab (\t)
+c\rd			abc\rdef	c\rd		return (\r)
+c\rd			abc\013def	c\rd		return (\r)
+c\r+d			abc\r\rdef	c\r\rd		return (\r)
+a\r+f			abcdef		nil		return (\r)
+b\rc			abc\rdef	nil		return (\r)
+c\fd			abc\fdef	c\fd		formfeed (\f)
+c\fd			abc\012def	c\fd		formfeed (\f)
+c\f+d			abc\f\fdef	c\f\fd		formfeed (\f)
+a\f+f			abcdef		nil		formfeed (\f)
+b\fc			abc\fdef	nil		formfeed (\f)
+c\033d			abc!def		c!d		dec (\0)
+c\033d			abc\033def	c!d		dec (\0)
+c\033+d			abc!!def	c!!d		dec (\0)
+a\033+f			abcdef		nil		dec (\0)
+b\033c			abc!def		nil		dec (\0)
+a%^d			a^d		a^d		escaped (useless)
+a^d			a^d		a^d		not escaped
+%^d			^d		^d		escaped
+a%$d			a$d		a$d		escaped (useless)
+a$d			a$d		a$d		not escaped
+a%$			a$		a$		escaped
+a%(d			a(d		a(d		escaped
+a%)d			a)d		a)d		escaped
+a%%d			a%d		a%d		escaped
+a%			a%		/malformed pattern %(ends with '%%'%)/	not escaped
+a%.d			a.d		a.d		escaped
+a%.d			abd		nil		escaped
+a%[d			a[d		a[d		escaped
+a%]d			a]d		a]d		escaped
+a%*d			a*d		a*d		escaped
+*ad			*ad		*ad		not escaped
+a%+d			a+d		a+d		escaped
+a%-d			a-d		a-d		escaped
+a%?d			a?d		a?d		escaped
+a%yd			ayd		ayd		escaped
+a%w+f			a=[ *f		nil		word character
+a%w+f			abcdef		abcdef		word character
+a%W+f			a&%- f		a&%- f		not word character
+a%W+f			abcdef		nil		not word character
+a%d+f			abcdef		nil		digit
+ab%d+cdef		ab42cdef	ab42cdef	digit
+a%D+f			abcdef		abcdef		not digit
+a%D+f			ab0cdef		nil		not digit
+a%l+f			aBCDEf		nil		lowercase letter
+a%l+f			abcdef		abcdef		lowercase letter
+a%L+f			a&2D f		a&2D f		not lowercase letter
+a%L+f			aBCdEf		nil		not lowercase letter
+a%u+f			abcdef		nil		uppercase letter
+a%u+f			aBCDEf		aBCDEf		uppercase letter
+a%U+f			a&2d f		a&2d f		not uppercase letter
+a%U+f			a&2D f		nil		not uppercase letter
+a%a+f			aBcDef		aBcDef		all letter
+a%a+f			a=[ *f		nil		all letter
+a%A+f			a&%- f		a&%- f		not all letter
+a%A+f			abcdef		nil		not all letter
+a%g+f			aBcDef		aBcDef		printable
+a%g+f			a=[ *f		nil		printable
+a%G+f			a \nf		a \nf		not printable
+a%G+f			abcdef		nil		not printable
+a%p+f			abcdef		nil		ponctuation
+a%p+f			a,;:!f		a,;:!f		ponctuation
+a%P+f			abcdef		abcdef		not ponctuation
+a%P+f			adc:ef		nil		not ponctuation
+a%c+f			abcdef		nil		control character
+a%c+f			a\04\03\02f	a\04\03\02f	control character
+a%C+f			abcdef		abcdef		not control character
+a%C+f			abc\01ef	nil		not control character
+a%x+f			axyzef		nil		hexadecimal
+a%x+f			ab3Def		ab3Def		hexadecimal
+a%X+f			abcdef		nil		not hexadecimal
+a%X+f			axy;Zf		axy;Zf		not hexadecimal
+a%z+f			abcdef		nil		zero (deprecated)
+a\0+f			abcdef		nil		zero
+a%z+f			a\0f		a\0f		zero (deprecated)
+a\0+f			a\0f		a\0f		zero
+a%Z+f			abcdef		abcdef		not zero (deprecated)
+a[^\0]+f		abcdef		abcdef		not zero
+a%Z+f			abc\0ef		nil		not zero (deprecated)
+a[^\0]+f		abc\0ef		nil		not zero
+a%b()f			a(bcde)f	a(bcde)f	balanced
+a%b()f			a(b(de)f	nil		balanced
+a%b()f			a(b(d)e)f	a(b(d)e)f	balanced
+a%b''f			a'bcde'f	a'bcde'f	balanced
+a%b""f			a"bcde"f	a"bcde"f	balanced
+%f[b]bc			abcdef		bc		frontier
+%f[b]c			abcdef		nil		frontier
+%f[^ab]c		abacdef		c		frontier
+%f[^ab]d		abacdef		nil		frontier
+
+## vim: noexpandtab tabstop=4 shiftwidth=4

+ 305 - 0
src/MoonSharp.Interpreter.Tests/TestMoreTests.cs

@@ -0,0 +1,305 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+
+namespace MoonSharp.Interpreter.Tests
+{
+	[TestFixture]
+	public class TestMoreTests
+	{
+		[Test]
+		public void TestMore_000_sanity()
+		{
+			TapRunner.Run(@"TestMore\000-sanity.t");
+		}
+
+
+		[Test]
+		public void TestMore_001_if()
+		{
+			TapRunner.Run(@"TestMore\001-if.t");
+		}
+
+
+		[Test]
+		public void TestMore_002_table()
+		{
+			TapRunner.Run(@"TestMore\002-table.t");
+		}
+
+
+		[Test]
+		public void TestMore_011_while()
+		{
+			TapRunner.Run(@"TestMore\011-while.t");
+		}
+
+
+		[Test]
+		public void TestMore_012_repeat()
+		{
+			TapRunner.Run(@"TestMore\012-repeat.t");
+		}
+
+
+		[Test]
+		public void TestMore_014_fornum()
+		{
+			TapRunner.Run(@"TestMore\014-fornum.t");
+		}
+
+
+		[Test]
+		public void TestMore_015_forlist()
+		{
+			TapRunner.Run(@"TestMore\015-forlist.t");
+		}
+
+
+		[Test]
+		public void TestMore_101_boolean()
+		{
+			TapRunner.Run(@"TestMore\101-boolean.t");
+		}
+
+
+		[Test]
+		public void TestMore_102_function()
+		{
+			TapRunner.Run(@"TestMore\102-function.t");
+		}
+
+
+		[Test]
+		public void TestMore_103_nil()
+		{
+			TapRunner.Run(@"TestMore\103-nil.t");
+		}
+
+
+		[Test]
+		public void TestMore_104_number()
+		{
+			TapRunner.Run(@"TestMore\104-number.t");
+		}
+
+
+		[Test]
+		public void TestMore_105_string()
+		{
+			TapRunner.Run(@"TestMore\105-string.t");
+		}
+
+
+		[Test]
+		public void TestMore_106_table()
+		{
+			TapRunner.Run(@"TestMore\106-table.t");
+		}
+
+
+		[Test]
+		public void TestMore_107_thread()
+		{
+			TapRunner.Run(@"TestMore\107-thread.t");
+		}
+
+
+		[Test]
+		public void TestMore_108_userdata()
+		{
+			TapRunner.Run(@"TestMore\108-userdata.t");
+		}
+
+
+		[Test]
+		public void TestMore_200_examples()
+		{
+			TapRunner.Run(@"TestMore\200-examples.t");
+		}
+
+
+		[Test]
+		public void TestMore_201_assign()
+		{
+			TapRunner.Run(@"TestMore\201-assign.t");
+		}
+
+
+		[Test]
+		public void TestMore_202_expr()
+		{
+			TapRunner.Run(@"TestMore\202-expr.t");
+		}
+
+
+		[Test]
+		public void TestMore_203_lexico()
+		{
+			TapRunner.Run(@"TestMore\203-lexico.t");
+		}
+
+
+		[Test]
+		public void TestMore_204_grammar()
+		{
+			TapRunner.Run(@"TestMore\204-grammar.t");
+		}
+
+
+		[Test]
+		public void TestMore_211_scope()
+		{
+			TapRunner.Run(@"TestMore\211-scope.t");
+		}
+
+
+		[Test]
+		public void TestMore_212_function()
+		{
+			TapRunner.Run(@"TestMore\212-function.t");
+		}
+
+
+		[Test]
+		public void TestMore_213_closure()
+		{
+			TapRunner.Run(@"TestMore\213-closure.t");
+		}
+
+
+		[Test]
+		public void TestMore_214_coroutine()
+		{
+			TapRunner.Run(@"TestMore\214-coroutine.t");
+		}
+
+
+		[Test]
+		public void TestMore_221_table()
+		{
+			TapRunner.Run(@"TestMore\221-table.t");
+		}
+
+
+		[Test]
+		public void TestMore_222_constructor()
+		{
+			TapRunner.Run(@"TestMore\222-constructor.t");
+		}
+
+
+		[Test]
+		public void TestMore_223_iterator()
+		{
+			TapRunner.Run(@"TestMore\223-iterator.t");
+		}
+
+
+		[Test]
+		public void TestMore_231_metatable()
+		{
+			TapRunner.Run(@"TestMore\231-metatable.t");
+		}
+
+
+		[Test]
+		public void TestMore_232_object()
+		{
+			TapRunner.Run(@"TestMore\232-object.t");
+		}
+
+
+		[Test]
+		public void TestMore_241_standalone()
+		{
+			TapRunner.Run(@"TestMore\241-standalone.t");
+		}
+
+
+		[Test]
+		public void TestMore_242_luac()
+		{
+			TapRunner.Run(@"TestMore\242-luac.t");
+		}
+
+
+		[Test]
+		public void TestMore_301_basic()
+		{
+			TapRunner.Run(@"TestMore\301-basic.t");
+		}
+
+
+		[Test]
+		public void TestMore_303_package()
+		{
+			TapRunner.Run(@"TestMore\303-package.t");
+		}
+
+
+		[Test]
+		public void TestMore_304_string()
+		{
+			TapRunner.Run(@"TestMore\304-string.t");
+		}
+
+
+		[Test]
+		public void TestMore_305_table()
+		{
+			TapRunner.Run(@"TestMore\305-table.t");
+		}
+
+
+		[Test]
+		public void TestMore_306_math()
+		{
+			TapRunner.Run(@"TestMore\306-math.t");
+		}
+
+
+		[Test]
+		public void TestMore_307_bit()
+		{
+			TapRunner.Run(@"TestMore\307-bit.t");
+		}
+
+
+		[Test]
+		public void TestMore_308_io()
+		{
+			TapRunner.Run(@"TestMore\308-io.t");
+		}
+
+
+		[Test]
+		public void TestMore_309_os()
+		{
+			TapRunner.Run(@"TestMore\309-os.t");
+		}
+
+
+		[Test]
+		public void TestMore_310_debug()
+		{
+			TapRunner.Run(@"TestMore\310-debug.t");
+		}
+
+
+		[Test]
+		public void TestMore_314_regex()
+		{
+			TapRunner.Run(@"TestMore\314-regex.t");
+		}
+
+
+		[Test]
+		public void TestMore_320_stdin()
+		{
+			TapRunner.Run(@"TestMore\320-stdin.t");
+		}
+	}
+}

+ 10 - 3
src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScopeFrame.cs

@@ -40,9 +40,16 @@ namespace MoonSharp.Interpreter.Execution
 
 		public int Define(string name)
 		{
-			m_IndexList.Add(name, MaxIndex - BaseIndex);
-			m_RevIndexList.Add(MaxIndex - BaseIndex, name);
-			return MaxIndex++;
+			if (!m_IndexList.ContainsKey(name))
+			{
+				m_IndexList.Add(name, MaxIndex - BaseIndex);
+				m_RevIndexList.Add(MaxIndex - BaseIndex, name);
+				return MaxIndex++;
+			}
+			else
+			{
+				return m_IndexList[name];
+			}
 		}
 
 	}

+ 14 - 0
src/MoonSharp.Interpreter/Execution/VM/Processor/Processor_InstructionLoop.cs

@@ -43,6 +43,9 @@ namespace MoonSharp.Interpreter.Execution.VM
 					case OpCode.Add:
 						ExecAdd(i);
 						break;
+					case OpCode.Concat:
+						ExecConcat(i);
+						break;
 					case OpCode.Neg:
 						ExecNeg(i);
 						break;
@@ -432,6 +435,17 @@ namespace MoonSharp.Interpreter.Execution.VM
 				throw new NotImplementedException("Meta operators");
 		}
 
+		private void ExecConcat(Instruction i)
+		{
+			RValue r = m_ValueStack.Pop();
+			RValue l = m_ValueStack.Pop();
+
+			if ((r.Type == DataType.String || r.Type == DataType.Number) && (l.Type == DataType.String || l.Type == DataType.Number))
+				m_ValueStack.Push(new RValue(l.AsString() + r.AsString()));
+			else
+				throw new NotImplementedException("Meta operators");
+		}
+
 		private void ExecSub(Instruction i)
 		{
 			RValue r = m_ValueStack.Pop();