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