1use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
9pub struct Program {
10 pub items: Vec<Item>,
11 #[serde(default, skip_serializing_if = "Vec::is_empty")]
16 pub leading_comments: Vec<String>,
17 #[serde(default, skip_serializing_if = "Vec::is_empty")]
20 pub trailing_comments: Vec<String>,
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
24pub enum Item {
25 Import(Import),
26 TypeDecl(TypeDecl),
27 FnDecl(FnDecl),
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
31pub struct Import {
32 pub reference: String,
33 pub alias: String,
34 #[serde(default, skip_serializing_if = "Vec::is_empty")]
38 pub leading_comments: Vec<String>,
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
42pub struct TypeDecl {
43 pub name: String,
44 pub params: Vec<String>,
45 pub definition: TypeExpr,
46 #[serde(default, skip_serializing_if = "Vec::is_empty")]
49 pub leading_comments: Vec<String>,
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
53pub struct FnDecl {
54 pub name: String,
55 pub type_params: Vec<String>,
56 pub params: Vec<Param>,
57 pub effects: Vec<Effect>,
58 #[serde(default, skip_serializing_if = "Option::is_none")]
65 pub effect_row_var: Option<String>,
66 pub return_type: TypeExpr,
67 pub body: Block,
68 #[serde(default, skip_serializing_if = "Vec::is_empty")]
75 pub examples: Vec<Example>,
76 #[serde(default, skip_serializing_if = "Vec::is_empty")]
79 pub leading_comments: Vec<String>,
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
83pub struct Example {
84 pub args: Vec<Expr>,
86 pub expected: Expr,
88}
89
90#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
91pub struct Param {
92 pub name: String,
93 pub ty: TypeExpr,
94}
95
96#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
97pub struct Effect {
98 pub name: String,
99 pub arg: Option<EffectArg>,
100}
101
102#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
103pub enum EffectArg {
104 Str(String),
105 Int(i64),
106 Ident(String),
107}
108
109#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
110pub enum TypeExpr {
111 Named { name: String, args: Vec<TypeExpr> },
114 Record(Vec<TypeField>),
115 Tuple(Vec<TypeExpr>),
116 Function {
117 params: Vec<TypeExpr>,
118 effects: Vec<Effect>,
119 #[serde(default, skip_serializing_if = "Option::is_none")]
122 effect_row_var: Option<String>,
123 ret: Box<TypeExpr>,
124 },
125 Union(Vec<UnionVariant>),
126 RecordWithSpreads {
129 spreads: Vec<String>,
130 fields: Vec<TypeField>,
131 },
132 Refined {
141 base: Box<TypeExpr>,
142 binding: String,
143 predicate: Box<Expr>,
144 },
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
148pub struct TypeField {
149 pub name: String,
150 pub ty: TypeExpr,
151}
152
153#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
154pub struct UnionVariant {
155 pub name: String,
156 pub payload: Option<TypeExpr>,
158}
159
160#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
161pub struct Block {
162 pub statements: Vec<Statement>,
163 pub result: Box<Expr>,
164}
165
166#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
167pub enum Statement {
168 Let { name: String, ty: Option<TypeExpr>, value: Expr },
169 Expr(Expr),
170}
171
172#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
173pub enum Expr {
174 Lit(Literal),
175 Var(String),
176 Block(Block),
177 Call { callee: Box<Expr>, args: Vec<Expr> },
178 Pipe { left: Box<Expr>, right: Box<Expr> },
179 Try(Box<Expr>),
181 Field { value: Box<Expr>, field: String },
183 BinOp { op: BinOp, lhs: Box<Expr>, rhs: Box<Expr> },
184 UnaryOp { op: UnaryOp, expr: Box<Expr> },
185 If { cond: Box<Expr>, then_block: Block, else_block: Block },
186 Match { scrutinee: Box<Expr>, arms: Vec<Arm> },
187 RecordLit(Vec<RecordLitField>),
188 TupleLit(Vec<Expr>),
189 ListLit(Vec<Expr>),
190 Constructor { name: String, args: Vec<Expr> },
196 Lambda(Box<Lambda>),
197 Ascription { value: Box<Expr>, ty: TypeExpr },
202}
203
204#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
205pub struct Lambda {
206 pub params: Vec<Param>,
207 pub return_type: TypeExpr,
208 pub effects: Vec<Effect>,
209 #[serde(default, skip_serializing_if = "Option::is_none")]
212 pub effect_row_var: Option<String>,
213 pub body: Block,
214}
215
216#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
217pub struct RecordLitField {
218 pub name: String,
219 pub value: Expr,
220}
221
222#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
223pub enum BinOp {
224 Add, Sub, Mul, Div, Mod,
225 Eq, Neq, Lt, Lte, Gt, Gte,
226 And, Or,
227}
228
229impl BinOp {
230 pub fn precedence(self) -> u8 {
231 use BinOp::*;
232 match self {
233 Or => 1,
234 And => 2,
235 Eq | Neq | Lt | Lte | Gt | Gte => 3,
236 Add | Sub => 4,
237 Mul | Div | Mod => 5,
238 }
239 }
240
241 pub fn as_str(self) -> &'static str {
242 use BinOp::*;
243 match self {
244 Add => "+", Sub => "-", Mul => "*", Div => "/", Mod => "%",
245 Eq => "==", Neq => "!=", Lt => "<", Lte => "<=", Gt => ">", Gte => ">=",
246 And => "and", Or => "or",
247 }
248 }
249}
250
251#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
252pub enum UnaryOp { Neg, Not }
253
254#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
255pub struct Arm {
256 pub pattern: Pattern,
257 pub body: Expr,
258}
259
260#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
261pub enum Pattern {
262 Lit(Literal),
263 Var(String),
265 Wild,
266 Constructor { name: String, args: Vec<Pattern> },
267 Record { fields: Vec<RecordPatField>, rest: bool },
268 Tuple(Vec<Pattern>),
269}
270
271#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
272pub struct RecordPatField {
273 pub name: String,
274 pub pattern: Option<Pattern>,
276}
277
278#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
279pub enum Literal {
280 Int(i64),
281 Float(f64),
282 Str(String),
283 Bytes(Vec<u8>),
284 Bool(bool),
285 Unit,
286}