use crate::diagnostic::Span;
#[derive(Debug, Clone)]
pub struct TypeAnn {
pub kind: TypeKind,
pub span: Span,
}
#[derive(Debug, Clone)]
pub enum TypeKind {
Named(String),
Array(Box<TypeAnn>),
Generic(String, Vec<TypeAnn>),
}
#[derive(Debug, Clone)]
pub struct Param {
pub name: String,
pub ty: TypeAnn,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct FieldDef {
pub name: String,
pub ty: TypeAnn,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct VariantDef {
pub name: String,
pub fields: Vec<FieldDef>,
pub span: Span,
}
#[derive(Debug, Clone)]
pub enum Stmt {
Let {
name: String,
ty: Option<TypeAnn>,
value: Expr,
span: Span,
},
Var {
name: String,
ty: Option<TypeAnn>,
value: Option<Expr>,
span: Span,
},
Assign {
name: String,
name_span: Span,
op: AssignOp,
value: Expr,
span: Span,
},
Func {
name: String,
params: Vec<Param>,
ret: Option<TypeAnn>,
body: Vec<Stmt>,
span: Span,
},
Return { value: Option<Expr>, span: Span },
Struct {
name: String,
fields: Vec<FieldDef>,
span: Span,
},
Enum {
name: String,
variants: Vec<VariantDef>,
span: Span,
},
If {
cond: Expr,
then_body: Vec<Stmt>,
else_body: Option<Vec<Stmt>>,
span: Span,
},
While {
cond: Expr,
body: Vec<Stmt>,
span: Span,
},
For {
var: String,
iter: Expr,
body: Vec<Stmt>,
span: Span,
},
Expr(Expr),
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum AssignOp {
Set,
Add,
Sub,
}
#[derive(Debug, Clone)]
pub enum Expr {
Int(i64, Span),
Float(f64, Span),
Str(String, Span),
Bool(bool, Span),
Ident(String, Span),
Array(Vec<Expr>, Span),
Unary {
op: UnOp,
rhs: Box<Expr>,
span: Span,
},
Binary {
op: BinOp,
lhs: Box<Expr>,
rhs: Box<Expr>,
span: Span,
},
Index {
base: Box<Expr>,
index: Box<Expr>,
span: Span,
},
Range {
start: Box<Expr>,
end: Box<Expr>,
span: Span,
},
Call {
name: String,
args: Vec<Expr>,
span: Span,
},
StructLit {
name: String,
fields: Vec<(String, Expr)>,
span: Span,
},
EnumLit {
enum_name: String,
variant: String,
fields: Vec<(String, Expr)>,
span: Span,
},
Field {
base: Box<Expr>,
field: String,
span: Span,
},
Match {
scrutinee: Box<Expr>,
arms: Vec<MatchArm>,
span: Span,
},
}
#[derive(Debug, Clone)]
pub struct MatchArm {
pub pattern: Pattern,
pub body: Expr,
pub span: Span,
}
#[derive(Debug, Clone)]
pub enum Pattern {
Wildcard(Span),
Int(i64, Span),
Str(String, Span),
Bool(bool, Span),
Variant {
name: String,
bindings: Vec<String>,
span: Span,
},
}
impl Pattern {
pub fn span(&self) -> Span {
match self {
Pattern::Wildcard(s)
| Pattern::Int(_, s)
| Pattern::Str(_, s)
| Pattern::Bool(_, s) => *s,
Pattern::Variant { span, .. } => *span,
}
}
}
impl Expr {
pub fn span(&self) -> Span {
match self {
Expr::Int(_, s)
| Expr::Float(_, s)
| Expr::Str(_, s)
| Expr::Bool(_, s)
| Expr::Ident(_, s)
| Expr::Array(_, s) => *s,
Expr::Unary { span, .. }
| Expr::Binary { span, .. }
| Expr::Index { span, .. }
| Expr::Range { span, .. }
| Expr::Call { span, .. }
| Expr::StructLit { span, .. }
| Expr::EnumLit { span, .. }
| Expr::Field { span, .. }
| Expr::Match { span, .. } => *span,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum UnOp {
Neg,
Not,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum BinOp {
Add,
Sub,
Mul,
Div,
Mod,
Eq,
Ne,
Lt,
Gt,
Le,
Ge,
And,
Or,
}