1use std::fmt::{Display, Error, Formatter};
5
6use fxhash::FxHashMap;
7use kind_span::Range;
8use linked_hash_map::LinkedHashMap;
9
10pub use crate::Operator;
11use crate::{
12 symbol::{Ident, QualifiedIdent},
13 Attributes,
14};
15
16pub type Spine = Vec<Box<Expr>>;
20
21#[derive(Clone, Debug, Hash, PartialEq, Eq)]
22pub enum ExprKind {
23 Var {
25 name: Ident,
26 },
27 Lambda {
29 param: Ident,
30 body: Box<Expr>,
31 erased: bool,
32 },
33 App {
35 fun: Box<Expr>,
36 args: Vec<Box<Expr>>,
37 },
38 Fun {
40 name: QualifiedIdent,
41 args: Spine,
42 },
43 Ctr {
45 name: QualifiedIdent,
46 args: Spine,
47 },
48 Let {
50 name: Ident,
51 val: Box<Expr>,
52 next: Box<Expr>,
53 },
54 U60 {
56 numb: u64,
57 },
58 F60 {
60 numb: u64,
61 },
62 Str {
64 val: String,
65 },
66 Binary {
68 op: Operator,
69 left: Box<Expr>,
70 right: Box<Expr>,
71 },
72
73 Err,
74}
75
76#[derive(Clone, Debug, Hash, PartialEq, Eq)]
77pub struct Expr {
78 pub data: ExprKind,
79 pub range: Range,
80}
81
82impl Expr {
83 pub fn var(name: Ident) -> Box<Expr> {
84 Box::new(Expr {
85 range: name.range,
86 data: ExprKind::Var { name },
87 })
88 }
89
90 pub fn str(range: Range, val: String) -> Box<Expr> {
91 Box::new(Expr {
92 range,
93 data: ExprKind::Str { val },
94 })
95 }
96
97 pub fn lambda(range: Range, param: Ident, body: Box<Expr>, erased: bool) -> Box<Expr> {
98 Box::new(Expr {
99 range,
100 data: ExprKind::Lambda {
101 param,
102 body,
103 erased,
104 },
105 })
106 }
107
108 pub fn fun(range: Range, name: QualifiedIdent, args: Vec<Box<Expr>>) -> Box<Expr> {
109 Box::new(Expr {
110 range,
111 data: ExprKind::Fun { name, args },
112 })
113 }
114
115 pub fn app(range: Range, fun: Box<Expr>, args: Vec<Box<Expr>>) -> Box<Expr> {
116 Box::new(Expr {
117 range,
118 data: ExprKind::App { fun, args },
119 })
120 }
121
122 pub fn ctr(range: Range, name: QualifiedIdent, args: Vec<Box<Expr>>) -> Box<Expr> {
123 Box::new(Expr {
124 range,
125 data: ExprKind::Ctr { name, args },
126 })
127 }
128
129 pub fn let_(range: Range, name: Ident, val: Box<Expr>, next: Box<Expr>) -> Box<Expr> {
130 Box::new(Expr {
131 range,
132 data: ExprKind::Let { name, val, next },
133 })
134 }
135
136 pub fn u60(range: Range, numb: u64) -> Box<Expr> {
137 Box::new(Expr {
138 range,
139 data: ExprKind::U60 { numb },
140 })
141 }
142
143 pub fn f60(range: Range, numb: u64) -> Box<Expr> {
144 Box::new(Expr {
145 range,
146 data: ExprKind::F60 { numb },
147 })
148 }
149
150 pub fn binary(range: Range, op: Operator, left: Box<Expr>, right: Box<Expr>) -> Box<Expr> {
151 Box::new(Expr {
152 range,
153 data: ExprKind::Binary { op, left, right },
154 })
155 }
156
157 pub fn err(range: Range) -> Box<Expr> {
158 Box::new(Expr {
159 range,
160 data: ExprKind::Err,
161 })
162 }
163}
164
165#[derive(Clone, Debug)]
172pub struct Argument {
173 pub hidden: bool,
174 pub erased: bool,
175 pub name: Ident,
176 pub typ: Box<Expr>,
177 pub range: Range,
178}
179
180#[derive(Clone, Debug)]
184pub struct Rule {
185 pub name: QualifiedIdent,
186 pub pats: Vec<Box<Expr>>,
187 pub body: Box<Expr>,
188 pub range: Range,
189}
190
191#[derive(Clone, Debug)]
196pub struct Entry {
197 pub name: QualifiedIdent,
198 pub args: Vec<(String, Range, bool)>,
199 pub rules: Vec<Rule>,
200 pub attrs: Attributes,
201 pub range: Range,
202}
203
204#[derive(Clone, Debug, Default)]
206pub struct Book {
207 pub entrs: LinkedHashMap<String, Box<Entry>>,
208 pub names: FxHashMap<String, usize>,
209}
210
211impl Expr {
212 pub fn new_var(name: Ident) -> Expr {
213 Expr {
214 range: name.range,
215 data: ExprKind::Var { name },
216 }
217 }
218}
219
220impl Display for Expr {
221 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
222 use ExprKind::*;
223 match &self.data {
224 Err => write!(f, "ERR"),
225 Str { val } => write!(f, "\"{}\"", val),
226 U60 { numb } => write!(f, "{}", numb),
227 F60 { numb: _ } => todo!(),
228 Var { name } => write!(f, "{}", name),
229 Lambda {
230 param,
231 body,
232 erased: false,
233 } => write!(f, "({} => {})", param, body),
234 Lambda {
235 param,
236 body,
237 erased: true,
238 } => write!(f, "(~{} => {})", param, body),
239 App { fun, args } => write!(
240 f,
241 "({}{})",
242 fun,
243 args.iter().map(|x| format!(" {}", x)).collect::<String>()
244 ),
245 Fun { name, args } | Ctr { name, args } => {
246 if args.is_empty() {
247 write!(f, "{}", name)
248 } else {
249 write!(
250 f,
251 "({}{})",
252 name,
253 args.iter().map(|x| format!(" {}", x)).collect::<String>()
254 )
255 }
256 }
257 Let { name, val, next } => write!(f, "(let {} = {}; {})", name, val, next),
258 Binary { op, left, right } => write!(f, "({} {} {})", op, left, right),
259 }
260 }
261}
262
263impl Display for Book {
264 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
265 for entr in self.entrs.values() {
266 if !entr.rules.is_empty() {
267 writeln!(f, "{}", entr)?;
268 } else {
269 writeln!(f, "ctr {}", entr.name)?;
270 }
271 }
272 Ok(())
273 }
274}
275
276impl Display for Argument {
277 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
278 let (open, close) = match (self.erased, self.hidden) {
279 (false, false) => ("(", ")"),
280 (false, true) => ("+<", ">"),
281 (true, false) => ("-(", ")"),
282 (true, true) => ("<", ">"),
283 };
284 write!(f, "{}{}: {}{}", open, self.name, self.typ, close)
285 }
286}
287
288impl Display for Entry {
289 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
290 for rule in &self.rules {
291 write!(f, "\n{}", rule)?
292 }
293
294 Ok(())
295 }
296}
297
298impl Display for Rule {
299 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
300 write!(f, "{}", self.name)?;
301 for pat in &self.pats {
302 write!(f, " {}", pat)?;
303 }
304 write!(f, " = {}", self.body)
305 }
306}
307
308impl Argument {
309 pub fn to_irrelevant(&self) -> Argument {
310 Argument {
311 hidden: true,
312 erased: true,
313 name: self.name.clone(),
314 typ: self.typ.clone(),
315 range: self.range,
316 }
317 }
318
319 pub fn from_field(name: &Ident, typ: Box<Expr>, range: Range) -> Argument {
320 Argument {
321 hidden: false,
322 erased: false,
323 name: name.clone(),
324 typ,
325 range,
326 }
327 }
328}