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 pub return_type: TypeExpr,
59 pub body: Block,
60 #[serde(default, skip_serializing_if = "Vec::is_empty")]
67 pub examples: Vec<Example>,
68 #[serde(default, skip_serializing_if = "Vec::is_empty")]
71 pub leading_comments: Vec<String>,
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
75pub struct Example {
76 pub args: Vec<Expr>,
78 pub expected: Expr,
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
83pub struct Param {
84 pub name: String,
85 pub ty: TypeExpr,
86}
87
88#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
89pub struct Effect {
90 pub name: String,
91 pub arg: Option<EffectArg>,
92}
93
94#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
95pub enum EffectArg {
96 Str(String),
97 Int(i64),
98 Ident(String),
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
102pub enum TypeExpr {
103 Named { name: String, args: Vec<TypeExpr> },
106 Record(Vec<TypeField>),
107 Tuple(Vec<TypeExpr>),
108 Function {
109 params: Vec<TypeExpr>,
110 effects: Vec<Effect>,
111 ret: Box<TypeExpr>,
112 },
113 Union(Vec<UnionVariant>),
114 RecordWithSpreads {
117 spreads: Vec<String>,
118 fields: Vec<TypeField>,
119 },
120 Refined {
129 base: Box<TypeExpr>,
130 binding: String,
131 predicate: Box<Expr>,
132 },
133}
134
135#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
136pub struct TypeField {
137 pub name: String,
138 pub ty: TypeExpr,
139}
140
141#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
142pub struct UnionVariant {
143 pub name: String,
144 pub payload: Option<TypeExpr>,
146}
147
148#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
149pub struct Block {
150 pub statements: Vec<Statement>,
151 pub result: Box<Expr>,
152}
153
154#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
155pub enum Statement {
156 Let { name: String, ty: Option<TypeExpr>, value: Expr },
157 Expr(Expr),
158}
159
160#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
161pub enum Expr {
162 Lit(Literal),
163 Var(String),
164 Block(Block),
165 Call { callee: Box<Expr>, args: Vec<Expr> },
166 Pipe { left: Box<Expr>, right: Box<Expr> },
167 Try(Box<Expr>),
169 Field { value: Box<Expr>, field: String },
171 BinOp { op: BinOp, lhs: Box<Expr>, rhs: Box<Expr> },
172 UnaryOp { op: UnaryOp, expr: Box<Expr> },
173 If { cond: Box<Expr>, then_block: Block, else_block: Block },
174 Match { scrutinee: Box<Expr>, arms: Vec<Arm> },
175 RecordLit(Vec<RecordLitField>),
176 TupleLit(Vec<Expr>),
177 ListLit(Vec<Expr>),
178 Constructor { name: String, args: Vec<Expr> },
184 Lambda(Box<Lambda>),
185 Ascription { value: Box<Expr>, ty: TypeExpr },
190}
191
192#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
193pub struct Lambda {
194 pub params: Vec<Param>,
195 pub return_type: TypeExpr,
196 pub effects: Vec<Effect>,
197 pub body: Block,
198}
199
200#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
201pub struct RecordLitField {
202 pub name: String,
203 pub value: Expr,
204}
205
206#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
207pub enum BinOp {
208 Add, Sub, Mul, Div, Mod,
209 Eq, Neq, Lt, Lte, Gt, Gte,
210 And, Or,
211}
212
213impl BinOp {
214 pub fn precedence(self) -> u8 {
215 use BinOp::*;
216 match self {
217 Or => 1,
218 And => 2,
219 Eq | Neq | Lt | Lte | Gt | Gte => 3,
220 Add | Sub => 4,
221 Mul | Div | Mod => 5,
222 }
223 }
224
225 pub fn as_str(self) -> &'static str {
226 use BinOp::*;
227 match self {
228 Add => "+", Sub => "-", Mul => "*", Div => "/", Mod => "%",
229 Eq => "==", Neq => "!=", Lt => "<", Lte => "<=", Gt => ">", Gte => ">=",
230 And => "and", Or => "or",
231 }
232 }
233}
234
235#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
236pub enum UnaryOp { Neg, Not }
237
238#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
239pub struct Arm {
240 pub pattern: Pattern,
241 pub body: Expr,
242}
243
244#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
245pub enum Pattern {
246 Lit(Literal),
247 Var(String),
249 Wild,
250 Constructor { name: String, args: Vec<Pattern> },
251 Record { fields: Vec<RecordPatField>, rest: bool },
252 Tuple(Vec<Pattern>),
253}
254
255#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
256pub struct RecordPatField {
257 pub name: String,
258 pub pattern: Option<Pattern>,
260}
261
262#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
263pub enum Literal {
264 Int(i64),
265 Float(f64),
266 Str(String),
267 Bytes(Vec<u8>),
268 Bool(bool),
269 Unit,
270}