diff --git a/zcl/zclsyntax/expression.go b/zcl/zclsyntax/expression.go index 65a038b..bad6fbe 100644 --- a/zcl/zclsyntax/expression.go +++ b/zcl/zclsyntax/expression.go @@ -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...) - vals[key.AsString()] = val + + 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 { diff --git a/zcl/zclsyntax/expression_test.go b/zcl/zclsyntax/expression_test.go index b3b59cb..73a4149 100644 --- a/zcl/zclsyntax/expression_test.go +++ b/zcl/zclsyntax/expression_test.go @@ -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,