lang: core, funcs, types: Add ctx to simple func
Plumb through the standard context.Context so that a function can be cancelled if someone requests this. It makes it less awkward to write simple functions that might depend on io or network access.
This commit is contained in:
@@ -55,7 +55,7 @@ func init() {
|
||||
// concatenation
|
||||
RegisterOperator("+", &types.FuncValue{
|
||||
T: types.NewType("func(a str, b str) str"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
return &types.StrValue{
|
||||
V: input[0].Str() + input[1].Str(),
|
||||
}, nil
|
||||
@@ -64,7 +64,7 @@ func init() {
|
||||
// addition
|
||||
RegisterOperator("+", &types.FuncValue{
|
||||
T: types.NewType("func(a int, b int) int"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
//if l := len(input); l != 2 {
|
||||
// return nil, fmt.Errorf("expected two inputs, got: %d", l)
|
||||
//}
|
||||
@@ -77,7 +77,7 @@ func init() {
|
||||
// floating-point addition
|
||||
RegisterOperator("+", &types.FuncValue{
|
||||
T: types.NewType("func(a float, b float) float"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
return &types.FloatValue{
|
||||
V: input[0].Float() + input[1].Float(),
|
||||
}, nil
|
||||
@@ -87,7 +87,7 @@ func init() {
|
||||
// subtraction
|
||||
RegisterOperator("-", &types.FuncValue{
|
||||
T: types.NewType("func(a int, b int) int"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
return &types.IntValue{
|
||||
V: input[0].Int() - input[1].Int(),
|
||||
}, nil
|
||||
@@ -96,7 +96,7 @@ func init() {
|
||||
// floating-point subtraction
|
||||
RegisterOperator("-", &types.FuncValue{
|
||||
T: types.NewType("func(a float, b float) float"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
return &types.FloatValue{
|
||||
V: input[0].Float() - input[1].Float(),
|
||||
}, nil
|
||||
@@ -106,7 +106,7 @@ func init() {
|
||||
// multiplication
|
||||
RegisterOperator("*", &types.FuncValue{
|
||||
T: types.NewType("func(a int, b int) int"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
// FIXME: check for overflow?
|
||||
return &types.IntValue{
|
||||
V: input[0].Int() * input[1].Int(),
|
||||
@@ -116,7 +116,7 @@ func init() {
|
||||
// floating-point multiplication
|
||||
RegisterOperator("*", &types.FuncValue{
|
||||
T: types.NewType("func(a float, b float) float"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
return &types.FloatValue{
|
||||
V: input[0].Float() * input[1].Float(),
|
||||
}, nil
|
||||
@@ -127,7 +127,7 @@ func init() {
|
||||
// division
|
||||
RegisterOperator("/", &types.FuncValue{
|
||||
T: types.NewType("func(a int, b int) float"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
divisor := input[1].Int()
|
||||
if divisor == 0 {
|
||||
return nil, fmt.Errorf("can't divide by zero")
|
||||
@@ -140,7 +140,7 @@ func init() {
|
||||
// floating-point division
|
||||
RegisterOperator("/", &types.FuncValue{
|
||||
T: types.NewType("func(a float, b float) float"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
divisor := input[1].Float()
|
||||
if divisor == 0.0 {
|
||||
return nil, fmt.Errorf("can't divide by zero")
|
||||
@@ -154,7 +154,7 @@ func init() {
|
||||
// string equality
|
||||
RegisterOperator("==", &types.FuncValue{
|
||||
T: types.NewType("func(a str, b str) bool"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
return &types.BoolValue{
|
||||
V: input[0].Str() == input[1].Str(),
|
||||
}, nil
|
||||
@@ -163,7 +163,7 @@ func init() {
|
||||
// bool equality
|
||||
RegisterOperator("==", &types.FuncValue{
|
||||
T: types.NewType("func(a bool, b bool) bool"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
return &types.BoolValue{
|
||||
V: input[0].Bool() == input[1].Bool(),
|
||||
}, nil
|
||||
@@ -172,7 +172,7 @@ func init() {
|
||||
// int equality
|
||||
RegisterOperator("==", &types.FuncValue{
|
||||
T: types.NewType("func(a int, b int) bool"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
return &types.BoolValue{
|
||||
V: input[0].Int() == input[1].Int(),
|
||||
}, nil
|
||||
@@ -181,7 +181,7 @@ func init() {
|
||||
// floating-point equality
|
||||
RegisterOperator("==", &types.FuncValue{
|
||||
T: types.NewType("func(a float, b float) bool"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
// TODO: should we do an epsilon check?
|
||||
return &types.BoolValue{
|
||||
V: input[0].Float() == input[1].Float(),
|
||||
@@ -192,7 +192,7 @@ func init() {
|
||||
// string in-equality
|
||||
RegisterOperator("!=", &types.FuncValue{
|
||||
T: types.NewType("func(a str, b str) bool"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
return &types.BoolValue{
|
||||
V: input[0].Str() != input[1].Str(),
|
||||
}, nil
|
||||
@@ -201,7 +201,7 @@ func init() {
|
||||
// bool in-equality
|
||||
RegisterOperator("!=", &types.FuncValue{
|
||||
T: types.NewType("func(a bool, b bool) bool"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
return &types.BoolValue{
|
||||
V: input[0].Bool() != input[1].Bool(),
|
||||
}, nil
|
||||
@@ -210,7 +210,7 @@ func init() {
|
||||
// int in-equality
|
||||
RegisterOperator("!=", &types.FuncValue{
|
||||
T: types.NewType("func(a int, b int) bool"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
return &types.BoolValue{
|
||||
V: input[0].Int() != input[1].Int(),
|
||||
}, nil
|
||||
@@ -219,7 +219,7 @@ func init() {
|
||||
// floating-point in-equality
|
||||
RegisterOperator("!=", &types.FuncValue{
|
||||
T: types.NewType("func(a float, b float) bool"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
// TODO: should we do an epsilon check?
|
||||
return &types.BoolValue{
|
||||
V: input[0].Float() != input[1].Float(),
|
||||
@@ -230,7 +230,7 @@ func init() {
|
||||
// less-than
|
||||
RegisterOperator("<", &types.FuncValue{
|
||||
T: types.NewType("func(a int, b int) bool"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
return &types.BoolValue{
|
||||
V: input[0].Int() < input[1].Int(),
|
||||
}, nil
|
||||
@@ -239,7 +239,7 @@ func init() {
|
||||
// floating-point less-than
|
||||
RegisterOperator("<", &types.FuncValue{
|
||||
T: types.NewType("func(a float, b float) bool"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
// TODO: should we do an epsilon check?
|
||||
return &types.BoolValue{
|
||||
V: input[0].Float() < input[1].Float(),
|
||||
@@ -249,7 +249,7 @@ func init() {
|
||||
// greater-than
|
||||
RegisterOperator(">", &types.FuncValue{
|
||||
T: types.NewType("func(a int, b int) bool"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
return &types.BoolValue{
|
||||
V: input[0].Int() > input[1].Int(),
|
||||
}, nil
|
||||
@@ -258,7 +258,7 @@ func init() {
|
||||
// floating-point greater-than
|
||||
RegisterOperator(">", &types.FuncValue{
|
||||
T: types.NewType("func(a float, b float) bool"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
// TODO: should we do an epsilon check?
|
||||
return &types.BoolValue{
|
||||
V: input[0].Float() > input[1].Float(),
|
||||
@@ -268,7 +268,7 @@ func init() {
|
||||
// less-than-equal
|
||||
RegisterOperator("<=", &types.FuncValue{
|
||||
T: types.NewType("func(a int, b int) bool"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
return &types.BoolValue{
|
||||
V: input[0].Int() <= input[1].Int(),
|
||||
}, nil
|
||||
@@ -277,7 +277,7 @@ func init() {
|
||||
// floating-point less-than-equal
|
||||
RegisterOperator("<=", &types.FuncValue{
|
||||
T: types.NewType("func(a float, b float) bool"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
// TODO: should we do an epsilon check?
|
||||
return &types.BoolValue{
|
||||
V: input[0].Float() <= input[1].Float(),
|
||||
@@ -287,7 +287,7 @@ func init() {
|
||||
// greater-than-equal
|
||||
RegisterOperator(">=", &types.FuncValue{
|
||||
T: types.NewType("func(a int, b int) bool"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
return &types.BoolValue{
|
||||
V: input[0].Int() >= input[1].Int(),
|
||||
}, nil
|
||||
@@ -296,7 +296,7 @@ func init() {
|
||||
// floating-point greater-than-equal
|
||||
RegisterOperator(">=", &types.FuncValue{
|
||||
T: types.NewType("func(a float, b float) bool"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
// TODO: should we do an epsilon check?
|
||||
return &types.BoolValue{
|
||||
V: input[0].Float() >= input[1].Float(),
|
||||
@@ -309,7 +309,7 @@ func init() {
|
||||
// short-circuit operators, and does it matter?
|
||||
RegisterOperator("and", &types.FuncValue{
|
||||
T: types.NewType("func(a bool, b bool) bool"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
return &types.BoolValue{
|
||||
V: input[0].Bool() && input[1].Bool(),
|
||||
}, nil
|
||||
@@ -318,7 +318,7 @@ func init() {
|
||||
// logical or
|
||||
RegisterOperator("or", &types.FuncValue{
|
||||
T: types.NewType("func(a bool, b bool) bool"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
return &types.BoolValue{
|
||||
V: input[0].Bool() || input[1].Bool(),
|
||||
}, nil
|
||||
@@ -328,7 +328,7 @@ func init() {
|
||||
// logical not (unary operator)
|
||||
RegisterOperator("not", &types.FuncValue{
|
||||
T: types.NewType("func(a bool) bool"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
return &types.BoolValue{
|
||||
V: !input[0].Bool(),
|
||||
}, nil
|
||||
@@ -338,7 +338,7 @@ func init() {
|
||||
// pi operator (this is an easter egg to demo a zero arg operator)
|
||||
RegisterOperator("π", &types.FuncValue{
|
||||
T: types.NewType("func() float"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
V: func(ctx context.Context, input []types.Value) (types.Value, error) {
|
||||
return &types.FloatValue{
|
||||
V: math.Pi,
|
||||
}, nil
|
||||
@@ -938,7 +938,7 @@ func (obj *OperatorFunc) Stream(ctx context.Context) error {
|
||||
lastOp = op
|
||||
|
||||
var result types.Value
|
||||
result, err := fn.Call(args) // run the function
|
||||
result, err := fn.Call(ctx, args) // run the function
|
||||
if err != nil {
|
||||
return errwrap.Wrapf(err, "problem running function")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user