Skip to content

Commit 4db8ffb

Browse files
committed
internal/core/adt: do list artihmetic with comprehensions
Change-Id: I60cf6a2ced7def18a1e0196d7a70a8e52ace9b12 Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7761 Reviewed-by: Marcel van Lohuizen <[email protected]> Reviewed-by: CUE cueckoo <[email protected]>
1 parent 76ea22c commit 4db8ffb

File tree

4 files changed

+51
-44
lines changed

4 files changed

+51
-44
lines changed

internal/core/adt/binop.go

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -183,20 +183,36 @@ func BinOp(c *OpContext, op Op, left, right Value) Value {
183183
return c.newBytes(b)
184184

185185
case leftKind == ListKind && rightKind == ListKind:
186-
a := c.Elems(left)
187-
b := c.Elems(right)
186+
// TODO: get rid of list addition. Semantically it is somewhat
187+
// unclear and, as it turns out, it is also hard to get right.
188+
// Simulate addition with comprehensions now.
188189
if err := c.Err(); err != nil {
189190
return err
190191
}
191-
n := c.newList(c.src, nil)
192-
if err := n.appendListArcs(a); err != nil {
193-
return err
192+
193+
x := MakeIdentLabel(c, "x", "")
194+
195+
forClause := func(src Expr) *ForClause {
196+
return &ForClause{
197+
Value: x,
198+
Src: src,
199+
Dst: &ValueClause{&StructLit{Decls: []Decl{
200+
&FieldReference{UpCount: 1, Label: x},
201+
}}},
202+
}
194203
}
195-
if err := n.appendListArcs(b); err != nil {
196-
return err
204+
205+
list := &ListLit{
206+
Elems: []Elem{
207+
forClause(left),
208+
forClause(right),
209+
},
197210
}
198-
// n.isList = true
199-
// n.IsClosed = true
211+
212+
n := &Vertex{}
213+
n.AddConjunct(MakeRootConjunct(c.Env(0), list))
214+
n.Finalize(c)
215+
200216
return n
201217
}
202218

@@ -230,21 +246,30 @@ func BinOp(c *OpContext, op Op, left, right Value) Value {
230246
fallthrough
231247

232248
case leftKind == IntKind && rightKind == ListKind:
233-
a := c.Elems(right)
234-
n := c.newList(c.src, nil)
235-
// n.IsClosed = true
236-
index := int64(0)
249+
// TODO: get rid of list multiplication.
250+
251+
list := &ListLit{}
252+
x := MakeIdentLabel(c, "x", "")
253+
237254
for i := c.uint64(left, "list multiplier"); i > 0; i-- {
238-
for _, a := range a {
239-
f, _ := MakeLabel(a.Source(), index, IntLabel)
240-
n.Arcs = append(n.Arcs, &Vertex{
241-
Parent: n,
242-
Label: f,
243-
Conjuncts: a.Conjuncts,
244-
})
245-
index++
246-
}
255+
list.Elems = append(list.Elems,
256+
&ForClause{
257+
Value: x,
258+
Src: right,
259+
Dst: &ValueClause{&StructLit{Decls: []Decl{
260+
&FieldReference{UpCount: 1, Label: x},
261+
}}},
262+
},
263+
)
264+
}
265+
if err := c.Err(); err != nil {
266+
return err
247267
}
268+
269+
n := &Vertex{}
270+
n.AddConjunct(MakeRootConjunct(c.Env(0), list))
271+
n.Finalize(c)
272+
248273
return n
249274
}
250275

internal/core/adt/composite.go

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -572,23 +572,6 @@ func appendPath(a []Feature, v *Vertex) []Feature {
572572
return a
573573
}
574574

575-
func (v *Vertex) appendListArcs(arcs []*Vertex) (err *Bottom) {
576-
for _, a := range arcs {
577-
// TODO(list): BUG this only works if lists do not have definitions
578-
// fields.
579-
label, err := MakeLabel(a.Source(), int64(len(v.Arcs)), IntLabel)
580-
if err != nil {
581-
return &Bottom{Src: a.Source(), Err: err}
582-
}
583-
v.Arcs = append(v.Arcs, &Vertex{
584-
Parent: v,
585-
Label: label,
586-
Conjuncts: a.Conjuncts,
587-
})
588-
}
589-
return nil
590-
}
591-
592575
// An Conjunct is an Environment-Expr pair. The Environment is the starting
593576
// point for reference lookup for any reference contained in X.
594577
type Conjunct struct {

internal/core/adt/expr.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -875,11 +875,7 @@ func (x *BinaryExpr) evaluate(c *OpContext) Value {
875875
return err
876876
}
877877

878-
value := BinOp(c, x.Op, left, right)
879-
if n, ok := value.(*Vertex); ok && n.IsList() {
880-
n.UpdateStatus(Partial)
881-
}
882-
return value
878+
return BinOp(c, x.Op, left, right)
883879
}
884880

885881
// A CallExpr represents a call to a builtin.

internal/core/eval/eval.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1731,6 +1731,9 @@ func (n *nodeContext) insertField(f adt.Feature, x adt.Conjunct) *adt.Vertex {
17311731
// TODO: disallow adding conjuncts when cache set?
17321732
arc.AddConjunct(x)
17331733

1734+
adt.Assert("invalid adt.ID",
1735+
x.CloseID == 0 || int(x.CloseID) < len(closedInfo(n.node).Canopy))
1736+
17341737
if isNew {
17351738
closedInfo(n.node).visitAllFieldSets(func(o *fieldSet) {
17361739
o.MatchAndInsert(ctx, arc)

0 commit comments

Comments
 (0)