use crate::ast::{BinaryOperator, Ident, NumberLiteral, ParamConvention, Type, UnaryOperator};
use crate::location::Span;
use serde::{Deserialize, Serialize};
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Expr {
Literal {
value: Literal,
span: Span,
},
Invocation {
path: Vec<Ident>,
type_args: Vec<Type>,
args: Vec<(Option<Ident>, Self)>,
span: Span,
},
EnumInstantiation {
enum_name: Ident,
variant: Ident,
data: Vec<(Ident, Self)>,
span: Span,
},
InferredEnumInstantiation {
variant: Ident,
data: Vec<(Ident, Self)>,
span: Span,
},
Array {
elements: Vec<Self>,
span: Span,
},
Tuple {
fields: Vec<(Ident, Self)>,
span: Span,
},
Reference {
path: Vec<Ident>,
span: Span,
},
BinaryOp {
left: Box<Self>,
op: BinaryOperator,
right: Box<Self>,
span: Span,
},
UnaryOp {
op: UnaryOperator,
operand: Box<Self>,
span: Span,
},
ForExpr {
var: Ident,
collection: Box<Self>,
body: Box<Self>,
span: Span,
},
IfExpr {
condition: Box<Self>,
then_branch: Box<Self>,
else_branch: Option<Box<Self>>,
span: Span,
},
MatchExpr {
scrutinee: Box<Self>,
arms: Vec<MatchArm>,
span: Span,
},
Group {
expr: Box<Self>,
span: Span,
},
DictLiteral {
entries: Vec<(Self, Self)>,
span: Span,
},
DictAccess {
dict: Box<Self>,
key: Box<Self>,
span: Span,
},
FieldAccess {
object: Box<Self>,
field: Ident,
span: Span,
},
ClosureExpr {
params: Vec<ClosureParam>,
return_type: Option<Type>,
body: Box<Self>,
span: Span,
},
LetExpr {
mutable: bool,
pattern: BindingPattern,
ty: Option<Type>,
value: Box<Self>,
body: Box<Self>,
span: Span,
},
MethodCall {
receiver: Box<Self>,
method: Ident,
args: Vec<(Option<Ident>, Self)>,
span: Span,
},
Block {
statements: Vec<BlockStatement>,
result: Box<Self>,
span: Span,
},
}
impl Expr {
#[must_use]
pub const fn span(&self) -> Span {
match self {
Self::Literal { span, .. }
| Self::Invocation { span, .. }
| Self::EnumInstantiation { span, .. }
| Self::InferredEnumInstantiation { span, .. }
| Self::Array { span, .. }
| Self::Tuple { span, .. }
| Self::Reference { span, .. }
| Self::BinaryOp { span, .. }
| Self::UnaryOp { span, .. }
| Self::ForExpr { span, .. }
| Self::IfExpr { span, .. }
| Self::MatchExpr { span, .. }
| Self::Group { span, .. }
| Self::DictLiteral { span, .. }
| Self::DictAccess { span, .. }
| Self::FieldAccess { span, .. }
| Self::ClosureExpr { span, .. }
| Self::LetExpr { span, .. }
| Self::MethodCall { span, .. }
| Self::Block { span, .. } => *span,
}
}
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum BlockStatement {
Let {
mutable: bool,
pattern: BindingPattern,
ty: Option<Type>,
value: Expr,
span: Span,
},
Assign {
target: Expr,
value: Expr,
span: Span,
},
Expr(Expr),
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ClosureParam {
pub convention: ParamConvention,
pub name: Ident,
pub ty: Option<Type>,
pub span: Span,
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Literal {
String(String),
Number(NumberLiteral),
Boolean(bool),
Regex {
pattern: String,
flags: String,
},
Path(String),
Nil,
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct MatchArm {
pub pattern: Pattern,
pub body: Expr,
pub span: Span,
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Pattern {
Variant { name: Ident, bindings: Vec<Ident> },
Wildcard,
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum BindingPattern {
Simple(Ident),
Array {
elements: Vec<ArrayPatternElement>,
span: Span,
},
Struct {
fields: Vec<StructPatternField>,
span: Span,
},
Tuple {
elements: Vec<Self>,
span: Span,
},
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum ArrayPatternElement {
Binding(BindingPattern),
Rest(Option<Ident>),
Wildcard,
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct StructPatternField {
pub name: Ident,
pub alias: Option<Ident>,
}