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}
57
58#[derive(Debug, Clone, Serialize)]
62pub struct EntityDecl {
63 pub doc: Option<DocBlock>,
64 pub name: String,
65 pub fields: Vec<FieldDecl>,
66 pub span: Span,
67}
68
69#[derive(Debug, Clone, Serialize)]
71pub struct FieldDecl {
72 pub name: String,
73 pub ty: TypeExpr,
74 pub span: Span,
75}
76
77#[derive(Debug, Clone, Serialize)]
81pub struct ActionDecl {
82 pub doc: Option<DocBlock>,
83 pub name: String,
84 pub params: Vec<FieldDecl>,
85 pub requires: Option<RequiresBlock>,
86 pub ensures: Option<EnsuresBlock>,
87 pub properties: Option<PropertiesBlock>,
88 pub span: Span,
89}
90
91#[derive(Debug, Clone, Serialize)]
93pub struct RequiresBlock {
94 pub conditions: Vec<Expr>,
95 pub span: Span,
96}
97
98#[derive(Debug, Clone, Serialize)]
100pub struct EnsuresBlock {
101 pub items: Vec<EnsuresItem>,
102 pub span: Span,
103}
104
105#[derive(Debug, Clone, Serialize)]
107pub enum EnsuresItem {
108 Expr(Expr),
109 When(WhenClause),
110}
111
112#[derive(Debug, Clone, Serialize)]
114pub struct WhenClause {
115 pub condition: Expr,
116 pub consequence: Expr,
117 pub span: Span,
118}
119
120#[derive(Debug, Clone, Serialize)]
122pub struct PropertiesBlock {
123 pub entries: Vec<PropEntry>,
124 pub span: Span,
125}
126
127#[derive(Debug, Clone, Serialize)]
129pub struct PropEntry {
130 pub key: String,
131 pub value: PropValue,
132 pub span: Span,
133}
134
135#[derive(Debug, Clone, Serialize)]
137pub enum PropValue {
138 Literal(Literal),
139 Ident(String),
140 List(Vec<PropValue>),
141 Object(Vec<(String, PropValue)>),
142}
143
144#[derive(Debug, Clone, Serialize)]
148pub struct InvariantDecl {
149 pub doc: Option<DocBlock>,
150 pub name: String,
151 pub body: Expr,
152 pub span: Span,
153}
154
155#[derive(Debug, Clone, Serialize)]
159pub struct EdgeCasesDecl {
160 pub rules: Vec<EdgeRule>,
161 pub span: Span,
162}
163
164#[derive(Debug, Clone, Serialize)]
166pub struct EdgeRule {
167 pub condition: Expr,
168 pub action: ActionCall,
169 pub span: Span,
170}
171
172#[derive(Debug, Clone, Serialize)]
174pub struct ActionCall {
175 pub name: String,
176 pub args: Vec<CallArg>,
177 pub span: Span,
178}
179
180#[derive(Debug, Clone, Serialize)]
182pub enum CallArg {
183 Named {
184 key: String,
185 value: Expr,
186 span: Span,
187 },
188 Positional(Expr),
189}
190
191#[derive(Debug, Clone, Serialize)]
195pub struct TypeExpr {
196 pub ty: TypeKind,
197 pub optional: bool,
198 pub span: Span,
199}
200
201#[derive(Debug, Clone, Serialize)]
203pub enum TypeKind {
204 Simple(String),
206 Union(Vec<TypeKind>),
208 List(Box<TypeExpr>),
210 Set(Box<TypeExpr>),
212 Map(Box<TypeExpr>, Box<TypeExpr>),
214 Parameterized {
216 name: String,
217 params: Vec<TypeParam>,
218 },
219}
220
221#[derive(Debug, Clone, Serialize)]
223pub struct TypeParam {
224 pub name: String,
225 pub value: Literal,
226 pub span: Span,
227}
228
229#[derive(Debug, Clone, Serialize)]
233pub struct Expr {
234 pub kind: ExprKind,
235 pub span: Span,
236}
237
238#[derive(Debug, Clone, Serialize)]
240pub enum ExprKind {
241 Implies(Box<Expr>, Box<Expr>),
243 Or(Box<Expr>, Box<Expr>),
245 And(Box<Expr>, Box<Expr>),
247 Not(Box<Expr>),
249 Compare {
251 left: Box<Expr>,
252 op: CmpOp,
253 right: Box<Expr>,
254 },
255 Arithmetic {
257 left: Box<Expr>,
258 op: ArithOp,
259 right: Box<Expr>,
260 },
261 Old(Box<Expr>),
263 Quantifier {
265 kind: QuantifierKind,
266 binding: String,
267 ty: String,
268 body: Box<Expr>,
269 },
270 Call { name: String, args: Vec<CallArg> },
272 FieldAccess {
275 root: Box<Expr>,
276 fields: Vec<String>,
277 },
278 List(Vec<Expr>),
280 Ident(String),
282 Literal(Literal),
284}
285
286impl Expr {
287 pub fn for_each_child(&self, mut f: impl FnMut(&Expr)) {
292 match &self.kind {
293 ExprKind::Implies(a, b)
294 | ExprKind::Or(a, b)
295 | ExprKind::And(a, b)
296 | ExprKind::Compare {
297 left: a, right: b, ..
298 }
299 | ExprKind::Arithmetic {
300 left: a, right: b, ..
301 } => {
302 f(a);
303 f(b);
304 }
305 ExprKind::Not(inner) | ExprKind::Old(inner) => f(inner),
306 ExprKind::Call { args, .. } => {
307 for arg in args {
308 match arg {
309 CallArg::Named { value, .. } => f(value),
310 CallArg::Positional(e) => f(e),
311 }
312 }
313 }
314 ExprKind::FieldAccess { root, .. } => f(root),
315 ExprKind::Quantifier { body, .. } => f(body),
316 ExprKind::List(items) => {
317 for item in items {
318 f(item);
319 }
320 }
321 ExprKind::Ident(_) | ExprKind::Literal(_) => {}
322 }
323 }
324}
325
326#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
328pub enum CmpOp {
329 Eq,
330 Ne,
331 Lt,
332 Gt,
333 Le,
334 Ge,
335}
336
337#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
339pub enum ArithOp {
340 Add,
341 Sub,
342}
343
344#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
346pub enum QuantifierKind {
347 Forall,
348 Exists,
349}
350
351#[derive(Debug, Clone, Serialize)]
353pub enum Literal {
354 Null,
355 Bool(bool),
356 Int(i64),
357 Decimal(String),
358 String(String),
359}