Skip to content

Commit 7a74082

Browse files
committed
feat: Add more math functions
1 parent 44538a3 commit 7a74082

27 files changed

+59
-4
lines changed

builtins.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,16 @@ func liftNumeric(f func(float64) float64) func(*interpreter, value) (value, erro
10591059
}
10601060
}
10611061

1062+
func liftNumericToBoolean(f func(float64) bool) func(*interpreter, value) (value, error) {
1063+
return func(i *interpreter, x value) (value, error) {
1064+
n, err := i.getNumber(x)
1065+
if err != nil {
1066+
return nil, err
1067+
}
1068+
return makeValueBoolean(f(n.value)), nil
1069+
}
1070+
}
1071+
10621072
var builtinSqrt = liftNumeric(math.Sqrt)
10631073
var builtinCeil = liftNumeric(math.Ceil)
10641074
var builtinFloor = liftNumeric(math.Floor)
@@ -1085,6 +1095,22 @@ var builtinExponent = liftNumeric(func(f float64) float64 {
10851095
return float64(exponent)
10861096
})
10871097
var builtinRound = liftNumeric(math.Round)
1098+
var builtinIsEven = liftNumericToBoolean(func(f float64) bool {
1099+
i, _ := math.Modf(f) // Get the integral part of the float
1100+
return math.Mod(i, 2) == 0
1101+
})
1102+
var builtinIsOdd = liftNumericToBoolean(func(f float64) bool {
1103+
i, _ := math.Modf(f) // Get the integral part of the float
1104+
return math.Mod(i, 2) != 0
1105+
})
1106+
var builtinIsInteger = liftNumericToBoolean(func(f float64) bool {
1107+
_, frac := math.Modf(f) // Get the fraction part of the float
1108+
return frac == 0
1109+
})
1110+
var builtinIsDecimal = liftNumericToBoolean(func(f float64) bool {
1111+
_, frac := math.Modf(f) // Get the fraction part of the float
1112+
return frac != 0
1113+
})
10881114

10891115
func liftBitwise(f func(int64, int64) int64, positiveRightArg bool) func(*interpreter, value, value) (value, error) {
10901116
return func(i *interpreter, xv, yv value) (value, error) {
@@ -2394,6 +2420,10 @@ var funcBuiltins = buildBuiltinMap([]builtin{
23942420
&unaryBuiltin{name: "mantissa", function: builtinMantissa, params: ast.Identifiers{"x"}},
23952421
&unaryBuiltin{name: "exponent", function: builtinExponent, params: ast.Identifiers{"x"}},
23962422
&unaryBuiltin{name: "round", function: builtinRound, params: ast.Identifiers{"x"}},
2423+
&unaryBuiltin{name: "isEven", function: builtinIsEven, params: ast.Identifiers{"x"}},
2424+
&unaryBuiltin{name: "isOdd", function: builtinIsOdd, params: ast.Identifiers{"x"}},
2425+
&unaryBuiltin{name: "isInteger", function: builtinIsInteger, params: ast.Identifiers{"x"}},
2426+
&unaryBuiltin{name: "isDecimal", function: builtinIsDecimal, params: ast.Identifiers{"x"}},
23972427
&binaryBuiltin{name: "pow", function: builtinPow, params: ast.Identifiers{"x", "n"}},
23982428
&binaryBuiltin{name: "modulo", function: builtinModulo, params: ast.Identifiers{"x", "y"}},
23992429
&unaryBuiltin{name: "md5", function: builtinMd5, params: ast.Identifiers{"s"}},

linter/internal/types/stdlib.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ func prepareStdlib(g *typeGraph) {
4545
"isNumber": g.newSimpleFuncType(boolType, "v"),
4646
"isObject": g.newSimpleFuncType(boolType, "v"),
4747
"isString": g.newSimpleFuncType(boolType, "v"),
48+
"isEven": g.newSimpleFuncType(boolType, "x"),
49+
"isOdd": g.newSimpleFuncType(boolType, "x"),
50+
"isInteger": g.newSimpleFuncType(boolType, "x"),
51+
"isDecimal": g.newSimpleFuncType(boolType, "x"),
4852

4953
// Mathematical utilities
5054
"abs": g.newSimpleFuncType(numberType, "n"),
@@ -145,10 +149,10 @@ func prepareStdlib(g *typeGraph) {
145149
"maxArray": g.newFuncType(anyArrayType, []ast.Parameter{required("arr"), optional("keyF")}),
146150
"contains": g.newSimpleFuncType(boolType, "arr", "elem"),
147151
// TODO these need test cases written by someone who understands how to make them
148-
"all": g.newSimpleFuncType(boolArrayType, "arr"),
149-
"any": g.newSimpleFuncType(boolArrayType, "arr"),
150-
"remove": g.newSimpleFuncType(anyArrayType, "arr", "elem"),
151-
"removeAt": g.newSimpleFuncType(anyArrayType, "arr", "i"),
152+
"all": g.newSimpleFuncType(boolArrayType, "arr"),
153+
"any": g.newSimpleFuncType(boolArrayType, "arr"),
154+
"remove": g.newSimpleFuncType(anyArrayType, "arr", "elem"),
155+
"removeAt": g.newSimpleFuncType(anyArrayType, "arr", "i"),
152156

153157
// Sets
154158

testdata/builtinIsDecimal.golden

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
true

testdata/builtinIsDecimal.jsonnet

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
std.isDecimal(1.1)

testdata/builtinIsDecimal.linter.golden

Whitespace-only changes.

testdata/builtinIsDecimal2.golden

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
false

testdata/builtinIsDecimal2.jsonnet

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
std.isDecimal(1)

testdata/builtinIsDecimal2.linter.golden

Whitespace-only changes.

testdata/builtinIsEven.golden

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
true

testdata/builtinIsEven.jsonnet

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
std.isEven(10)

0 commit comments

Comments
 (0)