Exec implements the InterpretableV2 interface method.
(frame *ExecutionFrame)
| 713 | |
| 714 | // Exec implements the InterpretableV2 interface method. |
| 715 | func (fn *evalVarArgs) Exec(frame *ExecutionFrame) ref.Val { |
| 716 | argVals := make([]ref.Val, len(fn.args)) |
| 717 | strict := !fn.nonStrict |
| 718 | var unk *types.Unknown |
| 719 | for i, arg := range fn.args { |
| 720 | argVals[i] = arg.Exec(frame) |
| 721 | if strict { |
| 722 | if types.IsError(argVals[i]) { |
| 723 | return argVals[i] |
| 724 | } |
| 725 | unk, _ = types.MaybeMergeUnknowns(argVals[i], unk) |
| 726 | } |
| 727 | } |
| 728 | if strict && unk != nil { |
| 729 | return unk |
| 730 | } |
| 731 | // If the implementation is bound and the argument value has the right traits required to |
| 732 | // invoke it, then call the implementation. |
| 733 | arg0 := argVals[0] |
| 734 | if fn.impl != nil && (fn.trait == 0 || (!strict && types.IsUnknownOrError(arg0)) || arg0.Type().HasTrait(fn.trait)) { |
| 735 | return types.LabelErrNode(fn.id, fn.impl(argVals...)) |
| 736 | } |
| 737 | // Otherwise, if the argument is a ReceiverType attempt to invoke the receiver method on the |
| 738 | // operand (arg0). |
| 739 | if arg0.Type().HasTrait(traits.ReceiverType) { |
| 740 | return types.LabelErrNode(fn.id, arg0.(traits.Receiver).Receive(fn.function, fn.overload, argVals[1:])) |
| 741 | } |
| 742 | return types.NewErrWithNodeID(fn.id, "no such overload: %s %d", fn.function, fn.id) |
| 743 | } |
| 744 | |
| 745 | // Eval implements the Interpretable interface method. |
| 746 | func (fn *evalVarArgs) Eval(ctx Activation) ref.Val { |
no test coverage detected