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, 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::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_line: Option<usize>,
166 pub intent: String,
167}
168
169#[derive(Debug, Clone, PartialEq)]
170pub enum VerifyGivenDomain {
171 IntRange { start: i64, end: i64 },
173 Explicit(Vec<Expr>),
175}
176
177#[derive(Debug, Clone, PartialEq)]
178pub struct VerifyGiven {
179 pub name: String,
180 pub type_name: String,
181 pub domain: VerifyGivenDomain,
182}
183
184#[derive(Debug, Clone, PartialEq)]
185pub struct VerifyLaw {
186 pub name: String,
187 pub givens: Vec<VerifyGiven>,
188 pub when: Option<Expr>,
190 pub lhs: Expr,
192 pub rhs: Expr,
193 pub sample_guards: Vec<Expr>,
195}
196
197#[derive(Debug, Clone, PartialEq)]
198pub enum VerifyKind {
199 Cases,
200 Law(Box<VerifyLaw>),
201}
202
203#[derive(Debug, Clone, PartialEq)]
204pub struct VerifyBlock {
205 pub fn_name: String,
206 pub line: usize,
207 pub cases: Vec<(Expr, Expr)>,
208 pub kind: VerifyKind,
209}
210
211#[derive(Debug, Clone, PartialEq)]
212pub struct DecisionBlock {
213 pub name: String,
214 pub line: usize,
215 pub date: String,
216 pub reason: String,
217 pub chosen: DecisionImpact,
218 pub rejected: Vec<DecisionImpact>,
219 pub impacts: Vec<DecisionImpact>,
220 pub author: Option<String>,
221}
222
223#[derive(Debug, Clone, PartialEq, Eq, Hash)]
224pub enum DecisionImpact {
225 Symbol(String),
226 Semantic(String),
227}
228
229impl DecisionImpact {
230 pub fn text(&self) -> &str {
231 match self {
232 DecisionImpact::Symbol(s) | DecisionImpact::Semantic(s) => s,
233 }
234 }
235
236 pub fn as_context_string(&self) -> String {
237 match self {
238 DecisionImpact::Symbol(s) => s.clone(),
239 DecisionImpact::Semantic(s) => format!("\"{}\"", s),
240 }
241 }
242}
243
244#[derive(Debug, Clone, PartialEq)]
247pub struct TypeVariant {
248 pub name: String,
249 pub fields: Vec<String>, }
251
252#[derive(Debug, Clone, PartialEq)]
254pub enum TypeDef {
255 Sum {
257 name: String,
258 variants: Vec<TypeVariant>,
259 line: usize,
260 },
261 Product {
263 name: String,
264 fields: Vec<(String, String)>,
265 line: usize,
266 },
267}
268
269#[derive(Debug, Clone, PartialEq)]
270pub enum TopLevel {
271 Module(Module),
272 FnDef(FnDef),
273 Verify(VerifyBlock),
274 Decision(DecisionBlock),
275 Stmt(Stmt),
276 TypeDef(TypeDef),
277 EffectSet {
279 name: String,
280 effects: Vec<String>,
281 line: usize,
282 },
283}