zclsyntax: correct evaluation of the for expression "group" mode

This further alters the object-construction mode so that rather than
producing a flat object it instead produces an object of tuples. All
items that produce the same key are grouped together under the same
key in the result, allowing projections that flip the orientation of
a key/value sequence where the new keys are not necessarily unique.
This commit is contained in:
Martin Atkins 2017-06-18 08:45:45 -07:00
parent b83b6b27be
commit 2506450b6e
2 changed files with 41 additions and 2 deletions

View File

@ -697,7 +697,13 @@ func (e *ForExpr) Value(ctx *zcl.EvalContext) (cty.Value, zcl.Diagnostics) {
if e.KeyExpr != nil {
// Producing an object
vals := map[string]cty.Value{}
var vals map[string]cty.Value
var groupVals map[string][]cty.Value
if e.Group {
groupVals = map[string][]cty.Value{}
} else {
vals = map[string]cty.Value{}
}
it := collVal.ElementIterator()
@ -791,13 +797,26 @@ func (e *ForExpr) Value(ctx *zcl.EvalContext) (cty.Value, zcl.Diagnostics) {
val, valDiags := e.ValExpr.Value(childCtx)
diags = append(diags, valDiags...)
if e.Group {
k := key.AsString()
groupVals[k] = append(groupVals[k], val)
} else {
vals[key.AsString()] = val
}
}
if !known {
return cty.DynamicVal, diags
}
if e.Group {
vals = map[string]cty.Value{}
for k, gvs := range groupVals {
vals[k] = cty.TupleVal(gvs)
}
}
return cty.ObjectVal(vals), diags
} else {

View File

@ -509,6 +509,26 @@ upper(
}),
1, // must have a key expr when producing a map
},
{
`{for i, v in ["a", "b", "c", "b", "d"]: v => i...}`,
nil,
cty.ObjectVal(map[string]cty.Value{
"a": cty.TupleVal([]cty.Value{
cty.NumberIntVal(0),
}),
"b": cty.TupleVal([]cty.Value{
cty.NumberIntVal(1),
cty.NumberIntVal(3),
}),
"c": cty.TupleVal([]cty.Value{
cty.NumberIntVal(2),
}),
"d": cty.TupleVal([]cty.Value{
cty.NumberIntVal(4),
}),
}),
0,
},
{
`[for v in {hello: "world"}: v...]`,
nil,