github.com/dfcfw/lua@v0.0.0-20230325031207-0cc7ffb7b8b9/luar/chan.go (about) 1 package luar 2 3 import ( 4 "reflect" 5 6 "github.com/dfcfw/lua" 7 ) 8 9 func chanIndex(L *lua.LState) int { 10 _, mt := check(L, 1) 11 key := L.CheckString(2) 12 13 if fn := mt.method(key); fn != nil { 14 L.Push(fn) 15 return 1 16 } 17 18 return 0 19 } 20 21 func chanLen(L *lua.LState) int { 22 ref, _ := check(L, 1) 23 24 L.Push(lua.LNumber(ref.Len())) 25 return 1 26 } 27 28 func chanEq(L *lua.LState) int { 29 ref1, _ := check(L, 1) 30 ref2, _ := check(L, 2) 31 32 L.Push(lua.LBool(ref1.Pointer() == ref2.Pointer())) 33 return 1 34 } 35 36 func chanCall(L *lua.LState) int { 37 ref, _ := check(L, 1) 38 39 switch L.GetTop() { 40 // Receive 41 case 1: 42 if ref.Type().ChanDir()&reflect.RecvDir == 0 { 43 L.ArgError(1, "receive from send-only type "+ref.Type().String()) 44 } 45 value, ok := ref.Recv() 46 if ok { 47 L.Push(New(L, value.Interface())) 48 L.Push(lua.LTrue) 49 } else { 50 L.Push(lua.LNil) 51 L.Push(lua.LFalse) 52 } 53 return 2 54 55 // Send 56 case 2: 57 if ref.Type().ChanDir()&reflect.SendDir == 0 { 58 L.ArgError(1, "send to receive-only type "+ref.Type().String()) 59 } 60 value := L.CheckAny(2) 61 62 hint := ref.Type().Elem() 63 convertedValue, err := lValueToReflect(L, value, hint, nil) 64 if err != nil { 65 L.ArgError(2, err.Error()) 66 } 67 68 ref.Send(convertedValue) 69 return 0 70 71 default: 72 L.RaiseError("expecting 1 or 2 arguments, got %d", L.GetTop()) 73 panic("never reaches") 74 } 75 } 76 77 func chanUnm(L *lua.LState) int { 78 ref, _ := check(L, 1) 79 ref.Close() 80 return 0 81 }