cover.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package muesli
  2. import "fmt"
  3. /* An overload is an overloaded value that can be called. */
  4. type Overload struct {
  5. Name string
  6. Callable
  7. }
  8. /* A cover is a callable that dispatches to other callables depending on
  9. the types of the arguments, in particular the first one. The individual
  10. callable functions are the overloads
  11. */
  12. type CoverValue struct {
  13. BasicCallable
  14. Overloads map[Signature]Overload
  15. }
  16. func (cv CoverValue) String() string {
  17. res := fmt.Sprintf("cover %s [ ", cv.Name)
  18. for k, v := range cv.Overloads {
  19. res = fmt.Sprintf("%s [%v] %s", res, k, v.Name)
  20. }
  21. res = fmt.Sprintf("%s].", res)
  22. return res;
  23. }
  24. func NewCoverValue(name string) *CoverValue {
  25. result := &CoverValue{}
  26. result.Name = name
  27. result.Overloads = make(map[Signature]Overload)
  28. return result
  29. }
  30. func (cover *CoverValue) Help() string {
  31. help := cover.BasicCallable.Help()
  32. extra := "\n"
  33. for signature, overload := range cover.Overloads {
  34. // fmt.Printf("overload: %v", signature)
  35. extra = extra + fmt.Sprintf("* %v -> %s\n", signature.String(), overload.Name)
  36. }
  37. return help + extra
  38. }
  39. func (cover *CoverValue) Call(vm *VM, arguments ...Value) []Value {
  40. signature := CalculateSignature(arguments...)
  41. if overload, ok := cover.Overloads[signature]; ok {
  42. return overload.Call(vm, arguments...)
  43. } else {
  44. for overloadSignature, overload := range cover.Overloads {
  45. if signature.IsMatch(overloadSignature) {
  46. return overload.Call(vm, arguments...)
  47. }
  48. }
  49. }
  50. vm.Fail()
  51. return Fail(NewErrorValuef("Could not match cover %s with arguments: %s<->%v", cover.String(), signature, arguments))
  52. }