Skip to content

Commit

Permalink
support of multi-indices
Browse files Browse the repository at this point in the history
  • Loading branch information
mandelsoft committed Feb 15, 2023
1 parent 7ed9e2f commit 705dedb
Show file tree
Hide file tree
Showing 8 changed files with 1,287 additions and 1,237 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ linux:
GOOS=linux GOARCH=amd64 go build -o spiff++/spiff++ .

test:
go test $(VERBOSE) ./...
go test $(VERBOSE) --count=1 ./...

spiff_linux_amd64.zip:
GOOS=linux GOARCH=amd64 go build -o spiff++/spiff++ .
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,9 @@ resolves `foo` again to the value `42`.

**Note**: The index operator is usable on the root element (`.[index]`), also.

It is possible, to specify multiple comma separated indicies to successive lists
(`foo[0][1]` is equivalent to `foo[0,1]). In such case the indices may not be again lists.

## `(( list.[1..3] ))`

The slice expression can be used to extract a dedicated sub list from a list
Expand Down
10 changes: 9 additions & 1 deletion dynaml/dynamic_expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ func (e DynamicExpr) Evaluate(binding Binding, locally bool) (interface{}, Evalu

debug.Debug("dynamic reference: %+v\n", dyn)

if a, ok := dyn.([]yaml.Node); ok {
if len(a) == 1 {
dyn = a[0].Value()
}
}
var qual []string
switch v := dyn.(type) {
case int64:
Expand All @@ -59,6 +64,9 @@ func (e DynamicExpr) Evaluate(binding Binding, locally bool) (interface{}, Evalu
case string:
qual = []string{v}
case []yaml.Node:
if len(v) == 0 {
return info.Error("at least one index or field name required for reference qualifier")
}
qual = make([]string, len(v))
for i, e := range v {
switch v := e.Value().(type) {
Expand Down Expand Up @@ -88,5 +96,5 @@ func (e DynamicExpr) Evaluate(binding Binding, locally bool) (interface{}, Evalu
}

func (e DynamicExpr) String() string {
return fmt.Sprintf("%s.[%s]", e.Root, e.Index)
return fmt.Sprintf("%s.%s", e.Root, e.Index)
}
28 changes: 27 additions & 1 deletion dynaml/dynamic_expression_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var _ = Describe("dynamic references", func() {
})
})

Context("when a dynamic array refernce is found", func() {
Context("when a dynamic array reference is found", func() {
It("evaluates to the indexed array entry", func() {
ref := ReferenceExpr{Path: []string{"foo"}}
idx := IntegerExpr{1}
Expand All @@ -39,5 +39,31 @@ var _ = Describe("dynamic references", func() {

Expect(expr).To(EvaluateAs(42, binding))
})

It("evaluates to the indexed array entry", func() {
ref := ReferenceExpr{Path: []string{"foo"}}
idx := ListExpr{[]Expression{IntegerExpr{1}}}
expr := DynamicExpr{ref, idx}
binding := FakeBinding{
FoundReferences: map[string]yaml.Node{
"foo": NewNode([]yaml.Node{NewNode(1, nil), NewNode(42, nil)}, nil),
},
}

Expect(expr).To(EvaluateAs(42, binding))
})

It("evaluates to the multi-indexed array entry", func() {
ref := ReferenceExpr{Path: []string{"foo"}}
idx := ListExpr{[]Expression{IntegerExpr{0}, IntegerExpr{1}}}
expr := DynamicExpr{ref, idx}
binding := FakeBinding{
FoundReferences: map[string]yaml.Node{
"foo": NewNode([]yaml.Node{NewNode([]yaml.Node{NewNode(1, nil), NewNode(42, nil)}, nil)}, nil),
},
}

Expect(expr).To(EvaluateAs(42, binding))
})
})
})
5 changes: 3 additions & 2 deletions dynaml/dynaml.peg
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ Level0 <- IP / String / Number / Boolean / Undefined / Nil / Symbol / Not /
Chained <- ( MapMapping / Sync / Catch / Mapping / MapSelection / Selection / Sum / List / Map / Range / Grouped / Reference / TopIndex ) ChainedQualifiedExpression*
ChainedQualifiedExpression <- ChainedCall / Currying / ChainedRef / ChainedDynRef / Projection
ChainedRef <- PathComponent FollowUpRef
ChainedDynRef <- '.'? '[' Expression ']'
TopIndex <- '.' '[' Expression ']'
ChainedDynRef <- '.'? Indices
TopIndex <- '.' Indices
Indices <- StartList ExpressionList ']'
Slice <- Range
Currying <- '*' ChainedCall
ChainedCall <- StartArguments NameArgumentList? ')'
Expand Down
Loading

0 comments on commit 705dedb

Please sign in to comment.