use super::{Name, VersionCond};
use crate::source::token::Span;
#[derive(Debug, Clone, PartialEq)]
pub struct Block {
pub stmts: Vec<Stmt>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Stmt {
Let {
pattern: Pattern,
ty: Option<Type>,
value: Expr,
},
Var {
name: Name,
ty: Option<Type>,
value: Option<Expr>,
},
Assign {
place: Expr,
op: Option<BinOp>,
value: Expr,
},
For {
pattern: Pattern,
iter: Expr,
body: Block,
},
While {
cond: Cond,
body: Block,
},
Loop(Block),
Break(Span),
Continue(Span),
Return(Option<Expr>, Span),
Skip(Option<Expr>, Span),
Expr(Expr),
}
#[derive(Debug, Clone, PartialEq)]
pub struct Expr {
pub kind: ExprKind,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ExprKind {
Int(i64),
Float(f64),
Unit {
value: String,
unit: String,
},
Str(Vec<StrSeg>),
RawStr(String),
Text(String),
Content {
kind: String,
id: String,
},
Tag(String),
Bool(bool),
None,
Ident(String),
SelfValue,
It,
Mc(VersionCond),
Tuple(Vec<Expr>),
List(Vec<Expr>),
Map(Vec<(Expr, Expr)>),
Lambda {
params: Vec<Name>,
body: Vec<Stmt>,
},
Unary {
op: UnOp,
expr: Box<Expr>,
},
Binary {
op: BinOp,
left: Box<Expr>,
right: Box<Expr>,
},
Range {
from: Box<Expr>,
to: Box<Expr>,
inclusive: bool,
},
Is {
expr: Box<Expr>,
ty: Type,
bind: Option<Name>,
negated: bool,
},
As {
expr: Box<Expr>,
ty: Type,
checked: bool,
},
Call {
callee: Box<Expr>,
args: Vec<Arg>,
},
Index {
expr: Box<Expr>,
index: Box<Expr>,
},
TypeArgs {
expr: Box<Expr>,
args: Vec<Type>,
},
Member {
expr: Box<Expr>,
name: Name,
safe: bool,
},
If {
cond: Box<Cond>,
then: Block,
otherwise: Option<Box<Expr>>,
},
Match {
expr: Box<Expr>,
arms: Vec<Arm>,
},
Block(Block),
Error,
}
#[derive(Debug, Clone, PartialEq)]
pub enum StrSeg {
Text(String),
Expr(Expr),
}
#[derive(Debug, Clone, PartialEq)]
pub enum Cond {
Expr(Expr),
Let { pattern: Box<Pattern>, value: Expr },
}
#[derive(Debug, Clone, PartialEq)]
pub struct Arg {
pub name: Option<Name>,
pub value: Expr,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Arm {
pub pattern: Pattern,
pub guard: Option<Expr>,
pub body: Expr,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UnOp {
Neg,
Not,
Try,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BinOp {
Coalesce,
Or,
And,
Eq,
NotEq,
Lt,
LtEq,
Gt,
GtEq,
In,
NotIn,
Add,
Sub,
Mul,
Div,
Rem,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Pattern {
Wild(Span),
Value(Expr),
Range {
from: Expr,
to: Expr,
},
Is {
ty: Type,
bind: Option<Name>,
},
Variant {
path: Vec<Name>,
args: Vec<Pattern>,
},
Tuple(Vec<Pattern>),
Or(Vec<Pattern>),
Else(Span),
}
#[derive(Debug, Clone, PartialEq)]
pub struct Type {
pub kind: TypeKind,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub enum TypeKind {
Path {
path: Vec<Name>,
args: Vec<Type>,
},
Bounded {
base: Box<Type>,
range: Box<Expr>,
},
Tuple(Vec<Type>),
Fn {
params: Vec<Type>,
ret: Box<Type>,
},
Optional(Box<Type>),
}