diff --git a/ast/builtins.go b/ast/builtins.go index 6317ef5808..d615a58179 100644 --- a/ast/builtins.go +++ b/ast/builtins.go @@ -80,6 +80,7 @@ var DefaultBuiltins = [...]*Builtin{ // Arrays ArrayConcat, ArraySlice, + ArrayReverse, // Conversions ToNumber, @@ -711,6 +712,16 @@ var ArraySlice = &Builtin{ ), } +var ArrayReverse = &Builtin{ + Name: "array.reverse", + Decl: types.NewFunction( + types.Args( + types.NewArray(nil, types.A), + ), + types.NewArray(nil, types.A), + ), +} + /** * Conversions */ diff --git a/topdown/array.go b/topdown/array.go index ca3e0d9fae..4be6bf7c4f 100644 --- a/topdown/array.go +++ b/topdown/array.go @@ -71,7 +71,27 @@ func builtinArraySlice(a, i, j ast.Value) (ast.Value, error) { return arr.Slice(startIndex, stopIndex), nil } +func builtinArrayReverse(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + arr, err := builtins.ArrayOperand(operands[0].Value, 1) + if err != nil { + return err + } + + length := arr.Len() + reversedArr := make([]*ast.Term, length) + index := 0 + + for index < length { + reversedArr[index] = arr.Elem(length - index - 1) // + index++ + } + + return iter(ast.ArrayTerm(reversedArr...)) + +} + func init() { RegisterFunctionalBuiltin2(ast.ArrayConcat.Name, builtinArrayConcat) RegisterFunctionalBuiltin3(ast.ArraySlice.Name, builtinArraySlice) + RegisterBuiltinFunc(ast.ArrayReverse.Name, builtinArrayReverse) }