### Set and Get Metatable Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/MoonSharp/Scripts/231-metatable.t.txt Demonstrates setting and retrieving metatables for a table. Note that metatables can be protected, preventing further changes. ```lua t = {} is(getmetatable(t), nil, "metatable") t1 = {} is(setmetatable(t, t1), t) is(getmetatable(t), t1) is(setmetatable(t, nil), t) ``` ```lua error_like(function () setmetatable(t, true) end, "^[^:]+:%d+: bad argument #2 to 'setmetatable' %(nil or table expected.+%)") ``` ```lua 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") ``` -------------------------------- ### Window Namespace and Prototype Setup Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/231-metatable.t.txt Sets up a 'Window' namespace, defines a prototype with default properties, and declares a constructor function using a metatable. ```lua -- 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 ``` -------------------------------- ### Basic Metatable Operations in Lua Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/231-metatable.t.txt Demonstrates setting and getting metatables for a table, including handling nil and invalid arguments. ```lua t = {} is(getmetatable(t), nil, "metatable") t1 = {} is(setmetatable(t, t1), t) is(getmetatable(t), t1) is(setmetatable(t, nil), t) ``` ```lua error_like(function () setmetatable(t, true) end, "^[^:]+:%d+: bad argument #2 to 'setmetatable' %(nil or table expected.+%)") ``` -------------------------------- ### Table Unpacking Examples Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/MoonSharp/Scripts/305-table.t.txt Demonstrates the usage of table.unpack with various arguments, including empty tables, single elements, multiple elements, and specified ranges. ```lua eq_array({table.unpack({})}, {}, "function sort (all permutations)") ``` ```lua eq_array({table.unpack({'a'})}, {'a'}) ``` ```lua eq_array({table.unpack({'a','b','c'})}, {'a','b','c'}) ``` ```lua eq_array({(table.unpack({'a','b','c'}))}, {'a'}) ``` ```lua eq_array({table.unpack({'a','b','c','d','e'},2,4)}, {'b','c','d'}) ``` ```lua eq_array({table.unpack({'a','b','c'},2,4)}, {'b','c'}) ``` -------------------------------- ### Unpack Table with Default Start Index Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/305-table.t.txt Shows `table.unpack` on a table, where by default it unpacks from the first element. ```lua eq_array({(table.unpack({'a','b','c'}))}, {'a'}) ``` -------------------------------- ### Initialize Lua Table with List-Style Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/222-constructor.t.txt Use this syntax to initialize a table with sequential integer keys starting from 1. Useful for creating arrays or lists. ```lua days = {'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'} is(days[4], 'Wednesday', "list-style init") is(#days, 7) ``` -------------------------------- ### Set and Get Output File Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/308-io.t.txt Tests the io.output() function to set and retrieve the default output file. It checks against stdout and a specified file. ```lua 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') ``` -------------------------------- ### Set and Get Input File Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/308-io.t.txt Tests the io.input() function to set and retrieve the default input file. It checks against stdin and a specified file. ```lua 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)) ``` -------------------------------- ### Local Nested Table Initialization and Access Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/Scripts/TestMore/221-table.txt Similar to the previous example, but uses a local variable for the table. Demonstrates initialization, access, modification, and concatenation of nested table elements. ```lua 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') ``` -------------------------------- ### Initialize TestMore Instance Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/Scripts/TestMore/Modules/Test/Builder.txt Creates a new instance of the TestMore testing framework. This is the primary way to get a test object to use. ```lua local test = require 'testmore'.new() ``` -------------------------------- ### Lua Numeric For Loop with Functions for Parameters Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/014-fornum.t.txt Illustrates using functions to define the start, limit, and step values for a numeric for loop. This allows for dynamic loop parameters. ```lua 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 ``` -------------------------------- ### Initialize TestMore Instance Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/MoonSharp/Scripts/Modules/Test/Builder.lua.txt Creates a new instance of the TestMore testing framework. It's recommended to call this function to get a fresh testing environment. ```lua local test = m.new() return test ``` -------------------------------- ### Generated R Class Structure Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Xamarin/XamarinTestBed_Android/XamarinTestBed_Android/Resources/AboutResources.txt This is an example of the 'R' class generated by the build system, which contains tokens for each resource. Use these tokens to reference resources programmatically. ```csharp public class R { public class drawable { public const int icon = 0x123; } public class layout { public const int main = 0x456; } public class strings { public const int first_string = 0xabc; public const int second_string = 0xbcd; } } ``` -------------------------------- ### Lua String Length and Indexing Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/MoonSharp/Scripts/105-string.t.txt Demonstrates getting the length of a string and attempting to index it. Indexing strings in Lua is not supported and results in an error. ```lua is(# 'text', 4, "#'text'") ``` ```lua a = 'text' is(a[1], nil, "index") ``` ```lua error_like(function () a = 'text'; a[1] = 1; end, "^[^:]+:%d+: attempt to index", "index") ``` -------------------------------- ### Run Subtest Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/Modules/Test/Builder.lua.txt Executes a function as a subtest. Handles setup, execution, and finalization of the subtest, reporting its success or failure to the parent. ```lua function m:subtest (name, func) if type(func) ~= 'function' then error("subtest()'s second argument must be a function") end self:diag('Subtest: ' .. name) local child = self:child(name) local parent = self.data self.data = child.data local r, msg = pcall(func) child.data = self.data self.data = parent if not r and not child._skip_all then error(msg, 0) end if not plan_handled(child) then child:done_testing() end child:finalize() end ``` -------------------------------- ### Lua Test Suite Example Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/000-sanity.t.txt This Lua script defines simple functions and prints test results. It's designed to be run with a test runner that understands the Test Anything Protocol (TAP). ```lua #! /usr/bin/lua -- -- 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: ``` -------------------------------- ### Lua Multiple Inheritance Setup Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/232-object.t.txt Provides a generic 'createClass' function that enables multiple inheritance by setting the metatable's '__index' to search through a list of parent classes. ```lua -- 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) ``` -------------------------------- ### Find a pattern starting from a specific position with string.match Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/Scripts/TestMore/304-string.txt Use string.match with a starting position to find a pattern. This example finds 'world' starting from the 2nd character. ```lua is(string.match(s, 'world', 2), 'world') ``` -------------------------------- ### Find a pattern at the beginning of a string with string.match Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/Scripts/TestMore/304-string.txt Use string.match to find the first occurrence of a pattern. This example matches 'hello' at the start of the string. ```lua is(string.match(s, '^hello'), 'hello', "function match") ``` -------------------------------- ### Table Initialization and Mixed Key Types Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/MoonSharp/Scripts/221-table.t.txt Shows how to initialize a table and populate it with a loop. It also illustrates accessing values using string keys, numeric keys, and checking for non-existent keys. Demonstrates using string keys that are valid identifiers with dot notation. ```lua 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) ``` ```lua a = {} x = 'y' a[x] = 10 is(a[x], 10) is(a.x, nil) is(a.y, 10) ``` ```lua 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") ``` -------------------------------- ### Lua Multiple Inheritance Example Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/232-object.t.txt Demonstrates multiple inheritance by creating a NamedAccount class that inherits from both Account and Named. Use this to model complex object relationships. ```lua NamedAccount = createClass(Account, Named) account = NamedAccount:new{name = "Paul"} is(account:getname(), 'Paul', "multiple inheritance (patched)") account:deposit(100.00) is(account.balance, 100) ``` -------------------------------- ### Basic Coroutine Creation and Execution Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/214-coroutine.t.txt Demonstrates the creation of a coroutine and its step-by-step execution using coroutine.resume. Shows how values are passed and returned between the main thread and the coroutine. ```lua 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', }) ``` -------------------------------- ### Build and Package MoonSharp VSCode Extension Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/moonsharp-vscode-debug/readme.md Commands to install dependencies, compile the extension, and package it into a VSIX file for installation. These are development-time commands. ```bash npm install npm run compile npm run package:vsix ``` -------------------------------- ### Window Constructor and __index Metamethod Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/Scripts/TestMore/231-metatable.txt Sets up a constructor (`Window.new`) and the `__index` metamethod for a 'Window' object. `__index` is set to `Window.prototype` to provide default values for properties not explicitly set on the instance. ```lua -- 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 ``` ```lua 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) ``` -------------------------------- ### Install MoonSharp UPM Package in Unity Source: https://github.com/moonsharp-devs/moonsharp/blob/master/README.md Add MoonSharp to your Unity project by modifying the Packages/manifest.json file. You can specify a version branch for installation. ```json "org.moonsharp.moonsharp": "https://github.com/moonsharp-devs/moonsharp.git?path=/interpreter#upm/v3.0" ``` -------------------------------- ### Get function information with debug.getinfo Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/Scripts/TestMore/310-debug.txt Retrieves information about a function or the current execution level. Use 'L' option to get line information. ```lua info = debug.getinfo(is) type_ok(info, 'table', "function getinfo (function)") is(info.func, is, " .func") ``` ```lua info = debug.getinfo(is, 'L') type_ok(info, 'table', "function getinfo (function, opt)") type_ok(info.activelines, 'table') ``` ```lua info = debug.getinfo(1) type_ok(info, 'table', "function getinfo (level)") like(info.func, "^function: [0]?[Xx]?%x+", " .func") ``` ```lua is(debug.getinfo(12), nil, "function getinfo (too depth)") ``` ```lua error_like(function () debug.getinfo('bad') end, "bad argument #1 to 'getinfo' %(function or level expected%)", "function getinfo (bad arg)") ``` ```lua error_like(function () debug.getinfo(is, 'X') end, "bad argument #2 to 'getinfo' %(invalid option%)", "function getinfo (bad opt)") ``` -------------------------------- ### Get Number of Arguments with Select Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/301-basic.t.txt The select function can be used to get the number of arguments passed to a function or to select specific arguments by their index. ```lua is(select('#'), 0, "function select") is(select('#','a','b','c'), 3) ``` ```lua eq_array({select(1,'a','b','c')}, {'a','b','c'}) ``` ```lua eq_array({select(3,'a','b','c')}, {'c'}) ``` ```lua eq_array({select(5,'a','b','c')}, {}) ``` ```lua eq_array({select(-1,'a','b','c')}, {'c'}) ``` ```lua eq_array({select(-2,'a','b','c')}, {'b', 'c'}) ``` ```lua eq_array({select(-3,'a','b','c')}, {'a', 'b', 'c'}) ``` -------------------------------- ### Table Initialization with Computed Keys Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/Scripts/TestMore/222-constructor.txt Shows how to initialize table fields using computed keys, such as arithmetic expressions or string concatenations. This allows for dynamic key assignment during table creation. ```lua --[[ ]] 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], '---') ``` -------------------------------- ### Basic Coroutine Creation and Execution Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/MoonSharp/Scripts/214-coroutine.t.txt Demonstrates the creation of a coroutine using `coroutine.create` and its subsequent execution with `coroutine.resume`. It shows how values are passed and returned between the main thread and the coroutine. ```lua 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', }) ``` -------------------------------- ### Get Function Information Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/310-debug.t.txt Use debug.getinfo to retrieve information about a function or the current execution level. Specify options like 'L' to get line information. ```lua info = debug.getinfo(is) type_ok(info, 'table', "function getinfo (function)") is(info.func, is, " .func") ``` ```lua info = debug.getinfo(is, 'L') type_ok(info, 'table', "function getinfo (function, opt)") type_ok(info.activelines, 'table') ``` ```lua info = debug.getinfo(1) type_ok(info, 'table', "function getinfo (level)") like(info.func, "^function: [0]?Xx?%x+", " .func") ``` ```lua is(debug.getinfo(12), nil, "function getinfo (too depth)") ``` ```lua error_like(function () debug.getinfo('bad') end, "bad argument #1 to 'getinfo' %(function or level expected%)", "function getinfo (bad arg)") ``` ```lua error_like(function () debug.getinfo(is, 'X') end, "bad argument #2 to 'getinfo' %(invalid option%)", "function getinfo (bad opt)") ``` -------------------------------- ### Basic Table Assignment and Access Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/Scripts/TestMore/221-table.txt Demonstrates basic assignment to table fields using string keys and integer keys. Shows how to access values using both string and variable keys. ```lua 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) ``` -------------------------------- ### Lua Length of Number Error Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/104-number.t.txt Tests that attempting to get the length of a number using the '#' operator results in an 'attempt to get length of a number value' error. ```lua error_like(function () return #1 end, "^[^:]+:%d+: attempt to get length of a number value", "#1") ``` -------------------------------- ### Mixed Key Types and Table Initialization Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/221-table.t.txt Demonstrates using different types of keys (numbers, strings) in the same table, including numeric keys derived from string conversions. Also shows initialization of nested tables. ```lua 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") ``` ```lua 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') ``` -------------------------------- ### Concatenate table elements Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/305-table.t.txt Concatenates elements of a table into a string. Specify a separator, and optionally start and end indices. Returns an empty string if the start index is greater than the end index. ```lua 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, ','), '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), '') ``` ```lua t = {'a','b',3,'d','e'} is(table.concat(t,','), 'a,b,3,d,e', "function concat (number)") ``` ```lua 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)") ``` ```lua 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)") ``` -------------------------------- ### Set and Get Hooks Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/310-debug.t.txt Configure and retrieve execution hooks using debug.sethook and debug.gethook. Hooks can be set for calls, returns, or line execution, with optional counts. Also demonstrates getting hooks for threads. ```lua debug.sethook() hook, mask, count = debug.gethook() is(hook, nil, "function gethook") is(mask, '') is(count, 0) ``` ```lua 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) ``` ```lua co = coroutine.create(function () print "thread" end) hook = debug.gethook(co) if jit then todo("LuaJIT TODO. debug.gethook(thread)", 1) end is(hook, nil, "function gethook(thread)") ``` -------------------------------- ### Match Frontier (Start of String) Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/314-regex.t.txt Illustrates matching the frontier at the start of a string. The pattern %f[b]bc matches the frontier before 'b', followed by 'bc'. The target string 'abcdef' results in 'bc' being matched. ```Lua [===[%f[b]bc abcdef bc frontier]===] ``` -------------------------------- ### Lua Table Initialization and Access Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/002-table.t.txt Shows how to initialize a Lua table as an array and access elements using numerical indices. Also demonstrates accessing elements with a variable index. ```lua print("1..8") a = {"ok 1", "ok 2", "ok 3"} print(a[1]) i = 2 print(a[i]) print(a[i+1]) ``` -------------------------------- ### Array-like Table Usage Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/221-table.t.txt Illustrates using tables as arrays with sequential numeric keys. Shows assignment and access of elements, and demonstrates that non-numeric keys can coexist with numeric ones. ```lua 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) ``` -------------------------------- ### Match Frontier (Start of String) Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/314-regex.t.txt Shows matching the frontier at the start of a string. The pattern %f[b]c matches the frontier before 'b', followed by 'c'. The target string 'abcdef' does not satisfy this pattern, resulting in nil. ```Lua [===[%f[b]c abcdef nil frontier]===] ``` -------------------------------- ### Get unique upvalue identifier with debug.upvalueid Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/Scripts/TestMore/310-debug.txt Returns a unique identifier for an upvalue of a given function. ```lua local id = debug.upvalueid(plan, 1) type_ok(id, 'userdata', "function upvalueid") ``` -------------------------------- ### Read File with Different Options Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/308-io.t.txt Demonstrates reading from a file using various format specifiers like '*l', '*L', and '*n'. ```lua 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() ``` -------------------------------- ### Lua String Length Operator Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/105-string.t.txt Shows the use of the length operator '#' on a string to get its length. ```lua is(# 'text', 4, "#'text'") ``` -------------------------------- ### Implementing __ipairs Metamethod Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/231-metatable.t.txt Demonstrates how to implement the __ipairs metamethod to control sequential iteration over a table's values using the 'ipairs' function. ```lua local mt = { __ipairs = function (op) return ipairs(op._VALUES) end } setmetatable(t, mt) ``` -------------------------------- ### Mixed Table Initialization and Modification Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/Scripts/TestMore/222-constructor.txt Demonstrates initializing a table with a mix of record-style and list-style elements, and how to add or modify fields after creation. Note that assigning `nil` to a field effectively removes it. ```lua --[[ ]] 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 ``` -------------------------------- ### Count replacements with string.gsub Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/Scripts/TestMore/304-string.txt Use `select(2, string.gsub(...))` to get the number of replacements made. ```lua is(select(2, string.gsub("string with 3 spaces", ' ', ' ')), 3) ``` -------------------------------- ### Get string length with string.len Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/304-string.t.txt string.len returns the length of a string, correctly handling null characters. ```lua is(string.len(''), 0, "function len") ``` ```lua is(string.len('test'), 4) ``` ```lua is(string.len("a\000b\000c"), 5) ``` ```lua is(string.len('"'), 1) ``` -------------------------------- ### Mixed Table Initialization in Lua Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/222-constructor.t.txt Demonstrates initializing a table with a mix of record-style fields and list-style elements, including assigning a table as a field. ```lua 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 ``` -------------------------------- ### Initialize Lua Table with Record-Style Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/222-constructor.t.txt Use this syntax to initialize a table with string keys, creating key-value pairs. Suitable for creating objects or dictionaries. ```lua a = {x=0, y=0} is(a.x, 0, "record-style init") is(a.y, 0) ``` -------------------------------- ### Replace words with string.gsub Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/Scripts/TestMore/304-string.txt Use string.gsub to replace occurrences of a pattern within a string. This example doubles each word. ```lua is(string.gsub("hello world", "(%w+)", "%1 %1"), "hello hello world world", "function gsub") ``` -------------------------------- ### Dynamic Key Assignment and Access Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/221-table.t.txt Shows how to use variables as keys for table assignments and access. Highlights the difference between direct key access and using a variable that holds the key name. ```lua a = {} x = 'y' a[x] = 10 is(a[x], 10) is(a.x, nil) is(a.y, 10) ``` -------------------------------- ### Unpack Table with Specified Range Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/305-table.t.txt Demonstrates `table.unpack` with explicit start and end indices to extract a subset of table elements. ```lua eq_array({table.unpack({'a','b','c','d','e'},2,4)}, {'b','c','d'}) ``` -------------------------------- ### Custom String Expansion with string.gsub and a function Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/MoonSharp/Scripts/304-string.t.txt Demonstrates using string.gsub with a function to dynamically replace patterns, such as environment variables. ```lua function expand (s) return (string.gsub(s, '$(%w+)', _G)) end ``` ```lua function expand (s) return (string.gsub(s, '$(%w+)', function (n) return tostring(_G[n]), 1 end)) end ``` -------------------------------- ### Lua Numeric For Loop (single iteration) Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/014-fornum.t.txt A numeric for loop designed to execute only once, with the start, end, and step all set to 5. ```lua for i = 5, 5 do print("ok " .. 19+i .. " - for 5, 5") end ``` -------------------------------- ### Lua Test Counter Management Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/Modules/Test/Builder.lua.txt Allows getting or setting the current test number. Useful for manual test tracking. ```lua function m:current_test (num) if num then self.curr_test = num end return self.curr_test end ``` -------------------------------- ### Implementing __pairs Metamethod Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/231-metatable.t.txt Demonstrates how to implement the __pairs metamethod to control iteration over a table's values using the 'next' function. ```lua local mt = { __pairs = function (op) return next, op._VALUES end } setmetatable(t, mt) ``` -------------------------------- ### Test os.rename() successfully Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/309-os.t.txt Creates a file, renames it using 'os.rename()', and verifies the operation's success. Includes cleanup of the renamed file. ```lua 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 ``` -------------------------------- ### Lua while loop with condition Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/011-while.t.txt A standard while loop that continues as long as a condition is met. This example iterates a specific number of times. ```lua 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 ``` -------------------------------- ### Create and Use Temporary File Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/308-io.t.txt Creates a temporary file using io.tmpfile(), writes content to it, and then closes it. ```lua f = io.tmpfile() is(io.type(f), 'file', "function tmpfile") f:write("some text") f:close() ``` -------------------------------- ### Basic Table Assignment and Access Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/221-table.t.txt Demonstrates basic assignment of values to table keys using string and numeric keys, and accessing these values. Shows how modifying an aliased table affects the original. ```lua 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) ``` ```lua a = {} a['x'] = 10 b = a is(b['x'], 10) b['x'] = 20 is(a['x'], 20) a = nil b = nil ``` -------------------------------- ### Swap words using string.gsub Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/Scripts/TestMore/304-string.txt Use string.gsub to reorder captured groups in the replacement string. This example swaps adjacent words. ```lua is(string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1"), "world hello Lua from") ``` -------------------------------- ### Lua String Coercion for Arithmetic (Revisited) Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/Scripts/TestMore/105-string.txt Further examples of successful string-to-number coercion for arithmetic operations, including cases where both operands are strings. ```lua 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'") ``` -------------------------------- ### Write Lua function to a file Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/320-stdin.t.txt Writes a simple Lua function `foo` to a file named 'foo.lua'. This is a setup for testing `loadfile`. ```lua f = io.open('foo.lua', 'w') f:write[[ function foo (x) return x ]] f:close() ``` -------------------------------- ### Initialize Lua Table with Record-Style Elements Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/MoonSharp/Scripts/222-constructor.t.txt Use curly braces with key-value pairs for record-style initialization. Access elements using dot notation or string keys. ```lua --[[ record-style init ]] a = {x=0, y=0} is(a.x, 0, "record-style init") is(a.y, 0) ``` -------------------------------- ### Lua Bit Replacement Test Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/307-bit.t.txt Tests the bit32.replace function to replace a sequence of bits in an integer. Requires valid start bit and width. ```lua is(bit32.replace(0x0000, 0xFFFF, 3, 3), 0x38, "function replace") ``` -------------------------------- ### Lua Bit Extraction Test Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/307-bit.t.txt Tests the bit32.extract function to extract a sequence of bits from an integer. Requires valid start bit and width. ```lua is(bit32.extract(0xFFFF, 3, 3), 0x07, "function extract") ``` -------------------------------- ### Install MoonSharp VSCode Debugger UPM Package Source: https://github.com/moonsharp-devs/moonsharp/blob/master/README.md To use the VSCode debugger with MoonSharp in Unity, add this separate package to your Packages/manifest.json file. ```json "org.moonsharp.debugger.vscode": "https://github.com/moonsharp-devs/moonsharp.git?path=/debugger/vscode#upm/v3.0" ``` -------------------------------- ### Lua String Length and Indexing Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/Scripts/TestMore/105-string.txt Demonstrates getting the length of a string and accessing characters by index. Note that string indexing in Lua is 1-based. ```lua is(# 'text', 4, "#'text'") a = 'text' is(a[1], nil, "index") ``` -------------------------------- ### Table Initialization with Function Return Values Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/Scripts/TestMore/222-constructor.txt Demonstrates initializing table elements with the multiple return values of a function. Lua automatically expands multiple return values into the table constructor when used in this context. ```lua --[[ ]] 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}) ``` -------------------------------- ### Lua Table Key-Value Access Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/002-table.t.txt Shows how to initialize a Lua table with string keys and access values using both bracket notation and dot notation. ```lua 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 ``` -------------------------------- ### Open and Write to a File Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/308-io.t.txt Opens a file in write mode, writes content to it, closes it, and then reopens it to verify the content. ```lua 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") ``` -------------------------------- ### __tostring Metamethod Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/MoonSharp/Scripts/231-metatable.t.txt Illustrates the __tostring metamethod for custom string representation of tables. It must return a string; otherwise, errors may occur. ```lua t = {} mt = { __tostring=function () return '__TABLE__' end } setmetatable(t, mt) is(tostring(t), '__TABLE__', "__tostring") ``` ```lua 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'") ``` ```lua mt.__tostring = function () return '__FIRST__', 2 end setmetatable(t, mt) is(tostring(t), '__FIRST__', "__tostring too-many-output") ``` ```lua t = {} mt = { __tostring = "not a function" } setmetatable(t, mt) error_like(function () tostring(t) end, "attempt to call", "__tostring invalid") ``` -------------------------------- ### Replace words with a limit using string.gsub Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/Scripts/TestMore/304-string.txt Use string.gsub with a count argument to limit the number of replacements. This example doubles only the first word. ```lua is(string.gsub("hello world", "%w+", "%0 %0", 1), "hello hello world") ``` -------------------------------- ### Window __index Metamethod - Table Implementation Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/231-metatable.t.txt Implements the __index metamethod for the Window class by directly assigning the Window.prototype table. ```lua Window.mt.__index = Window.prototype -- just a table ``` -------------------------------- ### Nested Table Initialization and Access Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/Scripts/TestMore/221-table.txt Demonstrates initializing a table with nested tables and accessing elements within the nested structure. Also shows modifying elements and concatenating parts of a nested table. ```lua 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') ``` -------------------------------- ### Table Sort with Invalid Order Function Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/MoonSharp/Scripts/305-table.t.txt This example shows how MoonSharp handles an invalid order function provided to table.sort, resulting in an error. ```lua 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)") ``` -------------------------------- ### Test os.getenv() for non-existent variable Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/MoonSharp/Scripts/309-os.t.txt Tests os.getenv() by requesting a variable that is not expected to be set, verifying it returns nil. ```lua is(os.getenv('__IMPROBABLE__'), nil, "function getenv") ``` -------------------------------- ### Lua Call by Reference Example Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/212-function.t.txt Shows that tables are passed by reference in Lua; modifications to the table inside the function affect the original table. ```lua 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') ``` -------------------------------- ### Lua Call by Value Example Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/212-function.t.txt Demonstrates that numbers are passed by value in Lua; modifying the parameter inside the function does not affect the original variable. ```lua 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) ``` -------------------------------- ### __len Metamethod Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/UnityTestBed/Assets/Resources/MoonSharp/Scripts/231-metatable.t.txt Demonstrates the __len metamethod for custom length calculation of tables. It should return a number; otherwise, errors may occur. ```lua t = {} mt = { __len=function () return 42 end } setmetatable(t, mt) is(#t, 42, "__len") ``` ```lua t = {} mt = { __len=function () return nil end } setmetatable(t, mt) if jit then todo("LuaJIT TODO. __len.", 1) end error_like(function () print(table.concat(t)) end, "object length is not a number", "__len invalid") ``` -------------------------------- ### Write Lua functions to a file Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/320-stdin.t.txt Writes Lua functions `norm` and `twice` to a file named 'lib1.lua'. This is a setup step for subsequent tests. ```lua 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 ]] f:close() ``` -------------------------------- ### Create and Manage Lua Coroutines from C# Source: https://context7.com/moonsharp-devs/moonsharp/llms.txt Demonstrates creating Lua coroutines from C# using Script.CreateCoroutine and managing their execution by resuming them manually or iterating over their yielded values. ```csharp using MoonSharp.Interpreter; Script script = new Script(); script.DoString(@" function counter(start, limit) for i = start, limit do coroutine.yield(i) end return 'done' end "); // Create coroutine DynValue func = script.Globals.Get("counter"); DynValue coroutine = script.CreateCoroutine(func); // Resume coroutine manually Coroutine co = coroutine.Coroutine; DynValue result; result = co.Resume(1, 5); Console.WriteLine($"State: {co.State}, Value: {result.Number}"); // 1 result = co.Resume(); Console.WriteLine($"State: {co.State}, Value: {result.Number}"); // 2 result = co.Resume(); Console.WriteLine($"State: {co.State}, Value: {result.Number}"); // 3 // Iterate as enumerable script.DoString(@" function generator() coroutine.yield('first') coroutine.yield('second') coroutine.yield('third') end "); DynValue genFunc = script.Globals.Get("generator"); DynValue genCo = script.CreateCoroutine(genFunc); foreach (DynValue value in genCo.Coroutine.AsTypedEnumerable()) { Console.WriteLine(value.String); } // Output: first, second, third ``` -------------------------------- ### Lua String Sub Function Test Source: https://github.com/moonsharp-devs/moonsharp/blob/master/src/Unity/MoonSharp/Assets/Resources/MoonSharp/Scripts/304-string.t.txt Tests the string.sub function for extracting a substring based on start and end positions. This is used in conjunction with string.find. ```lua s = "hello world" is(string.sub(s, 1, 5), "hello") ```