1#[derive(Debug, Clone, PartialEq)]
2pub enum Literal {
3 Int(i64),
4 Float(f64),
5 Str(String),
6 Bool(bool),
7 Unit,
8}
9
10#[derive(Debug, Clone, Copy, PartialEq)]
11pub enum BinOp {
12 Add,
13 Sub,
14 Mul,
15 Div,
16 Eq,
17 Neq,
18 Lt,
19 Gt,
20 Lte,
21 Gte,
22}
23
24#[derive(Debug, Clone, PartialEq)]
25pub struct MatchArm {
26 pub pattern: Pattern,
27 pub body: Box<Expr>,
28}
29
30#[derive(Debug, Clone, PartialEq)]
31pub enum Pattern {
32 Wildcard,
33 Literal(Literal),
34 Ident(String),
35 EmptyList,
37 Cons(String, String),
39 Tuple(Vec<Pattern>),
41 Constructor(String, Vec<String>),
45}
46
47#[derive(Debug, Clone, PartialEq)]
48pub enum StrPart {
49 Literal(String),
50 Parsed(Box<Expr>),
51}
52
53#[derive(Debug, Clone, PartialEq)]
54pub enum Expr {
55 Literal(Literal),
56 Ident(String),
57 Attr(Box<Expr>, String),
58 FnCall(Box<Expr>, Vec<Expr>),
59 BinOp(BinOp, Box<Expr>, Box<Expr>),
60 Match {
61 subject: Box<Expr>,
62 arms: Vec<MatchArm>,
63 line: usize,
64 },
65 Constructor(String, Option<Box<Expr>>),
66 ErrorProp(Box<Expr>),
67 InterpolatedStr(Vec<StrPart>),
68 List(Vec<Expr>),
69 Tuple(Vec<Expr>),
70 MapLiteral(Vec<(Expr, Expr)>),
72 RecordCreate {
74 type_name: String,
75 fields: Vec<(String, Expr)>,
76 },
77 RecordUpdate {
79 type_name: String,
80 base: Box<Expr>,
81 updates: Vec<(String, Expr)>,
82 },
83 TailCall(Box<(String, Vec<Expr>)>),
87 Resolved(u16),
90}
91
92#[derive(Debug, Clone, PartialEq)]
93pub enum Stmt {
94 Binding(String, Option<String>, Expr),
95 Expr(Expr),
96}
97
98#[derive(Debug, Clone, PartialEq)]
99pub enum FnBody {
100 Block(Vec<Stmt>),
101}
102
103impl FnBody {
104 pub fn from_expr(expr: Expr) -> Self {
105 Self::Block(vec![Stmt::Expr(expr)])
106 }
107
108 pub fn stmts(&self) -> &[Stmt] {
109 match self {
110 Self::Block(stmts) => stmts,
111 }
112 }
113
114 pub fn stmts_mut(&mut self) -> &mut Vec<Stmt> {
115 match self {
116 Self::Block(stmts) => stmts,
117 }
118 }
119
120 pub fn tail_expr(&self) -> Option<&Expr> {
121 match self.stmts().last() {
122 Some(Stmt::Expr(expr)) => Some(expr),
123 _ => None,
124 }
125 }
126
127 pub fn tail_expr_mut(&mut self) -> Option<&mut Expr> {
128 match self.stmts_mut().last_mut() {
129 Some(Stmt::Expr(expr)) => Some(expr),
130 _ => None,
131 }
132 }
133}
134
135#[derive(Debug, Clone, PartialEq)]
139pub struct FnResolution {
140 pub local_count: u16,
142 pub local_slots: std::rc::Rc<std::collections::HashMap<String, u16>>,
144}
145
146#[derive(Debug, Clone, PartialEq)]
147pub struct FnDef {
148 pub name: String,
149 pub line: usize,
150 pub params: Vec<(String, String)>,
151 pub return_type: String,
152 pub effects: Vec<String>,
153 pub desc: Option<String>,
154 pub body: std::rc::Rc<FnBody>,
155 pub resolution: Option<FnResolution>,
157}
158
159#[derive(Debug, Clone, PartialEq)]
160pub struct Module {
161 pub name: String,
162 pub line: usize,
163 pub depends: Vec<String>,
164 pub exposes: Vec<String>,
165 pub exposes_opaque: Vec<String>,
166 pub exposes_line: Option<usize>,
167 pub intent: String,
168}
169
170#[derive(Debug, Clone, PartialEq)]
171pub enum VerifyGivenDomain {
172 IntRange { start: i64, end: i64 },
174 Explicit(Vec<Expr>),
176}
177
178#[derive(Debug, Clone, PartialEq)]
179pub struct VerifyGiven {
180 pub name: String,
181 pub type_name: String,
182 pub domain: VerifyGivenDomain,
183}
184
185#[derive(Debug, Clone, PartialEq)]
186pub struct VerifyLaw {
187 pub name: String,
188 pub givens: Vec<VerifyGiven>,
189 pub when: Option<Expr>,
191 pub lhs: Expr,
193 pub rhs: Expr,
194 pub sample_guards: Vec<Expr>,
196}
197
198#[derive(Debug, Clone, PartialEq)]
199pub enum VerifyKind {
200 Cases,
201 Law(Box<VerifyLaw>),
202}
203
204#[derive(Debug, Clone, PartialEq)]
205pub struct VerifyBlock {
206 pub fn_name: String,
207 pub line: usize,
208 pub cases: Vec<(Expr, Expr)>,
209 pub kind: VerifyKind,
210}
211
212#[derive(Debug, Clone, PartialEq)]
213pub struct DecisionBlock {
214 pub name: String,
215 pub line: usize,
216 pub date: String,
217 pub reason: String,
218 pub chosen: DecisionImpact,
219 pub rejected: Vec<DecisionImpact>,
220 pub impacts: Vec<DecisionImpact>,
221 pub author: Option<String>,
222}
223
224#[derive(Debug, Clone, PartialEq, Eq, Hash)]
225pub enum DecisionImpact {
226 Symbol(String),
227 Semantic(String),
228}
229
230impl DecisionImpact {
231 pub fn text(&self) -> &str {
232 match self {
233 DecisionImpact::Symbol(s) | DecisionImpact::Semantic(s) => s,
234 }
235 }
236
237 pub fn as_context_string(&self) -> String {
238 match self {
239 DecisionImpact::Symbol(s) => s.clone(),
240 DecisionImpact::Semantic(s) => format!("\"{}\"", s),
241 }
242 }
243}
244
245#[derive(Debug, Clone, PartialEq)]
248pub struct TypeVariant {
249 pub name: String,
250 pub fields: Vec<String>, }
252
253#[derive(Debug, Clone, PartialEq)]
255pub enum TypeDef {
256 Sum {
258 name: String,
259 variants: Vec<TypeVariant>,
260 line: usize,
261 },
262 Product {
264 name: String,
265 fields: Vec<(String, String)>,
266 line: usize,
267 },
268}
269
270#[derive(Debug, Clone, PartialEq)]
271pub enum TopLevel {
272 Module(Module),
273 FnDef(FnDef),
274 Verify(VerifyBlock),
275 Decision(DecisionBlock),
276 Stmt(Stmt),
277 TypeDef(TypeDef),
278}