pub use super::{
Visibility,
Ident,
Path,
Import,
Type,
Dims,
ClassMember,
};
use base::code::Span;
use lex;
#[derive(Clone, Debug)]
pub struct Block {
pub stmts: Vec<BlockStatement>,
}
#[derive(Clone, Debug)]
pub enum BlockStatement {
LocalVariableDecl {
final_: bool,
ty: Type,
vars: Vec<VariableDeclarator>,
},
Statement(Statement),
}
#[derive(Clone, Debug)]
pub struct Statement {
pub label: Option<Ident>,
pub stmt: StatementType,
pub span: Span,
}
#[derive(Clone, Debug)]
pub enum StatementType {
Empty,
Block(Block),
Expr(Expr),
IfThenElse {
cond: Expr,
then_branch: Box<Statement>,
else_branch: Option<Box<Statement>>,
},
While {
cond: Expr,
body: Box<Statement>,
},
Switch {
val: Expr,
arms: Vec<SwitchArm>,
empty_arms: Vec<SwitchLabel>,
},
DoWhile {
cond: Expr,
body: Box<Statement>,
},
For {
init: ForInit,
cond: Option<Expr>,
update: Vec<Statement>,
body: Box<Statement>,
},
Break(Option<Ident>),
Continue(Option<Ident>),
Return(Option<Expr>),
Throw(Expr),
}
#[derive(Clone, Debug)]
pub struct SwitchArm {
pub labels: Vec<SwitchLabel>,
pub block: BlockStatement,
}
#[derive(Clone, Debug)]
pub enum SwitchLabel {
Expr(Expr),
Name(Ident),
Default,
}
#[derive(Clone, Debug)]
pub struct Expr {
pub expr: ExprType,
pub span: Span,
}
impl Expr {
pub fn boxed(self) -> Box<Self> {
Box::new(self)
}
}
#[derive(Clone, Debug)]
pub enum ExprType {
Conditional {
cond: Box<Expr>,
if_branch: Box<Expr>,
else_branch: Box<Expr>,
},
BinOp {
op: BinOpType,
lhs: Box<Expr>,
rhs: Box<Expr>,
},
UnaryOp {
op: UnaryOpType,
expr: Box<Expr>,
},
Literal(lex::Lit),
ClassLiteral(Type),
Name(Path),
This,
FieldAccess {
root: Option<Box<Expr>>,
path: Path,
},
ArrayAccess {
obj: Box<Expr>,
idx: Box<Expr>,
},
MethodInvocation {
name: MethodInvocationType,
args: Vec<Expr>,
},
ArrayInit {
items: Vec<Expr>,
},
Cast {
ty: Type,
expr: Box<Expr>,
},
InstanceCreation {
name: Path,
args: Vec<Expr>,
body: Option<Vec<ClassMember>>,
},
ArrayCreation {
ty: Type,
expr_dims: Vec<Expr>,
empty_dims: Dims,
init: Option<Box<Expr>>,
},
}
#[derive(Clone, Copy, Debug)]
pub enum BinOpType {
Assign,
MulAssign,
DivAssign,
ModAssign,
AddAssign,
SubAssign,
ShlAssign,
ShrAssign,
ShrUnAssign,
AndAssign,
XorAssign,
OrAssign,
LogicalOr,
LogicalAnd,
BitwiseOr,
BitwiseAnd,
BitwiseXor,
Equals,
Gt,
Lt,
Ge,
Le,
Ne,
Add,
Sub,
Mul,
Div,
Mod,
Shl,
Shr,
ShrUn,
}
impl BinOpType {
pub fn from_token(tok: &lex::Token) -> Option<Self> {
use lex::Token::*;
match *tok {
Eq => Some(BinOpType::Assign),
Gt => Some(BinOpType::Gt),
Lt => Some(BinOpType::Lt),
EqEq => Some(BinOpType::Equals),
Ge => Some(BinOpType::Ge),
Le => Some(BinOpType::Le),
Ne => Some(BinOpType::Ne),
AndAnd => Some(BinOpType::LogicalAnd),
OrOr => Some(BinOpType::LogicalOr),
Plus => Some(BinOpType::Add),
Minus => Some(BinOpType::Sub),
Star => Some(BinOpType::Mul),
Slash => Some(BinOpType::Div),
And => Some(BinOpType::BitwiseAnd),
Or => Some(BinOpType::BitwiseOr),
Caret => Some(BinOpType::BitwiseXor),
Percent => Some(BinOpType::Mod),
Shl => Some(BinOpType::Shl),
Shr => Some(BinOpType::Shr),
ShrUn => Some(BinOpType::ShrUn),
PlusEq => Some(BinOpType::AddAssign),
MinusEq => Some(BinOpType::SubAssign),
StarEq => Some(BinOpType::MulAssign),
SlashEq => Some(BinOpType::DivAssign),
AndEq => Some(BinOpType::AndAssign),
OrEq => Some(BinOpType::OrAssign),
CaretEq => Some(BinOpType::XorAssign),
PercentEq => Some(BinOpType::ModAssign),
ShlEq => Some(BinOpType::ShlAssign),
ShrEq => Some(BinOpType::ShrAssign),
ShrUnEq => Some(BinOpType::ShrUnAssign),
_ => None,
}
}
}
#[derive(Clone, Copy, Debug)]
pub enum UnaryOpType {
Plus,
Neg,
PreIncr,
PreDecr,
PostIncr,
PostDecr,
Not,
BitwiseNot,
}
#[derive(Clone, Debug)]
pub enum MethodInvocationType {
SimpleName(Ident),
SimplePath(Path),
Expr(Box<Expr>, Ident),
}
#[derive(Clone, Debug)]
pub enum ForInit {
VarDecl(Box<BlockStatement>),
Stmts(Vec<Statement>),
}
#[derive(Clone, Debug)]
pub struct VariableDeclarator {
pub name: Ident,
pub dims: Dims,
pub init: Option<Expr>,
}