use crate::intern::Symbol;
use crate::span::Span;
#[derive(Debug, Clone, PartialEq)]
pub struct Expr {
pub kind: ExprKind,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ExprKind {
IntLit(i64),
FloatLit(f64),
StringLit(String),
CharLit(char),
BoolLit(bool),
Unit,
Var(Symbol),
Constructor(Symbol),
Tuple(Vec<Expr>),
List(Vec<Expr>),
Cons(Box<Expr>, Box<Expr>),
BinOp(BinOp, Box<Expr>, Box<Expr>),
UnaryNeg(Box<Expr>),
Not(Box<Expr>),
App(Box<Expr>, Box<Expr>),
Fn(Pat, Box<Expr>),
If(Box<Expr>, Box<Expr>, Box<Expr>),
Let(Vec<Decl>, Box<Expr>),
Case(Box<Expr>, Vec<(Pat, Expr)>),
Ann(Box<Expr>, TypeExpr),
Paren(Box<Expr>),
Perform(Symbol, Box<Expr>),
Handle {
body: Box<Expr>,
return_var: Symbol,
return_body: Box<Expr>,
handlers: Vec<EffectHandler>,
},
Resume(Box<Expr>, Box<Expr>),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BinOp {
AddInt,
SubInt,
MulInt,
DivInt,
ModInt,
AddFloat,
SubFloat,
MulFloat,
DivFloat,
ConcatStr,
LtInt,
GtInt,
LeInt,
GeInt,
LtFloat,
GtFloat,
LeFloat,
GeFloat,
Eq,
Ne,
Andalso,
Orelse,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Decl {
pub kind: DeclKind,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub enum DeclKind {
Val(Pat, Expr),
ValRec(Symbol, Expr),
Fun(Vec<FunBinding>),
Datatype(DatatypeDecl),
TypeAlias(TypeAliasDecl),
Local(Vec<Decl>, Vec<Decl>),
Use(String),
Effect(Symbol, Option<TypeExpr>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct FunBinding {
pub name: Symbol,
pub clauses: Vec<FunClause>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct FunClause {
pub pats: Vec<Pat>,
pub body: Expr,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct DatatypeDecl {
pub tyvars: Vec<Symbol>,
pub name: Symbol,
pub constructors: Vec<ConDecl>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ConDecl {
pub name: Symbol,
pub payload: Option<TypeExpr>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct TypeAliasDecl {
pub tyvars: Vec<Symbol>,
pub name: Symbol,
pub ty: TypeExpr,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct EffectHandler {
pub effect_name: Symbol,
pub payload_var: Symbol,
pub cont_var: Symbol,
pub body: Expr,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Pat {
pub kind: PatKind,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub enum PatKind {
Wildcard,
Var(Symbol),
IntLit(i64),
FloatLit(f64),
StringLit(String),
CharLit(char),
BoolLit(bool),
Unit,
Tuple(Vec<Pat>),
Constructor(Symbol, Option<Box<Pat>>),
Cons(Box<Pat>, Box<Pat>),
List(Vec<Pat>),
Ann(Box<Pat>, TypeExpr),
As(Symbol, Box<Pat>),
Paren(Box<Pat>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct TypeExpr {
pub kind: TypeExprKind,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub enum TypeExprKind {
Named(Symbol),
Var(Symbol),
App(Symbol, Vec<TypeExpr>),
Arrow(Box<TypeExpr>, Box<TypeExpr>),
Tuple(Vec<TypeExpr>),
Paren(Box<TypeExpr>),
}
pub struct Program {
pub decls: Vec<Decl>,
pub interner: crate::intern::StringInterner,
}
impl std::fmt::Debug for Program {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Program")
.field("decls", &self.decls)
.finish()
}
}