1use crate::interner::{ExprNodeId, Symbol, TypeNodeId};
2use crate::types::Type;
4use crate::utils::metadata::{Location, Span};
5use crate::utils::miniprint::MiniPrint;
6
7#[derive(Debug, Clone, PartialEq)]
8pub enum Pattern {
9 Single(Symbol),
10 Tuple(Vec<Self>),
11 Record(Vec<(Symbol, Self)>),
12 Error,
13}
14
15impl std::fmt::Display for Pattern {
16 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17 match self {
18 Pattern::Single(id) => write!(f, "{id}"),
19 Pattern::Tuple(vec) => {
20 let s = vec
21 .iter()
22 .map(|p| p.to_string())
23 .collect::<Vec<_>>()
24 .join(",");
25 write!(f, "({s})")
26 }
27 Pattern::Record(items) => {
28 if items.is_empty() {
29 write!(f, "{{}}")
30 } else {
31 let s = items
32 .iter()
33 .map(|(k, v)| format!("{k}: {v}"))
34 .collect::<Vec<_>>()
35 .join(", ");
36 write!(f, "{{{s}}}")
37 }
38 }
39 Pattern::Error => {
40 write!(f, "<error pattern>")
41 }
42 }
43 }
44}
45
46#[derive(Clone, Debug, PartialEq)]
47pub struct TypedId {
48 pub id: Symbol,
49 pub ty: TypeNodeId,
52 pub default_value: Option<ExprNodeId>,
54}
55
56impl TypedId {
57 pub fn new(id: Symbol, ty: TypeNodeId) -> Self {
59 TypedId {
60 id,
61 ty,
62 default_value: None,
63 }
64 }
65
66 pub fn with_default(id: Symbol, ty: TypeNodeId, default_value: ExprNodeId) -> Self {
68 TypedId {
69 id,
70 ty,
71 default_value: Some(default_value),
72 }
73 }
74
75 pub fn to_span(&self) -> Span {
76 self.ty.to_span()
77 }
78
79 pub fn is_unknown(&self) -> bool {
80 self.ty.to_type() == Type::Unknown
81 }
82}
83
84impl std::fmt::Display for TypedId {
85 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
86 if !self.is_unknown() {
87 write!(f, "{} :{}", self.id, self.ty.to_type())
88 } else {
89 write!(f, "{}", self.id)
90 }
91 }
92}
93
94impl MiniPrint for TypedId {
95 fn simple_print(&self) -> String {
96 if !self.is_unknown() {
97 format!("(tid {} {})", self.id, self.ty.to_type())
98 } else {
99 self.id.to_string()
100 }
101 }
102}
103
104#[derive(Clone, Debug, PartialEq)]
105pub struct TypedPattern {
106 pub pat: Pattern,
107 pub ty: TypeNodeId,
108 pub default_value: Option<ExprNodeId>,
109}
110impl TypedPattern {
111 pub fn new(pat: Pattern, ty: TypeNodeId) -> Self {
112 TypedPattern {
113 pat,
114 ty,
115 default_value: None,
116 }
117 }
118}
119
120impl TypedPattern {
121 pub fn to_span(&self) -> Span {
122 self.ty.to_span()
123 }
124 pub fn to_loc(&self) -> Location {
125 self.ty.to_loc()
126 }
127
128 pub fn is_unknown(&self) -> bool {
129 self.ty.to_type() == Type::Unknown
130 }
131}
132
133#[derive(Debug)]
134pub struct ConversionError;
135impl std::fmt::Display for ConversionError {
136 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
137 write!(
138 f,
139 "Failed to convert pattern. The pattern did not matched to single identifier."
140 )
141 }
142}
143impl std::error::Error for ConversionError {}
144
145impl From<TypedId> for TypedPattern {
146 fn from(value: TypedId) -> Self {
147 TypedPattern {
148 pat: Pattern::Single(value.id),
149 ty: value.ty,
150 default_value: value.default_value, }
152 }
153}
154impl TryFrom<TypedPattern> for TypedId {
155 type Error = ConversionError;
156
157 fn try_from(value: TypedPattern) -> Result<Self, Self::Error> {
158 match value.pat {
159 Pattern::Single(id) => Ok(TypedId {
160 id,
161 ty: value.ty,
162 default_value: value.default_value,
163 }),
164 _ => Err(ConversionError),
165 }
166 }
167}
168
169impl MiniPrint for TypedPattern {
170 fn simple_print(&self) -> String {
171 if !self.is_unknown() {
172 format!("(tpat {} {})", self.pat, self.ty.to_type())
173 } else {
174 self.pat.to_string()
175 }
176 }
177}
178impl std::fmt::Display for TypedPattern {
179 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
180 if !self.is_unknown() {
181 write!(f, "{} :{}", self.pat, self.ty.to_type())
182 } else {
183 write!(f, "{}", self.pat)
184 }
185 }
186}