github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/fields/01_typemap/ops.go (about)

     1  package main
     2  
     3  import "reflect"
     4  
     5  //gistsnip:start:ops
     6  type Op struct {
     7  	Name  string
     8  	Left  reflect.Type
     9  	Right reflect.Type
    10  }
    11  
    12  var Ops = map[Op]func(a, b Field) Field{}
    13  
    14  func init() {
    15  	tUint := reflect.TypeOf(&Uint{})
    16  	tFloat := reflect.TypeOf(&Float{})
    17  
    18  	Ops[Op{"Add", tUint, tUint}] = func(a, b Field) Field { return a.(*Uint).Add(b.(*Uint)) }
    19  	Ops[Op{"Sub", tUint, tUint}] = func(a, b Field) Field { return a.(*Uint).Sub(b.(*Uint)) }
    20  
    21  	Ops[Op{"Add", tFloat, tFloat}] = func(a, b Field) Field { return a.(*Float).Add(b.(*Float)) }
    22  	Ops[Op{"Sub", tFloat, tFloat}] = func(a, b Field) Field { return a.(*Float).Sub(b.(*Float)) }
    23  }
    24  
    25  func Call(name string, a, b Field) Field {
    26  	if aerr, ok := a.(*Error); ok {
    27  		return aerr
    28  	}
    29  	if berr, ok := b.(*Error); ok {
    30  		return berr
    31  	}
    32  
    33  	ta, tb := reflect.TypeOf(a), reflect.TypeOf(b)
    34  	call, found := Ops[Op{"Add", ta, tb}]
    35  	if !found {
    36  		return &Error{"unhandled op"}
    37  	}
    38  	return call(a, b)
    39  }
    40  
    41  func Add(a, b Field) Field { return Call("Add", a, b) }
    42  func Sub(a, b Field) Field { return Call("Sub", a, b) }
    43  
    44  //gistsnip:end:ops