1use itertools::Itertools;
6use std::sync::Arc;
7
8pub use self::TypeKind::*;
9
10pub type Type = Arc<TypeKind>;
12
13#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize)]
15pub enum TypeKind {
16 VoidType,
18 TimeType,
20 IntType(usize),
22 EnumType(usize),
24 PointerType(Type),
26 SignalType(Type),
28 ArrayType(usize, Type),
30 StructType(Vec<Type>),
32 FuncType(Vec<Type>, Type),
34 EntityType(Vec<Type>, Vec<Type>),
36}
37
38impl std::fmt::Display for TypeKind {
39 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
40 match *self {
41 VoidType => write!(f, "void"),
42 TimeType => write!(f, "time"),
43 IntType(l) => write!(f, "i{}", l),
44 EnumType(l) => write!(f, "n{}", l),
45 PointerType(ref ty) => write!(f, "{}*", ty),
46 SignalType(ref ty) => write!(f, "{}$", ty),
47 ArrayType(l, ref ty) => write!(f, "[{} x {}]", l, ty),
48 StructType(ref tys) => write!(f, "{{{}}}", tys.iter().format(", ")),
49 FuncType(ref args, ref ret) => write!(f, "({}) {}", args.iter().format(", "), ret),
50 EntityType(ref ins, ref outs) => write!(
51 f,
52 "({}) -> ({})",
53 ins.iter().format(", "),
54 outs.iter().format(", ")
55 ),
56 }
57 }
58}
59
60impl TypeKind {
61 pub fn unwrap_int(&self) -> usize {
64 match *self {
65 IntType(size) => size,
66 _ => panic!("unwrap_int called on {}", self),
67 }
68 }
69
70 pub fn unwrap_enum(&self) -> usize {
73 match *self {
74 EnumType(size) => size,
75 _ => panic!("unwrap_enum called on {}", self),
76 }
77 }
78
79 pub fn unwrap_pointer(&self) -> &Type {
82 match *self {
83 PointerType(ref ty) => ty,
84 _ => panic!("unwrap_pointer called on {}", self),
85 }
86 }
87
88 pub fn unwrap_signal(&self) -> &Type {
91 match *self {
92 SignalType(ref ty) => ty,
93 _ => panic!("unwrap_signal called on {}", self),
94 }
95 }
96
97 pub fn unwrap_array(&self) -> (usize, &Type) {
100 match *self {
101 ArrayType(len, ref ty) => (len, ty),
102 _ => panic!("unwrap_array called on {}", self),
103 }
104 }
105
106 pub fn unwrap_struct(&self) -> &[Type] {
109 match *self {
110 StructType(ref fields) => fields,
111 _ => panic!("unwrap_struct called on {}", self),
112 }
113 }
114
115 pub fn unwrap_func(&self) -> (&[Type], &Type) {
118 match *self {
119 FuncType(ref args, ref ret) => (args, ret),
120 _ => panic!("unwrap_func called on {}", self),
121 }
122 }
123
124 pub fn unwrap_entity(&self) -> (&[Type], &[Type]) {
127 match *self {
128 EntityType(ref ins, ref outs) => (ins, outs),
129 _ => panic!("unwrap_entity called on {}", self),
130 }
131 }
132
133 pub fn is_void(&self) -> bool {
135 match *self {
136 VoidType => true,
137 _ => false,
138 }
139 }
140
141 pub fn is_time(&self) -> bool {
143 match *self {
144 TimeType => true,
145 _ => false,
146 }
147 }
148
149 pub fn is_int(&self) -> bool {
151 match *self {
152 IntType(..) => true,
153 _ => false,
154 }
155 }
156
157 pub fn is_enum(&self) -> bool {
159 match *self {
160 EnumType(..) => true,
161 _ => false,
162 }
163 }
164
165 pub fn is_pointer(&self) -> bool {
167 match *self {
168 PointerType(..) => true,
169 _ => false,
170 }
171 }
172
173 pub fn is_signal(&self) -> bool {
175 match *self {
176 SignalType(..) => true,
177 _ => false,
178 }
179 }
180
181 pub fn is_array(&self) -> bool {
183 match *self {
184 ArrayType(..) => true,
185 _ => false,
186 }
187 }
188
189 pub fn is_struct(&self) -> bool {
191 match *self {
192 StructType(..) => true,
193 _ => false,
194 }
195 }
196
197 pub fn is_func(&self) -> bool {
199 match *self {
200 FuncType(..) => true,
201 _ => false,
202 }
203 }
204
205 pub fn is_entity(&self) -> bool {
207 match *self {
208 EntityType(..) => true,
209 _ => false,
210 }
211 }
212
213 pub fn len(&self) -> usize {
223 match *self {
224 IntType(l) | EnumType(l) | ArrayType(l, _) => l,
225 StructType(ref f) => f.len(),
226 _ => 0,
227 }
228 }
229}
230
231pub fn void_ty() -> Type {
233 Type::new(VoidType)
234}
235
236pub fn time_ty() -> Type {
238 Type::new(TimeType)
239}
240
241pub fn int_ty(size: usize) -> Type {
243 Type::new(IntType(size))
244}
245
246pub fn enum_ty(size: usize) -> Type {
248 Type::new(EnumType(size))
249}
250
251pub fn pointer_ty(ty: Type) -> Type {
253 Type::new(PointerType(ty))
254}
255
256pub fn signal_ty(ty: Type) -> Type {
258 Type::new(SignalType(ty))
259}
260
261pub fn array_ty(size: usize, ty: Type) -> Type {
264 Type::new(ArrayType(size, ty))
265}
266
267pub fn struct_ty(fields: Vec<Type>) -> Type {
269 Type::new(StructType(fields))
270}
271
272pub fn func_ty(args: Vec<Type>, ret: Type) -> Type {
274 Type::new(FuncType(args, ret))
275}
276
277pub fn entity_ty(ins: Vec<Type>, outs: Vec<Type>) -> Type {
279 Type::new(EntityType(ins, outs))
280}