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 span: Span,
206 },
207 For {
208 variable: Expr,
209 iterable: Expr,
210 body: Vec<Stmt>,
211 span: Span,
212 },
213 While {
214 condition: Expr,
215 body: Vec<Stmt>,
216 span: Span,
217 },
218 DoWhile {
219 condition: Expr,
220 body: Vec<Stmt>,
221 span: Span,
222 },
223 Switch {
224 value: Expr,
225 arms: Vec<SwitchArm>,
226 span: Span,
227 },
228 Delete {
229 target: Expr,
230 span: Span,
231 },
232 Break {
233 span: Span,
234 },
235 Return {
236 span: Span,
237 },
238 Continue {
239 span: Span,
240 },
241 Goto {
242 label: Option<String>,
243 offset: Option<Expr>,
244 rule_start: bool,
245 span: Span,
246 },
247 Label {
248 name: String,
249 span: Span,
250 },
251 Pass {
252 span: Span,
253 },
254}
255
256#[derive(Debug, Clone)]
258pub enum SwitchArm {
259 Case {
260 value: Expr,
261 body: Vec<Stmt>,
262 span: Span,
263 },
264 Default {
265 body: Vec<Stmt>,
266 span: Span,
267 },
268}
269
270#[derive(Debug, Clone)]
272pub struct IfBranch {
273 pub marker: Span,
275 pub condition: Expr,
276 pub body: Vec<Stmt>,
277}
278
279#[derive(Debug, Clone)]
284pub struct CallArg {
285 pub keyword: Option<(String, Span)>,
288 pub value: Expr,
290}
291
292#[derive(Debug, Clone)]
294pub enum Expr {
295 Number {
296 value: f64,
297 text: String,
298 span: Span,
299 },
300 String {
301 value: String,
302 span: Span,
303 },
304 Bool {
305 value: bool,
306 span: Span,
307 },
308 Null {
309 span: Span,
310 },
311 Array {
312 elements: Vec<Expr>,
313 span: Span,
314 },
315 Dict {
316 entries: Vec<DictEntry>,
317 span: Span,
318 },
319 Comprehension {
320 element: Box<Expr>,
321 variable: String,
322 variable_span: Span,
323 index: Option<(String, Span)>,
324 iterable: Box<Expr>,
325 condition: Option<Box<Expr>>,
326 span: Span,
327 },
328 Lambda {
329 params: Vec<(String, Span)>,
330 body: Box<Expr>,
331 parenthesized: bool,
337 span: Span,
338 },
339 StringModifier {
340 modifier: char,
341 value: String,
342 format_text: Option<String>,
345 interpolations: Vec<Expr>,
348 span: Span,
349 },
350 Call {
352 name: String,
353 args: Vec<CallArg>,
354 debug_source: Option<String>,
355 span: Span,
356 },
357 ReceiverCall {
359 receiver: Box<Expr>,
360 name: String,
361 args: Vec<CallArg>,
362 span: Span,
363 },
364 Name {
366 name: String,
367 span: Span,
368 },
369 Member {
371 receiver: Box<Expr>,
372 member: String,
373 member_span: Span,
375 span: Span,
376 },
377 Type {
380 name: String,
381 args: Vec<Expr>,
382 span: Span,
383 },
384 Index {
385 array: Box<Expr>,
386 index: Box<Expr>,
387 span: Span,
388 },
389 Binary {
390 op: String,
391 left: Box<Expr>,
392 right: Box<Expr>,
393 span: Span,
394 },
395 Conditional {
396 then_value: Box<Expr>,
397 condition: Box<Expr>,
398 else_value: Box<Expr>,
399 span: Span,
400 },
401 Unary {
402 op: String,
403 operand: Box<Expr>,
404 span: Span,
405 },
406}
407
408#[derive(Debug, Clone)]
410pub struct DictEntry {
411 pub key: Expr,
412 pub value: Expr,
413 pub span: Span,
414}
415
416impl Expr {
417 pub fn span(&self) -> Span {
419 match self {
420 Expr::Number { span, .. }
421 | Expr::String { span, .. }
422 | Expr::Bool { span, .. }
423 | Expr::Null { span }
424 | Expr::Array { span, .. }
425 | Expr::Dict { span, .. }
426 | Expr::Comprehension { span, .. }
427 | Expr::Lambda { span, .. }
428 | Expr::StringModifier { span, .. }
429 | Expr::Call { span, .. }
430 | Expr::ReceiverCall { span, .. }
431 | Expr::Name { span, .. }
432 | Expr::Member { span, .. }
433 | Expr::Type { span, .. }
434 | Expr::Index { span, .. }
435 | Expr::Binary { span, .. }
436 | Expr::Conditional { span, .. }
437 | Expr::Unary { span, .. } => *span,
438 }
439 }
440}
441
442impl Stmt {
443 pub fn span(&self) -> Span {
445 match self {
446 Stmt::Expr { span, .. }
447 | Stmt::Assign { span, .. }
448 | Stmt::If { span, .. }
449 | Stmt::For { span, .. }
450 | Stmt::While { span, .. }
451 | Stmt::DoWhile { span, .. }
452 | Stmt::Switch { span, .. }
453 | Stmt::Delete { span, .. }
454 | Stmt::Break { span }
455 | Stmt::Return { span }
456 | Stmt::Continue { span }
457 | Stmt::Goto { span, .. }
458 | Stmt::Label { span, .. }
459 | Stmt::Pass { span } => *span,
460 }
461 }
462}
463
464impl CallArg {
465 pub fn span(&self) -> Span {
468 match &self.keyword {
469 Some((_, name_span)) => {
470 let end = self.value.span().end;
471 Span::new(name_span.file, name_span.start, end)
472 }
473 None => self.value.span(),
474 }
475 }
476}