Skip to main content

parser/
ast.rs

1use core::fmt;
2use core::fmt::Result;
3use lexer::token::{Span, Token};
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    Debugger(DebuggerStatement),
64    Expr(Expression),
65}
66
67#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
68#[serde(tag = "type")]
69pub struct ClassDeclaration {
70    pub name: IDENTIFIER,
71    pub methods: Vec<MethodDefinition>,
72    pub span: Span,
73}
74
75#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
76#[serde(tag = "type")]
77pub struct MethodDefinition {
78    pub kind: MethodKind,
79    pub name: IDENTIFIER,
80    pub params: Vec<Param>,
81    /// Always `None` for `MethodKind::Constructor` (parser rejects the annotation).
82    pub return_type: Option<TypeAnnotation>,
83    pub body: BlockStatement,
84    pub span: Span,
85}
86
87#[derive(Clone, Copy, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
88pub enum MethodKind {
89    Constructor,
90    Method,
91}
92
93#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
94#[serde(tag = "type")]
95pub struct SetPropertyStatement {
96    pub object: Box<Expression>,
97    pub property: IDENTIFIER,
98    pub value: Expression,
99    pub span: Span,
100}
101
102#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
103#[serde(tag = "type")]
104pub struct Let {
105    pub identifier: IDENTIFIER,
106    pub type_annotation: Option<TypeAnnotation>,
107    pub expr: Expression,
108    pub span: Span,
109}
110
111/// A function or method parameter: name plus its optional type annotation.
112#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
113#[serde(tag = "type")]
114pub struct Param {
115    pub identifier: IDENTIFIER,
116    pub type_annotation: Option<TypeAnnotation>,
117    pub span: Span,
118}
119
120impl fmt::Display for Param {
121    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
122        match &self.type_annotation {
123            Some(annotation) => write!(f, "{}: {}", self.identifier, annotation),
124            None => write!(f, "{}", self.identifier),
125        }
126    }
127}
128
129/// Type annotations are parsed and carried through the AST, but every execution
130/// backend erases them: see docs/type-system-design.md section 6.
131#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
132#[serde(untagged)]
133pub enum TypeAnnotation {
134    Named(NamedType),
135    Array(ArrayType),
136    Hash(HashType),
137    Function(FunctionType),
138    Optional(OptionalType),
139}
140
141#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
142#[serde(tag = "type", rename = "NamedType")]
143pub struct NamedType {
144    /// `int` | `bool` | `string` | `any` | `null` | a class name
145    pub name: String,
146    pub span: Span,
147}
148
149#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
150#[serde(tag = "type", rename = "ArrayType")]
151pub struct ArrayType {
152    pub element: Box<TypeAnnotation>,
153    pub span: Span,
154}
155
156#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
157#[serde(tag = "type", rename = "HashType")]
158pub struct HashType {
159    pub key: Box<TypeAnnotation>,
160    pub value: Box<TypeAnnotation>,
161    pub span: Span,
162}
163
164#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
165#[serde(tag = "type", rename = "FunctionType")]
166pub struct FunctionType {
167    pub params: Vec<TypeAnnotation>,
168    pub return_type: Box<TypeAnnotation>,
169    pub span: Span,
170}
171
172#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
173#[serde(tag = "type", rename = "OptionalType")]
174pub struct OptionalType {
175    pub inner: Box<TypeAnnotation>,
176    pub span: Span,
177}
178
179impl TypeAnnotation {
180    pub fn span(&self) -> &Span {
181        match self {
182            TypeAnnotation::Named(annotation) => &annotation.span,
183            TypeAnnotation::Array(annotation) => &annotation.span,
184            TypeAnnotation::Hash(annotation) => &annotation.span,
185            TypeAnnotation::Function(annotation) => &annotation.span,
186            TypeAnnotation::Optional(annotation) => &annotation.span,
187        }
188    }
189}
190
191impl fmt::Display for TypeAnnotation {
192    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
193        match self {
194            TypeAnnotation::Named(NamedType {
195                name,
196                ..
197            }) => write!(f, "{}", name),
198            TypeAnnotation::Array(ArrayType {
199                element,
200                ..
201            }) => write!(f, "[{}]", element),
202            TypeAnnotation::Hash(HashType {
203                key,
204                value,
205                ..
206            }) => write!(f, "{{{}: {}}}", key, value),
207            TypeAnnotation::Function(FunctionType {
208                params,
209                return_type,
210                ..
211            }) => {
212                let params = params
213                    .iter()
214                    .map(ToString::to_string)
215                    .collect::<Vec<String>>()
216                    .join(", ");
217                write!(f, "fn({}): {}", params, return_type)
218            }
219            TypeAnnotation::Optional(OptionalType {
220                inner,
221                ..
222            }) => match **inner {
223                // `fn(int): int?` would parse the `?` as part of the return
224                // type, so a nullable function type needs its grouping back.
225                TypeAnnotation::Function(_) => write!(f, "({})?", inner),
226                _ => write!(f, "{}?", inner),
227            },
228        }
229    }
230}
231
232/// Renders `: T` for an optional annotation, or nothing when absent.
233fn format_type_annotation(annotation: &Option<TypeAnnotation>) -> String {
234    match annotation {
235        Some(annotation) => format!(": {}", annotation),
236        None => String::new(),
237    }
238}
239
240fn format_params(params: &[Param]) -> String {
241    return params
242        .iter()
243        .map(ToString::to_string)
244        .collect::<Vec<String>>()
245        .join(", ");
246}
247
248#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
249#[serde(tag = "type")]
250pub struct ReturnStatement {
251    pub argument: Expression,
252    pub span: Span,
253}
254
255#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
256#[serde(tag = "type")]
257pub struct DebuggerStatement {
258    pub span: Span,
259}
260
261impl fmt::Display for Statement {
262    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
263        match self {
264            Statement::Let(Let {
265                identifier: id,
266                type_annotation,
267                expr,
268                ..
269            }) => {
270                write!(f, "let {}{} = {};", id.name, format_type_annotation(type_annotation), expr)
271            }
272            Statement::Return(ReturnStatement {
273                argument,
274                ..
275            }) => {
276                write!(f, "return {};", argument)
277            }
278            Statement::Class(class) => {
279                let methods = class
280                    .methods
281                    .iter()
282                    .map(|method| method.to_string())
283                    .collect::<Vec<_>>()
284                    .join("");
285                write!(f, "class {} {{{}}}", class.name, methods)
286            }
287            Statement::SetProperty(set) => {
288                write!(f, "{}.{} = {};", set.object, set.property, set.value)
289            }
290            Statement::Debugger(_) => write!(f, "debugger;"),
291            Statement::Expr(expr) => write!(f, "{}", expr),
292        }
293    }
294}
295
296impl fmt::Display for MethodDefinition {
297    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
298        write!(
299            f,
300            "{}({}){} {{{}}}",
301            self.name,
302            format_params(&self.params),
303            format_type_annotation(&self.return_type),
304            self.body
305        )
306    }
307}
308
309#[derive(Clone, Debug, Eq, Hash, Serialize, Deserialize, PartialEq)]
310#[serde(tag = "type")]
311pub struct BlockStatement {
312    pub body: Vec<Statement>,
313    pub span: Span,
314}
315
316impl fmt::Display for BlockStatement {
317    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
318        write!(f, "{}", format_statements(&self.body))
319    }
320}
321
322#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
323#[serde(untagged)]
324pub enum Expression {
325    IDENTIFIER(IDENTIFIER),
326    LITERAL(Literal), // need to flatten
327    PREFIX(UnaryExpression),
328    INFIX(BinaryExpression),
329    IF(IF),
330    FUNCTION(FunctionDeclaration),
331    FunctionCall(FunctionCall),
332    Index(Index),
333    This(ThisExpression),
334    Property(PropertyExpression),
335    New(NewExpression),
336}
337
338#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
339#[serde(tag = "type")]
340pub struct ThisExpression {
341    pub span: Span,
342}
343
344#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
345#[serde(tag = "type")]
346pub struct PropertyExpression {
347    pub object: Box<Expression>,
348    pub property: IDENTIFIER,
349    pub span: Span,
350}
351
352#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
353#[serde(tag = "type")]
354pub struct NewExpression {
355    pub callee: IDENTIFIER,
356    pub arguments: Vec<Expression>,
357    pub span: Span,
358}
359
360#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
361#[serde(tag = "type")]
362pub struct IDENTIFIER {
363    pub name: String,
364    pub span: Span,
365}
366
367impl fmt::Display for IDENTIFIER {
368    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
369        write!(f, "{}", self.name)
370    }
371}
372
373#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
374#[serde(tag = "type")]
375pub struct UnaryExpression {
376    pub op: Token,
377    pub operand: Box<Expression>,
378    pub span: Span,
379}
380
381#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
382#[serde(tag = "type")]
383pub struct BinaryExpression {
384    pub op: Token,
385    pub left: Box<Expression>,
386    pub right: Box<Expression>,
387    pub span: Span,
388}
389
390#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
391#[serde(tag = "type")]
392pub struct IF {
393    pub condition: Box<Expression>,
394    pub consequent: BlockStatement,
395    pub alternate: Option<BlockStatement>,
396    pub span: Span,
397}
398
399#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
400#[serde(tag = "type")]
401pub struct FunctionDeclaration {
402    pub params: Vec<Param>,
403    pub return_type: Option<TypeAnnotation>,
404    pub body: BlockStatement,
405    pub span: Span,
406    pub name: String,
407}
408
409// function can be Identifier or FunctionLiteral (think iife)
410#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
411#[serde(tag = "type")]
412pub struct FunctionCall {
413    pub callee: Box<Expression>,
414    pub arguments: Vec<Expression>,
415    pub span: Span,
416}
417
418#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
419#[serde(tag = "type")]
420pub struct Index {
421    pub object: Box<Expression>,
422    pub index: Box<Expression>,
423    pub span: Span,
424}
425
426impl fmt::Display for Expression {
427    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
428        match self {
429            Expression::IDENTIFIER(IDENTIFIER {
430                name: id,
431                ..
432            }) => write!(f, "{}", id),
433            Expression::LITERAL(l) => write!(f, "{}", l),
434            Expression::PREFIX(UnaryExpression {
435                op,
436                operand: expr,
437                ..
438            }) => {
439                write!(f, "({}{})", op.kind, expr)
440            }
441            Expression::INFIX(BinaryExpression {
442                op,
443                left,
444                right,
445                ..
446            }) => {
447                write!(f, "({} {} {})", left, op.kind, right)
448            }
449            Expression::IF(IF {
450                condition,
451                consequent,
452                alternate,
453                ..
454            }) => {
455                if let Some(else_block) = alternate {
456                    write!(f, "if {} {{ {} }} else {{ {} }}", condition, consequent, else_block,)
457                } else {
458                    write!(f, "if {} {{ {} }}", condition, consequent,)
459                }
460            }
461            Expression::FUNCTION(FunctionDeclaration {
462                name,
463                params,
464                return_type,
465                body,
466                ..
467            }) => {
468                write!(
469                    f,
470                    "fn {}({}){} {{ {} }}",
471                    name,
472                    format_params(params),
473                    format_type_annotation(return_type),
474                    body
475                )
476            }
477            Expression::FunctionCall(FunctionCall {
478                callee,
479                arguments,
480                ..
481            }) => {
482                write!(f, "{}({})", callee, format_expressions(arguments))
483            }
484            Expression::Index(Index {
485                object,
486                index,
487                ..
488            }) => {
489                write!(f, "({}[{}])", object, index)
490            }
491            Expression::This(_) => write!(f, "this"),
492            Expression::Property(PropertyExpression {
493                object,
494                property,
495                ..
496            }) => write!(f, "{}.{}", object, property),
497            Expression::New(NewExpression {
498                callee,
499                arguments,
500                ..
501            }) => write!(f, "new {}({})", callee, format_expressions(arguments)),
502        }
503    }
504}
505
506impl Statement {
507    pub fn span(&self) -> &Span {
508        match self {
509            Statement::Let(statement) => &statement.span,
510            Statement::Return(statement) => &statement.span,
511            Statement::Class(statement) => &statement.span,
512            Statement::SetProperty(statement) => &statement.span,
513            Statement::Debugger(statement) => &statement.span,
514            Statement::Expr(expression) => expression.span(),
515        }
516    }
517}
518
519impl Expression {
520    pub fn span(&self) -> &Span {
521        match self {
522            Expression::IDENTIFIER(identifier) => &identifier.span,
523            Expression::LITERAL(literal) => literal.span(),
524            Expression::PREFIX(expression) => &expression.span,
525            Expression::INFIX(expression) => &expression.span,
526            Expression::IF(expression) => &expression.span,
527            Expression::FUNCTION(expression) => &expression.span,
528            Expression::FunctionCall(expression) => &expression.span,
529            Expression::Index(expression) => &expression.span,
530            Expression::This(expression) => &expression.span,
531            Expression::Property(expression) => &expression.span,
532            Expression::New(expression) => &expression.span,
533        }
534    }
535}
536
537impl Literal {
538    pub fn span(&self) -> &Span {
539        match self {
540            Literal::Integer(literal) => &literal.span,
541            Literal::Boolean(literal) => &literal.span,
542            Literal::String(literal) => &literal.span,
543            Literal::Array(literal) => &literal.span,
544            Literal::Hash(literal) => &literal.span,
545        }
546    }
547}
548
549#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
550#[serde(tag = "type")]
551pub enum Literal {
552    Integer(Integer),
553    Boolean(Boolean),
554    String(StringType),
555    Array(Array),
556    Hash(Hash),
557}
558
559#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
560pub struct Integer {
561    pub raw: i64,
562    pub span: Span,
563}
564
565#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
566pub struct Boolean {
567    pub raw: bool,
568    pub span: Span,
569}
570
571#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
572pub struct StringType {
573    pub raw: String,
574    pub span: Span,
575}
576
577#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
578pub struct Array {
579    pub elements: Vec<Expression>,
580    pub span: Span,
581}
582
583#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
584pub struct Hash {
585    pub elements: Vec<(Expression, Expression)>,
586    pub span: Span,
587}
588
589impl fmt::Display for Literal {
590    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
591        match self {
592            Literal::Integer(Integer {
593                raw: i,
594                ..
595            }) => write!(f, "{}", i),
596            Literal::Boolean(Boolean {
597                raw: b,
598                ..
599            }) => write!(f, "{}", b),
600            Literal::String(StringType {
601                raw: s,
602                ..
603            }) => write!(f, "\"{}\"", s),
604            Literal::Array(Array {
605                elements: e,
606                ..
607            }) => write!(f, "[{}]", format_expressions(e)),
608            Literal::Hash(Hash {
609                elements: map,
610                ..
611            }) => {
612                let to_string = map
613                    .iter()
614                    .map(|(k, v)| format!("{}: {}", k, v))
615                    .collect::<Vec<String>>()
616                    .join(", ");
617
618                write!(f, "{{{}}}", to_string)
619            }
620        }
621    }
622}
623
624fn format_statements(statements: &[Statement]) -> String {
625    return statements
626        .iter()
627        .map(|stmt| stmt.to_string())
628        .collect::<Vec<String>>()
629        .join("");
630}
631
632fn format_expressions(exprs: &[Expression]) -> String {
633    return exprs
634        .iter()
635        .map(|stmt| stmt.to_string())
636        .collect::<Vec<String>>()
637        .join(", ");
638}