use super::{Name, Pattern, Stmt, Type, VersionCond};
use crate::source::token::Span;
#[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),
Char(char),
Bool(bool),
Null,
Ident(String),
This,
Base,
It,
Declare {
ty: Option<Type>,
name: Name,
mutable: bool,
},
TypeOf(Type),
NameOf(Box<Expr>),
Checked {
expr: Box<Expr>,
checked: bool,
},
Default(Option<Type>),
Mc(VersionCond),
Tuple {
items: Vec<Expr>,
names: Vec<Option<Name>>,
},
Collection(Vec<Element>),
New {
ty: Option<Type>,
args: Option<Vec<Arg>>,
init: Vec<(Name, Expr)>,
items: Vec<super::Stmt>,
},
NewArray {
elem: Option<Type>,
rank: usize,
sizes: Vec<Expr>,
init: Option<Vec<ArrayItem>>,
},
Lambda {
params: Vec<LambdaParam>,
body: LambdaBody,
asynchronous: bool,
},
Unary {
op: UnOp,
expr: Box<Expr>,
},
Cast {
ty: Type,
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>,
pattern: Box<Pattern>,
},
As {
expr: Box<Expr>,
ty: Type,
},
Has {
expr: Box<Expr>,
ty: Type,
},
Conditional {
cond: Box<Expr>,
then: Box<Expr>,
otherwise: Box<Expr>,
},
With {
expr: Box<Expr>,
inits: Vec<(Name, Expr)>,
},
Switch {
expr: Box<Expr>,
arms: Vec<Arm>,
},
Call {
callee: Box<Expr>,
args: Vec<Arg>,
},
Index {
expr: Box<Expr>,
args: Vec<Expr>,
safe: bool,
},
TypeArgs {
expr: Box<Expr>,
args: Vec<Type>,
},
Member {
expr: Box<Expr>,
name: Name,
safe: bool,
},
Macro {
name: Name,
args: Vec<Expr>,
},
Move(Box<Expr>),
NotNull(Box<Expr>),
Error,
}
#[derive(Debug, Clone, PartialEq)]
pub enum StrSeg {
Text(String),
Expr(Expr),
}
#[derive(Debug, Clone, PartialEq)]
pub enum ArrayItem {
Value(Expr),
Nested(Vec<ArrayItem>),
}
impl ArrayItem {
pub fn each_value<'e>(&'e self, f: &mut impl FnMut(&'e Expr)) {
match self {
ArrayItem::Value(e) => f(e),
ArrayItem::Nested(items) => items.iter().for_each(|i| i.each_value(f)),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum Element {
Item(Expr),
Entry(Expr, Expr),
Spread(Expr),
}
#[derive(Debug, Clone, PartialEq)]
pub struct LambdaParam {
pub ty: Option<Type>,
pub name: Name,
}
#[derive(Debug, Clone, PartialEq)]
pub enum LambdaBody {
Expr(Box<Expr>),
Block(Vec<Stmt>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct Arg {
pub name: Option<Name>,
pub pass: Option<super::Pass>,
pub value: Expr,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Arm {
pub pattern: Pattern,
pub guard: Option<Expr>,
pub value: Expr,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UnOp {
Neg,
Not,
BitNot,
Increment,
Decrement,
PostIncrement,
PostDecrement,
Try,
Await,
FromEnd,
}
impl UnOp {
pub fn steps(self) -> bool {
matches!(
self,
UnOp::Increment | UnOp::Decrement | UnOp::PostIncrement | UnOp::PostDecrement
)
}
pub fn declared(self) -> UnOp {
match self {
UnOp::PostIncrement => UnOp::Increment,
UnOp::PostDecrement => UnOp::Decrement,
op => op,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BinOp {
Coalesce,
Or,
And,
Eq,
NotEq,
Lt,
LtEq,
Gt,
GtEq,
In,
Add,
Sub,
Mul,
Div,
Rem,
BitAnd,
BitOr,
BitXor,
Shl,
Shr,
}