15
15
package adt
16
16
17
17
import (
18
- "sort"
19
-
20
18
"cuelang.org/go/cue/errors"
21
19
"cuelang.org/go/cue/token"
22
20
)
@@ -86,48 +84,30 @@ import (
86
84
87
85
type envDisjunct struct {
88
86
env * Environment
89
- values []disjunct
90
- numDefaults int
91
- hasDefaults bool
92
87
cloneID CloseInfo
93
- }
94
-
95
- type disjunct struct {
96
- v * Vertex
97
- expr Expr
98
- isDefault bool
88
+ expr * DisjunctionExpr
89
+ value * Disjunction
90
+ hasDefaults bool
99
91
}
100
92
101
93
func (n * nodeContext ) addDisjunction (env * Environment , x * DisjunctionExpr , cloneID CloseInfo ) {
102
- a := make ([]disjunct , 0 , len (x .Values ))
103
94
95
+ // TODO: precompute
104
96
numDefaults := 0
105
97
for _ , v := range x .Values {
106
98
isDef := v .Default // || n.hasDefaults(env, v.Val)
107
99
if isDef {
108
100
numDefaults ++
109
101
}
110
- a = append (a , disjunct {nil , v .Val , isDef })
111
102
}
112
103
113
- sort .SliceStable (a , func (i , j int ) bool {
114
- return ! a [j ].isDefault && a [i ].isDefault != a [j ].isDefault
115
- })
116
-
117
104
n .disjunctions = append (n .disjunctions ,
118
- envDisjunct {env , a , numDefaults , numDefaults > 0 , cloneID })
119
-
105
+ envDisjunct {env , cloneID , x , nil , numDefaults > 0 })
120
106
}
121
107
122
108
func (n * nodeContext ) addDisjunctionValue (env * Environment , x * Disjunction , cloneID CloseInfo ) {
123
- a := make ([]disjunct , 0 , len (x .Values ))
124
-
125
- for i , v := range x .Values {
126
- a = append (a , disjunct {v , nil , i < x .NumDefaults })
127
- }
128
-
129
109
n .disjunctions = append (n .disjunctions ,
130
- envDisjunct {env , a , x . NumDefaults , x .HasDefaults , cloneID })
110
+ envDisjunct {env , cloneID , nil , x , x .HasDefaults })
131
111
132
112
}
133
113
@@ -216,22 +196,33 @@ func (n *nodeContext) expandDisjuncts(
216
196
}
217
197
218
198
for _ , dn := range a {
219
- for _ , v := range d .values {
220
- cn := dn .clone ()
221
- * cn .node = snapshotVertex (dn .snapshot )
222
-
223
- if v .v != nil {
224
- cn .addValueConjunct (d .env , v .v , d .cloneID )
225
- } else {
226
- c := MakeConjunct (d .env , v .expr , d .cloneID )
199
+ switch {
200
+ case d .expr != nil :
201
+ for _ , v := range d .expr .Values {
202
+ cn := dn .clone ()
203
+ * cn .node = snapshotVertex (dn .snapshot )
204
+
205
+ c := MakeConjunct (d .env , v .Val , d .cloneID )
227
206
cn .addExprConjunct (c )
207
+
208
+ newMode := mode (d .hasDefaults , v .Default )
209
+ cn .defaultMode = combineDefault (dn .defaultMode , newMode )
210
+
211
+ cn .expandDisjuncts (state , n , newMode , true )
228
212
}
229
213
230
- newMode := mode (d , v )
214
+ case d .value != nil :
215
+ for i , v := range d .value .Values {
216
+ cn := dn .clone ()
217
+ * cn .node = snapshotVertex (dn .snapshot )
218
+
219
+ cn .addValueConjunct (d .env , v , d .cloneID )
231
220
232
- cn .expandDisjuncts (state , n , newMode , true )
221
+ newMode := mode (d .hasDefaults , i < d .value .NumDefaults )
222
+ cn .defaultMode = combineDefault (dn .defaultMode , newMode )
233
223
234
- cn .defaultMode = combineDefault (dn .defaultMode , newMode )
224
+ cn .expandDisjuncts (state , n , newMode , true )
225
+ }
235
226
}
236
227
}
237
228
@@ -243,6 +234,7 @@ func (n *nodeContext) expandDisjuncts(
243
234
244
235
if len (n .disjuncts ) == 0 {
245
236
n .makeError ()
237
+ break
246
238
}
247
239
}
248
240
@@ -271,6 +263,9 @@ func (n *nodeContext) expandDisjuncts(
271
263
for _ , v := range p .disjuncts {
272
264
if Equal (n .ctx , & v .result , & d .result ) {
273
265
n .ctx .Unifier .freeNodeContext (n )
266
+ if d .defaultMode == isDefault {
267
+ v .defaultMode = isDefault
268
+ }
274
269
continue outer
275
270
}
276
271
}
@@ -307,12 +302,12 @@ func (n *nodeContext) makeError() {
307
302
n .node .SetValue (n .ctx , Finalized , b )
308
303
}
309
304
310
- func mode (d envDisjunct , v disjunct ) defaultMode {
305
+ func mode (hasDefault , marked bool ) defaultMode {
311
306
var mode defaultMode
312
307
switch {
313
- case ! d . hasDefaults :
308
+ case ! hasDefault :
314
309
mode = maybeDefault
315
- case v . isDefault :
310
+ case marked :
316
311
mode = isDefault
317
312
default :
318
313
mode = notDefault
@@ -379,8 +374,8 @@ type defaultMode int
379
374
380
375
const (
381
376
maybeDefault defaultMode = iota
382
- notDefault
383
377
isDefault
378
+ notDefault
384
379
)
385
380
386
381
// combineDefaults combines default modes for unifying conjuncts.
@@ -391,24 +386,9 @@ const (
391
386
// U2: (v1, d1) & (v2, d2) => (v1&v2, d1&d2)
392
387
func combineDefault (a , b defaultMode ) defaultMode {
393
388
if a > b {
394
- a , b = b , a
395
- }
396
- switch {
397
- case a == maybeDefault && b == maybeDefault :
398
- return maybeDefault
399
- case a == maybeDefault && b == notDefault :
400
- return notDefault
401
- case a == maybeDefault && b == isDefault :
402
- return isDefault
403
- case a == notDefault && b == notDefault :
404
- return notDefault
405
- case a == notDefault && b == isDefault :
406
- return notDefault
407
- case a == isDefault && b == isDefault :
408
- return isDefault
409
- default :
410
- panic ("unreachable" )
389
+ return a
411
390
}
391
+ return b
412
392
}
413
393
414
394
// disjunctError returns a compound error for a failed disjunction.
0 commit comments