1
2
3
4
5 package unify
6
7 import (
8 "fmt"
9 "iter"
10 "reflect"
11 )
12
13
14
15
16
17
18
19
20 type Value struct {
21 Domain Domain
22
23
24 pos *Pos
25 parents *[2]*Value
26 }
27
28 var (
29 topValue = &Value{Domain: Top{}}
30 bottomValue = &Value{Domain: nil}
31 )
32
33
34
35 func NewValue(d Domain) *Value {
36 return &Value{Domain: d}
37 }
38
39
40 func NewValuePos(d Domain, p Pos) *Value {
41 return &Value{Domain: d, pos: &p}
42 }
43
44
45
46 func newValueFrom(d Domain, p *Value) *Value {
47 return &Value{Domain: d, pos: p.pos, parents: p.parents}
48 }
49
50 func unified(d Domain, p1, p2 *Value) *Value {
51 return &Value{Domain: d, parents: &[2]*Value{p1, p2}}
52 }
53
54 func (v *Value) Pos() Pos {
55 if v.pos == nil {
56 return Pos{}
57 }
58 return *v.pos
59 }
60
61 func (v *Value) PosString() string {
62 var b []byte
63 for root := range v.Provenance() {
64 if len(b) > 0 {
65 b = append(b, ' ')
66 }
67 b, _ = root.pos.AppendText(b)
68 }
69 return string(b)
70 }
71
72 func (v *Value) WhyNotExact() string {
73 if v.Domain == nil {
74 return "v.Domain is nil"
75 }
76 return v.Domain.WhyNotExact()
77 }
78
79 func (v *Value) Exact() bool {
80 if v.Domain == nil {
81 return false
82 }
83 return v.Domain.Exact()
84 }
85
86
87
88
89
90
91
92
93
94
95
96 func (v *Value) Decode(into any) error {
97 rv := reflect.ValueOf(into)
98 if rv.Kind() != reflect.Pointer {
99 return fmt.Errorf("cannot decode into non-pointer %T", into)
100 }
101 return decodeReflect(v, rv.Elem())
102 }
103
104 func decodeReflect(v *Value, rv reflect.Value) error {
105 var ptr reflect.Value
106 if rv.Kind() == reflect.Pointer {
107 if rv.IsNil() {
108
109
110
111
112
113 if _, ok := v.Domain.(Top); !ok {
114
115
116 ptr = rv
117 rv = reflect.New(rv.Type().Elem()).Elem()
118 }
119 } else {
120 rv = rv.Elem()
121 }
122 }
123
124 var err error
125 if reflect.PointerTo(rv.Type()).Implements(decoderType) {
126
127 err = rv.Addr().Interface().(Decoder).DecodeUnified(v)
128 } else {
129 err = v.Domain.decode(rv)
130 }
131 if err == nil && ptr.IsValid() {
132 ptr.Set(rv.Addr())
133 }
134 return err
135 }
136
137
138
139 type Decoder interface {
140 DecodeUnified(v *Value) error
141 }
142
143 var decoderType = reflect.TypeOf((*Decoder)(nil)).Elem()
144
145
146
147 func (v *Value) Provenance() iter.Seq[*Value] {
148 return func(yield func(*Value) bool) {
149 var rec func(d *Value) bool
150 rec = func(d *Value) bool {
151 if d.pos != nil {
152 if !yield(d) {
153 return false
154 }
155 }
156 if d.parents != nil {
157 for _, p := range d.parents {
158 if !rec(p) {
159 return false
160 }
161 }
162 }
163 return true
164 }
165 rec(v)
166 }
167 }
168
View as plain text