1use serde::Serialize;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
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 items: Vec<TopLevelItem>,
23 pub span: Span,
24}
25
26#[derive(Debug, Clone, Serialize)]
28pub struct ModuleDecl {
29 pub name: String,
30 pub span: Span,
31}
32
33#[derive(Debug, Clone, Serialize)]
35pub struct DocBlock {
36 pub lines: Vec<String>,
37 pub span: Span,
38}
39
40#[derive(Debug, Clone, Serialize)]
42pub enum TopLevelItem {
43 Entity(EntityDecl),
44 Action(ActionDecl),
45 Invariant(InvariantDecl),
46 EdgeCases(EdgeCasesDecl),
47}
48
49#[derive(Debug, Clone, Serialize)]
53pub struct EntityDecl {
54 pub doc: Option<DocBlock>,
55 pub name: String,
56 pub fields: Vec<FieldDecl>,
57 pub span: Span,
58}
59
60#[derive(Debug, Clone, Serialize)]
62pub struct FieldDecl {
63 pub name: String,
64 pub ty: TypeExpr,
65 pub span: Span,
66}
67
68#[derive(Debug, Clone, Serialize)]
72pub struct ActionDecl {
73 pub doc: Option<DocBlock>,
74 pub name: String,
75 pub params: Vec<FieldDecl>,
76 pub requires: Option<RequiresBlock>,
77 pub ensures: Option<EnsuresBlock>,
78 pub properties: Option<PropertiesBlock>,
79 pub span: Span,
80}
81
82#[derive(Debug, Clone, Serialize)]
84pub struct RequiresBlock {
85 pub conditions: Vec<Expr>,
86 pub span: Span,
87}
88
89#[derive(Debug, Clone, Serialize)]
91pub struct EnsuresBlock {
92 pub items: Vec<EnsuresItem>,
93 pub span: Span,
94}
95
96#[derive(Debug, Clone, Serialize)]
98pub enum EnsuresItem {
99 Expr(Expr),
100 When(WhenClause),
101}
102
103#[derive(Debug, Clone, Serialize)]
105pub struct WhenClause {
106 pub condition: Expr,
107 pub consequence: Expr,
108 pub span: Span,
109}
110
111#[derive(Debug, Clone, Serialize)]
113pub struct PropertiesBlock {
114 pub entries: Vec<PropEntry>,
115 pub span: Span,
116}
117
118#[derive(Debug, Clone, Serialize)]
120pub struct PropEntry {
121 pub key: String,
122 pub value: PropValue,
123 pub span: Span,
124}
125
126#[derive(Debug, Clone, Serialize)]
128pub enum PropValue {
129 Literal(Literal),
130 Ident(String),
131 List(Vec<PropValue>),
132 Object(Vec<(String, PropValue)>),
133}
134
135#[derive(Debug, Clone, Serialize)]
139pub struct InvariantDecl {
140 pub doc: Option<DocBlock>,
141 pub name: String,
142 pub body: Expr,
143 pub span: Span,
144}
145
146#[derive(Debug, Clone, Serialize)]
150pub struct EdgeCasesDecl {
151 pub rules: Vec<EdgeRule>,
152 pub span: Span,
153}
154
155#[derive(Debug, Clone, Serialize)]
157pub struct EdgeRule {
158 pub condition: Expr,
159 pub action: ActionCall,
160 pub span: Span,
161}
162
163#[derive(Debug, Clone, Serialize)]
165pub struct ActionCall {
166 pub name: String,
167 pub args: Vec<CallArg>,
168 pub span: Span,
169}
170
171#[derive(Debug, Clone, Serialize)]
173pub enum CallArg {
174 Named {
175 key: String,
176 value: Expr,
177 span: Span,
178 },
179 Positional(Expr),
180}
181
182#[derive(Debug, Clone, Serialize)]
186pub struct TypeExpr {
187 pub ty: TypeKind,
188 pub optional: bool,
189 pub span: Span,
190}
191
192#[derive(Debug, Clone, Serialize)]
194pub enum TypeKind {
195 Simple(String),
197 Union(Vec<TypeKind>),
199 List(Box<TypeExpr>),
201 Set(Box<TypeExpr>),
203 Map(Box<TypeExpr>, Box<TypeExpr>),
205 Parameterized {
207 name: String,
208 params: Vec<TypeParam>,
209 },
210}
211
212#[derive(Debug, Clone, Serialize)]
214pub struct TypeParam {
215 pub name: String,
216 pub value: Literal,
217 pub span: Span,
218}
219
220#[derive(Debug, Clone, Serialize)]
224pub struct Expr {
225 pub kind: ExprKind,
226 pub span: Span,
227}
228
229#[derive(Debug, Clone, Serialize)]
231pub enum ExprKind {
232 Implies(Box<Expr>, Box<Expr>),
234 Or(Box<Expr>, Box<Expr>),
236 And(Box<Expr>, Box<Expr>),
238 Not(Box<Expr>),
240 Compare {
242 left: Box<Expr>,
243 op: CmpOp,
244 right: Box<Expr>,
245 },
246 Arithmetic {
248 left: Box<Expr>,
249 op: ArithOp,
250 right: Box<Expr>,
251 },
252 Old(Box<Expr>),
254 Quantifier {
256 kind: QuantifierKind,
257 binding: String,
258 ty: String,
259 body: Box<Expr>,
260 },
261 Call { name: String, args: Vec<CallArg> },
263 FieldAccess {
266 root: Box<Expr>,
267 fields: Vec<String>,
268 },
269 Ident(String),
271 Literal(Literal),
273}
274
275impl Expr {
276 pub fn for_each_child(&self, mut f: impl FnMut(&Expr)) {
281 match &self.kind {
282 ExprKind::Implies(a, b)
283 | ExprKind::Or(a, b)
284 | ExprKind::And(a, b)
285 | ExprKind::Compare {
286 left: a, right: b, ..
287 }
288 | ExprKind::Arithmetic {
289 left: a, right: b, ..
290 } => {
291 f(a);
292 f(b);
293 }
294 ExprKind::Not(inner) | ExprKind::Old(inner) => f(inner),
295 ExprKind::Call { args, .. } => {
296 for arg in args {
297 match arg {
298 CallArg::Named { value, .. } => f(value),
299 CallArg::Positional(e) => f(e),
300 }
301 }
302 }
303 ExprKind::FieldAccess { root, .. } => f(root),
304 ExprKind::Quantifier { body, .. } => f(body),
305 ExprKind::Ident(_) | ExprKind::Literal(_) => {}
306 }
307 }
308}
309
310#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
312pub enum CmpOp {
313 Eq,
314 Ne,
315 Lt,
316 Gt,
317 Le,
318 Ge,
319}
320
321#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
323pub enum ArithOp {
324 Add,
325 Sub,
326}
327
328#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
330pub enum QuantifierKind {
331 Forall,
332 Exists,
333}
334
335#[derive(Debug, Clone, Serialize)]
337pub enum Literal {
338 Null,
339 Bool(bool),
340 Int(i64),
341 Decimal(String),
342 String(String),
343}