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 { body: vec![], span: Span { start: 0, end: 0 } }
35    }
36}
37
38impl fmt::Display for Program {
39    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
40        write!(f, "{}", format_statements(&self.body))
41    }
42}
43
44#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
45#[serde(untagged)]
46pub enum Statement {
47    Let(Let),
48    Return(ReturnStatement),
49    Expr(Expression),
50}
51
52#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
53#[serde(tag = "type")]
54pub struct Let {
55    pub identifier: Token, // rust can't do precise type with enum
56    pub expr: Expression,
57    pub span: Span,
58}
59
60#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
61#[serde(tag = "type")]
62pub struct ReturnStatement {
63    pub argument: Expression,
64    pub span: Span,
65}
66
67impl fmt::Display for Statement {
68    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
69        match self {
70            Statement::Let(Let { identifier: id, expr, .. }) => {
71                if let TokenKind::IDENTIFIER { name } = &id.kind {
72                    return write!(f, "let {} = {};", name, expr);
73                }
74                panic!("unreachable")
75            }
76            Statement::Return(ReturnStatement { argument, .. }) => {
77                write!(f, "return {};", argument)
78            }
79            Statement::Expr(expr) => write!(f, "{}", expr),
80        }
81    }
82}
83
84#[derive(Clone, Debug, Eq, Hash, Serialize, Deserialize, PartialEq)]
85#[serde(tag = "type")]
86pub struct BlockStatement {
87    pub body: Vec<Statement>,
88    pub span: Span,
89}
90
91impl fmt::Display for BlockStatement {
92    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
93        write!(f, "{}", format_statements(&self.body))
94    }
95}
96
97#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
98#[serde(untagged)]
99pub enum Expression {
100    IDENTIFIER(IDENTIFIER),
101    LITERAL(Literal), // need to flatten
102    PREFIX(UnaryExpression),
103    INFIX(BinaryExpression),
104    IF(IF),
105    FUNCTION(FunctionDeclaration),
106    FunctionCall(FunctionCall),
107    Index(Index),
108}
109
110#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
111#[serde(tag = "type")]
112pub struct IDENTIFIER {
113    pub name: String,
114    pub span: Span,
115}
116
117impl fmt::Display for IDENTIFIER {
118    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
119        write!(f, "{}", &self.name)
120    }
121}
122
123#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
124#[serde(tag = "type")]
125pub struct UnaryExpression {
126    pub op: Token,
127    pub operand: Box<Expression>,
128    pub span: Span,
129}
130
131#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
132#[serde(tag = "type")]
133pub struct BinaryExpression {
134    pub op: Token,
135    pub left: Box<Expression>,
136    pub right: Box<Expression>,
137    pub span: Span,
138}
139
140#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
141#[serde(tag = "type")]
142pub struct IF {
143    pub condition: Box<Expression>,
144    pub consequent: BlockStatement,
145    pub alternate: Option<BlockStatement>,
146    pub span: Span,
147}
148
149#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
150#[serde(tag = "type")]
151pub struct FunctionDeclaration {
152    pub params: Vec<IDENTIFIER>,
153    pub body: BlockStatement,
154    pub span: Span,
155    pub name: String,
156}
157
158// function can be Identifier or FunctionLiteral (think iife)
159#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
160#[serde(tag = "type")]
161pub struct FunctionCall {
162    pub callee: Box<Expression>,
163    pub arguments: Vec<Expression>,
164    pub span: Span,
165}
166
167#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
168#[serde(tag = "type")]
169pub struct Index {
170    pub object: Box<Expression>,
171    pub index: Box<Expression>,
172    pub span: Span,
173}
174
175impl fmt::Display for Expression {
176    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
177        match self {
178            Expression::IDENTIFIER(IDENTIFIER { name: id, .. }) => write!(f, "{}", id),
179            Expression::LITERAL(l) => write!(f, "{}", l),
180            Expression::PREFIX(UnaryExpression { op, operand: expr, .. }) => {
181                write!(f, "({}{})", op.kind, expr)
182            }
183            Expression::INFIX(BinaryExpression { op, left, right, .. }) => {
184                write!(f, "({} {} {})", left, op.kind, right)
185            }
186            Expression::IF(IF { condition, consequent, alternate, .. }) => {
187                if let Some(else_block) = alternate {
188                    write!(f, "if {} {{ {} }} else {{ {} }}", condition, consequent, else_block,)
189                } else {
190                    write!(f, "if {} {{ {} }}", condition, consequent,)
191                }
192            }
193            Expression::FUNCTION(FunctionDeclaration { name, params, body, .. }) => {
194                let func_params = params
195                    .iter()
196                    .map(|stmt| stmt.to_string())
197                    .collect::<Vec<String>>()
198                    .join(", ");
199                write!(f, "fn {}({}) {{ {} }}", name, func_params, body)
200            }
201            Expression::FunctionCall(FunctionCall { callee, arguments, .. }) => {
202                write!(f, "{}({})", callee, format_expressions(arguments))
203            }
204            Expression::Index(Index { object, index, .. }) => {
205                write!(f, "({}[{}])", object, index)
206            }
207        }
208    }
209}
210
211#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
212#[serde(tag = "type")]
213pub enum Literal {
214    Integer(Integer),
215    Boolean(Boolean),
216    String(StringType),
217    Array(Array),
218    Hash(Hash),
219}
220
221#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
222pub struct Integer {
223    pub raw: i64,
224    pub span: Span,
225}
226
227#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
228pub struct Boolean {
229    pub raw: bool,
230    pub span: Span,
231}
232
233#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
234pub struct StringType {
235    pub raw: String,
236    pub span: Span,
237}
238
239#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
240pub struct Array {
241    pub elements: Vec<Expression>,
242    pub span: Span,
243}
244
245#[derive(Clone, Debug, Eq, Serialize, Deserialize, Hash, PartialEq)]
246pub struct Hash {
247    pub elements: Vec<(Expression, Expression)>,
248    pub span: Span,
249}
250
251impl fmt::Display for Literal {
252    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
253        match self {
254            Literal::Integer(Integer { raw: i, .. }) => write!(f, "{}", i),
255            Literal::Boolean(Boolean { raw: b, .. }) => write!(f, "{}", b),
256            Literal::String(StringType { raw: s, .. }) => write!(f, "\"{}\"", s),
257            Literal::Array(Array { elements: e, .. }) => write!(f, "[{}]", format_expressions(e)),
258            Literal::Hash(Hash { elements: map, .. }) => {
259                let to_string = map
260                    .iter()
261                    .map(|(k, v)| format!("{}: {}", k, v))
262                    .collect::<Vec<String>>()
263                    .join(", ");
264
265                write!(f, "{{{}}}", to_string)
266            }
267        }
268    }
269}
270
271fn format_statements(statements: &Vec<Statement>) -> String {
272    return statements
273        .iter()
274        .map(|stmt| stmt.to_string())
275        .collect::<Vec<String>>()
276        .join("");
277}
278
279fn format_expressions(exprs: &Vec<Expression>) -> String {
280    return exprs
281        .iter()
282        .map(|stmt| stmt.to_string())
283        .collect::<Vec<String>>()
284        .join(", ");
285}