1use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
9pub struct Program {
10 pub items: Vec<Item>,
11}
12
13#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
14pub enum Item {
15 Import(Import),
16 TypeDecl(TypeDecl),
17 FnDecl(FnDecl),
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
21pub struct Import {
22 pub reference: String,
23 pub alias: String,
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
27pub struct TypeDecl {
28 pub name: String,
29 pub params: Vec<String>,
30 pub definition: TypeExpr,
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
34pub struct FnDecl {
35 pub name: String,
36 pub type_params: Vec<String>,
37 pub params: Vec<Param>,
38 pub effects: Vec<Effect>,
39 pub return_type: TypeExpr,
40 pub body: Block,
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
44pub struct Param {
45 pub name: String,
46 pub ty: TypeExpr,
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
50pub struct Effect {
51 pub name: String,
52 pub arg: Option<EffectArg>,
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
56pub enum EffectArg {
57 Str(String),
58 Int(i64),
59 Ident(String),
60}
61
62#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
63pub enum TypeExpr {
64 Named { name: String, args: Vec<TypeExpr> },
67 Record(Vec<TypeField>),
68 Tuple(Vec<TypeExpr>),
69 Function {
70 params: Vec<TypeExpr>,
71 effects: Vec<Effect>,
72 ret: Box<TypeExpr>,
73 },
74 Union(Vec<UnionVariant>),
75 Refined {
84 base: Box<TypeExpr>,
85 binding: String,
86 predicate: Box<Expr>,
87 },
88}
89
90#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
91pub struct TypeField {
92 pub name: String,
93 pub ty: TypeExpr,
94}
95
96#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
97pub struct UnionVariant {
98 pub name: String,
99 pub payload: Option<TypeExpr>,
101}
102
103#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
104pub struct Block {
105 pub statements: Vec<Statement>,
106 pub result: Box<Expr>,
107}
108
109#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
110pub enum Statement {
111 Let { name: String, ty: Option<TypeExpr>, value: Expr },
112 Expr(Expr),
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
116pub enum Expr {
117 Lit(Literal),
118 Var(String),
119 Block(Block),
120 Call { callee: Box<Expr>, args: Vec<Expr> },
121 Pipe { left: Box<Expr>, right: Box<Expr> },
122 Try(Box<Expr>),
124 Field { value: Box<Expr>, field: String },
126 BinOp { op: BinOp, lhs: Box<Expr>, rhs: Box<Expr> },
127 UnaryOp { op: UnaryOp, expr: Box<Expr> },
128 If { cond: Box<Expr>, then_block: Block, else_block: Block },
129 Match { scrutinee: Box<Expr>, arms: Vec<Arm> },
130 RecordLit(Vec<RecordLitField>),
131 TupleLit(Vec<Expr>),
132 ListLit(Vec<Expr>),
133 Constructor { name: String, args: Vec<Expr> },
139 Lambda(Box<Lambda>),
140 Ascription { value: Box<Expr>, ty: TypeExpr },
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
148pub struct Lambda {
149 pub params: Vec<Param>,
150 pub return_type: TypeExpr,
151 pub effects: Vec<Effect>,
152 pub body: Block,
153}
154
155#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
156pub struct RecordLitField {
157 pub name: String,
158 pub value: Expr,
159}
160
161#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
162pub enum BinOp {
163 Add, Sub, Mul, Div, Mod,
164 Eq, Neq, Lt, Lte, Gt, Gte,
165 And, Or,
166}
167
168impl BinOp {
169 pub fn precedence(self) -> u8 {
170 use BinOp::*;
171 match self {
172 Or => 1,
173 And => 2,
174 Eq | Neq | Lt | Lte | Gt | Gte => 3,
175 Add | Sub => 4,
176 Mul | Div | Mod => 5,
177 }
178 }
179
180 pub fn as_str(self) -> &'static str {
181 use BinOp::*;
182 match self {
183 Add => "+", Sub => "-", Mul => "*", Div => "/", Mod => "%",
184 Eq => "==", Neq => "!=", Lt => "<", Lte => "<=", Gt => ">", Gte => ">=",
185 And => "and", Or => "or",
186 }
187 }
188}
189
190#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
191pub enum UnaryOp { Neg, Not }
192
193#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
194pub struct Arm {
195 pub pattern: Pattern,
196 pub body: Expr,
197}
198
199#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
200pub enum Pattern {
201 Lit(Literal),
202 Var(String),
204 Wild,
205 Constructor { name: String, args: Vec<Pattern> },
206 Record { fields: Vec<RecordPatField>, rest: bool },
207 Tuple(Vec<Pattern>),
208}
209
210#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
211pub struct RecordPatField {
212 pub name: String,
213 pub pattern: Option<Pattern>,
215}
216
217#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
218pub enum Literal {
219 Int(i64),
220 Float(f64),
221 Str(String),
222 Bytes(Vec<u8>),
223 Bool(bool),
224 Unit,
225}