local function test(name, condition)
if condition then
print("[PASS] " .. name)
else
print("[FAIL] " .. name)
error("Test failed: " .. name)
end
end
print("=== Extended Lua Feature Tests ===\n")
print("--- Lexer/Parser ---")
test("uppercase hex 0XFF", 0XFF == 255 and 0XAB == 171)
test("number with leading dot", .5 == 0.5 and .125 == 0.125)
test("number with trailing dot", 5. == 5.0)
test("negative exponent", 1e-3 == 0.001)
test("positive exponent explicit", 1e+3 == 1000)
test("uppercase E exponent", 1E3 == 1000)
test("escape \\r exists", #"\r" == 1)
test("escape \\a exists", #"\a" == 1)
test("escape \\b exists", #"\b" == 1)
test("escape \\f exists", #"\f" == 1)
test("escape \\v exists", #"\v" == 1)
test("escape \\0 exists", #"\0" == 1)
test("escape \\' exists", #"\'" == 1)
test("escape \\\" exists", #"\"" == 1)
local comment_test = 1 test("single line comment", comment_test == 1)
local multiline_comment_test = 2
test("multi-line comment", multiline_comment_test == 2)
local inline_test = 3
test("inline multi-line comment", inline_test == 3)
print("\n--- Table Constructors ---")
local t1 = {1, 2, 3,} test("trailing comma", t1[3] == 3)
local t2 = {1; 2; 3} test("semicolon separators", t2[1] == 1 and t2[2] == 2 and t2[3] == 3)
local t3 = {1, 2; 3, 4} test("mixed separators", t3[1] == 1 and t3[4] == 4)
local t4 = {} test("empty table", #t4 == 0)
local t5 = {;} test("empty table with semicolon", #t5 == 0)
local t5b = {,} test("empty table with comma", #t5b == 0)
local key = "dynamic"
local t6 = {[key] = 42, ["literal"] = 100, [1+1] = 200}
test("computed keys", t6.dynamic == 42 and t6.literal == 100 and t6[2] == 200)
local t7 = {a = {b = {c = 1}}}
test("nested table literals", t7.a.b.c == 1)
local t8 = {[true] = "yes", [false] = "no"}
test("boolean keys", t8[true] == "yes" and t8[false] == "no")
print("\n--- Function Edge Cases ---")
local is_even, is_odd
is_even = function(n)
if n == 0 then return true end
return is_odd(n - 1)
end
is_odd = function(n)
if n == 0 then return false end
return is_even(n - 1)
end
test("mutual recursion", is_even(10) == true and is_odd(7) == true)
local function return_three() return 1, 2, 3 end
local function pass_through(...) return ... end
local a, b, c = pass_through(return_three())
test("pass through varargs", a == 1 and b == 2 and c == 3)
local function sum3(x, y, z) return x + y + z end
local result = sum3(return_three(), 10, 20)
test("varargs in middle position", result == 31)
local function take_one(x) return x end
test("extra args discarded", take_one(1, 2, 3) == 1)
local function with_defaults(a, b, c)
a = a or 10
b = b or 20
c = c or 30
return a + b + c
end
test("default values via or", with_defaults() == 60)
local function make_deep()
local a = 1
return function()
local b = 2
return function()
local c = 3
return function()
return a + b + c
end
end
end
end
test("deeply nested closures", make_deep()()()() == 6)
print("\n--- Control Flow Edge Cases ---")
local empty_count = 0
for i = 1, 5 do
empty_count = empty_count + 1
end
test("for loop increments", empty_count == 5)
local zero_count = 0
for i = 1, 0 do
zero_count = zero_count + 1
end
test("zero iteration for loop", zero_count == 0)
local neg_count = 0
for i = 1, 10, -1 do
neg_count = neg_count + 1
end
test("wrong direction step", neg_count == 0)
local outer_count = 0
local inner_count = 0
for i = 1, 10 do
outer_count = outer_count + 1
for j = 1, 10 do
inner_count = inner_count + 1
if j == 3 then break end
end
if i == 5 then break end
end
test("nested break", outer_count == 5 and inner_count == 15)
local w = 0
while w < 10 and w ~= 5 do
w = w + 1
end
test("while complex condition", w == 5)
local r = 0
repeat
r = r + 1
until r >= 5 or r == 3
test("repeat complex condition", r == 3)
print("\n--- Arithmetic Metamethods ---")
print("SKIP: __add, __sub, __mul, __div, __mod, __pow, __unm not implemented")
print("\n--- Comparison Metamethods ---")
print("SKIP: __eq, __lt, __le not implemented")
print("\n--- Concat Metamethod ---")
print("SKIP: __concat not implemented")
print("\n--- String Patterns ---")
test("pattern %d+", string.match("abc123def", "%d+") == "123")
test("pattern %a+", string.match("123abc456", "%a+") == "abc")
test("pattern %w+", string.match(" hello123 ", "%w+") == "hello123")
test("pattern %s+", string.match("hello world", "%s+") == " ")
test("pattern ^anchor", string.match("hello", "^hel") == "hel")
test("pattern $anchor", string.match("hello", "llo$") == "llo")
test("pattern ^$", string.match("exact", "^exact$") == "exact")
test("pattern char class [abc]", string.match("xxxbbbxxx", "[abc]+") == "bbb")
test("pattern negated class [^abc]", string.match("abcdef", "[^abc]+") == "def")
test("pattern optional ?", string.match("color", "colou?r") == "color")
test("pattern optional match", string.match("colour", "colou?r") == "colour")
test("pattern * zero or more", string.match("aaa", "a*") == "aaa")
test("pattern * empty", string.match("bbb", "a*") == "")
test("pattern captures", (function()
local a, b = string.match("hello world", "(%a+) (%a+)")
return a == "hello" and b == "world"
end)())
test("pattern gsub count", (function()
local result, count = string.gsub("hello", "l", "L")
return result == "heLLo" and count == 2
end)())
print("\n--- More Edge Cases ---")
local t = {a = 1, b = 2, c = 3}
local count = 0
for k, v in pairs(t) do
count = count + 1
end
test("pairs iteration count", count == 3)
local sparse = {1, 2, nil, 4, 5}
local icount = 0
for i, v in ipairs(sparse) do
icount = icount + 1
end
test("ipairs stops at nil", icount == 2)
local nt = {a = 1}
local k1 = next(nt, nil)
test("next with nil key", k1 == "a")
local function ret2() return 10, 20 end
local x, y, z = ret2(), 30
test("multi-assign func then value", x == 10 and y == 30 and z == nil)
local t0 = {[0] = "zero", [1] = "one"}
test("table with index 0", t0[0] == "zero" and t0[1] == "one")
local tneg = {[-1] = "neg1", [-2] = "neg2"}
test("negative table indices", tneg[-1] == "neg1" and tneg[-2] == "neg2")
local tbig = {[1000000] = "big"}
test("large table index", tbig[1000000] == "big")
local chain = 1 < 2 and 2 < 3 and 3 < 4
test("chained comparisons", chain == true)
local short1 = nil or "default"
test("or returns right on nil", short1 == "default")
local short2 = false or "default"
test("or returns right on false", short2 == "default")
local short3 = "value" and "other"
test("and returns right on truthy", short3 == "other")
local short4 = nil and "other"
test("and returns left on nil", short4 == nil)
print("\n--- Recursive Structures ---")
local self_ref = {}
self_ref.self = self_ref
test("self-referencing table", self_ref.self.self.self == self_ref)
local t_a = {}
local t_b = {}
t_a.other = t_b
t_b.other = t_a
test("mutual table references", t_a.other.other == t_a)
print("\n--- Global Environment ---")
_G.my_global = 42
test("_G set global", my_global == 42)
local gval = _G.my_global
test("_G read global", gval == 42)
test("_G.print works", (function() _G.print("testing _G.print"); return true end)())
test("_G._G is _G", _G._G == _G)
my_global = nil
print("\n=== All extended tests passed! ===")