use crate::expression::Expression;
use crate::pattern::Pattern;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VariableDeclaration {
kind: VariableKind,
declarators: Vec<VariableDeclarator>,
}
impl VariableDeclaration {
#[must_use]
pub fn new(kind: VariableKind, declarators: Vec<VariableDeclarator>) -> Self {
Self { kind, declarators }
}
#[must_use]
pub fn kind(&self) -> VariableKind {
self.kind
}
#[must_use]
pub fn declarators(&self) -> &[VariableDeclarator] {
&self.declarators
}
}
impl std::fmt::Display for VariableDeclaration {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} ", self.kind)?;
let parts = self
.declarators
.iter()
.map(|d| format!("{d}"))
.collect::<Vec<_>>()
.join(", ");
f.write_str(&parts)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum VariableKind {
Var,
Let,
Const,
}
impl std::fmt::Display for VariableKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
Self::Var => "var",
Self::Let => "let",
Self::Const => "const",
})
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VariableDeclarator {
id: Pattern,
init: Option<Expression>,
}
impl VariableDeclarator {
#[must_use]
pub fn new(id: Pattern, init: Option<Expression>) -> Self {
Self { id, init }
}
#[must_use]
pub fn id(&self) -> &Pattern {
&self.id
}
#[must_use]
pub fn init(&self) -> Option<&Expression> {
self.init.as_ref()
}
}
impl std::fmt::Display for VariableDeclarator {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self.init {
Some(expr) => write!(f, "{} = {expr}", self.id),
None => write!(f, "{}", self.id),
}
}
}