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 Default for Program {
33    fn default() -> Self {
34        Self::new()
35    }
36}
37
38impl Program {
39    pub fn new() -> Self {
40        Program {
41            body: vec![],
42            span: Span {
43                start: 0,
44                end: 0,
45            },
46        }
47    }
48}
49
50impl fmt::Display for Program {
51    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
52        write!(f, "{}", format_statements(&self.body))
53    }
54}
55
56#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
57#[serde(untagged)]
58pub enum Statement {
59    Let(Let),
60    Return(ReturnStatement),
61    Class(ClassDeclaration),
62    SetProperty(SetPropertyStatement),
63    Expr(Expression),
64}
65
66#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
67#[serde(tag = "type")]
68pub struct ClassDeclaration {
69    pub name: IDENTIFIER,
70    pub methods: Vec<MethodDefinition>,
71    pub span: Span,
72}
73
74#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
75#[serde(tag = "type")]
76pub struct MethodDefinition {
77    pub kind: MethodKind,
78    pub name: IDENTIFIER,
79    pub params: Vec<IDENTIFIER>,
80    pub body: BlockStatement,
81    pub span: Span,
82}
83
84#[derive(Clone, Copy, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
85pub enum MethodKind {
86    Constructor,
87    Method,
88}
89
90#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
91#[serde(tag = "type")]
92pub struct SetPropertyStatement {
93    pub object: Box<Expression>,
94    pub property: IDENTIFIER,
95    pub value: Expression,
96    pub span: Span,
97}
98
99#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
100#[serde(tag = "type")]
101pub struct Let {
102    pub identifier: Token, // rust can't do precise type with enum
103    pub expr: Expression,
104    pub span: Span,
105}
106
107#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
108#[serde(tag = "type")]
109pub struct ReturnStatement {
110    pub argument: Expression,
111    pub span: Span,
112}
113
114impl fmt::Display for Statement {
115    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
116        match self {
117            Statement::Let(Let {
118                identifier: id,
119                expr,
120                ..
121            }) => {
122                if let TokenKind::IDENTIFIER {
123                    name,
124                } = &id.kind
125                {
126                    return write!(f, "let {} = {};", name, expr);
127                }
128                panic!("unreachable")
129            }
130            Statement::Return(ReturnStatement {
131                argument,
132                ..
133            }) => {
134                write!(f, "return {};", argument)
135            }
136            Statement::Class(class) => {
137                let methods = class
138                    .methods
139                    .iter()
140                    .map(|method| method.to_string())
141                    .collect::<Vec<_>>()
142                    .join("");
143                write!(f, "class {} {{{}}}", class.name, methods)
144            }
145            Statement::SetProperty(set) => {
146                write!(f, "{}.{} = {};", set.object, set.property, set.value)
147            }
148            Statement::Expr(expr) => write!(f, "{}", expr),
149        }
150    }
151}
152
153impl fmt::Display for MethodDefinition {
154    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
155        let params = self
156            .params
157            .iter()
158            .map(ToString::to_string)
159            .collect::<Vec<_>>()
160            .join(", ");
161        write!(f, "{}({}) {{{}}}", self.name, params, self.body)
162    }
163}
164
165#[derive(Clone, Debug, Eq, Hash, Serialize, Deserialize, PartialEq)]
166#[serde(tag = "type")]
167pub struct BlockStatement {
168    pub body: Vec<Statement>,
169    pub span: Span,
170}
171
172impl fmt::Display for BlockStatement {
173    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
174        write!(f, "{}", format_statements(&self.body))
175    }
176}
177
178#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
179#[serde(untagged)]
180pub enum Expression {
181    IDENTIFIER(IDENTIFIER),
182    LITERAL(Literal), // need to flatten
183    PREFIX(UnaryExpression),
184    INFIX(BinaryExpression),
185    IF(IF),
186    FUNCTION(FunctionDeclaration),
187    FunctionCall(FunctionCall),
188    Index(Index),
189    This(ThisExpression),
190    Property(PropertyExpression),
191    New(NewExpression),
192}
193
194#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
195#[serde(tag = "type")]
196pub struct ThisExpression {
197    pub span: Span,
198}
199
200#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
201#[serde(tag = "type")]
202pub struct PropertyExpression {
203    pub object: Box<Expression>,
204    pub property: IDENTIFIER,
205    pub span: Span,
206}
207
208#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
209#[serde(tag = "type")]
210pub struct NewExpression {
211    pub callee: IDENTIFIER,
212    pub arguments: Vec<Expression>,
213    pub span: Span,
214}
215
216#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
217#[serde(tag = "type")]
218pub struct IDENTIFIER {
219    pub name: String,
220    pub span: Span,
221}
222
223impl fmt::Display for IDENTIFIER {
224    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
225        write!(f, "{}", self.name)
226    }
227}
228
229#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
230#[serde(tag = "type")]
231pub struct UnaryExpression {
232    pub op: Token,
233    pub operand: Box<Expression>,
234    pub span: Span,
235}
236
237#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
238#[serde(tag = "type")]
239pub struct BinaryExpression {
240    pub op: Token,
241    pub left: Box<Expression>,
242    pub right: Box<Expression>,
243    pub span: Span,
244}
245
246#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
247#[serde(tag = "type")]
248pub struct IF {
249    pub condition: Box<Expression>,
250    pub consequent: BlockStatement,
251    pub alternate: Option<BlockStatement>,
252    pub span: Span,
253}
254
255#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
256#[serde(tag = "type")]
257pub struct FunctionDeclaration {
258    pub params: Vec<IDENTIFIER>,
259    pub body: BlockStatement,
260    pub span: Span,
261    pub name: String,
262}
263
264// function can be Identifier or FunctionLiteral (think iife)
265#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
266#[serde(tag = "type")]
267pub struct FunctionCall {
268    pub callee: Box<Expression>,
269    pub arguments: Vec<Expression>,
270    pub span: Span,
271}
272
273#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
274#[serde(tag = "type")]
275pub struct Index {
276    pub object: Box<Expression>,
277    pub index: Box<Expression>,
278    pub span: Span,
279}
280
281impl fmt::Display for Expression {
282    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
283        match self {
284            Expression::IDENTIFIER(IDENTIFIER {
285                name: id,
286                ..
287            }) => write!(f, "{}", id),
288            Expression::LITERAL(l) => write!(f, "{}", l),
289            Expression::PREFIX(UnaryExpression {
290                op,
291                operand: expr,
292                ..
293            }) => {
294                write!(f, "({}{})", op.kind, expr)
295            }
296            Expression::INFIX(BinaryExpression {
297                op,
298                left,
299                right,
300                ..
301            }) => {
302                write!(f, "({} {} {})", left, op.kind, right)
303            }
304            Expression::IF(IF {
305                condition,
306                consequent,
307                alternate,
308                ..
309            }) => {
310                if let Some(else_block) = alternate {
311                    write!(f, "if {} {{ {} }} else {{ {} }}", condition, consequent, else_block,)
312                } else {
313                    write!(f, "if {} {{ {} }}", condition, consequent,)
314                }
315            }
316            Expression::FUNCTION(FunctionDeclaration {
317                name,
318                params,
319                body,
320                ..
321            }) => {
322                let func_params = params
323                    .iter()
324                    .map(|stmt| stmt.to_string())
325                    .collect::<Vec<String>>()
326                    .join(", ");
327                write!(f, "fn {}({}) {{ {} }}", name, func_params, body)
328            }
329            Expression::FunctionCall(FunctionCall {
330                callee,
331                arguments,
332                ..
333            }) => {
334                write!(f, "{}({})", callee, format_expressions(arguments))
335            }
336            Expression::Index(Index {
337                object,
338                index,
339                ..
340            }) => {
341                write!(f, "({}[{}])", object, index)
342            }
343            Expression::This(_) => write!(f, "this"),
344            Expression::Property(PropertyExpression {
345                object,
346                property,
347                ..
348            }) => write!(f, "{}.{}", object, property),
349            Expression::New(NewExpression {
350                callee,
351                arguments,
352                ..
353            }) => write!(f, "new {}({})", callee, format_expressions(arguments)),
354        }
355    }
356}
357
358impl Statement {
359    pub fn span(&self) -> &Span {
360        match self {
361            Statement::Let(statement) => &statement.span,
362            Statement::Return(statement) => &statement.span,
363            Statement::Class(statement) => &statement.span,
364            Statement::SetProperty(statement) => &statement.span,
365            Statement::Expr(expression) => expression.span(),
366        }
367    }
368}
369
370impl Expression {
371    pub fn span(&self) -> &Span {
372        match self {
373            Expression::IDENTIFIER(identifier) => &identifier.span,
374            Expression::LITERAL(literal) => literal.span(),
375            Expression::PREFIX(expression) => &expression.span,
376            Expression::INFIX(expression) => &expression.span,
377            Expression::IF(expression) => &expression.span,
378            Expression::FUNCTION(expression) => &expression.span,
379            Expression::FunctionCall(expression) => &expression.span,
380            Expression::Index(expression) => &expression.span,
381            Expression::This(expression) => &expression.span,
382            Expression::Property(expression) => &expression.span,
383            Expression::New(expression) => &expression.span,
384        }
385    }
386}
387
388impl Literal {
389    pub fn span(&self) -> &Span {
390        match self {
391            Literal::Integer(literal) => &literal.span,
392            Literal::Boolean(literal) => &literal.span,
393            Literal::String(literal) => &literal.span,
394            Literal::Array(literal) => &literal.span,
395            Literal::Hash(literal) => &literal.span,
396        }
397    }
398}
399
400#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
401#[serde(tag = "type")]
402pub enum Literal {
403    Integer(Integer),
404    Boolean(Boolean),
405    String(StringType),
406    Array(Array),
407    Hash(Hash),
408}
409
410#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
411pub struct Integer {
412    pub raw: i64,
413    pub span: Span,
414}
415
416#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
417pub struct Boolean {
418    pub raw: bool,
419    pub span: Span,
420}
421
422#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
423pub struct StringType {
424    pub raw: String,
425    pub span: Span,
426}
427
428#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
429pub struct Array {
430    pub elements: Vec<Expression>,
431    pub span: Span,
432}
433
434#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
435pub struct Hash {
436    pub elements: Vec<(Expression, Expression)>,
437    pub span: Span,
438}
439
440impl fmt::Display for Literal {
441    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
442        match self {
443            Literal::Integer(Integer {
444                raw: i,
445                ..
446            }) => write!(f, "{}", i),
447            Literal::Boolean(Boolean {
448                raw: b,
449                ..
450            }) => write!(f, "{}", b),
451            Literal::String(StringType {
452                raw: s,
453                ..
454            }) => write!(f, "\"{}\"", s),
455            Literal::Array(Array {
456                elements: e,
457                ..
458            }) => write!(f, "[{}]", format_expressions(e)),
459            Literal::Hash(Hash {
460                elements: map,
461                ..
462            }) => {
463                let to_string = map
464                    .iter()
465                    .map(|(k, v)| format!("{}: {}", k, v))
466                    .collect::<Vec<String>>()
467                    .join(", ");
468
469                write!(f, "{{{}}}", to_string)
470            }
471        }
472    }
473}
474
475fn format_statements(statements: &[Statement]) -> String {
476    return statements
477        .iter()
478        .map(|stmt| stmt.to_string())
479        .collect::<Vec<String>>()
480        .join("");
481}
482
483fn format_expressions(exprs: &[Expression]) -> String {
484    return exprs
485        .iter()
486        .map(|stmt| stmt.to_string())
487        .collect::<Vec<String>>()
488        .join(", ");
489}