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