package muesli import "fmt" /* An overload is an overloaded value that can be called. */ type Overload struct { Name string Callable } /* A cover is a callable that dispatches to other callables depending on the types of the arguments, in particular the first one. The individual callable functions are the overloads */ type CoverValue struct { BasicCallable Overloads map[Signature]Overload } func (cv CoverValue) String() string { res := fmt.Sprintf("cover %s [ ", cv.Name) for k, v := range cv.Overloads { res = fmt.Sprintf("%s [%v] %s", res, k, v.Name) } res = fmt.Sprintf("%s].", res) return res; } func NewCoverValue(name string) *CoverValue { result := &CoverValue{} result.Name = name result.Overloads = make(map[Signature]Overload) return result } func (cover *CoverValue) Help() string { help := cover.BasicCallable.Help() extra := "\n" for signature, overload := range cover.Overloads { // fmt.Printf("overload: %v", signature) extra = extra + fmt.Sprintf("* %v -> %s\n", signature.String(), overload.Name) } return help + extra } func (cover *CoverValue) Call(vm *VM, arguments ...Value) []Value { signature := CalculateSignature(arguments...) if overload, ok := cover.Overloads[signature]; ok { return overload.Call(vm, arguments...) } else { for overloadSignature, overload := range cover.Overloads { if signature.IsMatch(overloadSignature) { return overload.Call(vm, arguments...) } } } vm.Fail() return Fail(NewErrorValuef("Could not match cover %s with arguments: %s<->%v", cover.String(), signature, arguments)) }