1use serde::Serialize;
2
3#[derive(Debug, Clone, Copy, Serialize)]
4pub struct SourceLocation {
5 pub start_line: usize,
6 pub start_column: usize,
7 pub end_line: usize,
8 pub end_column: usize,
9}
10
11impl SourceLocation {
12 pub fn new(start_line: usize, start_column: usize, end_line: usize, end_column: usize) -> Self {
13 Self {
14 start_line,
15 start_column,
16 end_line,
17 end_column,
18 }
19 }
20
21 pub fn from_spans(source_code: &str, start_offset: usize, end_offset: usize) -> Self {
22 let (start_line, start_column) = get_line_column(source_code, start_offset);
23 let (end_line, end_column) = get_line_column(source_code, end_offset);
24 Self::new(start_line, start_column, end_line, end_column)
25 }
26}
27
28
29fn get_line_column(source: &str, offset: usize) -> (usize, usize) {
30 let mut line = 1;
31 let mut column = 1;
32
33 for (i, ch) in source.chars().enumerate() {
34 if i >= offset {
35 break;
36 }
37
38 if ch == '\n' {
39 line += 1;
40 column = 1;
41 } else {
42 column += 1;
43 }
44 }
45
46 (line, column)
47}
48
49
50#[derive(Debug, Clone, Copy, Serialize)]
51pub struct Span {
52 pub start: usize,
53 pub end: usize,
54}
55
56#[derive(Debug, Clone, Serialize)]
57pub struct Program {
58 #[serde(rename = "type")]
59 pub node_type: String,
60 pub statements: Vec<Statement>,
61 pub location: SourceLocation,
62}
63
64impl Program {
65 pub fn new(statements: Vec<Statement>, location: SourceLocation) -> Self {
66 Self {
67 node_type: "PROGRAM".to_string(),
68 statements,
69 location,
70 }
71 }
72}
73
74#[derive(Debug, Clone, Serialize)]
75#[serde(tag = "type")]
76pub enum Statement {
77 #[serde(rename = "VARIABLE_DECLARATION")]
78 VariableDeclaration {
79 name: String,
80 value: Expression,
81 location: SourceLocation,
82 },
83 #[serde(rename = "EXPRESSION_STATEMENT")]
84 ExpressionStatement {
85 expression: Expression,
86 location: SourceLocation,
87 },
88 #[serde(rename = "IF_STATEMENT")]
89 IfStatement {
90 condition: Expression,
91 body: Block,
92 #[serde(skip_serializing_if = "Option::is_none")]
93 else_body: Option<Block>,
94 location: SourceLocation,
95 },
96 #[serde(rename = "BLOCK")]
97 Block {
98 block: Block,
99 location: SourceLocation,
100 },
101 #[serde(rename = "CALLBACK_DECLARATION")]
102 CallbackDeclaration {
103 name: String,
104 params: Vec<String>,
105 body: Block,
106 location: SourceLocation,
107 },
108 #[serde(rename = "RETURN_STATEMENT")]
109 ReturnStatement {
110 value: Expression,
111 location: SourceLocation,
112 },
113 #[serde(rename = "LOOP_STATEMENT")]
114 LoopStatement {
115 variable: String,
116 iterable: Expression,
117 body: Block,
118 location: SourceLocation,
119 },
120 #[serde(rename = "END_STATEMENT")]
121 EndStatement {
122 location: SourceLocation,
123 },
124 #[serde(rename = "CONTINUE_STATEMENT")]
125 ContinueStatement {
126 location: SourceLocation,
127 },
128}
129
130#[derive(Debug, Clone, Serialize)]
131pub struct Block {
132 #[serde(rename = "type")]
133 pub node_type: String,
134 pub statements: Vec<Statement>,
135 pub location: SourceLocation,
136}
137
138impl Block {
139 pub fn new(statements: Vec<Statement>, location: SourceLocation) -> Self {
140 Self {
141 node_type: "BLOCK".to_string(),
142 statements,
143 location,
144 }
145 }
146}
147
148#[derive(Debug, Clone, Serialize)]
149#[serde(tag = "type")]
150pub enum Expression {
151 #[serde(rename = "STRING_LITERAL")]
152 StringLiteral {
153 value: String,
154 location: SourceLocation,
155 },
156 #[serde(rename = "NUMBER_LITERAL")]
157 NumberLiteral {
158 value: f64,
159 location: SourceLocation,
160 },
161 #[serde(rename = "IDENTIFIER")]
162 Identifier {
163 name: String,
164 location: SourceLocation,
165 },
166 #[serde(rename = "BINARY_EXPRESSION")]
167 BinaryExpression {
168 left: Box<Expression>,
169 operator: Operator,
170 right: Box<Expression>,
171 location: SourceLocation,
172 },
173 #[serde(rename = "ASSIGNMENT_EXPRESSION")]
174 AssignmentExpression {
175 target: String,
176 value: Box<Expression>,
177 location: SourceLocation,
178 },
179 #[serde(rename = "MEMBER_ASSIGNMENT_EXPRESSION")]
180 MemberAssignmentExpression {
181 object: Box<Expression>,
182 #[serde(skip_serializing_if = "Option::is_none")]
183 property: Option<String>,
184 #[serde(skip_serializing_if = "Option::is_none")]
185 property_expr: Option<Box<Expression>>,
186 computed: bool,
187 value: Box<Expression>,
188 location: SourceLocation,
189 },
190 #[serde(rename = "CALL_EXPRESSION")]
191 CallExpression {
192 callee: String,
193 arguments: Vec<Expression>,
194 location: SourceLocation,
195 },
196 #[serde(rename = "MEMBER_CALL_EXPRESSION")]
197 MemberCallExpression {
198 object: Box<Expression>,
199 #[serde(skip_serializing_if = "Option::is_none")]
200 property: Option<String>,
201 #[serde(skip_serializing_if = "Option::is_none")]
202 property_expr: Option<Box<Expression>>,
203 computed: bool,
204 arguments: Vec<Expression>,
205 location: SourceLocation,
206 },
207 #[serde(rename = "INLINE_CALLBACK_EXPRESSION")]
208 InlineCallbackExpression {
209 name: String,
210 params: Vec<String>,
211 body: Block,
212 location: SourceLocation,
213 },
214 #[serde(rename = "ARRAY_EXPRESSION")]
215 ArrayExpression {
216 elements: Vec<Expression>,
217 location: SourceLocation,
218 },
219 #[serde(rename = "OBJECT_EXPRESSION")]
220 ObjectExpression {
221 properties: Vec<Property>,
222 location: SourceLocation,
223 },
224 #[serde(rename = "MEMBER_EXPRESSION")]
225 MemberExpression {
226 object: Box<Expression>,
227 #[serde(skip_serializing_if = "Option::is_none")]
228 property: Option<String>,
229 #[serde(skip_serializing_if = "Option::is_none")]
230 property_expr: Option<Box<Expression>>,
231 computed: bool,
232 location: SourceLocation,
233 },
234 #[serde(rename = "KEYS_OF_EXPRESSION")]
235 KeysOfExpression {
236 object: Box<Expression>,
237 location: SourceLocation,
238 },
239 #[serde(rename = "BOOLEAN_LITERAL")]
240 BooleanLiteral {
241 value: bool,
242 location: SourceLocation,
243 },
244 #[serde(rename = "UNARY_EXPRESSION")]
245 UnaryExpression {
246 operator: UnaryOperator,
247 operand: Box<Expression>,
248 location: SourceLocation,
249 },
250 #[serde(rename = "NULL_LITERAL")]
251 NullLiteral {
252 location: SourceLocation,
253 },
254}
255
256#[derive(Debug, Clone, Serialize)]
257pub struct Property {
258 #[serde(rename = "type")]
259 pub node_type: String,
260 pub key: String,
261 pub value: Expression,
262 pub location: SourceLocation,
263}
264
265impl Property {
266 pub fn new(key: String, value: Expression, location: SourceLocation) -> Self {
267 Self {
268 node_type: "PROPERTY".to_string(),
269 key,
270 value,
271 location,
272 }
273 }
274}
275
276#[derive(Debug, Clone, PartialEq, Serialize)]
277pub enum Operator {
278 Equal,
279 NotEqual,
280 Plus,
281 Minus,
282 Multiply,
283 Divide,
284 Greater,
285 Less,
286 GreaterEqual,
287 LessEqual,
288 And,
289 Or,
290}
291
292#[derive(Debug, Clone, PartialEq, Serialize)]
293pub enum UnaryOperator {
294 Not,
295}
296