1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use serde_json::json;
use crate::{
ast::*,
prelude::*,
JSON,
};
pub trait ToESTree {
fn to_estree(&self) -> JSON;
}
impl ToESTree for JSON {
fn to_estree(&self) -> JSON {
self.clone() }
}
impl ToESTree for Program {
fn to_estree(&self) -> JSON {
let body: Vec<JSON> = self.body.body.iter().map(|stmt| stmt.to_estree()).collect();
json!({"type": "Program", "sourceType": "script", "body": body})
}
}
impl ToESTree for BlockStatement {
fn to_estree(&self) -> JSON {
let body: Vec<JSON> = self.body.iter().map(|stmt| stmt.to_estree()).collect();
json!({"type": "BlockStatement", "body": body})
}
}
impl ToESTree for VariableDeclaration {
fn to_estree(&self) -> JSON {
let declarations: Vec<JSON> = self
.declarations
.iter()
.map(|(name, maybe_init)| {
let jid = name.to_estree();
let jinit = match maybe_init.as_ref() {
Some(init) => init.to_estree(),
None => JSON::Null,
};
json!({"type": "VariableDeclarator", "id": jid, "init": jinit})
})
.collect();
let kind = self.kind.to_estree();
json!({"type": "VariableDeclaration", "kind": kind, "declarations": declarations })
}
}
impl ToESTree for DeclarationKind {
fn to_estree(&self) -> JSON {
JSON::from(match self {
DeclarationKind::Var => "var",
DeclarationKind::Let => "let",
DeclarationKind::Const => "const",
})
}
}
impl ToESTree for Statement {
fn to_estree(&self) -> JSON {
match &self.stmt {
Stmt::Empty => json!({"type": "EmptyStatement"}),
Stmt::Expr(stmt) => {
let jexpr = stmt.expression.to_estree();
json!({"type": "ExpressionStatement", "expression": jexpr})
}
Stmt::Variable(vardecl) => vardecl.to_estree(),
_ => todo!(),
}
}
}
impl ToESTree for Expression {
fn to_estree(&self) -> JSON {
match &self.expr {
Expr::Literal(lit) => lit.to_estree(),
Expr::Identifier(id) => id.to_estree(),
Expr::BinaryOp(binop) => {
let BinaryExpression(left, op, right) = binop.as_ref();
let left = left.to_estree();
let right = right.to_estree();
let op = op.to_estree();
json!({"type": "BinaryExpression", "left": left, "operator": op, "right": right})
}
_ => todo!(),
}
}
}
impl ToESTree for Literal {
fn to_estree(&self) -> JSON {
json!({"type": "Literal", "value": self.to_json()})
}
}
impl ToESTree for Identifier {
fn to_estree(&self) -> JSON {
json!({"type": "Identifier", "name": self.as_str()})
}
}
impl ToESTree for BinOp {
fn to_estree(&self) -> JSON {
JSON::from(match self {
BinOp::Plus => "+",
_ => todo!(),
})
}
}