1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9pub struct Position(usize);
10
11impl Position {
12 #[must_use]
14 pub fn value(&self) -> usize {
15 self.0
16 }
17}
18
19impl From<usize> for Position {
20 fn from(value: usize) -> Self {
21 Self(value)
22 }
23}
24
25impl std::fmt::Display for Position {
26 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 write!(f, "{}", self.0)
28 }
29}
30
31#[derive(Debug, Clone, PartialEq, Eq, Hash)]
33pub struct VarName(String);
34
35impl VarName {
36 #[must_use]
38 pub fn as_str(&self) -> &str {
39 &self.0
40 }
41}
42
43impl From<String> for VarName {
44 fn from(value: String) -> Self {
45 Self(value)
46 }
47}
48
49impl From<&str> for VarName {
50 fn from(value: &str) -> Self {
51 Self(value.to_owned())
52 }
53}
54
55impl std::fmt::Display for VarName {
56 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57 f.write_str(&self.0)
58 }
59}
60
61#[derive(Debug, Clone, PartialEq, Eq)]
63pub enum Expr {
64 Var(VarName),
66 Lam {
68 param: VarName,
70 body: Box<Expr>,
72 },
73 App {
75 func: Box<Expr>,
77 arg: Box<Expr>,
79 },
80 Let {
82 name: VarName,
84 value: Box<Expr>,
86 body: Box<Expr>,
88 },
89 Fix {
91 name: VarName,
93 body: Box<Expr>,
95 },
96 Ref {
98 inner: Box<Expr>,
100 },
101 Deref {
103 inner: Box<Expr>,
107 },
108 Assign {
110 target: Box<Expr>,
114 value: Box<Expr>,
116 },
117 Seq {
120 first: Box<Expr>,
122 second: Box<Expr>,
124 },
125}
126
127impl Expr {
128 #[must_use]
130 pub fn var(name: impl Into<VarName>) -> Self {
131 Self::Var(name.into())
132 }
133
134 #[must_use]
136 pub fn lam(param: impl Into<VarName>, body: Self) -> Self {
137 Self::Lam {
138 param: param.into(),
139 body: Box::new(body),
140 }
141 }
142
143 #[must_use]
145 pub fn app(func: Self, arg: Self) -> Self {
146 Self::App {
147 func: Box::new(func),
148 arg: Box::new(arg),
149 }
150 }
151
152 #[must_use]
154 pub fn bind(name: impl Into<VarName>, value: Self, body: Self) -> Self {
155 Self::Let {
156 name: name.into(),
157 value: Box::new(value),
158 body: Box::new(body),
159 }
160 }
161
162 #[must_use]
164 pub fn fix(name: impl Into<VarName>, body: Self) -> Self {
165 Self::Fix {
166 name: name.into(),
167 body: Box::new(body),
168 }
169 }
170
171 #[must_use]
174 pub fn alloc(inner: Self) -> Self {
175 Self::Ref {
176 inner: Box::new(inner),
177 }
178 }
179
180 #[must_use]
182 pub fn deref(inner: Self) -> Self {
183 Self::Deref {
184 inner: Box::new(inner),
185 }
186 }
187
188 #[must_use]
190 pub fn assign(target: Self, value: Self) -> Self {
191 Self::Assign {
192 target: Box::new(target),
193 value: Box::new(value),
194 }
195 }
196
197 #[must_use]
199 pub fn seq(first: Self, second: Self) -> Self {
200 Self::Seq {
201 first: Box::new(first),
202 second: Box::new(second),
203 }
204 }
205}
206
207impl std::fmt::Display for Expr {
208 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
209 match self {
210 Self::Var(name) => write!(f, "{name}"),
211 Self::Lam { param, body } => write!(f, "(\\{param}. {body})"),
212 Self::App { func, arg } => write!(f, "({func} {arg})"),
213 Self::Let { name, value, body } => {
214 write!(f, "(let {name} = {value} in {body})")
215 }
216 Self::Fix { name, body } => write!(f, "(fix {name}. {body})"),
217 Self::Ref { inner } => write!(f, "(ref {inner})"),
218 Self::Deref { inner } => write!(f, "(!{inner})"),
219 Self::Assign { target, value } => write!(f, "({target} := {value})"),
220 Self::Seq { first, second } => write!(f, "({first} ; {second})"),
221 }
222 }
223}