80 lines
1.6 KiB
Go
80 lines
1.6 KiB
Go
package luar
|
|
|
|
import (
|
|
"reflect"
|
|
|
|
"github.com/yuin/gopher-lua"
|
|
)
|
|
|
|
func checkMap(L *lua.LState, idx int) reflect.Value {
|
|
ud := L.CheckUserData(idx)
|
|
ref := reflect.ValueOf(ud.Value)
|
|
if ref.Kind() != reflect.Map {
|
|
L.ArgError(idx, "expecting map")
|
|
}
|
|
return ref
|
|
}
|
|
|
|
func mapIndex(L *lua.LState) int {
|
|
ref := checkMap(L, 1)
|
|
key := L.CheckAny(2)
|
|
|
|
convertedKey := lValueToReflect(key, ref.Type().Key())
|
|
item := ref.MapIndex(convertedKey)
|
|
if !item.IsValid() {
|
|
return 0
|
|
}
|
|
L.Push(New(L, item.Interface()))
|
|
return 1
|
|
}
|
|
|
|
func mapNewIndex(L *lua.LState) int {
|
|
ref := checkMap(L, 1)
|
|
key := L.CheckAny(2)
|
|
value := L.CheckAny(3)
|
|
|
|
convertedKey := lValueToReflect(key, ref.Type().Key())
|
|
if convertedKey.Type() != ref.Type().Key() {
|
|
L.ArgError(2, "invalid map key type")
|
|
}
|
|
var convertedValue reflect.Value
|
|
if value != lua.LNil {
|
|
convertedValue = lValueToReflect(value, ref.Type().Elem())
|
|
if convertedValue.Type() != ref.Type().Elem() {
|
|
L.ArgError(3, "invalid map value type")
|
|
}
|
|
}
|
|
ref.SetMapIndex(convertedKey, convertedValue)
|
|
return 0
|
|
}
|
|
|
|
func mapLen(L *lua.LState) int {
|
|
ref := checkMap(L, 1)
|
|
L.Push(lua.LNumber(ref.Len()))
|
|
return 1
|
|
}
|
|
|
|
func mapCall(L *lua.LState) int {
|
|
ref := checkMap(L, 1)
|
|
keys := ref.MapKeys()
|
|
i := 0
|
|
fn := func(L *lua.LState) int {
|
|
if i >= len(keys) {
|
|
return 0
|
|
}
|
|
L.Push(New(L, keys[i].Interface()))
|
|
L.Push(New(L, ref.MapIndex(keys[i]).Interface()))
|
|
i++
|
|
return 2
|
|
}
|
|
L.Push(L.NewFunction(fn))
|
|
return 1
|
|
}
|
|
|
|
func mapEq(L *lua.LState) int {
|
|
map1 := checkMap(L, 1)
|
|
map2 := checkMap(L, 2)
|
|
L.Push(lua.LBool(map1 == map2))
|
|
return 1
|
|
}
|