aboutsummaryrefslogtreecommitdiff
path: root/src/lisp/expr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lisp/expr.rs')
-rw-r--r--src/lisp/expr.rs87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/lisp/expr.rs b/src/lisp/expr.rs
new file mode 100644
index 0000000..94e778f
--- /dev/null
+++ b/src/lisp/expr.rs
@@ -0,0 +1,87 @@
1use std::fmt;
2
3use crate::lisp::number::LispNumber;
4
5#[derive(Debug, PartialEq, Clone)]
6pub enum LispExpr {
7 Number(LispNumber),
8 List(Vec<LispExpr>),
9 StringLit(String),
10 BoolLit(bool),
11 Ident(String),
12 Function(LispFunction),
13
14 // none of these depths should be zero
15 Quasiquote(Box<LispExpr>, u32),
16 Comma(Box<LispExpr>, u32),
17 CommaAt(Box<LispExpr>, u32),
18 Quote(Box<LispExpr>, u32),
19}
20
21impl LispExpr {
22 pub fn comma(self, n: u32) -> LispExpr {
23 match self {
24 LispExpr::Comma(v, i) => LispExpr::Comma(v, i.checked_add(n).expect("comma overflow")),
25 LispExpr::CommaAt(v, i) => LispExpr::CommaAt(v, i + n),
26 v => LispExpr::Comma(Box::new(v), n),
27 }
28 }
29
30 pub fn comma_at(self, n: u32) -> LispExpr {
31 match self {
32 LispExpr::CommaAt(v, i) => {
33 LispExpr::CommaAt(v, i.checked_add(n).expect("comma_at overflow"))
34 }
35 v => LispExpr::CommaAt(Box::new(v), n),
36 }
37 }
38
39 pub fn quote(self, n: u32) -> LispExpr {
40 match self {
41 LispExpr::Quote(v, i) => LispExpr::Quote(v, i.checked_add(n).expect("quote overflow")),
42 v => LispExpr::Quote(Box::new(v), n),
43 }
44 }
45
46 pub fn quasiquote(self, n: u32) -> LispExpr {
47 match self {
48 LispExpr::Quasiquote(v, i) => {
49 LispExpr::Quasiquote(v, i.checked_add(n).expect("quasiquote overflow"))
50 }
51 v => LispExpr::Quasiquote(Box::new(v), n),
52 }
53 }
54}
55
56impl fmt::Display for LispExpr {
57 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58 match self {
59 LispExpr::Number(n) => write!(f, "{}", n)?,
60 LispExpr::List(l) => {
61 for expr in l.iter() {
62 write!(f, " {} ", expr)?
63 }
64 }
65 LispExpr::StringLit(s) => write!(f, "{:?}", s)?,
66 LispExpr::BoolLit(b) => {
67 if *b {
68 write!(f, "#t")?
69 } else {
70 write!(f, "#f")?
71 }
72 }
73 LispExpr::Ident(s) => write!(f, "{}", s)?,
74 LispExpr::Function(_) => write!(f, "<#procedure>")?,
75 LispExpr::Quasiquote(val, depth) => {
76 write!(f, "{}{}", "`".repeat(*depth as usize), val)?
77 }
78 LispExpr::Comma(val, depth) => write!(f, "{}{}", ",".repeat(*depth as usize), val)?,
79 LispExpr::CommaAt(val, depth) => write!(f, "{}@{}", ",".repeat(*depth as usize), val)?,
80 LispExpr::Quote(val, depth) => write!(f, "{}{}", "'".repeat(*depth as usize), val)?,
81 };
82 Ok(())
83 }
84}
85
86#[derive(Debug, PartialEq, Clone)]
87struct LispFunction {}