1use crate::diag::Span;
10
11#[derive(Debug, Clone)]
13pub struct Program {
14 pub declarations: Vec<Decl>,
15 pub rules: Vec<RuleEntry>,
16 pub top_level: Vec<TopLevel>,
20 pub settings: Option<Settings>,
22}
23
24#[derive(Debug, Clone)]
26pub enum TopLevel {
27 Declaration(Decl),
28 Rule(RuleEntry),
29}
30
31#[derive(Debug, Clone)]
33pub struct Settings {
34 pub span: Span,
35 pub children: Vec<SettingsNode>,
36}
37
38#[derive(Debug, Clone)]
40pub enum SettingsNode {
41 Group {
42 name: String,
43 children: Vec<SettingsNode>,
44 span: Span,
45 },
46 Number {
47 name: String,
48 value: f64,
49 span: Span,
50 },
51 Bool {
52 name: String,
53 value: bool,
54 span: Span,
55 },
56 String {
57 name: String,
58 value: String,
59 span: Span,
60 },
61 Raw {
63 name: String,
64 value: String,
65 span: Span,
66 },
67 List {
68 name: String,
69 elements: Vec<SettingsListElement>,
70 span: Span,
71 },
72}
73
74#[derive(Debug, Clone)]
76pub struct SettingsListElement {
77 pub value: String,
81 pub expr: bool,
83 pub span: Span,
84}
85
86#[derive(Debug, Clone)]
88pub enum Decl {
89 GlobalVariable {
90 name: String,
91 index: Option<u32>,
93 span: Span,
94 name_span: Span,
96 initializer: Option<Expr>,
97 },
98 PlayerVariable {
99 name: String,
100 index: Option<u32>,
101 span: Span,
102 name_span: Span,
104 initializer: Option<Expr>,
105 },
106 Subroutine {
107 name: String,
108 span: Span,
109 name_span: Span,
111 },
112 Enum {
114 name: String,
115 members: Vec<(String, Span)>,
116 span: Span,
117 },
118 Constant {
120 name: String,
121 value: Expr,
122 span: Span,
123 },
124 Macro {
126 name: String,
127 args: Vec<String>,
128 body: Vec<Stmt>,
129 span: Span,
130 },
131}
132
133#[derive(Debug, Clone)]
135pub enum RuleEntry {
136 Rule(Rule),
137 SubroutineDef {
138 name: String,
139 presentation_name: Option<String>,
140 span: Span,
141 name_span: Span,
143 body: Vec<Stmt>,
144 annotations: Vec<Annotation>,
145 rule_prefix: Option<String>,
146 },
147}
148
149#[derive(Debug, Clone)]
151pub struct Rule {
152 pub name: String,
153 pub span: Span,
154 pub name_span: Span,
156 pub disabled: bool,
157 pub delimiter: bool,
158 pub new_page: Option<String>,
159 pub annotations: Vec<Annotation>,
160 pub rule_prefix: Option<String>,
161 pub event: Event,
162 pub conditions: Vec<Expr>,
163 pub actions: Vec<Stmt>,
164}
165
166#[derive(Debug, Clone)]
168pub struct Annotation {
169 pub name: String,
170 pub args: Vec<AnnotationArg>,
171 pub span: Span,
172}
173
174#[derive(Debug, Clone)]
177pub struct AnnotationArg {
178 pub text: String,
179 pub span: Span,
180}
181
182#[derive(Debug, Clone)]
184pub struct Event {
185 pub name: String,
186 pub args: Vec<Expr>,
187 pub span: Span,
188}
189
190#[derive(Debug, Clone)]
192pub enum Stmt {
193 Expr {
194 expr: Expr,
195 span: Span,
196 },
197 Assign {
198 target: Expr,
199 value: Expr,
200 span: Span,
201 },
202 If {
203 branches: Vec<IfBranch>,
204 r#else: Option<Vec<Stmt>>,
205 else_span: Option<Span>,
207 end_span: Span,
210 orphan: bool,
214 span: Span,
215 },
216 For {
217 variable: Expr,
218 iterable: Expr,
219 body: Vec<Stmt>,
220 span: Span,
221 },
222 While {
223 condition: Expr,
224 body: Vec<Stmt>,
225 span: Span,
226 },
227 DoWhile {
228 condition: Expr,
229 body: Vec<Stmt>,
230 span: Span,
231 },
232 Switch {
233 value: Expr,
234 arms: Vec<SwitchArm>,
235 span: Span,
236 },
237 Delete {
238 target: Expr,
239 span: Span,
240 },
241 Break {
242 span: Span,
243 },
244 Return {
245 span: Span,
246 },
247 Continue {
248 span: Span,
249 },
250 Goto {
251 label: Option<String>,
252 offset: Option<Expr>,
253 rule_start: bool,
254 span: Span,
255 },
256 Label {
257 name: String,
258 span: Span,
259 },
260 Pass {
261 span: Span,
262 },
263}
264
265#[derive(Debug, Clone)]
267pub enum SwitchArm {
268 Case {
269 value: Expr,
270 body: Vec<Stmt>,
271 span: Span,
272 },
273 Default {
274 body: Vec<Stmt>,
275 span: Span,
276 },
277}
278
279#[derive(Debug, Clone)]
281pub struct IfBranch {
282 pub marker: Span,
284 pub condition: Expr,
285 pub body: Vec<Stmt>,
286}
287
288#[derive(Debug, Clone)]
293pub struct CallArg {
294 pub keyword: Option<(String, Span)>,
297 pub value: Expr,
299}
300
301#[derive(Debug, Clone)]
303pub enum Expr {
304 Number {
305 value: f64,
306 text: String,
307 span: Span,
308 },
309 String {
310 value: String,
311 span: Span,
312 },
313 Bool {
314 value: bool,
315 span: Span,
316 },
317 Null {
318 span: Span,
319 },
320 Array {
321 elements: Vec<Expr>,
322 span: Span,
323 },
324 Dict {
325 entries: Vec<DictEntry>,
326 span: Span,
327 },
328 Comprehension {
329 element: Box<Expr>,
330 variable: String,
331 variable_span: Span,
332 index: Option<(String, Span)>,
333 iterable: Box<Expr>,
334 condition: Option<Box<Expr>>,
335 span: Span,
336 },
337 Lambda {
338 params: Vec<(String, Span)>,
339 body: Box<Expr>,
340 parenthesized: bool,
346 span: Span,
347 },
348 StringModifier {
349 modifier: char,
350 value: String,
351 format_text: Option<String>,
354 interpolations: Vec<Expr>,
357 span: Span,
358 },
359 Call {
361 name: String,
362 args: Vec<CallArg>,
363 debug_source: Option<String>,
364 span: Span,
365 },
366 ReceiverCall {
368 receiver: Box<Expr>,
369 name: String,
370 args: Vec<CallArg>,
371 span: Span,
372 },
373 Name {
375 name: String,
376 span: Span,
377 },
378 Member {
380 receiver: Box<Expr>,
381 member: String,
382 member_span: Span,
384 span: Span,
385 },
386 Type {
389 name: String,
390 args: Vec<Expr>,
391 span: Span,
392 },
393 Index {
394 array: Box<Expr>,
395 index: Box<Expr>,
396 span: Span,
397 },
398 Binary {
399 op: String,
400 left: Box<Expr>,
401 right: Box<Expr>,
402 span: Span,
403 },
404 Conditional {
405 then_value: Box<Expr>,
406 condition: Box<Expr>,
407 else_value: Box<Expr>,
408 span: Span,
409 },
410 Unary {
411 op: String,
412 operand: Box<Expr>,
413 span: Span,
414 },
415}
416
417#[derive(Debug, Clone)]
419pub struct DictEntry {
420 pub key: Expr,
421 pub value: Expr,
422 pub span: Span,
423}
424
425impl Expr {
426 pub fn span(&self) -> Span {
428 match self {
429 Expr::Number { span, .. }
430 | Expr::String { span, .. }
431 | Expr::Bool { span, .. }
432 | Expr::Null { span }
433 | Expr::Array { span, .. }
434 | Expr::Dict { span, .. }
435 | Expr::Comprehension { span, .. }
436 | Expr::Lambda { span, .. }
437 | Expr::StringModifier { span, .. }
438 | Expr::Call { span, .. }
439 | Expr::ReceiverCall { span, .. }
440 | Expr::Name { span, .. }
441 | Expr::Member { span, .. }
442 | Expr::Type { span, .. }
443 | Expr::Index { span, .. }
444 | Expr::Binary { span, .. }
445 | Expr::Conditional { span, .. }
446 | Expr::Unary { span, .. } => *span,
447 }
448 }
449}
450
451impl Stmt {
452 pub fn span(&self) -> Span {
454 match self {
455 Stmt::Expr { span, .. }
456 | Stmt::Assign { span, .. }
457 | Stmt::If { span, .. }
458 | Stmt::For { span, .. }
459 | Stmt::While { span, .. }
460 | Stmt::DoWhile { span, .. }
461 | Stmt::Switch { span, .. }
462 | Stmt::Delete { span, .. }
463 | Stmt::Break { span }
464 | Stmt::Return { span }
465 | Stmt::Continue { span }
466 | Stmt::Goto { span, .. }
467 | Stmt::Label { span, .. }
468 | Stmt::Pass { span } => *span,
469 }
470 }
471}
472
473impl CallArg {
474 pub fn span(&self) -> Span {
477 match &self.keyword {
478 Some((_, name_span)) => {
479 let end = self.value.span().end;
480 Span::new(name_span.file, name_span.start, end)
481 }
482 None => self.value.span(),
483 }
484 }
485}