zclsyntax: evaluation of ForExpr into a tuple
This commit is contained in:
parent
fdd68833f3
commit
833ff9ecd7
@ -672,7 +672,7 @@ func (e *ForExpr) Value(ctx *zcl.EvalContext) (cty.Value, zcl.Diagnostics) {
|
|||||||
})
|
})
|
||||||
return cty.DynamicVal, diags
|
return cty.DynamicVal, diags
|
||||||
}
|
}
|
||||||
if !collVal.IsKnown() {
|
if collVal.Type() == cty.DynamicPseudoType {
|
||||||
return cty.DynamicVal, diags
|
return cty.DynamicVal, diags
|
||||||
}
|
}
|
||||||
if !collVal.CanIterateElements() {
|
if !collVal.CanIterateElements() {
|
||||||
@ -688,6 +688,9 @@ func (e *ForExpr) Value(ctx *zcl.EvalContext) (cty.Value, zcl.Diagnostics) {
|
|||||||
})
|
})
|
||||||
return cty.DynamicVal, diags
|
return cty.DynamicVal, diags
|
||||||
}
|
}
|
||||||
|
if !collVal.IsKnown() {
|
||||||
|
return cty.DynamicVal, diags
|
||||||
|
}
|
||||||
|
|
||||||
childCtx := ctx.NewChild()
|
childCtx := ctx.NewChild()
|
||||||
childCtx.Variables = map[string]cty.Value{}
|
childCtx.Variables = map[string]cty.Value{}
|
||||||
@ -800,7 +803,71 @@ func (e *ForExpr) Value(ctx *zcl.EvalContext) (cty.Value, zcl.Diagnostics) {
|
|||||||
} else {
|
} else {
|
||||||
// Producing a tuple
|
// Producing a tuple
|
||||||
vals := []cty.Value{}
|
vals := []cty.Value{}
|
||||||
panic("for into a tuple is not yet implemented")
|
|
||||||
|
it := collVal.ElementIterator()
|
||||||
|
|
||||||
|
known := true
|
||||||
|
for it.Next() {
|
||||||
|
k, v := it.Element()
|
||||||
|
if e.KeyVar != "" {
|
||||||
|
childCtx.Variables[e.KeyVar] = k
|
||||||
|
}
|
||||||
|
childCtx.Variables[e.ValVar] = v
|
||||||
|
|
||||||
|
if e.CondExpr != nil {
|
||||||
|
includeRaw, condDiags := e.CondExpr.Value(childCtx)
|
||||||
|
diags = append(diags, condDiags...)
|
||||||
|
if includeRaw.IsNull() {
|
||||||
|
if known {
|
||||||
|
diags = append(diags, &zcl.Diagnostic{
|
||||||
|
Severity: zcl.DiagError,
|
||||||
|
Summary: "Condition is null",
|
||||||
|
Detail: "The value of the 'if' clause must not be null.",
|
||||||
|
Subject: e.CondExpr.Range().Ptr(),
|
||||||
|
Context: &e.SrcRange,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
known = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !includeRaw.IsKnown() {
|
||||||
|
// We will eventually return DynamicVal, but we'll continue
|
||||||
|
// iterating in case there are other diagnostics to gather
|
||||||
|
// for later elements.
|
||||||
|
known = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
include, err := convert.Convert(includeRaw, cty.Bool)
|
||||||
|
if err != nil {
|
||||||
|
if known {
|
||||||
|
diags = append(diags, &zcl.Diagnostic{
|
||||||
|
Severity: zcl.DiagError,
|
||||||
|
Summary: "Invalid 'for' condition",
|
||||||
|
Detail: fmt.Sprintf("The 'if' clause value is invalid: %s.", err.Error()),
|
||||||
|
Subject: e.CondExpr.Range().Ptr(),
|
||||||
|
Context: &e.SrcRange,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
known = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if include.False() {
|
||||||
|
// Skip this element
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val, valDiags := e.ValExpr.Value(childCtx)
|
||||||
|
diags = append(diags, valDiags...)
|
||||||
|
vals = append(vals, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !known {
|
||||||
|
return cty.DynamicVal, diags
|
||||||
|
}
|
||||||
|
|
||||||
return cty.TupleVal(vals), diags
|
return cty.TupleVal(vals), diags
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -485,6 +485,14 @@ upper(
|
|||||||
}),
|
}),
|
||||||
0,
|
0,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
`[for k, v in {hello: "world"}: "${k}=${v}"]`,
|
||||||
|
nil,
|
||||||
|
cty.TupleVal([]cty.Value{
|
||||||
|
cty.StringVal("hello=world"),
|
||||||
|
}),
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
`[{name: "Steve"}, {name: "Ermintrude"}].*.name`,
|
`[{name: "Steve"}, {name: "Ermintrude"}].*.name`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user