interop.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package common
  2. import "reflect"
  3. type MachineHandle interface {
  4. Call(fv Value, arg Value) Value
  5. }
  6. var __MachineHandleType = reflect.TypeOf(MachineHandle(nil))
  7. type NativeFunction func(arg Value, handle MachineHandle) Value
  8. func AdaptNativeFunction(f interface{}) NativeFunction {
  9. var f_fit, ok = f.(NativeFunction)
  10. if ok {
  11. return f_fit
  12. }
  13. var f_rv = reflect.ValueOf(f)
  14. if f_rv.Kind() != reflect.Func { panic("invalid function") }
  15. var t = f_rv.Type()
  16. var arity = t.NumIn()
  17. if arity == 0 {
  18. return func(_ Value, handle MachineHandle) Value {
  19. return AdaptReturnValue(f_rv.Call([]reflect.Value {}))
  20. }
  21. } else {
  22. if t.In(arity-1).AssignableTo(__MachineHandleType) {
  23. var net_arity = arity - 1
  24. if net_arity == 1 {
  25. return func(arg Value, handle MachineHandle) Value {
  26. var rv_args = []reflect.Value{
  27. reflect.ValueOf(arg),
  28. reflect.ValueOf(handle),
  29. }
  30. return AdaptReturnValue(f_rv.Call(rv_args))
  31. }
  32. } else {
  33. return func(arg Value, handle MachineHandle) Value {
  34. var p = arg.(ProductValue)
  35. if len(p.Elements) != net_arity {
  36. panic("invalid input quantity")
  37. }
  38. var rv_args = make([]reflect.Value, arity)
  39. for i, e := range p.Elements {
  40. rv_args[i] = reflect.ValueOf(e)
  41. }
  42. rv_args[net_arity] = reflect.ValueOf(handle)
  43. return AdaptReturnValue(f_rv.Call(rv_args))
  44. }
  45. }
  46. } else {
  47. if arity == 1 {
  48. return func(arg Value, handle MachineHandle) Value {
  49. return AdaptReturnValue(f_rv.Call([]reflect.Value {
  50. reflect.ValueOf(arg),
  51. }))
  52. }
  53. } else {
  54. return func(arg Value, handle MachineHandle) Value {
  55. var p = arg.(ProductValue)
  56. if len(p.Elements) != arity {
  57. panic("invalid input quantity")
  58. }
  59. var args = make([]reflect.Value, arity)
  60. for i, e := range p.Elements {
  61. args[i] = reflect.ValueOf(e)
  62. }
  63. return AdaptReturnValue(f_rv.Call(args))
  64. }
  65. }
  66. }
  67. }
  68. }
  69. func AdaptReturnValue(values []reflect.Value) Value {
  70. if len(values) == 0 {
  71. return nil
  72. } else if len(values) == 1 {
  73. return values[0]
  74. } else {
  75. var elements = make([]Value, len(values))
  76. for i, e := range values {
  77. elements[i] = e.Interface()
  78. }
  79. return ProductValue { elements }
  80. }
  81. }