Skip to main content

parser/
ast.rs

1use core::fmt;
2use core::fmt::Result;
3use lexer::token::{Span, Token, TokenKind};
4use serde::{Deserialize, Serialize};
5use std::fmt::Formatter;
6
7// still wait for https://github.com/serde-rs/serde/issues/1402
8#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
9pub enum Node {
10    Program(Program),
11    Statement(Statement),
12    Expression(Expression),
13}
14
15impl fmt::Display for Node {
16    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
17        match self {
18            Node::Program(p) => write!(f, "{}", p),
19            Node::Statement(stmt) => write!(f, "{}", stmt),
20            Node::Expression(expr) => write!(f, "{}", expr),
21        }
22    }
23}
24
25#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
26#[serde(tag = "type")]
27pub struct Program {
28    pub body: Vec<Statement>,
29    pub span: Span,
30}
31
32impl Program {
33    pub fn new() -> Self {
34        Program {
35            body: vec![],
36            span: Span {
37                start: 0,
38                end: 0,
39            },
40        }
41    }
42}
43
44impl fmt::Display for Program {
45    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
46        write!(f, "{}", format_statements(&self.body))
47    }
48}
49
50#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
51#[serde(untagged)]
52pub enum Statement {
53    Let(Let),
54    Return(ReturnStatement),
55    Expr(Expression),
56}
57
58#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
59#[serde(tag = "type")]
60pub struct Let {
61    pub identifier: Token, // rust can't do precise type with enum
62    pub expr: Expression,
63    pub span: Span,
64}
65
66#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
67#[serde(tag = "type")]
68pub struct ReturnStatement {
69    pub argument: Expression,
70    pub span: Span,
71}
72
73impl fmt::Display for Statement {
74    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
75        match self {
76            Statement::Let(Let {
77                identifier: id,
78                expr,
79                ..
80            }) => {
81                if let TokenKind::IDENTIFIER {
82                    name,
83                } = &id.kind
84                {
85                    return write!(f, "let {} = {};", name, expr);
86                }
87                panic!("unreachable")
88            }
89            Statement::Return(ReturnStatement {
90                argument,
91                ..
92            }) => {
93                write!(f, "return {};", argument)
94            }
95            Statement::Expr(expr) => write!(f, "{}", expr),
96        }
97    }
98}
99
100#[derive(Clone, Debug, Eq, Hash, Serialize, Deserialize, PartialEq)]
101#[serde(tag = "type")]
102pub struct BlockStatement {
103    pub body: Vec<Statement>,
104    pub span: Span,
105}
106
107impl fmt::Display for BlockStatement {
108    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
109        write!(f, "{}", format_statements(&self.body))
110    }
111}
112
113#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
114#[serde(untagged)]
115pub enum Expression {
116    IDENTIFIER(IDENTIFIER),
117    LITERAL(Literal), // need to flatten
118    PREFIX(UnaryExpression),
119    INFIX(BinaryExpression),
120    IF(IF),
121    FUNCTION(FunctionDeclaration),
122    FunctionCall(FunctionCall),
123    Index(Index),
124}
125
126#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
127#[serde(tag = "type")]
128pub struct IDENTIFIER {
129    pub name: String,
130    pub span: Span,
131}
132
133impl fmt::Display for IDENTIFIER {
134    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
135        write!(f, "{}", &self.name)
136    }
137}
138
139#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
140#[serde(tag = "type")]
141pub struct UnaryExpression {
142    pub op: Token,
143    pub operand: Box<Expression>,
144    pub span: Span,
145}
146
147#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
148#[serde(tag = "type")]
149pub struct BinaryExpression {
150    pub op: Token,
151    pub left: Box<Expression>,
152    pub right: Box<Expression>,
153    pub span: Span,
154}
155
156#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
157#[serde(tag = "type")]
158pub struct IF {
159    pub condition: Box<Expression>,
160    pub consequent: BlockStatement,
161    pub alternate: Option<BlockStatement>,
162    pub span: Span,
163}
164
165#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
166#[serde(tag = "type")]
167pub struct FunctionDeclaration {
168    pub params: Vec<IDENTIFIER>,
169    pub body: BlockStatement,
170    pub span: Span,
171    pub name: String,
172}
173
174// function can be Identifier or FunctionLiteral (think iife)
175#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
176#[serde(tag = "type")]
177pub struct FunctionCall {
178    pub callee: Box<Expression>,
179    pub arguments: Vec<Expression>,
180    pub span: Span,
181}
182
183#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
184#[serde(tag = "type")]
185pub struct Index {
186    pub object: Box<Expression>,
187    pub index: Box<Expression>,
188    pub span: Span,
189}
190
191impl fmt::Display for Expression {
192    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
193        match self {
194            Expression::IDENTIFIER(IDENTIFIER {
195                name: id,
196                ..
197            }) => write!(f, "{}", id),
198            Expression::LITERAL(l) => write!(f, "{}", l),
199            Expression::PREFIX(UnaryExpression {
200                op,
201                operand: expr,
202                ..
203            }) => {
204                write!(f, "({}{})", op.kind, expr)
205            }
206            Expression::INFIX(BinaryExpression {
207                op,
208                left,
209                right,
210                ..
211            }) => {
212                write!(f, "({} {} {})", left, op.kind, right)
213            }
214            Expression::IF(IF {
215                condition,
216                consequent,
217                alternate,
218                ..
219            }) => {
220                if let Some(else_block) = alternate {
221                    write!(f, "if {} {{ {} }} else {{ {} }}", condition, consequent, else_block,)
222                } else {
223                    write!(f, "if {} {{ {} }}", condition, consequent,)
224                }
225            }
226            Expression::FUNCTION(FunctionDeclaration {
227                name,
228                params,
229                body,
230                ..
231            }) => {
232                let func_params = params
233                    .iter()
234                    .map(|stmt| stmt.to_string())
235                    .collect::<Vec<String>>()
236                    .join(", ");
237                write!(f, "fn {}({}) {{ {} }}", name, func_params, body)
238            }
239            Expression::FunctionCall(FunctionCall {
240                callee,
241                arguments,
242                ..
243            }) => {
244                write!(f, "{}({})", callee, format_expressions(arguments))
245            }
246            Expression::Index(Index {
247                object,
248                index,
249                ..
250            }) => {
251                write!(f, "({}[{}])", object, index)
252            }
253        }
254    }
255}
256
257#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
258#[serde(tag = "type")]
259pub enum Literal {
260    Integer(Integer),
261    Boolean(Boolean),
262    String(StringType),
263    Array(Array),
264    Hash(Hash),
265}
266
267#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
268pub struct Integer {
269    pub raw: i64,
270    pub span: Span,
271}
272
273#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
274pub struct Boolean {
275    pub raw: bool,
276    pub span: Span,
277}
278
279#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
280pub struct StringType {
281    pub raw: String,
282    pub span: Span,
283}
284
285#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
286pub struct Array {
287    pub elements: Vec<Expression>,
288    pub span: Span,
289}
290
291#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
292pub struct Hash {
293    pub elements: Vec<(Expression, Expression)>,
294    pub span: Span,
295}
296
297impl fmt::Display for Literal {
298    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
299        match self {
300            Literal::Integer(Integer {
301                raw: i,
302                ..
303            }) => write!(f, "{}", i),
304            Literal::Boolean(Boolean {
305                raw: b,
306                ..
307            }) => write!(f, "{}", b),
308            Literal::String(StringType {
309                raw: s,
310                ..
311            }) => write!(f, "\"{}\"", s),
312            Literal::Array(Array {
313                elements: e,
314                ..
315            }) => write!(f, "[{}]", format_expressions(e)),
316            Literal::Hash(Hash {
317                elements: map,
318                ..
319            }) => {
320                let to_string = map
321                    .iter()
322                    .map(|(k, v)| format!("{}: {}", k, v))
323                    .collect::<Vec<String>>()
324                    .join(", ");
325
326                write!(f, "{{{}}}", to_string)
327            }
328        }
329    }
330}
331
332fn format_statements(statements: &Vec<Statement>) -> String {
333    return statements
334        .iter()
335        .map(|stmt| stmt.to_string())
336        .collect::<Vec<String>>()
337        .join("");
338}
339
340fn format_expressions(exprs: &Vec<Expression>) -> String {
341    return exprs
342        .iter()
343        .map(|stmt| stmt.to_string())
344        .collect::<Vec<String>>()
345        .join(", ");
346}