Skip to content

Commit

Permalink
made ipairs respect __index metamethod
Browse files Browse the repository at this point in the history
  • Loading branch information
matthias314 committed Jan 4, 2025
1 parent ccacf66 commit f76de1a
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 6 deletions.
4 changes: 3 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ GopherLua: VM and compiler for Lua in Go.
|

GopherLua is a Lua5.1(+ `goto` statement in Lua5.2) VM and compiler written in Go. GopherLua has a same goal
GopherLua is a Lua 5.1 (+ `goto` statement from Lua 5.2 and `ipairs` as in Lua 5.3)
VM and compiler written in Go. GopherLua has a same goal
with Lua: **Be a scripting language with extensible semantics** . It provides
Go APIs that allow you to easily embed a scripting language to your Go host
programs.
Expand Down Expand Up @@ -835,6 +836,7 @@ Miscellaneous notes
- GopherLua has a function to set an environment variable : ``os.setenv(name, value)``
- GopherLua support ``goto`` and ``::label::`` statement in Lua5.2.
- `goto` is a keyword and not a valid variable name.
- GopherLua respects the `__index` metamethod in `ipairs` as in Lua 5.3.

----------------------------------------------------------------
Standalone interpreter
Expand Down
9 changes: 9 additions & 0 deletions _glua-tests/vm.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ assert(#tbl == 10)
setmetatable(tbl, nil)
assert(#tbl == 3)

setmetatable(tbl, {__index = function(t, i)
return i <= 5 and -i or nil
end})
local s = 0
for _, x in ipairs(tbl) do
s = s+x
end
assert(s == -3) -- == 1+2+3-4-5

local ok, msg = pcall(function()
return 1 < "hoge"
end)
Expand Down
11 changes: 6 additions & 5 deletions baselib.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,23 +133,24 @@ func baseGetMetatable(L *LState) int {
}

func ipairsaux(L *LState) int {
tb := L.CheckTable(1)
tb := L.Get(1)
i := L.CheckInt(2)
i++
v := tb.RawGetInt(i)
li := LNumber(i)
v := L.getField(tb, li)
if v == LNil {
return 0
} else {
L.Pop(1)
L.Push(LNumber(i))
L.Push(LNumber(i))
L.Push(li)
L.Push(li)
L.Push(v)
return 2
}
}

func baseIpairs(L *LState) int {
tb := L.CheckTable(1)
tb := L.Get(1)
L.Push(L.Get(UpvalueIndex(1)))
L.Push(tb)
L.Push(LNumber(0))
Expand Down

0 comments on commit f76de1a

Please sign in to comment.