...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package adt
16
17
18 func Default(v Value) Value {
19 switch x := v.(type) {
20 case *Vertex:
21 return x.Default()
22 case *Disjunction:
23 return x.Default()
24 default:
25 return v
26 }
27 }
28
29 func (d *Disjunction) Default() Value {
30 switch d.NumDefaults {
31 case 0:
32 return d
33 case 1:
34 return d.Values[0]
35 default:
36 return &Disjunction{
37 Src: d.Src,
38 Values: d.Values[:d.NumDefaults],
39 NumDefaults: 0,
40 }
41 }
42 }
43
44
45
46
47 func (v *Vertex) Default() *Vertex {
48 switch d := v.BaseValue.(type) {
49 default:
50 return v
51
52 case *Disjunction:
53 var w *Vertex
54
55 switch d.NumDefaults {
56 case 0:
57 return v
58 case 1:
59 w = ToVertex(Default(d.Values[0]))
60 default:
61 x := *v
62 x.state = nil
63 x.BaseValue = &Disjunction{
64 Src: d.Src,
65 Values: d.Values[:d.NumDefaults],
66 NumDefaults: 0,
67 }
68 w = &x
69 w.Conjuncts = nil
70 }
71
72 if w.Conjuncts == nil {
73 for _, c := range v.Conjuncts {
74
75 expr, _ := stripNonDefaults(c.Elem())
76 w.Conjuncts = append(w.Conjuncts, MakeRootConjunct(c.Env, expr))
77 }
78 }
79 return w
80
81 case *ListMarker:
82 m := *d
83 m.IsOpen = false
84
85 w := *v
86 w.BaseValue = &m
87 w.state = nil
88 return &w
89 }
90 }
91
92
93 func stripNonDefaults(elem Elem) (r Elem, stripped bool) {
94 expr, ok := elem.(Expr)
95 if !ok {
96 return elem, false
97 }
98 switch x := expr.(type) {
99 case *DisjunctionExpr:
100 if !x.HasDefaults {
101 return x, false
102 }
103 d := *x
104 d.Values = []Disjunct{}
105 for _, v := range x.Values {
106 if v.Default {
107 d.Values = append(d.Values, v)
108 }
109 }
110 if len(d.Values) == 1 {
111 return d.Values[0].Val, true
112 }
113 return &d, true
114
115 case *BinaryExpr:
116 if x.Op != AndOp {
117 return x, false
118 }
119 a, sa := stripNonDefaults(x.X)
120 b, sb := stripNonDefaults(x.Y)
121 if sa || sb {
122 bin := *x
123 bin.X = a.(Expr)
124 bin.Y = b.(Expr)
125 return &bin, true
126 }
127 return x, false
128
129 default:
130 return x, false
131 }
132 }
133
View as plain text