Efficient native implementation of std.join

It changes the behavior slightly - mixing strings
and arrays in join is no longer allowed.
This commit is contained in:
Stanisław Barzowski 2017-11-03 18:50:35 +01:00 committed by Dave Cunningham
parent 3481c9c698
commit 8ade994928
17 changed files with 96 additions and 0 deletions

View File

@ -285,6 +285,59 @@ func builtinFlatMap(e *evaluator, funcp potentialValue, arrp potentialValue) (va
return makeValueArray(elems), nil
}
func joinArrays(e *evaluator, sep *valueArray, arr *valueArray) (value, error) {
result := make([]potentialValue, 0, arr.length())
for i, elem := range arr.elements {
if i != 0 {
for _, subElem := range sep.elements {
result = append(result, subElem)
}
}
elemArr, err := e.evaluateArray(elem)
if err != nil {
return nil, err
}
for _, subElem := range elemArr.elements {
result = append(result, subElem)
}
}
return makeValueArray(result), nil
}
func joinStrings(e *evaluator, sep *valueString, arr *valueArray) (value, error) {
result := make([]rune, 0, arr.length())
for i, elem := range arr.elements {
if i != 0 {
result = append(result, sep.value...)
}
elemString, err := e.evaluateString(elem)
if err != nil {
return nil, err
}
result = append(result, elemString.value...)
}
return &valueString{value: result}, nil
}
func builtinJoin(e *evaluator, sepp potentialValue, arrp potentialValue) (value, error) {
arr, err := e.evaluateArray(arrp)
if err != nil {
return nil, err
}
sep, err := e.evaluate(sepp)
if err != nil {
return nil, err
}
switch sep := sep.(type) {
case *valueString:
return joinStrings(e, sep, arr)
case *valueArray:
return joinArrays(e, sep, arr)
default:
return nil, e.Error("join first parameter should be string or array, got " + sep.getType().name)
}
}
func builtinFilter(e *evaluator, funcp potentialValue, arrp potentialValue) (value, error) {
arr, err := e.evaluateArray(arrp)
if err != nil {
@ -771,6 +824,7 @@ var funcBuiltins = buildBuiltinMap([]builtin{
&UnaryBuiltin{name: "toString", function: builtinToString, parameters: ast.Identifiers{"a"}},
&BinaryBuiltin{name: "makeArray", function: builtinMakeArray, parameters: ast.Identifiers{"sz", "func"}},
&BinaryBuiltin{name: "flatMap", function: builtinFlatMap, parameters: ast.Identifiers{"func", "arr"}},
&BinaryBuiltin{name: "join", function: builtinJoin, parameters: ast.Identifiers{"sep", "arr"}},
&BinaryBuiltin{name: "filter", function: builtinFilter, parameters: ast.Identifiers{"func", "arr"}},
&BinaryBuiltin{name: "range", function: builtinRange, parameters: ast.Identifiers{"from", "to"}},
&BinaryBuiltin{name: "primitiveEquals", function: primitiveEquals, parameters: ast.Identifiers{"sz", "func"}},

1
testdata/std.join.golden vendored Normal file
View File

@ -0,0 +1 @@
[ ]

1
testdata/std.join.jsonnet vendored Normal file
View File

@ -0,0 +1 @@
std.join([], [])

1
testdata/std.join2.golden vendored Normal file
View File

@ -0,0 +1 @@
[ ]

1
testdata/std.join2.jsonnet vendored Normal file
View File

@ -0,0 +1 @@
std.join([42], [])

3
testdata/std.join3.golden vendored Normal file
View File

@ -0,0 +1,3 @@
[
1
]

1
testdata/std.join3.jsonnet vendored Normal file
View File

@ -0,0 +1 @@
std.join([42], [[1]])

5
testdata/std.join4.golden vendored Normal file
View File

@ -0,0 +1,5 @@
[
1,
42,
2
]

1
testdata/std.join4.jsonnet vendored Normal file
View File

@ -0,0 +1 @@
std.join([42], [[1], [2]])

7
testdata/std.join5.golden vendored Normal file
View File

@ -0,0 +1,7 @@
[
1,
42,
2,
42,
3
]

1
testdata/std.join5.jsonnet vendored Normal file
View File

@ -0,0 +1 @@
std.join([42], [[1], [2], [3]])

1
testdata/std.join6.golden vendored Normal file
View File

@ -0,0 +1 @@
"aaxxxbb"

1
testdata/std.join6.jsonnet vendored Normal file
View File

@ -0,0 +1 @@
std.join("xxx", ["aa", "bb"])

8
testdata/std.join7.golden vendored Normal file
View File

@ -0,0 +1,8 @@
RUNTIME ERROR: Unexpected type array, expected string
-------------------------------------------------
<builtin> builtin function <join>
-------------------------------------------------
During evaluation

1
testdata/std.join7.jsonnet vendored Normal file
View File

@ -0,0 +1 @@
std.join("aa", [[1], [2]])

8
testdata/std.join8.golden vendored Normal file
View File

@ -0,0 +1,8 @@
RUNTIME ERROR: Unexpected type string, expected array
-------------------------------------------------
<builtin> builtin function <join>
-------------------------------------------------
During evaluation

1
testdata/std.join8.jsonnet vendored Normal file
View File

@ -0,0 +1 @@
std.join([3, 4], [[1, 2], "56"])