1use crate::diag::Span;
10
11#[derive(Debug, Clone)]
13pub struct Program {
14 pub declarations: Vec<Decl>,
15 pub rules: Vec<RuleEntry>,
16 pub settings: Option<Settings>,
18}
19
20#[derive(Debug, Clone)]
22pub struct Settings {
23 pub span: Span,
24 pub children: Vec<SettingsNode>,
25}
26
27#[derive(Debug, Clone)]
29pub enum SettingsNode {
30 Group {
31 name: String,
32 children: Vec<SettingsNode>,
33 span: Span,
34 },
35 Number {
36 name: String,
37 value: f64,
38 span: Span,
39 },
40 Bool {
41 name: String,
42 value: bool,
43 span: Span,
44 },
45 String {
46 name: String,
47 value: String,
48 span: Span,
49 },
50 List {
51 name: String,
52 elements: Vec<SettingsListElement>,
53 span: Span,
54 },
55}
56
57#[derive(Debug, Clone)]
59pub struct SettingsListElement {
60 pub value: String,
61 pub span: Span,
62}
63
64#[derive(Debug, Clone)]
66pub enum Decl {
67 GlobalVariable {
68 name: String,
69 index: Option<u32>,
71 span: Span,
72 name_span: Span,
74 initializer: Option<Expr>,
75 },
76 PlayerVariable {
77 name: String,
78 index: Option<u32>,
79 span: Span,
80 name_span: Span,
82 initializer: Option<Expr>,
83 },
84 Subroutine {
85 name: String,
86 span: Span,
87 name_span: Span,
89 },
90 Enum {
92 name: String,
93 members: Vec<(String, Span)>,
94 span: Span,
95 },
96 Macro {
98 name: String,
99 args: Vec<String>,
100 body: Vec<Stmt>,
101 span: Span,
102 },
103}
104
105#[derive(Debug, Clone)]
107pub enum RuleEntry {
108 Rule(Rule),
109 SubroutineDef {
110 name: String,
111 presentation_name: Option<String>,
112 span: Span,
113 name_span: Span,
115 body: Vec<Stmt>,
116 annotations: Vec<Annotation>,
117 rule_prefix: Option<String>,
118 },
119}
120
121#[derive(Debug, Clone)]
123pub struct Rule {
124 pub name: String,
125 pub span: Span,
126 pub name_span: Span,
128 pub disabled: bool,
129 pub delimiter: bool,
130 pub new_page: Option<String>,
131 pub annotations: Vec<Annotation>,
132 pub rule_prefix: Option<String>,
133 pub event: Event,
134 pub conditions: Vec<Expr>,
135 pub actions: Vec<Stmt>,
136}
137
138#[derive(Debug, Clone)]
140pub struct Annotation {
141 pub name: String,
142 pub args: Vec<AnnotationArg>,
143 pub span: Span,
144}
145
146#[derive(Debug, Clone)]
149pub struct AnnotationArg {
150 pub text: String,
151 pub span: Span,
152}
153
154#[derive(Debug, Clone)]
156pub struct Event {
157 pub name: String,
158 pub args: Vec<Expr>,
159 pub span: Span,
160}
161
162#[derive(Debug, Clone)]
164pub enum Stmt {
165 Expr {
166 expr: Expr,
167 span: Span,
168 },
169 Assign {
170 target: Expr,
171 value: Expr,
172 span: Span,
173 },
174 If {
175 branches: Vec<IfBranch>,
176 r#else: Option<Vec<Stmt>>,
177 span: Span,
178 },
179 For {
180 variable: Expr,
181 iterable: Expr,
182 body: Vec<Stmt>,
183 span: Span,
184 },
185 While {
186 condition: Expr,
187 body: Vec<Stmt>,
188 span: Span,
189 },
190 DoWhile {
191 condition: Expr,
192 body: Vec<Stmt>,
193 span: Span,
194 },
195 Switch {
196 value: Expr,
197 arms: Vec<SwitchArm>,
198 span: Span,
199 },
200 Break {
201 span: Span,
202 },
203 Pass {
204 span: Span,
205 },
206}
207
208#[derive(Debug, Clone)]
210pub enum SwitchArm {
211 Case {
212 value: Expr,
213 body: Vec<Stmt>,
214 span: Span,
215 },
216 Default {
217 body: Vec<Stmt>,
218 span: Span,
219 },
220}
221
222#[derive(Debug, Clone)]
224pub struct IfBranch {
225 pub condition: Expr,
226 pub body: Vec<Stmt>,
227}
228
229#[derive(Debug, Clone)]
234pub struct CallArg {
235 pub keyword: Option<(String, Span)>,
238 pub value: Expr,
240}
241
242#[derive(Debug, Clone)]
244pub enum Expr {
245 Number {
246 value: f64,
247 text: String,
248 span: Span,
249 },
250 String {
251 value: String,
252 span: Span,
253 },
254 Bool {
255 value: bool,
256 span: Span,
257 },
258 Null {
259 span: Span,
260 },
261 Array {
262 elements: Vec<Expr>,
263 span: Span,
264 },
265 Dict {
266 entries: Vec<DictEntry>,
267 span: Span,
268 },
269 Comprehension {
270 element: Box<Expr>,
271 variable: String,
272 variable_span: Span,
273 index: Option<(String, Span)>,
274 iterable: Box<Expr>,
275 condition: Option<Box<Expr>>,
276 span: Span,
277 },
278 Lambda {
279 params: Vec<(String, Span)>,
280 body: Box<Expr>,
281 span: Span,
282 },
283 StringModifier {
284 modifier: char,
285 value: String,
286 format_text: Option<String>,
289 interpolations: Vec<Expr>,
292 span: Span,
293 },
294 Call {
296 name: String,
297 args: Vec<CallArg>,
298 span: Span,
299 },
300 ReceiverCall {
302 receiver: Box<Expr>,
303 name: String,
304 args: Vec<CallArg>,
305 span: Span,
306 },
307 Name {
309 name: String,
310 span: Span,
311 },
312 Member {
314 receiver: Box<Expr>,
315 member: String,
316 member_span: Span,
318 span: Span,
319 },
320 Index {
321 array: Box<Expr>,
322 index: Box<Expr>,
323 span: Span,
324 },
325 Binary {
326 op: String,
327 left: Box<Expr>,
328 right: Box<Expr>,
329 span: Span,
330 },
331 Unary {
332 op: String,
333 operand: Box<Expr>,
334 span: Span,
335 },
336}
337
338#[derive(Debug, Clone)]
340pub struct DictEntry {
341 pub key: Expr,
342 pub value: Expr,
343 pub span: Span,
344}
345
346impl Expr {
347 pub fn span(&self) -> Span {
349 match self {
350 Expr::Number { span, .. }
351 | Expr::String { span, .. }
352 | Expr::Bool { span, .. }
353 | Expr::Null { span }
354 | Expr::Array { span, .. }
355 | Expr::Dict { span, .. }
356 | Expr::Comprehension { span, .. }
357 | Expr::Lambda { span, .. }
358 | Expr::StringModifier { span, .. }
359 | Expr::Call { span, .. }
360 | Expr::ReceiverCall { span, .. }
361 | Expr::Name { span, .. }
362 | Expr::Member { span, .. }
363 | Expr::Index { span, .. }
364 | Expr::Binary { span, .. }
365 | Expr::Unary { span, .. } => *span,
366 }
367 }
368}
369
370impl Stmt {
371 pub fn span(&self) -> Span {
373 match self {
374 Stmt::Expr { span, .. }
375 | Stmt::Assign { span, .. }
376 | Stmt::If { span, .. }
377 | Stmt::For { span, .. }
378 | Stmt::While { span, .. }
379 | Stmt::DoWhile { span, .. }
380 | Stmt::Switch { span, .. }
381 | Stmt::Break { span }
382 | Stmt::Pass { span } => *span,
383 }
384 }
385}
386
387impl CallArg {
388 pub fn span(&self) -> Span {
391 match &self.keyword {
392 Some((_, name_span)) => {
393 let end = self.value.span().end;
394 Span::new(name_span.file, name_span.start, end)
395 }
396 None => self.value.span(),
397 }
398 }
399}