#[derive(Debug, Clone, PartialEq)]
pub struct Program(pub Vec<Statement>);
#[derive(Debug, Clone, PartialEq)]
pub struct Block {
pub statements: Vec<Statement>,
pub final_expr: Option<Box<Expression>>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Statement {
Macro {
name: String,
args: Vec<MacroArg>,
statement: Box<Statement>,
},
Expression(Expression),
VarDecl {
pattern: Pattern,
value: Option<Expression>,
},
Assignment {
target: LValue,
op: AssignOp,
value: Expression,
},
FnDecl {
name: String,
params: Vec<Parameter>,
body: Block, is_pub: bool, },
ClassDecl {
name: String,
members: Vec<ClassMember>,
is_pub: bool, },
Import(ImportSpec),
Return(Option<Expression>),
Break(Option<Expression>), Continue,
Empty,
}
#[derive(Debug, Clone, PartialEq)]
pub enum AssignOp {
Assign, AddAssign, SubAssign, MulAssign, DivAssign, ModAssign, }
#[derive(Debug, Clone, PartialEq)]
pub enum LValue {
Identifier(String),
GetAttr(Box<Expression>, String), GetItem(Box<Expression>, Box<Expression>), }
#[derive(Debug, Clone, PartialEq)]
pub enum Expression {
Literal(LiteralValue),
Identifier(String),
InterpolatedString(Vec<InterpolationPart>),
GetAttr(Box<Expression>, String), GetItem(Box<Expression>, Box<Expression>), FunctionCall(Box<Expression>, Vec<Expression>), MethodCall(Box<Expression>, String, Vec<Expression>),
Add(Box<Expression>, Box<Expression>), Sub(Box<Expression>, Box<Expression>), Mul(Box<Expression>, Box<Expression>), Div(Box<Expression>, Box<Expression>), Mod(Box<Expression>, Box<Expression>), Pow(Box<Expression>, Box<Expression>),
Eq(Box<Expression>, Box<Expression>), Ne(Box<Expression>, Box<Expression>), Lt(Box<Expression>, Box<Expression>), Le(Box<Expression>, Box<Expression>), Gt(Box<Expression>, Box<Expression>), Ge(Box<Expression>, Box<Expression>),
In(Box<Expression>, Box<Expression>), Is(Box<Expression>, Box<Expression>), NotIn(Box<Expression>, Box<Expression>), IsNot(Box<Expression>, Box<Expression>),
And(Box<Expression>, Box<Expression>), Or(Box<Expression>, Box<Expression>), Xor(Box<Expression>, Box<Expression>),
Neg(Box<Expression>), Not(Box<Expression>),
Pipe(Box<Expression>, Box<Expression>),
RangeExclusive(Box<Expression>, Box<Expression>), RangeInclusive(Box<Expression>, Box<Expression>),
Block(Block),
If {
condition: Box<Expression>,
then_expr: Block,
else_expr: Option<Block>,
},
Match {
expr: Box<Expression>,
cases: Vec<MatchCase>,
},
While {
condition: Box<Expression>,
body: Block,
},
For {
pattern: Pattern,
iter: Box<Expression>,
body: Block,
},
Loop {
body: Block,
},
Try {
body: Block,
catch: CatchClause,
},
With {
resources: Vec<WithResource>,
body: Block,
},
Lambda {
params: Vec<String>,
body: LambdaBody,
},
List(Vec<Expression>),
Dict(Vec<(Expression, Expression)>),
}
#[derive(Debug, Clone, PartialEq)]
pub enum LiteralValue {
Null,
Bool(bool),
Int(i64),
Float(f64),
String(String),
RawString(String), }
#[derive(Debug, Clone, PartialEq)]
pub enum LambdaBody {
Expression(Box<Expression>), Block(Block), }
#[derive(Debug, Clone, PartialEq)]
pub struct Parameter {
pub name: String,
pub default: Option<LiteralValue>, pub kind: ParameterKind,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ParameterKind {
Regular, Rest, Keyword, }
#[derive(Debug, Clone, PartialEq)]
pub struct ClassMember {
pub name: String,
pub kind: ClassMemberKind,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ClassMemberKind {
Field(Option<Expression>), Method {
params: Vec<Parameter>,
body: Block, },
StaticMethod {
params: Vec<Parameter>,
body: Block,
},
}
#[derive(Debug, Clone, PartialEq)]
pub struct ImportSpec {
pub module: String,
pub items: ImportItems,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ImportItems {
All, Specific(Vec<ImportItem>), }
#[derive(Debug, Clone, PartialEq)]
pub struct ImportItem {
pub name: String,
pub alias: Option<String>, }
#[derive(Debug, Clone, PartialEq)]
pub struct MatchCase {
pub pattern: Pattern,
pub guard: Option<Expression>,
pub body: Block, }
#[derive(Debug, Clone, PartialEq)]
pub enum Pattern {
Literal(LiteralValue),
Variable(String),
Wildcard, List(Vec<Pattern>), ListRest(Vec<Pattern>, Option<String>), Dict(Vec<DictPattern>), Range(Box<Pattern>, Box<Pattern>), }
#[derive(Debug, Clone, PartialEq)]
pub struct DictPattern {
pub key: String,
pub alias: Option<String>, }
#[derive(Debug, Clone, PartialEq)]
pub struct CatchClause {
pub pattern: Pattern, pub body: Block, }
#[derive(Debug, Clone, PartialEq)]
pub struct WithResource {
pub name: String,
pub value: Expression,
}
#[derive(Debug, Clone, PartialEq)]
pub enum InterpolationPart {
Text(String),
Expression(Expression),
}
#[derive(Debug, Clone, PartialEq)]
pub enum MacroArg {
Positional(LiteralValue),
Named(String, LiteralValue), }
impl Expression {
pub fn binary_op_method_name(&self) -> Option<&'static str> {
match self {
Expression::Add(_, _) => Some("op_add"),
Expression::Sub(_, _) => Some("op_sub"),
Expression::Mul(_, _) => Some("op_mul"),
Expression::Div(_, _) => Some("op_div"),
Expression::Mod(_, _) => Some("op_mod"),
Expression::Pow(_, _) => Some("op_pow"),
Expression::Eq(_, _) => Some("op_eq"),
Expression::Ne(_, _) => Some("op_ne"),
Expression::Lt(_, _) => Some("op_lt"),
Expression::Le(_, _) => Some("op_le"),
Expression::Gt(_, _) => Some("op_gt"),
Expression::Ge(_, _) => Some("op_ge"),
Expression::In(_, _) => Some("op_contains"),
_ => None,
}
}
}
impl AssignOp {
pub fn to_method_name(&self) -> &'static str {
match self {
AssignOp::Assign => panic!("Assign is not a compound operator"),
AssignOp::AddAssign => "op_add",
AssignOp::SubAssign => "op_sub",
AssignOp::MulAssign => "op_mul",
AssignOp::DivAssign => "op_div",
AssignOp::ModAssign => "op_mod",
}
}
}