1use std::fmt::{self, Debug, Display, Formatter};
7
8use crate::value::primitive::binary::{Natural, Integer};
9use crate::value::primitive::logical::{LogicalOp, Bool};
10
11#[derive(Clone, Eq, PartialEq)]
13pub struct Scope<'a> {
14 pub definitions: Vec<Let<'a>>,
16 pub value: Option<Box<Expr<'a>>>
18}
19
20impl Debug for Scope<'_> {
21 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
22 <Self as Display>::fmt(self, fmt)
23 }
24}
25
26impl Display for Scope<'_> {
27 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
28 if self.definitions.len() == 0 {
29 return if let Some(value) = &self.value { write!(fmt, "{{ {} }}", value) }
30 else { write!(fmt, "{{}}")}
31 }
32 write!(fmt, "{{\n")?;
33 for definition in self.definitions.iter() {
34 write!(fmt, "{}\n", definition)?;
35 }
36 if let Some(value) = &self.value { write!(fmt, "{}\n", value)? }
37 write!(fmt, "}}")
38 }
39}
40
41#[derive(Clone, Eq, PartialEq)]
43pub struct Phi<'a>(pub Scope<'a>);
44
45impl Debug for Phi<'_> {
46 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
47 <Self as Display>::fmt(self, fmt)
48 }
49}
50
51impl Display for Phi<'_> {
52 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> { write!(fmt, "#phi {}", self.0) }
53}
54
55
56#[derive(Clone, Eq, PartialEq)]
58pub struct Path<'a> {
59 pub base: Option<()>,
61 pub names: Vec<&'a str>
63}
64
65impl Debug for Path<'_> {
66 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
67 <Self as Display>::fmt(self, fmt)
68 }
69}
70
71impl Display for Path<'_> {
72 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
73 let tail_names = if let Some(base) = self.base {
74 write!(fmt, "{:?}", base)?; &self.names[..]
76 } else if self.names.len() > 0 {
77 write!(fmt, "{}", self.names[0])?;
78 &self.names[1..]
79 }
80 else {
81 return Ok(())
83 };
84 for name in tail_names { write!(fmt, ".{}", name)?; }
85 Ok(())
86 }
87}
88
89impl<'a> Path<'a> {
90 pub fn ident<T>(ident: T) -> Path<'a> where T: Into<&'a str> {
92 Path { base: None, names: vec![ident.into()] }
93 }
94}
95
96impl<'a> From<Vec<&'a str>> for Path<'a> {
97 fn from(names: Vec<&'a str>) -> Path<'a> { Path { names, base: None } }
98}
99
100#[derive(Clone, Eq, PartialEq)]
102pub enum Expr<'a> {
103 Path(Path<'a>),
105 Scope(Scope<'a>),
107 Sexpr(Sexpr<'a>),
109 Lambda(Lambda<'a>),
111 Pi(Pi<'a>),
113 Phi(Phi<'a>),
115 Gamma(Gamma<'a>),
117 Bool(bool),
119 BoolTy(Bool),
121 LogicalOp(LogicalOp),
123 Natural(Natural),
125 Integer(Integer)
127}
128
129impl<'a> Expr<'a> {
130 pub fn ident<T>(ident: T) -> Expr<'a> where T: Into<&'a str> {
132 Expr::Path(Path::ident(ident))
133 }
134 pub fn push<T>(self, other: T) -> Expr<'a> where T: Into<Box<Expr<'a>>> {
137 match self {
138 Expr::Sexpr(mut s) => { s.push(other); Expr::Sexpr(s) }
139 atom => {
140 Expr::Sexpr(Sexpr { ops: vec![Box::new(atom), other.into()] })
141 },
142 }
143 }
144}
145
146impl Debug for Expr<'_> {
147 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
148 <Self as Display>::fmt(self, fmt)
149 }
150}
151
152impl Display for Expr<'_> {
153 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
154 match self {
155 Expr::Path(p) => std::fmt::Display::fmt(p, fmt),
156 Expr::Scope(s) => std::fmt::Display::fmt(s, fmt),
157 Expr::Sexpr(s) => std::fmt::Display::fmt(s, fmt),
158 Expr::Lambda(l) => std::fmt::Display::fmt(l, fmt),
159 Expr::Pi(p) => std::fmt::Display::fmt(p, fmt),
160 Expr::Phi(p) => std::fmt::Display::fmt(p, fmt),
161 Expr::Gamma(g) => std::fmt::Display::fmt(g, fmt),
162 Expr::Bool(b) => write!(fmt, "#{}", b),
163 Expr::BoolTy(b) => std::fmt::Display::fmt(b, fmt),
164 Expr::LogicalOp(l) => std::fmt::Display::fmt(l, fmt),
165 Expr::Natural(n) => std::fmt::Display::fmt(n, fmt),
166 Expr::Integer(z) => std::fmt::Display::fmt(z, fmt)
167 }
168 }
169}
170
171#[derive(Clone, Eq, PartialEq)]
173pub struct Sexpr<'a> {
174 pub ops: Vec<Box<Expr<'a>>>
177}
178
179impl<'a> From<Vec<Box<Expr<'a>>>> for Sexpr<'a> {
180 fn from(ops: Vec<Box<Expr<'a>>>) -> Sexpr<'a> { Sexpr { ops } }
181}
182
183impl<'a> Sexpr<'a> {
184 pub fn push<T>(&mut self, op: T) where T: Into<Box<Expr<'a>>> {
186 self.ops.push(op.into())
187 }
188}
189
190impl Debug for Sexpr<'_> {
191 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
192 <Self as Display>::fmt(self, fmt)
193 }
194}
195
196impl Display for Sexpr<'_> {
197 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
198 write!(fmt, "(")?;
199 let mut first: bool = true;
200 for op in self.ops.iter().rev() {
201 write!(fmt, "{}{}", if first {""} else {" "}, op)?;
202 first = false;
203 }
204 write!(fmt, ")")
205 }
206}
207
208#[derive(Clone, Eq, PartialEq)]
210pub struct Lambda<'a>(pub Parametrized<'a>);
211
212impl Debug for Lambda<'_> {
213 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
214 <Self as Display>::fmt(self, fmt)
215 }
216}
217
218impl Display for Lambda<'_> {
219 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
220 write!(fmt, "#lambda {}", self.0)
221 }
222}
223
224#[derive(Clone, Eq, PartialEq)]
226pub struct Pi<'a>(pub Parametrized<'a>);
227
228impl Debug for Pi<'_> {
229 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
230 <Self as Display>::fmt(self, fmt)
231 }
232}
233
234impl Display for Pi<'_> {
235 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
236 write!(fmt, "#pi {}", self.0)
237 }
238}
239
240#[derive(Clone, Eq, PartialEq)]
242pub struct Parametrized<'a> {
243 pub args: Vec<(Option<&'a str>, Expr<'a>)>,
245 pub ret_ty: Option<Box<Expr<'a>>>,
247 pub result: Box<Expr<'a>>
249}
250
251impl Debug for Parametrized<'_> {
252 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
253 <Self as Display>::fmt(self, fmt)
254 }
255}
256
257impl Display for Parametrized<'_> {
258 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
259 write!(fmt, "|")?;
260 let mut first: bool = true;
261 for (arg, ty) in self.args.iter() {
262 let sep = if first {""} else {", "};
263 let arg = if let Some(arg) = arg { arg } else { "_" };
264 write!(fmt, "{}{} : {}", sep, arg, ty)?;
265 first = false;
266 }
267 write!(fmt, "| ")?;
268 if let Some(ty) = &self.ret_ty {
269 write!(fmt, "=> {} ", ty)?;
270 }
271 write!(fmt, "{}", self.result)
272 }
273}
274
275#[derive(Clone, Eq, PartialEq)]
277pub struct SimpleAssignment<'a> {
278 pub name: &'a str,
280 pub ty: Option<Expr<'a>>
282}
283
284impl Debug for SimpleAssignment<'_> {
285 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
286 <Self as Display>::fmt(self, fmt)
287 }
288}
289
290impl Display for SimpleAssignment<'_> {
291 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
292 write!(fmt, "{}", self.name)?;
293 if let Some(ty) = &self.ty { write!(fmt, " : {}", ty) } else { Ok(()) }
294 }
295}
296
297
298#[derive(Clone, Eq, PartialEq)]
300pub enum Pattern<'a> {
301 Simple(SimpleAssignment<'a>)
303}
304
305impl Debug for Pattern<'_> {
306 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
307 <Self as Display>::fmt(self, fmt)
308 }
309}
310
311impl Display for Pattern<'_> {
312 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
313 match self {
314 Pattern::Simple(s) => write!(fmt, "{}", s)
315 }
316 }
317}
318
319#[derive(Clone, Eq, PartialEq)]
321pub struct Let<'a> {
322 pub pattern: Pattern<'a>,
324 pub expr: Expr<'a>
326}
327
328impl Debug for Let<'_> {
329 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
330 <Self as Display>::fmt(self, fmt)
331 }
332}
333
334impl Display for Let<'_> {
335 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
336 write!(fmt, "let {} = {};", self.pattern, self.expr) }
338}
339
340#[derive(Clone, Eq, PartialEq)]
342pub struct Gamma<'a> {
343 pub branches: Vec<(Pattern<'a>, Expr<'a>)>
345}
346
347impl Debug for Gamma<'_> {
348 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
349 <Self as Display>::fmt(self, fmt)
350 }
351}
352
353impl Display for Gamma<'_> {
354 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
355 write!(fmt, "#match {{\n")?;
356 let mut first = true;
357 for (pattern, value) in self.branches.iter() {
358 write!(fmt, "{}{} => {}", if first { "" } else { ",\n" }, pattern, value)?;
359 first = false;
360 }
361 write!(fmt, "{}}}", if first { "" } else { "\n" })
362 }
363}
364
365#[cfg(test)]
366mod tests {
367 use super::*;
368
369 #[test]
370 fn expr_push_works_as_expected() {
371 assert_eq!(
372 Expr::ident("x").push(Expr::ident("f")),
373 Expr::Sexpr(vec![Expr::ident("x").into(), Expr::ident("f").into()].into())
374 );
375 assert_eq!(
376 Expr::ident("x").push(Expr::ident("y")).push(Expr::ident("f")),
377 Expr::Sexpr(vec![
378 Expr::ident("x").into(),
379 Expr::ident("y").into(),
380 Expr::ident("f").into()]
381 .into())
382 )
383 }
384}