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