1use std::{
2 fmt::{self, Display},
3 rc::Rc,
4};
5
6use crate::token::Token;
7
8macro_rules! expressions {
9 ( $($type:ident),* ) => {
10 pub enum Expression {
11 $( $type($type),)*
12 }
13
14 impl Display for Expression {
15 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16 let res = match &self {
17 $( Expression::$type(x) => x.to_string(),)*
18 };
19 f.write_str(res.as_str())
20 }
21 }
22 };
23}
24
25expressions!(
26 Identifier,
27 IntegerLiteral,
28 Boolean,
29 StringLiteral,
30 ArrayLiteral,
31 HashLiteral,
32 CallExpression,
33 IfExpression,
34 FunctionLiteral,
35 InfixExpression,
36 PrefixExpression,
37 IndexExpression
38);
39
40
41impl Display for Statement {
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43 let res = match &self {
44 Statement::LetStatement(x) => x.to_string(),
45 Statement::ReturnStatement(x) => x.to_string(),
46 Statement::ExpressionStatement(x) => x.to_string(),
47 };
48 f.write_str(res.as_str())
49 }
50}
51
52pub enum Statement {
53 LetStatement(LetStatement),
54 ReturnStatement(ReturnStatement),
55 ExpressionStatement(ExpressionStatement),
56}
57
58pub struct Program {
59 pub statements: Vec<Statement>,
60}
61
62impl Display for Program {
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 let res = self
65 .statements
66 .iter()
67 .map(|s| s.to_string())
68 .collect::<Vec<String>>()
69 .join("\n");
70 write!(f, "{}", res)
71 }
72}
73
74pub struct Identifier {
75 pub token: Token,
76 pub name: String,
77}
78
79impl Identifier {
80 pub fn new(token: Token) -> Identifier {
81 let name = if let Token::Ident(s) = &token {
82 s.clone()
83 } else {
84 panic!(
85 "Trying to create an Identifier with non-ident token {}",
86 token
87 );
88 };
89 Identifier { token, name }
90 }
91}
92
93impl Display for Identifier {
94 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95 write!(f, "{}", self.name)
96 }
97}
98
99pub struct IntegerLiteral {
100 pub token: Token,
101 pub value: i64,
102}
103
104impl Display for IntegerLiteral {
105 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106 write!(f, "{}", self.value)
107 }
108}
109
110impl IntegerLiteral {
111 pub fn new(token: Token) -> IntegerLiteral {
112 let value = if let Token::Int(x) = token {
113 x
114 } else {
115 panic!(
116 "Trying to create an IntegerLiteral with non int token: {}",
117 token
118 );
119 };
120 IntegerLiteral { token, value }
121 }
122}
123
124pub struct StringLiteral {
125 pub token: Token,
126 pub value: String,
127}
128
129impl Display for StringLiteral {
130 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131 write!(f, "{}", self.value)
132 }
133}
134
135impl StringLiteral {
136 pub fn new(token: Token) -> StringLiteral {
137 let value = if let Token::String(x) = &token {
138 x.clone()
139 } else {
140 panic!(
141 "Trying to create a StringLiteral with non String token: {}",
142 token
143 );
144 };
145 StringLiteral { token, value }
146 }
147}
148
149pub struct ArrayLiteral {
150 pub token: Token,
151 pub elements: Vec<Expression>,
152}
153
154impl Display for ArrayLiteral {
155 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
156 write!(
157 f,
158 "[{}]",
159 self.elements
160 .iter()
161 .map(|e| e.to_string())
162 .collect::<Vec<_>>()
163 .join(", ")
164 )
165 }
166}
167
168pub struct HashLiteral {
169 pub token: Token,
170 pub elements: Vec<(Expression, Expression)>,
171}
172
173impl Display for HashLiteral {
174 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
175 write!(
176 f,
177 "{{{}}}",
178 self.elements
179 .iter()
180 .map(|e| format!("{}: {}", e.0.to_string(), e.1.to_string()))
181 .collect::<Vec<_>>()
182 .join(", ")
183 )
184 }
185}
186
187pub struct IndexExpression {
188 pub token: Token,
189 pub left: Box<Expression>,
190 pub index: Box<Expression>,
191}
192
193impl Display for IndexExpression {
194 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
195 write!(f, "({}[{}])", self.left, self.index)
196 }
197}
198
199pub struct Boolean {
200 pub token: Token,
201 pub value: bool,
202}
203
204impl Display for Boolean {
205 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
206 write!(f, "{}", self.value)
207 }
208}
209
210impl Boolean {
211 pub fn new(token: Token) -> Boolean {
212 let value = match token {
213 Token::True => true,
214 Token::False => false,
215 _ => panic!("Trying to create Boolean from non bool token {}", token),
216 };
217 Boolean { token, value }
218 }
219}
220
221pub struct CallExpression {
222 pub token: Token,
223 pub function: Box<Expression>,
224 pub arguments: Vec<Expression>,
225}
226
227impl Display for CallExpression {
228 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
229 write!(
230 f,
231 "{}({})",
232 self.function,
233 self.arguments
234 .iter()
235 .map(|a| a.to_string())
236 .collect::<Vec<_>>()
237 .join(", ")
238 )
239 }
240}
241
242pub struct PrefixExpression {
243 pub token: Token,
244 pub right: Box<Expression>,
245}
246
247impl Display for PrefixExpression {
248 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
249 write!(f, "({}{})", self.token, self.right)
250 }
251}
252
253pub struct InfixExpression {
254 pub token: Token,
255 pub left: Box<Expression>,
256 pub right: Box<Expression>,
257 pub operator: Token,
258}
259
260impl Display for InfixExpression {
261 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
262 write!(f, "({} {} {})", self.left, self.operator, self.right)
263 }
264}
265
266impl InfixExpression {
267 pub fn new(operator: Token, left: Expression, right: Expression) -> InfixExpression {
268 InfixExpression {
269 token: operator.clone(),
270 left: Box::new(left),
271 right: Box::new(right),
272 operator,
273 }
274 }
275}
276
277pub struct BlockStatement {
278 pub token: Token,
279 pub statements: Vec<Statement>,
280}
281
282impl Display for BlockStatement {
283 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
284 let s = self
285 .statements
286 .iter()
287 .map(|s| s.to_string())
288 .collect::<Vec<_>>()
289 .join("\n");
290 write!(f, "{}", s)
291 }
292}
293
294pub struct FunctionLiteral {
295 pub token: Token,
296 pub parameters: Rc<Vec<Identifier>>,
297 pub body: Rc<BlockStatement>,
298}
299
300impl Display for FunctionLiteral {
301 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
302 write!(
303 f,
304 "{} ({}) {}",
305 self.token,
306 self.parameters
307 .iter()
308 .map(|i| i.to_string())
309 .collect::<Vec<_>>()
310 .join(","),
311 self.body
312 )
313 }
314}
315
316pub struct IfExpression {
317 pub token: Token,
318 pub condition: Box<Expression>,
319 pub consequence: BlockStatement,
320 pub alternate: Option<BlockStatement>,
321}
322
323impl Display for IfExpression {
324 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
325 let s = format!(
326 "if ({})\n{}{}",
327 self.condition,
328 self.consequence,
329 self.alternate
330 .as_ref()
331 .map_or("".to_owned(), |a| format!("\n{}", a))
332 );
333 write!(f, "{}", s)
334 }
335}
336
337pub struct LetStatement {
338 pub token: Token,
339 pub name: Identifier,
340 pub value: Expression,
341}
342
343impl Display for LetStatement {
344 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
345 write!(f, "{} {} = {}", self.token, self.name, self.value)
346 }
347}
348
349impl LetStatement {
350 pub fn new(token: Token, identifier: Token, value: Expression) -> LetStatement {
351 let name = match &identifier {
352 Token::Ident(name) => name.clone(),
353 _ => panic!(
354 "LetStatement constructor called with non identifier token: {}",
355 identifier
356 ),
357 };
358 LetStatement {
359 token,
360 name: Identifier {
361 token: identifier,
362 name,
363 },
364 value,
365 }
366 }
367}
368
369pub struct ReturnStatement {
370 pub token: Token,
371 pub return_value: Expression,
372}
373
374impl Display for ReturnStatement {
375 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
376 write!(f, "{} {}", self.token, self.return_value)
377 }
378}
379
380pub struct ExpressionStatement {
381 pub token: Token, pub expression: Expression,
383}
384
385impl Display for ExpressionStatement {
386 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
387 write!(f, "{}", self.expression)
388 }
389}