From 331e71c1e17905512ed1e5d55f1139879f82ed60 Mon Sep 17 00:00:00 2001 From: Rohit Jangid Date: Wed, 14 Jun 2023 00:44:26 +0530 Subject: [PATCH] feat: Add more math functions (#702) Co-authored-by: Dave Cunningham --- builtins.go | 30 ++++++++++++++++++++++++ linter/internal/types/stdlib.go | 4 ++++ testdata/builtinIsDecimal.golden | 1 + testdata/builtinIsDecimal.jsonnet | 1 + testdata/builtinIsDecimal.linter.golden | 0 testdata/builtinIsDecimal2.golden | 1 + testdata/builtinIsDecimal2.jsonnet | 1 + testdata/builtinIsDecimal2.linter.golden | 0 testdata/builtinIsEven.golden | 1 + testdata/builtinIsEven.jsonnet | 1 + testdata/builtinIsEven.linter.golden | 0 testdata/builtinIsEven2.golden | 1 + testdata/builtinIsEven2.jsonnet | 1 + testdata/builtinIsEven2.linter.golden | 0 testdata/builtinIsInteger.golden | 1 + testdata/builtinIsInteger.jsonnet | 1 + testdata/builtinIsInteger.linter.golden | 0 testdata/builtinIsInteger2.golden | 1 + testdata/builtinIsInteger2.jsonnet | 1 + testdata/builtinIsInteger2.linter.golden | 0 testdata/builtinIsOdd.golden | 1 + testdata/builtinIsOdd.jsonnet | 1 + testdata/builtinIsOdd.linter.golden | 0 testdata/builtinIsOdd2.golden | 1 + testdata/builtinIsOdd2.jsonnet | 1 + testdata/builtinIsOdd2.linter.golden | 0 26 files changed, 50 insertions(+) create mode 100644 testdata/builtinIsDecimal.golden create mode 100644 testdata/builtinIsDecimal.jsonnet create mode 100644 testdata/builtinIsDecimal.linter.golden create mode 100644 testdata/builtinIsDecimal2.golden create mode 100644 testdata/builtinIsDecimal2.jsonnet create mode 100644 testdata/builtinIsDecimal2.linter.golden create mode 100644 testdata/builtinIsEven.golden create mode 100644 testdata/builtinIsEven.jsonnet create mode 100644 testdata/builtinIsEven.linter.golden create mode 100644 testdata/builtinIsEven2.golden create mode 100644 testdata/builtinIsEven2.jsonnet create mode 100644 testdata/builtinIsEven2.linter.golden create mode 100644 testdata/builtinIsInteger.golden create mode 100644 testdata/builtinIsInteger.jsonnet create mode 100644 testdata/builtinIsInteger.linter.golden create mode 100644 testdata/builtinIsInteger2.golden create mode 100644 testdata/builtinIsInteger2.jsonnet create mode 100644 testdata/builtinIsInteger2.linter.golden create mode 100644 testdata/builtinIsOdd.golden create mode 100644 testdata/builtinIsOdd.jsonnet create mode 100644 testdata/builtinIsOdd.linter.golden create mode 100644 testdata/builtinIsOdd2.golden create mode 100644 testdata/builtinIsOdd2.jsonnet create mode 100644 testdata/builtinIsOdd2.linter.golden diff --git a/builtins.go b/builtins.go index a5deb411a..e426b069c 100644 --- a/builtins.go +++ b/builtins.go @@ -1099,6 +1099,16 @@ func liftNumeric(f func(float64) float64) func(*interpreter, value) (value, erro } } +func liftNumericToBoolean(f func(float64) bool) func(*interpreter, value) (value, error) { + return func(i *interpreter, x value) (value, error) { + n, err := i.getNumber(x) + if err != nil { + return nil, err + } + return makeValueBoolean(f(n.value)), nil + } +} + var builtinSqrt = liftNumeric(math.Sqrt) var builtinCeil = liftNumeric(math.Ceil) var builtinFloor = liftNumeric(math.Floor) @@ -1125,6 +1135,22 @@ var builtinExponent = liftNumeric(func(f float64) float64 { return float64(exponent) }) var builtinRound = liftNumeric(math.Round) +var builtinIsEven = liftNumericToBoolean(func(f float64) bool { + i, _ := math.Modf(f) // Get the integral part of the float + return math.Mod(i, 2) == 0 +}) +var builtinIsOdd = liftNumericToBoolean(func(f float64) bool { + i, _ := math.Modf(f) // Get the integral part of the float + return math.Mod(i, 2) != 0 +}) +var builtinIsInteger = liftNumericToBoolean(func(f float64) bool { + _, frac := math.Modf(f) // Get the fraction part of the float + return frac == 0 +}) +var builtinIsDecimal = liftNumericToBoolean(func(f float64) bool { + _, frac := math.Modf(f) // Get the fraction part of the float + return frac != 0 +}) func liftBitwise(f func(int64, int64) int64, positiveRightArg bool) func(*interpreter, value, value) (value, error) { return func(i *interpreter, xv, yv value) (value, error) { @@ -2467,6 +2493,10 @@ var funcBuiltins = buildBuiltinMap([]builtin{ &unaryBuiltin{name: "mantissa", function: builtinMantissa, params: ast.Identifiers{"x"}}, &unaryBuiltin{name: "exponent", function: builtinExponent, params: ast.Identifiers{"x"}}, &unaryBuiltin{name: "round", function: builtinRound, params: ast.Identifiers{"x"}}, + &unaryBuiltin{name: "isEven", function: builtinIsEven, params: ast.Identifiers{"x"}}, + &unaryBuiltin{name: "isOdd", function: builtinIsOdd, params: ast.Identifiers{"x"}}, + &unaryBuiltin{name: "isInteger", function: builtinIsInteger, params: ast.Identifiers{"x"}}, + &unaryBuiltin{name: "isDecimal", function: builtinIsDecimal, params: ast.Identifiers{"x"}}, &binaryBuiltin{name: "pow", function: builtinPow, params: ast.Identifiers{"x", "n"}}, &binaryBuiltin{name: "modulo", function: builtinModulo, params: ast.Identifiers{"x", "y"}}, &unaryBuiltin{name: "md5", function: builtinMd5, params: ast.Identifiers{"s"}}, diff --git a/linter/internal/types/stdlib.go b/linter/internal/types/stdlib.go index eb4646d6b..062d00858 100644 --- a/linter/internal/types/stdlib.go +++ b/linter/internal/types/stdlib.go @@ -45,6 +45,10 @@ func prepareStdlib(g *typeGraph) { "isNumber": g.newSimpleFuncType(boolType, "v"), "isObject": g.newSimpleFuncType(boolType, "v"), "isString": g.newSimpleFuncType(boolType, "v"), + "isEven": g.newSimpleFuncType(boolType, "x"), + "isOdd": g.newSimpleFuncType(boolType, "x"), + "isInteger": g.newSimpleFuncType(boolType, "x"), + "isDecimal": g.newSimpleFuncType(boolType, "x"), // Mathematical utilities "abs": g.newSimpleFuncType(numberType, "n"), diff --git a/testdata/builtinIsDecimal.golden b/testdata/builtinIsDecimal.golden new file mode 100644 index 000000000..27ba77dda --- /dev/null +++ b/testdata/builtinIsDecimal.golden @@ -0,0 +1 @@ +true diff --git a/testdata/builtinIsDecimal.jsonnet b/testdata/builtinIsDecimal.jsonnet new file mode 100644 index 000000000..77d5556f2 --- /dev/null +++ b/testdata/builtinIsDecimal.jsonnet @@ -0,0 +1 @@ +std.isDecimal(1.1) \ No newline at end of file diff --git a/testdata/builtinIsDecimal.linter.golden b/testdata/builtinIsDecimal.linter.golden new file mode 100644 index 000000000..e69de29bb diff --git a/testdata/builtinIsDecimal2.golden b/testdata/builtinIsDecimal2.golden new file mode 100644 index 000000000..c508d5366 --- /dev/null +++ b/testdata/builtinIsDecimal2.golden @@ -0,0 +1 @@ +false diff --git a/testdata/builtinIsDecimal2.jsonnet b/testdata/builtinIsDecimal2.jsonnet new file mode 100644 index 000000000..a21818e4e --- /dev/null +++ b/testdata/builtinIsDecimal2.jsonnet @@ -0,0 +1 @@ +std.isDecimal(1) \ No newline at end of file diff --git a/testdata/builtinIsDecimal2.linter.golden b/testdata/builtinIsDecimal2.linter.golden new file mode 100644 index 000000000..e69de29bb diff --git a/testdata/builtinIsEven.golden b/testdata/builtinIsEven.golden new file mode 100644 index 000000000..27ba77dda --- /dev/null +++ b/testdata/builtinIsEven.golden @@ -0,0 +1 @@ +true diff --git a/testdata/builtinIsEven.jsonnet b/testdata/builtinIsEven.jsonnet new file mode 100644 index 000000000..d80782244 --- /dev/null +++ b/testdata/builtinIsEven.jsonnet @@ -0,0 +1 @@ +std.isEven(10) \ No newline at end of file diff --git a/testdata/builtinIsEven.linter.golden b/testdata/builtinIsEven.linter.golden new file mode 100644 index 000000000..e69de29bb diff --git a/testdata/builtinIsEven2.golden b/testdata/builtinIsEven2.golden new file mode 100644 index 000000000..c508d5366 --- /dev/null +++ b/testdata/builtinIsEven2.golden @@ -0,0 +1 @@ +false diff --git a/testdata/builtinIsEven2.jsonnet b/testdata/builtinIsEven2.jsonnet new file mode 100644 index 000000000..c0e4fd419 --- /dev/null +++ b/testdata/builtinIsEven2.jsonnet @@ -0,0 +1 @@ +std.isEven(5) \ No newline at end of file diff --git a/testdata/builtinIsEven2.linter.golden b/testdata/builtinIsEven2.linter.golden new file mode 100644 index 000000000..e69de29bb diff --git a/testdata/builtinIsInteger.golden b/testdata/builtinIsInteger.golden new file mode 100644 index 000000000..27ba77dda --- /dev/null +++ b/testdata/builtinIsInteger.golden @@ -0,0 +1 @@ +true diff --git a/testdata/builtinIsInteger.jsonnet b/testdata/builtinIsInteger.jsonnet new file mode 100644 index 000000000..ecfe8ee7f --- /dev/null +++ b/testdata/builtinIsInteger.jsonnet @@ -0,0 +1 @@ +std.isInteger(1) \ No newline at end of file diff --git a/testdata/builtinIsInteger.linter.golden b/testdata/builtinIsInteger.linter.golden new file mode 100644 index 000000000..e69de29bb diff --git a/testdata/builtinIsInteger2.golden b/testdata/builtinIsInteger2.golden new file mode 100644 index 000000000..c508d5366 --- /dev/null +++ b/testdata/builtinIsInteger2.golden @@ -0,0 +1 @@ +false diff --git a/testdata/builtinIsInteger2.jsonnet b/testdata/builtinIsInteger2.jsonnet new file mode 100644 index 000000000..62c6fe01d --- /dev/null +++ b/testdata/builtinIsInteger2.jsonnet @@ -0,0 +1 @@ +std.isInteger(1.1) \ No newline at end of file diff --git a/testdata/builtinIsInteger2.linter.golden b/testdata/builtinIsInteger2.linter.golden new file mode 100644 index 000000000..e69de29bb diff --git a/testdata/builtinIsOdd.golden b/testdata/builtinIsOdd.golden new file mode 100644 index 000000000..27ba77dda --- /dev/null +++ b/testdata/builtinIsOdd.golden @@ -0,0 +1 @@ +true diff --git a/testdata/builtinIsOdd.jsonnet b/testdata/builtinIsOdd.jsonnet new file mode 100644 index 000000000..164a93b08 --- /dev/null +++ b/testdata/builtinIsOdd.jsonnet @@ -0,0 +1 @@ +std.isOdd(5) \ No newline at end of file diff --git a/testdata/builtinIsOdd.linter.golden b/testdata/builtinIsOdd.linter.golden new file mode 100644 index 000000000..e69de29bb diff --git a/testdata/builtinIsOdd2.golden b/testdata/builtinIsOdd2.golden new file mode 100644 index 000000000..c508d5366 --- /dev/null +++ b/testdata/builtinIsOdd2.golden @@ -0,0 +1 @@ +false diff --git a/testdata/builtinIsOdd2.jsonnet b/testdata/builtinIsOdd2.jsonnet new file mode 100644 index 000000000..1501bbc1b --- /dev/null +++ b/testdata/builtinIsOdd2.jsonnet @@ -0,0 +1 @@ +std.isOdd(10) \ No newline at end of file diff --git a/testdata/builtinIsOdd2.linter.golden b/testdata/builtinIsOdd2.linter.golden new file mode 100644 index 000000000..e69de29bb