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 = "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