neyuki 0.5.0

A small Lua-like scripting language implemented in Rust
-- GetImport: cached `module.field` reads with exact invalidation.
-- Every assert below passes on the dynamic path too; they pin behavior
-- so the cached path cannot drift (stale reads would fail loudly here).
assert(math.sqrt(16) == 4, "stdlib chain call")
assert(string.len("hello") == 5, "string chain")
assert(table.concat({ "a", "b" }) == "ab", "table chain")

-- user tables stay dynamic and observe every write
global my_mod = { answer = function() return 42 end }
assert(my_mod.answer() == 42, "user chain")
my_mod.answer = function() return 43 end
assert(my_mod.answer() == 43, "field reassignment observed")
my_mod = { answer = function() return 44 end }
assert(my_mod.answer() == 44, "global rebinding observed")

-- missing fields stay nil and dynamic
assert(my_mod.nope == nil, "missing field")

-- metatable games on a frozen module never corrupt present fields, and
-- misses still go through __index (never cached)
setmetatable(math, { __index = function() return 999 end })
assert(math.sqrt(16) == 4, "present field wins over __index")
assert(math.missing_thing == 999, "miss goes through __index")
setmetatable(math, nil)
assert(math.sqrt(16) == 4, "exact after metatable restore")

-- chains inside hot loops stay exact across iterations
local acc = 0
for i = 1, 100 do acc = acc + math.sqrt(i) end
assert(acc > 0, "looped chain reads")