monkeyinterpreter/
ast.rs

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, // the first token of the expression
382    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}