use crate::comment::Comment;
use crate::ident::{Ident, ModuleName};
use crate::literal::Literal;
use crate::node::Spanned;
use crate::operator::InfixDirection;
use crate::pattern::Pattern;
use crate::type_annotation::TypeAnnotation;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq)]
pub enum Expr {
Unit,
Literal(Literal),
FunctionOrValue {
module_name: ModuleName,
name: Ident,
},
PrefixOperator(Ident),
OperatorApplication {
operator: Ident,
direction: InfixDirection,
left: Box<Spanned<Expr>>,
right: Box<Spanned<Expr>>,
},
BinOps {
operands_and_operators: Vec<(Spanned<Expr>, Spanned<Ident>)>,
final_operand: Box<Spanned<Expr>>,
},
Application(Vec<Spanned<Expr>>),
IfElse {
branches: Vec<IfBranch>,
else_branch: Box<Spanned<Expr>>,
},
Negation(Box<Spanned<Expr>>),
Tuple(Vec<Spanned<Expr>>),
Parenthesized {
expr: Box<Spanned<Expr>>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Vec::is_empty")
)]
trailing_comments: Vec<Spanned<Comment>>,
},
LetIn {
declarations: Vec<Spanned<LetDeclaration>>,
body: Box<Spanned<Expr>>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Vec::is_empty")
)]
trailing_comments: Vec<Spanned<Comment>>,
},
CaseOf {
expr: Box<Spanned<Expr>>,
branches: Vec<CaseBranch>,
},
Lambda {
args: Vec<Spanned<Pattern>>,
body: Box<Spanned<Expr>>,
},
Record(Vec<Spanned<RecordSetter>>),
RecordUpdate {
base: Spanned<Ident>,
updates: Vec<Spanned<RecordSetter>>,
},
RecordAccess {
record: Box<Spanned<Expr>>,
field: Spanned<Ident>,
},
RecordAccessFunction(Ident),
List {
elements: Vec<Spanned<Expr>>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Vec::is_empty")
)]
element_inline_comments: Vec<Option<Spanned<Comment>>>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Vec::is_empty")
)]
trailing_comments: Vec<Spanned<Comment>>,
},
GLSLExpression(String),
}
impl Eq for Expr {}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct IfBranch {
pub condition: Spanned<Expr>,
pub then_branch: Spanned<Expr>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Vec::is_empty")
)]
pub trailing_comments: Vec<Spanned<Comment>>,
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RecordSetter {
pub field: Spanned<Ident>,
pub value: Spanned<Expr>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub trailing_comment: Option<Spanned<Comment>>,
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CaseBranch {
pub pattern: Spanned<Pattern>,
pub body: Spanned<Expr>,
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum LetDeclaration {
Function(Box<Function>),
Destructuring {
pattern: Box<Spanned<Pattern>>,
body: Box<Spanned<Expr>>,
},
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Function {
pub documentation: Option<Spanned<String>>,
pub signature: Option<Spanned<Signature>>,
pub declaration: Spanned<FunctionImplementation>,
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Signature {
pub name: Spanned<Ident>,
pub type_annotation: Spanned<TypeAnnotation>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub trailing_comment: Option<Spanned<Comment>>,
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct FunctionImplementation {
pub name: Spanned<Ident>,
pub args: Vec<Spanned<Pattern>>,
pub body: Spanned<Expr>,
}