use super::{Expr, Name, Type};
use crate::source::token::Span;
#[derive(Debug, Clone, PartialEq)]
pub enum Goto {
Label(Name),
Case(Expr),
Default,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Block {
pub stmts: Vec<Stmt>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Binding {
One(Name),
Tuple(Vec<Name>),
}
impl Binding {
pub fn names(&self) -> impl Iterator<Item = &str> {
let names: Vec<&str> = match self {
Binding::One(n) => vec![n.text.as_str()],
Binding::Tuple(ns) => ns.iter().map(|n| n.text.as_str()).collect(),
};
names.into_iter()
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum Stmt {
Local {
ty: Option<Type>,
binding: Binding,
value: Option<Expr>,
mutable: bool,
},
Assign {
place: Expr,
op: Option<super::BinOp>,
value: Expr,
},
If {
cond: Expr,
then: Box<Stmt>,
otherwise: Option<Box<Stmt>>,
},
Foreach {
ty: Option<Type>,
binding: Binding,
iter: Expr,
body: Box<Stmt>,
mutable: bool,
awaits: bool,
},
For {
init: Option<Box<Stmt>>,
cond: Option<Expr>,
step: Option<Box<Stmt>>,
body: Box<Stmt>,
},
While {
cond: Expr,
body: Box<Stmt>,
},
DoWhile {
body: Box<Stmt>,
cond: Expr,
},
Block(Block),
Label(Name),
Goto(Goto, Span),
Break(Span),
Continue(Span),
Return(Option<Expr>, Span),
Skip(Option<Expr>, Span),
Yield(Option<Expr>, Span),
Unsafe(Block, Span),
Checked(Block, bool),
Switch {
expr: Expr,
sections: Vec<Section>,
},
Function(Box<super::Decl>),
Lock {
target: Expr,
value: Option<super::Name>,
body: Box<Stmt>,
at: Span,
},
Expr(Expr),
Value(Expr),
}
pub fn local_functions(stmts: &[Stmt]) -> impl Iterator<Item = &super::Method> {
stmts.iter().filter_map(|s| match s {
Stmt::Function(d) => match &d.kind {
super::DeclKind::Method(m) => Some(m),
_ => None,
},
_ => None,
})
}
#[derive(Debug, Clone, PartialEq)]
pub struct Section {
pub labels: Vec<Option<(super::Pattern, Option<Expr>)>>,
pub body: Vec<Stmt>,
}