package muesli // CallableValue is is both a Value and a Callable. type CallableValue interface { Callable Value } // Redispath takes the first argument i args, and if that is a word, // calls the command named by that word, replacing the target CalableValue // as the first argument. This allows some OOP style trickery where // custom_value foo gets called as foo custom_value where custom_value is // of CustomType. // In this case foo should the be an overloaded command that takes CustomType. func Redispatch(target CallableValue, vm *VM, args...Value) []Value { if len(args) < 1 { return EmptyValueArray() } var word WordValue _, err := ParseOptArgs(args, 1, &word) if err != nil { return Fail(err) } args[0] = target vm.Trace("Redispatching with args %v\n", args) return vm.CallNamed(string(word), args...) } // RedispatchCallable can be embedded into a type to allow it to // become redispatchable, that is, it can support OOP style // calling of pseudo methods by rearranging the command. type RedispatchCallable struct { target CallableValue BasicCallable } func (rc * RedispatchCallable) Call(vm *VM, args...Value) []Value { if (rc.target == nil) { return Fail(NewErrorValuef("Cannot redispatch call due to nil target.")) } return Redispatch(rc.target, vm, args...) } var _ Callable = &RedispatchCallable{} func NewRedispatchCallable(name string, value CallableValue) RedispatchCallable { return RedispatchCallable{target: value, BasicCallable: NewBasicCallable(name)} } var _ Callable = &ListValue{}