...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package adt
16
17 import (
18 "fmt"
19 "math/bits"
20 "strings"
21 )
22
23
24
25 type Concreteness int
26
27 const (
28 BottomLevel Concreteness = iota
29
30
31 Concrete
32
33
34
35 Constraint
36
37
38
39 Type
40
41
42 Any
43 )
44
45
46 func IsConcrete(v Value) bool {
47 if x, ok := v.(*Vertex); ok {
48 return x.IsConcrete()
49 }
50 if v == nil {
51 return false
52 }
53 return v.Concreteness() <= Concrete
54 }
55
56
57 type Kind uint16
58
59 const (
60 NullKind Kind = (1 << iota)
61 BoolKind
62 IntKind
63 FloatKind
64 StringKind
65 BytesKind
66 FuncKind
67 ListKind
68 StructKind
69
70 allKinds
71
72 _numberKind
73
74 NumberKind = IntKind | FloatKind
75
76 BottomKind Kind = 0
77
78 NumKind = IntKind | FloatKind
79 TopKind Kind = (allKinds - 1)
80 ScalarKinds = NullKind | BoolKind |
81 IntKind | FloatKind | StringKind | BytesKind
82
83 CompositKind = StructKind | ListKind
84 )
85
86 func kind(v Value) Kind {
87 if v == nil {
88 return BottomKind
89 }
90 return v.Kind()
91 }
92
93
94
95
96
97 func (k Kind) IsAnyOf(of Kind) bool {
98 return k&of != BottomKind
99 }
100
101
102 func (k Kind) CanString() bool {
103 return k&StringKind|ScalarKinds != BottomKind
104 }
105
106
107
108
109
110
111
112
113
114 func (k Kind) String() string {
115 return toString(k, kindStrs)
116 }
117
118
119
120 func (k Kind) TypeString() string {
121 return toString(k, typeStrs)
122 }
123
124 func toString(k Kind, m map[Kind]string) string {
125 if k == BottomKind {
126 return "_|_"
127 }
128 if k == TopKind {
129 return "_"
130 }
131 if (k & NumberKind) == NumberKind {
132 k = (k &^ NumberKind) | _numberKind
133 }
134 var buf strings.Builder
135 multiple := bits.OnesCount(uint(k)) > 1
136 if multiple {
137 buf.WriteByte('(')
138 }
139 for count := 0; ; count++ {
140 n := bits.TrailingZeros(uint(k))
141 if n == bits.UintSize {
142 break
143 }
144 bit := Kind(1 << uint(n))
145 k &^= bit
146 s, ok := m[bit]
147 if !ok {
148 s = fmt.Sprintf("bad(%d)", n)
149 }
150 if count > 0 {
151 buf.WriteByte('|')
152 }
153 buf.WriteString(s)
154 }
155 if multiple {
156 buf.WriteByte(')')
157 }
158 return buf.String()
159 }
160
161 var kindStrs = map[Kind]string{
162 NullKind: "null",
163 BoolKind: "bool",
164 IntKind: "int",
165 FloatKind: "float",
166 StringKind: "string",
167 BytesKind: "bytes",
168 FuncKind: "func",
169 StructKind: "struct",
170 ListKind: "list",
171 _numberKind: "number",
172 }
173
174
175 var typeStrs = map[Kind]string{
176 NullKind: "null",
177 BoolKind: "bool",
178 IntKind: "int",
179 FloatKind: "float",
180 StringKind: "string",
181 BytesKind: "bytes",
182 FuncKind: "_",
183 StructKind: "{...}",
184 ListKind: "[...]",
185 _numberKind: "number",
186 }
187
View as plain text