mirror of
https://github.com/google/go-jsonnet.git
synced 2025-09-28 17:01:02 +02:00
More builtins
This commit is contained in:
parent
b1427d563b
commit
5cd467fd18
108
builtins.go
108
builtins.go
@ -16,7 +16,12 @@ limitations under the License.
|
|||||||
|
|
||||||
package jsonnet
|
package jsonnet
|
||||||
|
|
||||||
import "github.com/google/go-jsonnet/ast"
|
import (
|
||||||
|
"math"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/google/go-jsonnet/ast"
|
||||||
|
)
|
||||||
|
|
||||||
// TODO(sbarzowski) Is this the best option? It's the first one that worked for me...
|
// TODO(sbarzowski) Is this the best option? It's the first one that worked for me...
|
||||||
//go:generate esc -o std.go -pkg=jsonnet std/std.jsonnet
|
//go:generate esc -o std.go -pkg=jsonnet std/std.jsonnet
|
||||||
@ -248,8 +253,81 @@ func builtinType(e *evaluator, xp potentialValue) (value, error) {
|
|||||||
return makeValueString(x.typename()), nil
|
return makeValueString(x.typename()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeDoubleCheck(e *evaluator, x float64) (value, error) {
|
||||||
|
if math.IsNaN(x) {
|
||||||
|
return nil, e.Error("Not a number")
|
||||||
|
}
|
||||||
|
if math.IsInf(x, 0) {
|
||||||
|
return nil, e.Error("Overflow")
|
||||||
|
}
|
||||||
|
return makeValueNumber(x), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(sbarzowski) perhaps it is too magical for Go style
|
||||||
|
func liftNumeric(f func(float64) float64) func(*evaluator, potentialValue) (value, error) {
|
||||||
|
return func(e *evaluator, xp potentialValue) (value, error) {
|
||||||
|
x, err := e.evaluateNumber(xp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return makeDoubleCheck(e, f(x.value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var builtinSqrt = liftNumeric(math.Sqrt)
|
||||||
|
var builtinCeil = liftNumeric(math.Ceil)
|
||||||
|
var builtinFloor = liftNumeric(math.Floor)
|
||||||
|
var builtinSin = liftNumeric(math.Sin)
|
||||||
|
var builtinCos = liftNumeric(math.Cos)
|
||||||
|
var builtinTan = liftNumeric(math.Tan)
|
||||||
|
var builtinAsin = liftNumeric(math.Asin)
|
||||||
|
var builtinAcos = liftNumeric(math.Acos)
|
||||||
|
var builtinAtan = liftNumeric(math.Atan)
|
||||||
|
var builtinLog = liftNumeric(math.Log)
|
||||||
|
var builtinExp = liftNumeric(math.Exp)
|
||||||
|
|
||||||
|
func builtinObjectFieldsEx(e *evaluator, objp potentialValue, hiddenp potentialValue) (value, error) {
|
||||||
|
obj, err := e.evaluateObject(objp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
hidden, err := e.evaluateBoolean(hiddenp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fields := objectFields(obj, hidden.value)
|
||||||
|
sort.Strings(fields)
|
||||||
|
elems := []potentialValue{}
|
||||||
|
for _, fieldname := range fields {
|
||||||
|
elems = append(elems, &readyValue{makeValueString(fieldname)})
|
||||||
|
}
|
||||||
|
return makeValueArray(elems), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func builtinObjectHasEx(e *evaluator, objp potentialValue, fnamep potentialValue, hiddenp potentialValue) (value, error) {
|
||||||
|
obj, err := e.evaluateObject(objp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fname, err := e.evaluateString(fnamep)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
hidden, err := e.evaluateBoolean(hiddenp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, fieldname := range objectFields(obj, hidden.value) {
|
||||||
|
if fieldname == fname.value {
|
||||||
|
return makeValueBoolean(true), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return makeValueBoolean(false), nil
|
||||||
|
}
|
||||||
|
|
||||||
type unaryBuiltin func(*evaluator, potentialValue) (value, error)
|
type unaryBuiltin func(*evaluator, potentialValue) (value, error)
|
||||||
type binaryBuiltin func(*evaluator, potentialValue, potentialValue) (value, error)
|
type binaryBuiltin func(*evaluator, potentialValue, potentialValue) (value, error)
|
||||||
|
type ternaryBuiltin func(*evaluator, potentialValue, potentialValue, potentialValue) (value, error)
|
||||||
|
|
||||||
type UnaryBuiltin struct {
|
type UnaryBuiltin struct {
|
||||||
name ast.Identifier
|
name ast.Identifier
|
||||||
@ -289,6 +367,21 @@ func (b *BinaryBuiltin) Parameters() ast.Identifiers {
|
|||||||
return b.parameters
|
return b.parameters
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TernaryBuiltin struct {
|
||||||
|
name ast.Identifier
|
||||||
|
function ternaryBuiltin
|
||||||
|
parameters ast.Identifiers
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *TernaryBuiltin) EvalCall(args callArguments, e *evaluator) (value, error) {
|
||||||
|
// TODO check args
|
||||||
|
return b.function(getBuiltinEvaluator(e, b.name), args.positional[0], args.positional[1], args.positional[2])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *TernaryBuiltin) Parameters() ast.Identifiers {
|
||||||
|
return b.parameters
|
||||||
|
}
|
||||||
|
|
||||||
func todoFunc(e *evaluator, x, y potentialValue) (value, error) {
|
func todoFunc(e *evaluator, x, y potentialValue) (value, error) {
|
||||||
return nil, e.Error("not implemented yet")
|
return nil, e.Error("not implemented yet")
|
||||||
}
|
}
|
||||||
@ -341,5 +434,18 @@ var funcBuiltins = map[string]evalCallable{
|
|||||||
"length": &UnaryBuiltin{name: "length", function: builtinLength, parameters: ast.Identifiers{"x"}},
|
"length": &UnaryBuiltin{name: "length", function: builtinLength, parameters: ast.Identifiers{"x"}},
|
||||||
"makeArray": &BinaryBuiltin{name: "makeArray", function: builtinMakeArray, parameters: ast.Identifiers{"sz", "func"}},
|
"makeArray": &BinaryBuiltin{name: "makeArray", function: builtinMakeArray, parameters: ast.Identifiers{"sz", "func"}},
|
||||||
"primitiveEquals": &BinaryBuiltin{name: "primitiveEquals", function: primitiveEquals, parameters: ast.Identifiers{"sz", "func"}},
|
"primitiveEquals": &BinaryBuiltin{name: "primitiveEquals", function: primitiveEquals, parameters: ast.Identifiers{"sz", "func"}},
|
||||||
|
"objectFieldsEx": &BinaryBuiltin{name: "objectFields", function: builtinObjectFieldsEx, parameters: ast.Identifiers{"obj", "hidden"}},
|
||||||
|
"objectHasEx": &TernaryBuiltin{name: "objectHasEx", function: builtinObjectHasEx, parameters: ast.Identifiers{"obj", "fname", "hidden"}},
|
||||||
"type": &UnaryBuiltin{name: "type", function: builtinType, parameters: ast.Identifiers{"x"}},
|
"type": &UnaryBuiltin{name: "type", function: builtinType, parameters: ast.Identifiers{"x"}},
|
||||||
|
"ceil": &UnaryBuiltin{name: "ceil", function: builtinCeil, parameters: ast.Identifiers{"x"}},
|
||||||
|
"floor": &UnaryBuiltin{name: "floor", function: builtinFloor, parameters: ast.Identifiers{"x"}},
|
||||||
|
"sqrt": &UnaryBuiltin{name: "sqrt", function: builtinSqrt, parameters: ast.Identifiers{"x"}},
|
||||||
|
"sin": &UnaryBuiltin{name: "sin", function: builtinSin, parameters: ast.Identifiers{"x"}},
|
||||||
|
"cos": &UnaryBuiltin{name: "cos", function: builtinCos, parameters: ast.Identifiers{"x"}},
|
||||||
|
"tan": &UnaryBuiltin{name: "tan", function: builtinTan, parameters: ast.Identifiers{"x"}},
|
||||||
|
"asin": &UnaryBuiltin{name: "asin", function: builtinAsin, parameters: ast.Identifiers{"x"}},
|
||||||
|
"acos": &UnaryBuiltin{name: "acos", function: builtinAcos, parameters: ast.Identifiers{"x"}},
|
||||||
|
"atan": &UnaryBuiltin{name: "atan", function: builtinAtan, parameters: ast.Identifiers{"x"}},
|
||||||
|
"log": &UnaryBuiltin{name: "log", function: builtinLog, parameters: ast.Identifiers{"x"}},
|
||||||
|
"exp": &UnaryBuiltin{name: "exp", function: builtinExp, parameters: ast.Identifiers{"x"}},
|
||||||
}
|
}
|
||||||
|
5
testdata/builtinObjectFieldsEx.golden
vendored
Normal file
5
testdata/builtinObjectFieldsEx.golden
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[
|
||||||
|
"x",
|
||||||
|
"y",
|
||||||
|
"z"
|
||||||
|
]
|
1
testdata/builtinObjectFieldsEx.input
vendored
Normal file
1
testdata/builtinObjectFieldsEx.input
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
std.objectFieldsEx({x: 1, y:: 1, z::: 2}, false)
|
1
testdata/builtinObjectHasEx.golden
vendored
Normal file
1
testdata/builtinObjectHasEx.golden
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
true
|
1
testdata/builtinObjectHasEx.input
vendored
Normal file
1
testdata/builtinObjectHasEx.input
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
std.objectHasEx({x: 1, y:: 1, z::: 2}, "x", false)
|
1
testdata/builtinObjectHasExBadField.golden
vendored
Normal file
1
testdata/builtinObjectHasExBadField.golden
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
RUNTIME ERROR: Unexpected type number, expected string
|
1
testdata/builtinObjectHasExBadField.input
vendored
Normal file
1
testdata/builtinObjectHasExBadField.input
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
std.objectHasEx({}, 42, false)
|
1
testdata/builtinObjectHasExBadObject.golden
vendored
Normal file
1
testdata/builtinObjectHasExBadObject.golden
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
RUNTIME ERROR: Unexpected type number, expected object
|
1
testdata/builtinObjectHasExBadObject.input
vendored
Normal file
1
testdata/builtinObjectHasExBadObject.input
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
std.objectHasEx(42, "x", false)
|
1
testdata/builtin_acos.golden
vendored
Normal file
1
testdata/builtin_acos.golden
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
0
|
1
testdata/builtin_acos.input
vendored
Normal file
1
testdata/builtin_acos.input
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
std.acos(1)
|
1
testdata/builtin_asin.golden
vendored
Normal file
1
testdata/builtin_asin.golden
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
1.5707963267948966
|
1
testdata/builtin_asin.input
vendored
Normal file
1
testdata/builtin_asin.input
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
std.asin(1)
|
1
testdata/builtin_atan.golden
vendored
Normal file
1
testdata/builtin_atan.golden
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
0.78539816339744828
|
1
testdata/builtin_atan.input
vendored
Normal file
1
testdata/builtin_atan.input
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
std.atan(1)
|
1
testdata/builtin_ceil.golden
vendored
Normal file
1
testdata/builtin_ceil.golden
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
3
|
1
testdata/builtin_ceil.input
vendored
Normal file
1
testdata/builtin_ceil.input
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
std.ceil(2.5)
|
1
testdata/builtin_cos.golden
vendored
Normal file
1
testdata/builtin_cos.golden
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
0.54030230586813977
|
1
testdata/builtin_cos.input
vendored
Normal file
1
testdata/builtin_cos.input
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
std.cos(1)
|
1
testdata/builtin_exp.golden
vendored
Normal file
1
testdata/builtin_exp.golden
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
162754.79141900392
|
1
testdata/builtin_exp.input
vendored
Normal file
1
testdata/builtin_exp.input
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
std.exp(12)
|
1
testdata/builtin_floor.golden
vendored
Normal file
1
testdata/builtin_floor.golden
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
2
|
1
testdata/builtin_floor.input
vendored
Normal file
1
testdata/builtin_floor.input
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
std.floor(2.5)
|
1
testdata/builtin_log.golden
vendored
Normal file
1
testdata/builtin_log.golden
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
3.7376696182833684
|
1
testdata/builtin_log.input
vendored
Normal file
1
testdata/builtin_log.input
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
std.log(42)
|
1
testdata/builtin_sin.golden
vendored
Normal file
1
testdata/builtin_sin.golden
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
0.8414709848078965
|
1
testdata/builtin_sin.input
vendored
Normal file
1
testdata/builtin_sin.input
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
std.sin(1)
|
1
testdata/builtin_sqrt.golden
vendored
Normal file
1
testdata/builtin_sqrt.golden
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
2
|
1
testdata/builtin_sqrt.input
vendored
Normal file
1
testdata/builtin_sqrt.input
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
std.sqrt(4)
|
1
testdata/builtin_tan.golden
vendored
Normal file
1
testdata/builtin_tan.golden
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
1.5574077246549021
|
1
testdata/builtin_tan.input
vendored
Normal file
1
testdata/builtin_tan.input
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
std.tan(1)
|
Loading…
x
Reference in New Issue
Block a user