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