1pub mod meta_types;
2
3use std::collections::HashMap;
4
5use num::BigInt;
6use serde::{Deserialize, Serialize};
7use spade_common::{
8 location_info::WithLocation,
9 name::{Identifier, NameID},
10 num_ext::InfallibleToBigInt,
11};
12
13#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
14pub enum PrimitiveType {
15 Int,
16 Uint,
17 Clock,
18 Bool,
19 Bit,
20 Memory,
21 InOut,
22}
23
24impl std::fmt::Display for PrimitiveType {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 let str = match self {
27 PrimitiveType::Int => "int",
28 PrimitiveType::Uint => "uint",
29 PrimitiveType::Clock => "clk",
30 PrimitiveType::Bool => "bool",
31 PrimitiveType::Bit => "bit",
32 PrimitiveType::Memory => "Memory",
33 PrimitiveType::InOut => "inout",
34 };
35 write!(f, "{str}")
36 }
37}
38
39#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
40pub enum ConcreteType {
41 Error,
42 Tuple(Vec<ConcreteType>),
43 Struct {
44 name: NameID,
45 is_port: bool,
46 members: Vec<(Identifier, ConcreteType)>,
47 field_translators: HashMap<Identifier, String>,
48 },
49 Array {
50 inner: Box<ConcreteType>,
51 size: BigInt,
52 },
53 Enum {
54 options: Vec<(NameID, Vec<(Identifier, ConcreteType)>)>,
55 },
56 Single {
57 base: PrimitiveType,
58 params: Vec<ConcreteType>,
59 },
60 Integer(BigInt),
61 Bool(bool),
62 Backward(Box<ConcreteType>),
63 Wire(Box<ConcreteType>),
64}
65
66impl ConcreteType {
67 pub fn assume_struct(&self) -> (&NameID, &Vec<(Identifier, ConcreteType)>) {
68 match self {
69 ConcreteType::Struct {
70 name,
71 is_port: _,
72 members,
73 field_translators: _,
74 } => (name, members),
75 t => unreachable!("Assumed {} was a struct", t),
76 }
77 }
78
79 pub fn is_port(&self) -> bool {
80 match self {
81 ConcreteType::Error => false,
82 ConcreteType::Tuple(inner) => inner.iter().any(Self::is_port),
83 ConcreteType::Struct {
84 name: _,
85 is_port,
86 members: _,
87 field_translators: _,
88 } => *is_port,
89 ConcreteType::Array { inner, size: _ } => inner.is_port(),
90 ConcreteType::Enum { .. } => false,
92 ConcreteType::Single {
93 base: PrimitiveType::Memory,
94 ..
95 } => true,
96 ConcreteType::Single {
97 base: PrimitiveType::Clock,
98 ..
99 } => true,
100 ConcreteType::Single { .. } => false,
101 ConcreteType::Integer(_) | ConcreteType::Bool(_) => false,
102 ConcreteType::Backward(_) => true,
103 ConcreteType::Wire(_) => true,
104 }
105 }
106}
107
108impl std::fmt::Display for ConcreteType {
109 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
110 let str = match self {
111 ConcreteType::Error => "{error}".to_string(),
112 ConcreteType::Tuple(inner) => {
113 format!(
114 "({})",
115 inner
116 .iter()
117 .map(|p| format!("{}", p))
118 .collect::<Vec<_>>()
119 .join(", ")
120 )
121 }
122 ConcreteType::Struct {
123 name,
124 is_port,
125 members,
126 field_translators: _,
127 } => {
128 let port = if *is_port { "port " } else { "" };
129 format!(
130 "struct {port}{name} {{{}}}",
131 members
132 .iter()
133 .map(|(name, t)| format!("{}: {}", name, t))
134 .collect::<Vec<_>>()
135 .join(", ")
136 )
137 }
138 ConcreteType::Array { inner, size } => {
139 format!("[{}; {}]", inner, size)
140 }
141 ConcreteType::Enum { options } => {
142 let inner = options
143 .iter()
144 .map(|o| {
145 let param_list =
146 o.1.iter()
147 .map(|t| format!("{}", t.1))
148 .collect::<Vec<_>>()
149 .join(",");
150 format!("{} ( {} )", o.0 .0, param_list)
151 })
152 .collect::<Vec<_>>()
153 .join(",");
154 format!("enum {{{}}}", inner)
155 }
156 ConcreteType::Single { base, params } => {
157 let params_str = if params.is_empty() {
158 String::new()
159 } else {
160 params
161 .iter()
162 .map(|p| format!("{}", p))
163 .collect::<Vec<_>>()
164 .join(", ")
165 };
166
167 format!("{}{}", base, params_str)
168 }
169 ConcreteType::Integer(size) => {
170 format!("{}", size)
171 }
172 ConcreteType::Bool(val) => {
173 format!("{}", val)
174 }
175 ConcreteType::Backward(inner) => {
176 format!("inv &{}", inner)
177 }
178 ConcreteType::Wire(inner) => {
179 format!("&{}", inner)
180 }
181 };
182
183 write!(f, "{str}")
184 }
185}
186
187#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
188pub enum KnownType {
189 Named(NameID),
190 Integer(BigInt),
191 Bool(bool),
192 Tuple,
193 Array,
194 Wire,
195 Inverted,
196 Error,
199}
200
201impl WithLocation for KnownType {}
202
203impl KnownType {
204 pub fn integer(val: u64) -> Self {
205 Self::Integer(val.to_bigint())
206 }
207}