1use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
10pub struct Span {
11 pub start: usize,
12 pub end: usize,
13}
14
15#[derive(Debug, Clone, Serialize)]
19pub struct File {
20 pub module: ModuleDecl,
21 pub doc: Option<DocBlock>,
22 pub imports: Vec<UseDecl>,
23 pub items: Vec<TopLevelItem>,
24 pub span: Span,
25}
26
27#[derive(Debug, Clone, Serialize)]
29pub struct UseDecl {
30 pub module_name: String,
31 pub item: Option<String>,
32 pub span: Span,
33}
34
35#[derive(Debug, Clone, Serialize)]
37pub struct ModuleDecl {
38 pub name: String,
39 pub span: Span,
40}
41
42#[derive(Debug, Clone, Serialize)]
44pub struct DocBlock {
45 pub lines: Vec<String>,
46 pub span: Span,
47}
48
49#[derive(Debug, Clone, Serialize)]
51pub enum TopLevelItem {
52 Entity(EntityDecl),
53 Action(ActionDecl),
54 Invariant(InvariantDecl),
55 EdgeCases(EdgeCasesDecl),
56 Test(TestDecl),
57}
58
59#[derive(Debug, Clone, Serialize)]
63pub struct TestDecl {
64 pub name: String,
65 pub given: Vec<GivenBinding>,
66 pub when_action: WhenAction,
67 pub then: ThenClause,
68 pub span: Span,
69}
70
71#[derive(Debug, Clone, Serialize)]
73pub struct GivenBinding {
74 pub name: String,
75 pub value: GivenValue,
76 pub span: Span,
77}
78
79#[derive(Debug, Clone, Serialize)]
81pub enum GivenValue {
82 EntityConstructor {
84 type_name: String,
85 fields: Vec<ConstructorField>,
86 },
87 Expr(Expr),
89}
90
91#[derive(Debug, Clone, Serialize)]
93pub struct ConstructorField {
94 pub name: String,
95 pub value: Expr,
96 pub span: Span,
97}
98
99#[derive(Debug, Clone, Serialize)]
101pub struct WhenAction {
102 pub action_name: String,
103 pub args: Vec<ConstructorField>,
104 pub span: Span,
105}
106
107#[derive(Debug, Clone, Serialize)]
109pub enum ThenClause {
110 Asserts(Vec<Expr>, Span),
112 Fails(Option<String>, Span),
114}
115
116#[derive(Debug, Clone, Serialize)]
120pub struct EntityDecl {
121 pub doc: Option<DocBlock>,
122 pub name: String,
123 pub fields: Vec<FieldDecl>,
124 pub span: Span,
125}
126
127#[derive(Debug, Clone, Serialize)]
129pub struct FieldDecl {
130 pub name: String,
131 pub ty: TypeExpr,
132 pub span: Span,
133}
134
135#[derive(Debug, Clone, Serialize)]
139pub struct ActionDecl {
140 pub doc: Option<DocBlock>,
141 pub name: String,
142 pub params: Vec<FieldDecl>,
143 pub requires: Option<RequiresBlock>,
144 pub ensures: Option<EnsuresBlock>,
145 pub properties: Option<PropertiesBlock>,
146 pub span: Span,
147}
148
149#[derive(Debug, Clone, Serialize)]
151pub struct RequiresBlock {
152 pub conditions: Vec<Expr>,
153 pub span: Span,
154}
155
156#[derive(Debug, Clone, Serialize)]
158pub struct EnsuresBlock {
159 pub items: Vec<EnsuresItem>,
160 pub span: Span,
161}
162
163#[derive(Debug, Clone, Serialize)]
165pub enum EnsuresItem {
166 Expr(Expr),
167 When(WhenClause),
168}
169
170#[derive(Debug, Clone, Serialize)]
172pub struct WhenClause {
173 pub condition: Expr,
174 pub consequence: Expr,
175 pub span: Span,
176}
177
178#[derive(Debug, Clone, Serialize)]
180pub struct PropertiesBlock {
181 pub entries: Vec<PropEntry>,
182 pub span: Span,
183}
184
185#[derive(Debug, Clone, Serialize)]
187pub struct PropEntry {
188 pub key: String,
189 pub value: PropValue,
190 pub span: Span,
191}
192
193#[derive(Debug, Clone, Serialize)]
195pub enum PropValue {
196 Literal(Literal),
197 Ident(String),
198 List(Vec<PropValue>),
199 Object(Vec<(String, PropValue)>),
200}
201
202#[derive(Debug, Clone, Serialize)]
206pub struct InvariantDecl {
207 pub doc: Option<DocBlock>,
208 pub name: String,
209 pub body: Expr,
210 pub span: Span,
211}
212
213#[derive(Debug, Clone, Serialize)]
217pub struct EdgeCasesDecl {
218 pub rules: Vec<EdgeRule>,
219 pub span: Span,
220}
221
222#[derive(Debug, Clone, Serialize)]
224pub struct EdgeRule {
225 pub condition: Expr,
226 pub action: ActionCall,
227 pub span: Span,
228}
229
230#[derive(Debug, Clone, Serialize)]
232pub struct ActionCall {
233 pub name: String,
234 pub args: Vec<CallArg>,
235 pub span: Span,
236}
237
238#[derive(Debug, Clone, Serialize)]
240pub enum CallArg {
241 Named {
242 key: String,
243 value: Expr,
244 span: Span,
245 },
246 Positional(Expr),
247}
248
249#[derive(Debug, Clone, Serialize)]
253pub struct TypeExpr {
254 pub ty: TypeKind,
255 pub optional: bool,
256 pub span: Span,
257}
258
259#[derive(Debug, Clone, Serialize)]
261pub enum TypeKind {
262 Simple(String),
264 Union(Vec<TypeKind>),
266 List(Box<TypeExpr>),
268 Set(Box<TypeExpr>),
270 Map(Box<TypeExpr>, Box<TypeExpr>),
272 Parameterized {
274 name: String,
275 params: Vec<TypeParam>,
276 },
277}
278
279#[derive(Debug, Clone, Serialize)]
281pub struct TypeParam {
282 pub name: String,
283 pub value: Literal,
284 pub span: Span,
285}
286
287#[derive(Debug, Clone, Serialize)]
291pub struct Expr {
292 pub kind: ExprKind,
293 pub span: Span,
294}
295
296#[derive(Debug, Clone, Serialize)]
298pub enum ExprKind {
299 Implies(Box<Expr>, Box<Expr>),
301 Or(Box<Expr>, Box<Expr>),
303 And(Box<Expr>, Box<Expr>),
305 Not(Box<Expr>),
307 Compare {
309 left: Box<Expr>,
310 op: CmpOp,
311 right: Box<Expr>,
312 },
313 Arithmetic {
315 left: Box<Expr>,
316 op: ArithOp,
317 right: Box<Expr>,
318 },
319 Old(Box<Expr>),
321 Quantifier {
323 kind: QuantifierKind,
324 binding: String,
325 ty: String,
326 body: Box<Expr>,
327 },
328 Call { name: String, args: Vec<CallArg> },
330 FieldAccess {
333 root: Box<Expr>,
334 fields: Vec<String>,
335 },
336 List(Vec<Expr>),
338 Ident(String),
340 Literal(Literal),
342}
343
344impl Expr {
345 pub fn for_each_child(&self, mut f: impl FnMut(&Expr)) {
350 match &self.kind {
351 ExprKind::Implies(a, b)
352 | ExprKind::Or(a, b)
353 | ExprKind::And(a, b)
354 | ExprKind::Compare {
355 left: a, right: b, ..
356 }
357 | ExprKind::Arithmetic {
358 left: a, right: b, ..
359 } => {
360 f(a);
361 f(b);
362 }
363 ExprKind::Not(inner) | ExprKind::Old(inner) => f(inner),
364 ExprKind::Call { args, .. } => {
365 for arg in args {
366 match arg {
367 CallArg::Named { value, .. } => f(value),
368 CallArg::Positional(e) => f(e),
369 }
370 }
371 }
372 ExprKind::FieldAccess { root, .. } => f(root),
373 ExprKind::Quantifier { body, .. } => f(body),
374 ExprKind::List(items) => {
375 for item in items {
376 f(item);
377 }
378 }
379 ExprKind::Ident(_) | ExprKind::Literal(_) => {}
380 }
381 }
382}
383
384#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
386pub enum CmpOp {
387 Eq,
388 Ne,
389 Lt,
390 Gt,
391 Le,
392 Ge,
393}
394
395#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
397pub enum ArithOp {
398 Add,
399 Sub,
400}
401
402#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
404pub enum QuantifierKind {
405 Forall,
406 Exists,
407}
408
409#[derive(Debug, Clone, Serialize)]
411pub enum Literal {
412 Null,
413 Bool(bool),
414 Int(i64),
415 Decimal(String),
416 String(String),
417}