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  }