...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package adt
16
17
18
19
20 func (o *StructInfo) MatchAndInsert(c *OpContext, arc *Vertex) {
21 env := o.Env
22
23 closeInfo := o.CloseInfo
24 closeInfo.IsClosed = false
25
26
27 matched := false
28
29
30 for _, f := range o.Fields {
31 if f.Label == arc.Label {
32 matched = true
33 break
34 }
35 }
36
37 f := arc.Label
38 if !f.IsRegular() {
39 return
40 }
41 var label Value
42
43 if int64(f.Index()) == MaxIndex {
44 f = 0
45 } else if o.types&HasComplexPattern != 0 && f.IsString() {
46 label = f.ToValue(c)
47 }
48
49 if len(o.Bulk) > 0 {
50 bulkEnv := *env
51 bulkEnv.DynamicLabel = f
52
53
54 for _, b := range o.Bulk {
55
56
57
58
59
60
61
62
63
64 saved := arc.BaseValue
65 arc.BaseValue = cycle
66 match := matchBulk(c, env, b, f, label)
67 arc.BaseValue = saved
68
69 if match {
70 matched = true
71 info := closeInfo.SpawnSpan(b.Value, ConstraintSpan)
72 arc.AddConjunct(MakeConjunct(&bulkEnv, b, info))
73 }
74 }
75 }
76
77 if matched || len(o.Additional) == 0 {
78 return
79 }
80
81
82 for _, x := range o.Additional {
83 info := closeInfo
84 if _, ok := x.expr().(*Top); !ok {
85 info = info.SpawnSpan(x, ConstraintSpan)
86 }
87
88 arc.AddConjunct(MakeConjunct(env, x, info))
89 }
90 }
91
92
93
94 func matchBulk(c *OpContext, env *Environment, p *BulkOptionalField, f Feature, label Value) bool {
95 v := env.evalCached(c, p.Filter)
96 v = Unwrap(v)
97
98
99 switch x := v.(type) {
100 case *Bottom:
101 if x == cycle {
102 err := c.NewPosf(pos(p.Filter), "cyclic pattern constraint")
103 for _, c := range c.vertex.Conjuncts {
104 err.AddPosition(c.Elem())
105 }
106 c.AddBottom(&Bottom{
107 Err: err,
108 })
109 }
110 if c.errs == nil {
111 c.AddBottom(x)
112 }
113 return false
114 case *Top:
115 return true
116
117 case *BasicType:
118 return x.K&StringKind != 0
119
120 case *BoundValue:
121 switch x.Kind() {
122 case StringKind:
123 if label == nil {
124 return false
125 }
126 str := label.(*String).Str
127 return x.validateStr(c, str)
128
129 case IntKind:
130 return x.validateInt(c, int64(f.Index()))
131 }
132 }
133
134 if label == nil {
135 return false
136 }
137
138 n := Vertex{
139 IsDynamic: true,
140 }
141 m := MakeConjunct(env, v, c.ci)
142 n.AddConjunct(m)
143 n.AddConjunct(MakeConjunct(m.Env, label, c.ci))
144
145 c.inConstraint++
146 n.Finalize(c)
147 c.inConstraint--
148
149 b, _ := n.BaseValue.(*Bottom)
150 return b == nil
151 }
152
View as plain text