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 List {
62 name: String,
63 elements: Vec<SettingsListElement>,
64 span: Span,
65 },
66}
67
68#[derive(Debug, Clone)]
70pub struct SettingsListElement {
71 pub value: String,
72 pub span: Span,
73}
74
75#[derive(Debug, Clone)]
77pub enum Decl {
78 GlobalVariable {
79 name: String,
80 index: Option<u32>,
82 span: Span,
83 name_span: Span,
85 initializer: Option<Expr>,
86 },
87 PlayerVariable {
88 name: String,
89 index: Option<u32>,
90 span: Span,
91 name_span: Span,
93 initializer: Option<Expr>,
94 },
95 Subroutine {
96 name: String,
97 span: Span,
98 name_span: Span,
100 },
101 Enum {
103 name: String,
104 members: Vec<(String, Span)>,
105 span: Span,
106 },
107 Macro {
109 name: String,
110 args: Vec<String>,
111 body: Vec<Stmt>,
112 span: Span,
113 },
114}
115
116#[derive(Debug, Clone)]
118pub enum RuleEntry {
119 Rule(Rule),
120 SubroutineDef {
121 name: String,
122 presentation_name: Option<String>,
123 span: Span,
124 name_span: Span,
126 body: Vec<Stmt>,
127 annotations: Vec<Annotation>,
128 rule_prefix: Option<String>,
129 },
130}
131
132#[derive(Debug, Clone)]
134pub struct Rule {
135 pub name: String,
136 pub span: Span,
137 pub name_span: Span,
139 pub disabled: bool,
140 pub delimiter: bool,
141 pub new_page: Option<String>,
142 pub annotations: Vec<Annotation>,
143 pub rule_prefix: Option<String>,
144 pub event: Event,
145 pub conditions: Vec<Expr>,
146 pub actions: Vec<Stmt>,
147}
148
149#[derive(Debug, Clone)]
151pub struct Annotation {
152 pub name: String,
153 pub args: Vec<AnnotationArg>,
154 pub span: Span,
155}
156
157#[derive(Debug, Clone)]
160pub struct AnnotationArg {
161 pub text: String,
162 pub span: Span,
163}
164
165#[derive(Debug, Clone)]
167pub struct Event {
168 pub name: String,
169 pub args: Vec<Expr>,
170 pub span: Span,
171}
172
173#[derive(Debug, Clone)]
175pub enum Stmt {
176 Expr {
177 expr: Expr,
178 span: Span,
179 },
180 Assign {
181 target: Expr,
182 value: Expr,
183 span: Span,
184 },
185 If {
186 branches: Vec<IfBranch>,
187 r#else: Option<Vec<Stmt>>,
188 span: Span,
189 },
190 For {
191 variable: Expr,
192 iterable: Expr,
193 body: Vec<Stmt>,
194 span: Span,
195 },
196 While {
197 condition: Expr,
198 body: Vec<Stmt>,
199 span: Span,
200 },
201 DoWhile {
202 condition: Expr,
203 body: Vec<Stmt>,
204 span: Span,
205 },
206 Switch {
207 value: Expr,
208 arms: Vec<SwitchArm>,
209 span: Span,
210 },
211 Delete {
212 target: Expr,
213 span: Span,
214 },
215 Break {
216 span: Span,
217 },
218 Return {
219 span: Span,
220 },
221 Continue {
222 span: Span,
223 },
224 Goto {
225 label: Option<String>,
226 offset: Option<Expr>,
227 rule_start: bool,
228 span: Span,
229 },
230 Label {
231 name: String,
232 span: Span,
233 },
234 Pass {
235 span: Span,
236 },
237}
238
239#[derive(Debug, Clone)]
241pub enum SwitchArm {
242 Case {
243 value: Expr,
244 body: Vec<Stmt>,
245 span: Span,
246 },
247 Default {
248 body: Vec<Stmt>,
249 span: Span,
250 },
251}
252
253#[derive(Debug, Clone)]
255pub struct IfBranch {
256 pub condition: Expr,
257 pub body: Vec<Stmt>,
258}
259
260#[derive(Debug, Clone)]
265pub struct CallArg {
266 pub keyword: Option<(String, Span)>,
269 pub value: Expr,
271}
272
273#[derive(Debug, Clone)]
275pub enum Expr {
276 Number {
277 value: f64,
278 text: String,
279 span: Span,
280 },
281 String {
282 value: String,
283 span: Span,
284 },
285 Bool {
286 value: bool,
287 span: Span,
288 },
289 Null {
290 span: Span,
291 },
292 Array {
293 elements: Vec<Expr>,
294 span: Span,
295 },
296 Dict {
297 entries: Vec<DictEntry>,
298 span: Span,
299 },
300 Comprehension {
301 element: Box<Expr>,
302 variable: String,
303 variable_span: Span,
304 index: Option<(String, Span)>,
305 iterable: Box<Expr>,
306 condition: Option<Box<Expr>>,
307 span: Span,
308 },
309 Lambda {
310 params: Vec<(String, Span)>,
311 body: Box<Expr>,
312 span: Span,
313 },
314 StringModifier {
315 modifier: char,
316 value: String,
317 format_text: Option<String>,
320 interpolations: Vec<Expr>,
323 span: Span,
324 },
325 Call {
327 name: String,
328 args: Vec<CallArg>,
329 span: Span,
330 },
331 ReceiverCall {
333 receiver: Box<Expr>,
334 name: String,
335 args: Vec<CallArg>,
336 span: Span,
337 },
338 Name {
340 name: String,
341 span: Span,
342 },
343 Member {
345 receiver: Box<Expr>,
346 member: String,
347 member_span: Span,
349 span: Span,
350 },
351 Type {
354 name: String,
355 args: Vec<Expr>,
356 span: Span,
357 },
358 Index {
359 array: Box<Expr>,
360 index: Box<Expr>,
361 span: Span,
362 },
363 Binary {
364 op: String,
365 left: Box<Expr>,
366 right: Box<Expr>,
367 span: Span,
368 },
369 Conditional {
370 then_value: Box<Expr>,
371 condition: Box<Expr>,
372 else_value: Box<Expr>,
373 span: Span,
374 },
375 Unary {
376 op: String,
377 operand: Box<Expr>,
378 span: Span,
379 },
380}
381
382#[derive(Debug, Clone)]
384pub struct DictEntry {
385 pub key: Expr,
386 pub value: Expr,
387 pub span: Span,
388}
389
390impl Expr {
391 pub fn span(&self) -> Span {
393 match self {
394 Expr::Number { span, .. }
395 | Expr::String { span, .. }
396 | Expr::Bool { span, .. }
397 | Expr::Null { span }
398 | Expr::Array { span, .. }
399 | Expr::Dict { span, .. }
400 | Expr::Comprehension { span, .. }
401 | Expr::Lambda { span, .. }
402 | Expr::StringModifier { span, .. }
403 | Expr::Call { span, .. }
404 | Expr::ReceiverCall { span, .. }
405 | Expr::Name { span, .. }
406 | Expr::Member { span, .. }
407 | Expr::Type { span, .. }
408 | Expr::Index { span, .. }
409 | Expr::Binary { span, .. }
410 | Expr::Conditional { span, .. }
411 | Expr::Unary { span, .. } => *span,
412 }
413 }
414}
415
416impl Stmt {
417 pub fn span(&self) -> Span {
419 match self {
420 Stmt::Expr { span, .. }
421 | Stmt::Assign { span, .. }
422 | Stmt::If { span, .. }
423 | Stmt::For { span, .. }
424 | Stmt::While { span, .. }
425 | Stmt::DoWhile { span, .. }
426 | Stmt::Switch { span, .. }
427 | Stmt::Delete { span, .. }
428 | Stmt::Break { span }
429 | Stmt::Return { span }
430 | Stmt::Continue { span }
431 | Stmt::Goto { span, .. }
432 | Stmt::Label { span, .. }
433 | Stmt::Pass { span } => *span,
434 }
435 }
436}
437
438impl CallArg {
439 pub fn span(&self) -> Span {
442 match &self.keyword {
443 Some((_, name_span)) => {
444 let end = self.value.span().end;
445 Span::new(name_span.file, name_span.start, end)
446 }
447 None => self.value.span(),
448 }
449 }
450}