From 7edd5d373b8d5fd74153582e331d8076a7808929 Mon Sep 17 00:00:00 2001 From: Deep Goel <34025930+DeepanshuGoel17@users.noreply.github.com> Date: Thu, 25 May 2023 18:15:24 +0530 Subject: [PATCH] feat: implement std.maxArray (#696) --- builtins.go | 37 ++++++++++++++++++++++++++ linter/internal/types/stdlib.go | 3 ++- testdata/builtinMaxArray.golden | 1 + testdata/builtinMaxArray.jsonnet | 1 + testdata/builtinMaxArray.linter.golden | 0 5 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 testdata/builtinMaxArray.golden create mode 100644 testdata/builtinMaxArray.jsonnet create mode 100644 testdata/builtinMaxArray.linter.golden diff --git a/builtins.go b/builtins.go index 93beace..2d93943 100644 --- a/builtins.go +++ b/builtins.go @@ -1953,6 +1953,42 @@ func builtinMinArray(i *interpreter, arguments []value) (value, error) { return minVal, nil } +func builtinMaxArray(i *interpreter, arguments []value) (value, error) { + arrv := arguments[0] + keyFv := arguments[1] + + arr, err := i.getArray(arrv) + if err != nil { + return nil, err + } + keyF, err := i.getFunction(keyFv) + if err != nil { + return nil, err + } + num := arr.length() + if num == 0 { + return nil, i.Error("Expected at least one element in array. Got none") + } + maxVal, err := keyF.call(i, args(arr.elements[0])) + if err != nil { + return nil, err + } + for index := 1; index < num; index++ { + current, err := keyF.call(i, args(arr.elements[index])) + if err != nil { + return nil, err + } + cmp, err := valueCmp(i, maxVal, current) + if err != nil { + return nil, err + } + if cmp < 0 { + maxVal = current + } + } + return maxVal, nil +} + func builtinNative(i *interpreter, name value) (value, error) { str, err := i.getString(name) if err != nil { @@ -2385,6 +2421,7 @@ var funcBuiltins = buildBuiltinMap([]builtin{ &unaryBuiltin{name: "decodeUTF8", function: builtinDecodeUTF8, params: ast.Identifiers{"arr"}}, &generalBuiltin{name: "sort", function: builtinSort, params: []generalBuiltinParameter{{name: "arr"}, {name: "keyF", defaultValue: functionID}}}, &generalBuiltin{name: "minArray", function: builtinMinArray, params: []generalBuiltinParameter{{name: "arr"}, {name: "keyF", defaultValue: functionID}}}, + &generalBuiltin{name: "maxArray", function: builtinMaxArray, params: []generalBuiltinParameter{{name: "arr"}, {name: "keyF", defaultValue: functionID}}}, &unaryBuiltin{name: "native", function: builtinNative, params: ast.Identifiers{"x"}}, &unaryBuiltin{name: "sum", function: builtinSum, params: ast.Identifiers{"arr"}}, &binaryBuiltin{name: "contains", function: builtinContains, params: ast.Identifiers{"arr", "elem"}}, diff --git a/linter/internal/types/stdlib.go b/linter/internal/types/stdlib.go index b2322b0..0e3c5e8 100644 --- a/linter/internal/types/stdlib.go +++ b/linter/internal/types/stdlib.go @@ -141,7 +141,8 @@ func prepareStdlib(g *typeGraph) { "sort": g.newFuncType(anyArrayType, []ast.Parameter{required("arr"), optional("keyF")}), "uniq": g.newFuncType(anyArrayType, []ast.Parameter{required("arr"), optional("keyF")}), "sum": g.newSimpleFuncType(numberType, "arr"), - "minArray": g.newSimpleFuncType(anyType, "arr"), + "minArray": g.newFuncType(anyArrayType, []ast.Parameter{required("arr"), optional("keyF")}), + "maxArray": g.newFuncType(anyArrayType, []ast.Parameter{required("arr"), optional("keyF")}), "contains": g.newSimpleFuncType(boolType, "arr", "elem"), "remove": g.newSimpleFuncType(anyArrayType, "arr", "elem"), "removeAt": g.newSimpleFuncType(anyArrayType, "arr", "i"), diff --git a/testdata/builtinMaxArray.golden b/testdata/builtinMaxArray.golden new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/testdata/builtinMaxArray.golden @@ -0,0 +1 @@ +1 diff --git a/testdata/builtinMaxArray.jsonnet b/testdata/builtinMaxArray.jsonnet new file mode 100644 index 0000000..c60f9ff --- /dev/null +++ b/testdata/builtinMaxArray.jsonnet @@ -0,0 +1 @@ +std.maxArray([1,-1,0]) \ No newline at end of file diff --git a/testdata/builtinMaxArray.linter.golden b/testdata/builtinMaxArray.linter.golden new file mode 100644 index 0000000..e69de29