1use xdl_core::XdlValue;
4#[derive(Debug, Clone, PartialEq)]
6pub struct Location {
7 pub line: usize,
8 pub column: usize,
9 pub filename: Option<String>,
10}
11
12#[derive(Debug, Clone, PartialEq)]
14pub struct Program {
15 pub statements: Vec<Statement>,
16 pub location: Location,
17}
18
19#[derive(Debug, Clone, PartialEq)]
21pub enum Statement {
22 Assignment {
23 target: Expression,
24 value: Expression,
25 location: Location,
26 },
27 Expression {
28 expr: Expression,
29 location: Location,
30 },
31 If {
32 condition: Expression,
33 then_block: Vec<Statement>,
34 else_block: Option<Vec<Statement>>,
35 location: Location,
36 },
37 For {
38 variable: String,
39 start: Expression,
40 end: Expression,
41 step: Option<Expression>,
42 body: Vec<Statement>,
43 location: Location,
44 },
45 Foreach {
46 variable: String,
47 iterable: Expression,
48 index_var: Option<String>,
49 body: Vec<Statement>,
50 location: Location,
51 },
52 While {
53 condition: Expression,
54 body: Vec<Statement>,
55 location: Location,
56 },
57 Repeat {
58 body: Vec<Statement>,
59 condition: Expression,
60 location: Location,
61 },
62 Break {
63 location: Location,
64 },
65 Continue {
66 location: Location,
67 },
68 Return {
69 value: Option<Expression>,
70 location: Location,
71 },
72 ProcedureCall {
73 name: String,
74 args: Vec<Expression>,
75 keywords: Vec<Keyword>,
76 location: Location,
77 },
78 Common {
79 name: String,
80 variables: Vec<String>,
81 location: Location,
82 },
83 CompileOpt {
84 options: Vec<String>,
85 location: Location,
86 },
87 FunctionDef {
88 name: String,
89 params: Vec<Parameter>,
90 keywords: Vec<KeywordDecl>,
91 body: Vec<Statement>,
92 location: Location,
93 },
94 ProcedureDef {
95 name: String,
96 params: Vec<Parameter>,
97 keywords: Vec<KeywordDecl>,
98 body: Vec<Statement>,
99 location: Location,
100 },
101 Label {
102 name: String,
103 location: Location,
104 },
105 Goto {
106 label: String,
107 location: Location,
108 },
109 Case {
110 expr: Expression,
111 branches: Vec<CaseBranch>,
112 else_block: Option<Vec<Statement>>,
113 location: Location,
114 },
115 Switch {
116 expr: Expression,
117 branches: Vec<CaseBranch>,
118 else_block: Option<Vec<Statement>>,
119 location: Location,
120 },
121 ClassDefinition {
123 name: String,
124 body: Vec<Statement>,
125 location: Location,
126 },
127 MethodDefinition {
128 class_name: String,
129 method_name: String,
130 is_function: bool, params: Vec<Parameter>,
132 keywords: Vec<KeywordDecl>,
133 body: Vec<Statement>,
134 location: Location,
135 },
136 ObjectDestroy {
137 objects: Vec<Expression>,
138 location: Location,
139 },
140}
141
142#[derive(Debug, Clone, PartialEq)]
144pub enum Expression {
145 Literal {
146 value: XdlValue,
147 location: Location,
148 },
149 Variable {
150 name: String,
151 location: Location,
152 },
153 SystemVariable {
154 name: String,
155 location: Location,
156 },
157 ArrayRef {
158 array: Box<Expression>,
159 indices: Vec<ArrayIndex>,
160 location: Location,
161 },
162 StructRef {
163 object: Box<Expression>,
164 field: String,
165 location: Location,
166 },
167 MethodCall {
168 object: Box<Expression>,
169 method: String,
170 args: Vec<Expression>,
171 keywords: Vec<Keyword>,
172 location: Location,
173 },
174 FunctionCall {
175 name: String,
176 args: Vec<Expression>,
177 keywords: Vec<Keyword>,
178 location: Location,
179 },
180 Binary {
181 op: BinaryOp,
182 left: Box<Expression>,
183 right: Box<Expression>,
184 location: Location,
185 },
186 Unary {
187 op: UnaryOp,
188 expr: Box<Expression>,
189 location: Location,
190 },
191 Ternary {
192 condition: Box<Expression>,
193 if_true: Box<Expression>,
194 if_false: Box<Expression>,
195 location: Location,
196 },
197 ArrayDef {
198 elements: Vec<Expression>,
199 location: Location,
200 },
201 StructDef {
202 name: Option<String>,
203 fields: Vec<StructField>,
204 location: Location,
205 },
206 Pointer {
207 expr: Box<Expression>,
208 location: Location,
209 },
210 Deref {
211 expr: Box<Expression>,
212 location: Location,
213 },
214 PostIncrement {
215 expr: Box<Expression>,
216 location: Location,
217 },
218 PostDecrement {
219 expr: Box<Expression>,
220 location: Location,
221 },
222 PreIncrement {
223 expr: Box<Expression>,
224 location: Location,
225 },
226 PreDecrement {
227 expr: Box<Expression>,
228 location: Location,
229 },
230 ObjectNew {
232 class_name: String,
233 args: Vec<Expression>,
234 keywords: Vec<Keyword>,
235 location: Location,
236 },
237}
238
239#[derive(Debug, Clone, PartialEq)]
241pub enum ArrayIndex {
242 Single(Box<Expression>),
243 Range {
244 start: Option<Box<Expression>>,
245 end: Option<Box<Expression>>,
246 step: Option<Box<Expression>>,
247 },
248 All, }
250
251#[derive(Debug, Clone, Copy, PartialEq, Eq)]
253pub enum BinaryOp {
254 Add,
256 Subtract,
257 Multiply,
258 Divide,
259 Modulo,
260 Power,
261 MatrixMultiply,
262
263 And,
265 Or,
266 Xor,
267
268 BitwiseAnd,
270 BitwiseOr,
271 BitwiseXor,
272 LeftShift,
273 RightShift,
274
275 Equal,
277 NotEqual,
278 Less,
279 LessEqual,
280 Greater,
281 GreaterEqual,
282
283 Concatenate,
285
286 Assign,
288 PlusAssign,
289 MinusAssign,
290 MultiplyAssign,
291 DivideAssign,
292 ModuloAssign,
293 PowerAssign,
294 AndAssign,
295 OrAssign,
296 XorAssign,
297}
298
299#[derive(Debug, Clone, Copy, PartialEq, Eq)]
301pub enum UnaryOp {
302 Plus,
303 Minus,
304 Not,
305 BitwiseNot,
306}
307
308#[derive(Debug, Clone, PartialEq)]
310pub struct Parameter {
311 pub name: String,
312 pub by_reference: bool,
313 pub optional: bool,
314 pub location: Location,
315}
316
317#[derive(Debug, Clone, PartialEq)]
319pub struct KeywordDecl {
320 pub name: String,
321 pub by_reference: bool,
322 pub location: Location,
323}
324
325#[derive(Debug, Clone, PartialEq)]
327pub struct Keyword {
328 pub name: String,
329 pub value: Option<Expression>,
330 pub location: Location,
331}
332
333#[derive(Debug, Clone, PartialEq)]
335pub struct CaseBranch {
336 pub values: Vec<Expression>, pub body: Vec<Statement>,
338 pub location: Location,
339}
340
341#[derive(Debug, Clone, PartialEq)]
343pub struct StructField {
344 pub name: String,
345 pub value: Expression,
346 pub location: Location,
347}
348
349impl Location {
350 pub fn new(line: usize, column: usize) -> Self {
351 Self {
352 line,
353 column,
354 filename: None,
355 }
356 }
357
358 pub fn with_file(line: usize, column: usize, filename: String) -> Self {
359 Self {
360 line,
361 column,
362 filename: Some(filename),
363 }
364 }
365
366 pub fn unknown() -> Self {
367 Self {
368 line: 0,
369 column: 0,
370 filename: None,
371 }
372 }
373}
374
375impl Statement {
376 pub fn location(&self) -> &Location {
378 match self {
379 Statement::Assignment { location, .. } => location,
380 Statement::Expression { location, .. } => location,
381 Statement::If { location, .. } => location,
382 Statement::For { location, .. } => location,
383 Statement::Foreach { location, .. } => location,
384 Statement::While { location, .. } => location,
385 Statement::Repeat { location, .. } => location,
386 Statement::Break { location } => location,
387 Statement::Continue { location } => location,
388 Statement::Return { location, .. } => location,
389 Statement::ProcedureCall { location, .. } => location,
390 Statement::Common { location, .. } => location,
391 Statement::CompileOpt { location, .. } => location,
392 Statement::FunctionDef { location, .. } => location,
393 Statement::ProcedureDef { location, .. } => location,
394 Statement::Label { location, .. } => location,
395 Statement::Goto { location, .. } => location,
396 Statement::Case { location, .. } => location,
397 Statement::Switch { location, .. } => location,
398 Statement::ClassDefinition { location, .. } => location,
399 Statement::MethodDefinition { location, .. } => location,
400 Statement::ObjectDestroy { location, .. } => location,
401 }
402 }
403}
404
405impl Expression {
406 pub fn location(&self) -> &Location {
408 match self {
409 Expression::Literal { location, .. } => location,
410 Expression::Variable { location, .. } => location,
411 Expression::SystemVariable { location, .. } => location,
412 Expression::ArrayRef { location, .. } => location,
413 Expression::StructRef { location, .. } => location,
414 Expression::MethodCall { location, .. } => location,
415 Expression::FunctionCall { location, .. } => location,
416 Expression::Binary { location, .. } => location,
417 Expression::Unary { location, .. } => location,
418 Expression::Ternary { location, .. } => location,
419 Expression::ArrayDef { location, .. } => location,
420 Expression::StructDef { location, .. } => location,
421 Expression::Pointer { location, .. } => location,
422 Expression::Deref { location, .. } => location,
423 Expression::PostIncrement { location, .. } => location,
424 Expression::PostDecrement { location, .. } => location,
425 Expression::PreIncrement { location, .. } => location,
426 Expression::PreDecrement { location, .. } => location,
427 Expression::ObjectNew { location, .. } => location,
428 }
429 }
430
431 pub fn is_constant(&self) -> bool {
433 matches!(self, Expression::Literal { .. })
434 }
435
436 pub fn is_variable(&self) -> bool {
438 matches!(self, Expression::Variable { .. })
439 }
440}