1use crate::Span;
12
13#[derive(Debug, Clone)]
19pub struct Module {
20 pub span: Span,
21 pub version: Option<u32>,
23 pub declarations: Vec<Decl>,
24}
25
26#[derive(Debug, Clone)]
31pub enum Decl {
32 Use(UseDecl),
33 ModuleDecl(ModuleDecl),
34 Block(BlockDecl),
35 Default(DefaultDecl),
36 Variant(VariantDecl),
37 Deferred(DeferredDecl),
38 OpenQuestion(OpenQuestionDecl),
39}
40
41#[derive(Debug, Clone)]
43pub struct ModuleDecl {
44 pub span: Span,
45 pub name: Ident,
46}
47
48#[derive(Debug, Clone)]
50pub struct UseDecl {
51 pub span: Span,
52 pub path: StringLiteral,
53 pub alias: Option<Ident>,
54}
55
56#[derive(Debug, Clone)]
58pub struct BlockDecl {
59 pub span: Span,
60 pub kind: BlockKind,
61 pub name: Option<Ident>,
63 pub items: Vec<BlockItem>,
64}
65
66#[derive(Debug, Clone, Copy, PartialEq, Eq)]
67pub enum BlockKind {
68 Entity,
69 ExternalEntity,
70 Value,
71 Enum,
72 Given,
73 Config,
74 Rule,
75 Surface,
76 Actor,
77}
78
79#[derive(Debug, Clone)]
81pub struct DefaultDecl {
82 pub span: Span,
83 pub type_name: Option<Ident>,
84 pub name: Ident,
85 pub value: Expr,
86}
87
88#[derive(Debug, Clone)]
90pub struct VariantDecl {
91 pub span: Span,
92 pub name: Ident,
93 pub base: Expr,
94 pub items: Vec<BlockItem>,
95}
96
97#[derive(Debug, Clone)]
99pub struct DeferredDecl {
100 pub span: Span,
101 pub path: Expr,
102}
103
104#[derive(Debug, Clone)]
106pub struct OpenQuestionDecl {
107 pub span: Span,
108 pub text: StringLiteral,
109}
110
111#[derive(Debug, Clone)]
116pub struct BlockItem {
117 pub span: Span,
118 pub kind: BlockItemKind,
119}
120
121#[derive(Debug, Clone)]
122pub enum BlockItemKind {
123 Clause { keyword: String, value: Expr },
125 Assignment { name: Ident, value: Expr },
127 ParamAssignment {
129 name: Ident,
130 params: Vec<Ident>,
131 value: Expr,
132 },
133 Let { name: Ident, value: Expr },
135 EnumVariant { name: Ident },
137 ForBlock {
139 binding: Ident,
140 collection: Expr,
141 filter: Option<Expr>,
142 items: Vec<BlockItem>,
143 },
144 OpenQuestion { text: StringLiteral },
146}
147
148#[derive(Debug, Clone)]
153pub enum Expr {
154 Ident(Ident),
156
157 StringLiteral(StringLiteral),
159
160 NumberLiteral { span: Span, value: String },
162
163 BoolLiteral { span: Span, value: bool },
165
166 Null { span: Span },
168
169 Now { span: Span },
171
172 This { span: Span },
174
175 Within { span: Span },
177
178 DurationLiteral { span: Span, value: String },
180
181 SetLiteral { span: Span, elements: Vec<Expr> },
183
184 ListLiteral { span: Span, elements: Vec<Expr> },
186
187 ObjectLiteral { span: Span, fields: Vec<NamedArg> },
189
190 GenericType {
192 span: Span,
193 name: Box<Expr>,
194 args: Vec<Expr>,
195 },
196
197 Includes {
199 span: Span,
200 collection: Box<Expr>,
201 element: Box<Expr>,
202 },
203 Excludes {
204 span: Span,
205 collection: Box<Expr>,
206 element: Box<Expr>,
207 },
208
209 MemberAccess {
211 span: Span,
212 object: Box<Expr>,
213 field: Ident,
214 },
215
216 OptionalAccess {
218 span: Span,
219 object: Box<Expr>,
220 field: Ident,
221 },
222
223 NullCoalesce {
225 span: Span,
226 left: Box<Expr>,
227 right: Box<Expr>,
228 },
229
230 Call {
232 span: Span,
233 function: Box<Expr>,
234 args: Vec<CallArg>,
235 },
236
237 JoinLookup {
239 span: Span,
240 entity: Box<Expr>,
241 fields: Vec<JoinField>,
242 },
243
244 BinaryOp {
246 span: Span,
247 left: Box<Expr>,
248 op: BinaryOp,
249 right: Box<Expr>,
250 },
251
252 Comparison {
254 span: Span,
255 left: Box<Expr>,
256 op: ComparisonOp,
257 right: Box<Expr>,
258 },
259
260 LogicalOp {
262 span: Span,
263 left: Box<Expr>,
264 op: LogicalOp,
265 right: Box<Expr>,
266 },
267
268 Not { span: Span, operand: Box<Expr> },
270
271 In {
273 span: Span,
274 element: Box<Expr>,
275 collection: Box<Expr>,
276 },
277
278 NotIn {
280 span: Span,
281 element: Box<Expr>,
282 collection: Box<Expr>,
283 },
284
285 Exists { span: Span, operand: Box<Expr> },
287
288 NotExists { span: Span, operand: Box<Expr> },
290
291 Where {
293 span: Span,
294 source: Box<Expr>,
295 condition: Box<Expr>,
296 },
297
298 With {
300 span: Span,
301 source: Box<Expr>,
302 predicate: Box<Expr>,
303 },
304
305 Pipe {
307 span: Span,
308 left: Box<Expr>,
309 right: Box<Expr>,
310 },
311
312 Lambda {
314 span: Span,
315 param: Box<Expr>,
316 body: Box<Expr>,
317 },
318
319 Conditional {
321 span: Span,
322 branches: Vec<CondBranch>,
323 else_body: Option<Box<Expr>>,
324 },
325
326 For {
328 span: Span,
329 binding: Ident,
330 collection: Box<Expr>,
331 filter: Option<Box<Expr>>,
332 body: Box<Expr>,
333 },
334
335 ProjectionMap {
337 span: Span,
338 source: Box<Expr>,
339 field: Ident,
340 },
341
342 TransitionsTo {
344 span: Span,
345 subject: Box<Expr>,
346 new_state: Box<Expr>,
347 },
348
349 Becomes {
351 span: Span,
352 subject: Box<Expr>,
353 new_state: Box<Expr>,
354 },
355
356 Binding {
358 span: Span,
359 name: Ident,
360 value: Box<Expr>,
361 },
362
363 WhenGuard {
365 span: Span,
366 action: Box<Expr>,
367 condition: Box<Expr>,
368 },
369
370 TypeOptional {
372 span: Span,
373 inner: Box<Expr>,
374 },
375
376 LetExpr {
378 span: Span,
379 name: Ident,
380 value: Box<Expr>,
381 },
382
383 QualifiedName(QualifiedName),
385
386 Block { span: Span, items: Vec<Expr> },
388
389 Predicate {
393 span: Span,
394 subject: Box<Expr>,
395 tail: Vec<Expr>,
396 },
397
398 Range {
400 span: Span,
401 start: Box<Expr>,
402 end: Box<Expr>,
403 },
404}
405
406impl Expr {
407 pub fn span(&self) -> Span {
408 match self {
409 Expr::Ident(id) => id.span,
410 Expr::StringLiteral(s) => s.span,
411 Expr::NumberLiteral { span, .. }
412 | Expr::BoolLiteral { span, .. }
413 | Expr::Null { span }
414 | Expr::Now { span }
415 | Expr::This { span }
416 | Expr::Within { span }
417 | Expr::DurationLiteral { span, .. }
418 | Expr::SetLiteral { span, .. }
419 | Expr::ListLiteral { span, .. }
420 | Expr::ObjectLiteral { span, .. }
421 | Expr::GenericType { span, .. }
422 | Expr::Includes { span, .. }
423 | Expr::Excludes { span, .. }
424 | Expr::MemberAccess { span, .. }
425 | Expr::OptionalAccess { span, .. }
426 | Expr::NullCoalesce { span, .. }
427 | Expr::Call { span, .. }
428 | Expr::JoinLookup { span, .. }
429 | Expr::BinaryOp { span, .. }
430 | Expr::Comparison { span, .. }
431 | Expr::LogicalOp { span, .. }
432 | Expr::Not { span, .. }
433 | Expr::In { span, .. }
434 | Expr::NotIn { span, .. }
435 | Expr::Exists { span, .. }
436 | Expr::NotExists { span, .. }
437 | Expr::Where { span, .. }
438 | Expr::With { span, .. }
439 | Expr::Pipe { span, .. }
440 | Expr::Lambda { span, .. }
441 | Expr::Conditional { span, .. }
442 | Expr::For { span, .. }
443 | Expr::ProjectionMap { span, .. }
444 | Expr::TransitionsTo { span, .. }
445 | Expr::Becomes { span, .. }
446 | Expr::Binding { span, .. }
447 | Expr::WhenGuard { span, .. }
448 | Expr::TypeOptional { span, .. }
449 | Expr::LetExpr { span, .. }
450 | Expr::Block { span, .. }
451 | Expr::Predicate { span, .. }
452 | Expr::Range { span, .. } => *span,
453 Expr::QualifiedName(q) => q.span,
454 }
455 }
456}
457
458#[derive(Debug, Clone)]
459pub struct CondBranch {
460 pub span: Span,
461 pub condition: Expr,
462 pub body: Expr,
463}
464
465#[derive(Debug, Clone)]
470pub struct Ident {
471 pub span: Span,
472 pub name: String,
473}
474
475#[derive(Debug, Clone)]
476pub struct QualifiedName {
477 pub span: Span,
478 pub qualifier: Option<String>,
479 pub name: String,
480}
481
482#[derive(Debug, Clone)]
483pub struct StringLiteral {
484 pub span: Span,
485 pub parts: Vec<StringPart>,
486}
487
488#[derive(Debug, Clone)]
489pub enum StringPart {
490 Text(String),
491 Interpolation(Ident),
492}
493
494#[derive(Debug, Clone)]
495pub struct NamedArg {
496 pub span: Span,
497 pub name: Ident,
498 pub value: Expr,
499}
500
501#[derive(Debug, Clone)]
502pub enum CallArg {
503 Positional(Expr),
504 Named(NamedArg),
505}
506
507#[derive(Debug, Clone)]
508pub struct JoinField {
509 pub span: Span,
510 pub field: Ident,
511 pub value: Option<Expr>,
513}
514
515#[derive(Debug, Clone, Copy, PartialEq, Eq)]
516pub enum BinaryOp {
517 Add,
518 Sub,
519 Mul,
520 Div,
521}
522
523#[derive(Debug, Clone, Copy, PartialEq, Eq)]
524pub enum ComparisonOp {
525 Eq,
526 NotEq,
527 Lt,
528 LtEq,
529 Gt,
530 GtEq,
531}
532
533#[derive(Debug, Clone, Copy, PartialEq, Eq)]
534pub enum LogicalOp {
535 And,
536 Or,
537}