hexput_ast_api/
ast_structs.rs

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 = "CALLBACK_REFERENCE")]
208    CallbackReference {
209        name: String,
210        location: SourceLocation,
211    },
212    #[serde(rename = "ARRAY_EXPRESSION")]
213    ArrayExpression {
214        elements: Vec<Expression>,
215        location: SourceLocation,
216    },
217    #[serde(rename = "OBJECT_EXPRESSION")]
218    ObjectExpression {
219        properties: Vec<Property>,
220        location: SourceLocation,
221    },
222    #[serde(rename = "MEMBER_EXPRESSION")]
223    MemberExpression {
224        object: Box<Expression>,
225        #[serde(skip_serializing_if = "Option::is_none")]
226        property: Option<String>,
227        #[serde(skip_serializing_if = "Option::is_none")]
228        property_expr: Option<Box<Expression>>,
229        computed: bool,  
230        location: SourceLocation,
231    },
232    #[serde(rename = "KEYS_OF_EXPRESSION")]
233    KeysOfExpression {
234        object: Box<Expression>,
235        location: SourceLocation,
236    },
237    #[serde(rename = "BOOLEAN_LITERAL")]
238    BooleanLiteral {
239        value: bool,
240        location: SourceLocation,
241    },
242    #[serde(rename = "UNARY_EXPRESSION")]
243    UnaryExpression {
244        operator: UnaryOperator,
245        operand: Box<Expression>,
246        location: SourceLocation,
247    },
248    #[serde(rename = "NULL_LITERAL")]
249    NullLiteral {
250        location: SourceLocation,
251    },
252}
253
254#[derive(Debug, Clone, Serialize)]
255pub struct Property {
256    #[serde(rename = "type")]
257    pub node_type: String,
258    pub key: String,
259    pub value: Expression,
260    pub location: SourceLocation,
261}
262
263impl Property {
264    pub fn new(key: String, value: Expression, location: SourceLocation) -> Self {
265        Self {
266            node_type: "PROPERTY".to_string(),
267            key,
268            value,
269            location,
270        }
271    }
272}
273
274#[derive(Debug, Clone, PartialEq, Serialize)]
275pub enum Operator {
276    Equal,
277    NotEqual,
278    Plus,
279    Minus,
280    Multiply,
281    Divide,
282    Greater,
283    Less,
284    GreaterEqual,
285    LessEqual,
286    And,
287    Or,
288}
289
290#[derive(Debug, Clone, PartialEq, Serialize)]
291pub enum UnaryOperator {
292    Not,
293}
294