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,
78 pub span: Span,
79}
80
81#[derive(Debug, Clone)]
83pub enum Decl {
84 GlobalVariable {
85 name: String,
86 index: Option<u32>,
88 span: Span,
89 name_span: Span,
91 initializer: Option<Expr>,
92 },
93 PlayerVariable {
94 name: String,
95 index: Option<u32>,
96 span: Span,
97 name_span: Span,
99 initializer: Option<Expr>,
100 },
101 Subroutine {
102 name: String,
103 span: Span,
104 name_span: Span,
106 },
107 Enum {
109 name: String,
110 members: Vec<(String, Span)>,
111 span: Span,
112 },
113 Constant {
115 name: String,
116 value: Expr,
117 span: Span,
118 },
119 Macro {
121 name: String,
122 args: Vec<String>,
123 body: Vec<Stmt>,
124 span: Span,
125 },
126}
127
128#[derive(Debug, Clone)]
130pub enum RuleEntry {
131 Rule(Rule),
132 SubroutineDef {
133 name: String,
134 presentation_name: Option<String>,
135 span: Span,
136 name_span: Span,
138 body: Vec<Stmt>,
139 annotations: Vec<Annotation>,
140 rule_prefix: Option<String>,
141 },
142}
143
144#[derive(Debug, Clone)]
146pub struct Rule {
147 pub name: String,
148 pub span: Span,
149 pub name_span: Span,
151 pub disabled: bool,
152 pub delimiter: bool,
153 pub new_page: Option<String>,
154 pub annotations: Vec<Annotation>,
155 pub rule_prefix: Option<String>,
156 pub event: Event,
157 pub conditions: Vec<Expr>,
158 pub actions: Vec<Stmt>,
159}
160
161#[derive(Debug, Clone)]
163pub struct Annotation {
164 pub name: String,
165 pub args: Vec<AnnotationArg>,
166 pub span: Span,
167}
168
169#[derive(Debug, Clone)]
172pub struct AnnotationArg {
173 pub text: String,
174 pub span: Span,
175}
176
177#[derive(Debug, Clone)]
179pub struct Event {
180 pub name: String,
181 pub args: Vec<Expr>,
182 pub span: Span,
183}
184
185#[derive(Debug, Clone)]
187pub enum Stmt {
188 Expr {
189 expr: Expr,
190 span: Span,
191 },
192 Assign {
193 target: Expr,
194 value: Expr,
195 span: Span,
196 },
197 If {
198 branches: Vec<IfBranch>,
199 r#else: Option<Vec<Stmt>>,
200 else_span: Option<Span>,
202 end_span: Span,
205 orphan: bool,
209 span: Span,
210 },
211 For {
212 variable: Expr,
213 iterable: Expr,
214 body: Vec<Stmt>,
215 span: Span,
216 },
217 While {
218 condition: Expr,
219 body: Vec<Stmt>,
220 span: Span,
221 },
222 DoWhile {
223 condition: Expr,
224 body: Vec<Stmt>,
225 span: Span,
226 },
227 Switch {
228 value: Expr,
229 arms: Vec<SwitchArm>,
230 span: Span,
231 },
232 Delete {
233 target: Expr,
234 span: Span,
235 },
236 Break {
237 span: Span,
238 },
239 Return {
240 span: Span,
241 },
242 Continue {
243 span: Span,
244 },
245 Goto {
246 label: Option<String>,
247 offset: Option<Expr>,
248 rule_start: bool,
249 span: Span,
250 },
251 Label {
252 name: String,
253 span: Span,
254 },
255 Pass {
256 span: Span,
257 },
258}
259
260#[derive(Debug, Clone)]
262pub enum SwitchArm {
263 Case {
264 value: Expr,
265 body: Vec<Stmt>,
266 span: Span,
267 },
268 Default {
269 body: Vec<Stmt>,
270 span: Span,
271 },
272}
273
274#[derive(Debug, Clone)]
276pub struct IfBranch {
277 pub marker: Span,
279 pub condition: Expr,
280 pub body: Vec<Stmt>,
281}
282
283#[derive(Debug, Clone)]
288pub struct CallArg {
289 pub keyword: Option<(String, Span)>,
292 pub value: Expr,
294}
295
296#[derive(Debug, Clone)]
298pub enum Expr {
299 Number {
300 value: f64,
301 text: String,
302 span: Span,
303 },
304 String {
305 value: String,
306 span: Span,
307 },
308 Bool {
309 value: bool,
310 span: Span,
311 },
312 Null {
313 span: Span,
314 },
315 Array {
316 elements: Vec<Expr>,
317 span: Span,
318 },
319 Dict {
320 entries: Vec<DictEntry>,
321 span: Span,
322 },
323 Comprehension {
324 element: Box<Expr>,
325 variable: String,
326 variable_span: Span,
327 index: Option<(String, Span)>,
328 iterable: Box<Expr>,
329 condition: Option<Box<Expr>>,
330 span: Span,
331 },
332 Lambda {
333 params: Vec<(String, Span)>,
334 body: Box<Expr>,
335 parenthesized: bool,
341 span: Span,
342 },
343 StringModifier {
344 modifier: char,
345 value: String,
346 format_text: Option<String>,
349 interpolations: Vec<Expr>,
352 span: Span,
353 },
354 Call {
356 name: String,
357 args: Vec<CallArg>,
358 debug_source: Option<String>,
359 span: Span,
360 },
361 ReceiverCall {
363 receiver: Box<Expr>,
364 name: String,
365 args: Vec<CallArg>,
366 span: Span,
367 },
368 Name {
370 name: String,
371 span: Span,
372 },
373 Member {
375 receiver: Box<Expr>,
376 member: String,
377 member_span: Span,
379 span: Span,
380 },
381 Type {
384 name: String,
385 args: Vec<Expr>,
386 span: Span,
387 },
388 Index {
389 array: Box<Expr>,
390 index: Box<Expr>,
391 span: Span,
392 },
393 Binary {
394 op: String,
395 left: Box<Expr>,
396 right: Box<Expr>,
397 span: Span,
398 },
399 Conditional {
400 then_value: Box<Expr>,
401 condition: Box<Expr>,
402 else_value: Box<Expr>,
403 span: Span,
404 },
405 Unary {
406 op: String,
407 operand: Box<Expr>,
408 span: Span,
409 },
410}
411
412#[derive(Debug, Clone)]
414pub struct DictEntry {
415 pub key: Expr,
416 pub value: Expr,
417 pub span: Span,
418}
419
420impl Expr {
421 pub fn span(&self) -> Span {
423 match self {
424 Expr::Number { span, .. }
425 | Expr::String { span, .. }
426 | Expr::Bool { span, .. }
427 | Expr::Null { span }
428 | Expr::Array { span, .. }
429 | Expr::Dict { span, .. }
430 | Expr::Comprehension { span, .. }
431 | Expr::Lambda { span, .. }
432 | Expr::StringModifier { span, .. }
433 | Expr::Call { span, .. }
434 | Expr::ReceiverCall { span, .. }
435 | Expr::Name { span, .. }
436 | Expr::Member { span, .. }
437 | Expr::Type { span, .. }
438 | Expr::Index { span, .. }
439 | Expr::Binary { span, .. }
440 | Expr::Conditional { span, .. }
441 | Expr::Unary { span, .. } => *span,
442 }
443 }
444}
445
446impl Stmt {
447 pub fn span(&self) -> Span {
449 match self {
450 Stmt::Expr { span, .. }
451 | Stmt::Assign { span, .. }
452 | Stmt::If { span, .. }
453 | Stmt::For { span, .. }
454 | Stmt::While { span, .. }
455 | Stmt::DoWhile { span, .. }
456 | Stmt::Switch { span, .. }
457 | Stmt::Delete { span, .. }
458 | Stmt::Break { span }
459 | Stmt::Return { span }
460 | Stmt::Continue { span }
461 | Stmt::Goto { span, .. }
462 | Stmt::Label { span, .. }
463 | Stmt::Pass { span } => *span,
464 }
465 }
466}
467
468impl CallArg {
469 pub fn span(&self) -> Span {
472 match &self.keyword {
473 Some((_, name_span)) => {
474 let end = self.value.span().end;
475 Span::new(name_span.file, name_span.start, end)
476 }
477 None => self.value.span(),
478 }
479 }
480}