use super::{join_nodes, FormalParameter, Identifier, Node, StatementList};
use gc::{Finalize, Trace};
use std::fmt;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
pub struct VarDeclList {
#[cfg_attr(feature = "serde", serde(flatten))]
vars: Box<[VarDecl]>,
}
impl<T> From<T> for VarDeclList
where
T: Into<Box<[VarDecl]>>,
{
fn from(list: T) -> Self {
Self { vars: list.into() }
}
}
impl From<VarDecl> for VarDeclList {
fn from(decl: VarDecl) -> Self {
Self {
vars: Box::new([decl]),
}
}
}
impl AsRef<[VarDecl]> for VarDeclList {
fn as_ref(&self) -> &[VarDecl] {
&self.vars
}
}
impl fmt::Display for VarDeclList {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if !self.vars.is_empty() {
write!(f, "var ")?;
join_nodes(f, &self.vars)
} else {
Ok(())
}
}
}
impl From<VarDeclList> for Node {
fn from(list: VarDeclList) -> Self {
Self::VarDeclList(list)
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
pub struct VarDecl {
name: Identifier,
init: Option<Node>,
}
impl fmt::Display for VarDecl {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.name, f)?;
if let Some(ref init) = self.init {
write!(f, " = {}", init)?;
}
Ok(())
}
}
impl VarDecl {
pub(in crate::syntax) fn new<N, I>(name: N, init: I) -> Self
where
N: Into<Identifier>,
I: Into<Option<Node>>,
{
Self {
name: name.into(),
init: init.into(),
}
}
pub fn name(&self) -> &str {
self.name.as_ref()
}
pub fn init(&self) -> Option<&Node> {
self.init.as_ref()
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
pub struct FunctionExpr {
name: Option<Box<str>>,
parameters: Box<[FormalParameter]>,
body: StatementList,
}
impl FunctionExpr {
pub(in crate::syntax) fn new<N, P, B>(name: N, parameters: P, body: B) -> Self
where
N: Into<Option<Box<str>>>,
P: Into<Box<[FormalParameter]>>,
B: Into<StatementList>,
{
Self {
name: name.into(),
parameters: parameters.into(),
body: body.into(),
}
}
pub fn name(&self) -> Option<&str> {
self.name.as_ref().map(Box::as_ref)
}
pub fn parameters(&self) -> &[FormalParameter] {
&self.parameters
}
pub fn body(&self) -> &[Node] {
self.body.statements()
}
pub(super) fn display(&self, f: &mut fmt::Formatter<'_>, indentation: usize) -> fmt::Result {
f.write_str("function")?;
if let Some(ref name) = self.name {
write!(f, " {}", name)?;
}
f.write_str("(")?;
join_nodes(f, &self.parameters)?;
f.write_str(") {{")?;
self.body.display(f, indentation + 1)?;
writeln!(f, "}}")
}
}
impl fmt::Display for FunctionExpr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.display(f, 0)
}
}
impl From<FunctionExpr> for Node {
fn from(expr: FunctionExpr) -> Self {
Self::FunctionExpr(expr)
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
pub struct FunctionDecl {
name: Box<str>,
parameters: Box<[FormalParameter]>,
body: StatementList,
}
impl FunctionDecl {
pub(in crate::syntax) fn new<N, P, B>(name: N, parameters: P, body: B) -> Self
where
N: Into<Box<str>>,
P: Into<Box<[FormalParameter]>>,
B: Into<StatementList>,
{
Self {
name: name.into(),
parameters: parameters.into(),
body: body.into(),
}
}
pub fn name(&self) -> &str {
&self.name
}
pub fn parameters(&self) -> &[FormalParameter] {
&self.parameters
}
pub fn body(&self) -> &[Node] {
self.body.statements()
}
pub(super) fn display(&self, f: &mut fmt::Formatter<'_>, indentation: usize) -> fmt::Result {
write!(f, "function {}(", self.name)?;
join_nodes(f, &self.parameters)?;
f.write_str(") {{")?;
self.body.display(f, indentation + 1)?;
writeln!(f, "}}")
}
}
impl From<FunctionDecl> for Node {
fn from(decl: FunctionDecl) -> Self {
Self::FunctionDecl(decl)
}
}
impl fmt::Display for FunctionDecl {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.display(f, 0)
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
pub struct ArrowFunctionDecl {
params: Box<[FormalParameter]>,
body: StatementList,
}
impl ArrowFunctionDecl {
pub(in crate::syntax) fn new<P, B>(params: P, body: B) -> Self
where
P: Into<Box<[FormalParameter]>>,
B: Into<StatementList>,
{
Self {
params: params.into(),
body: body.into(),
}
}
pub(crate) fn params(&self) -> &[FormalParameter] {
&self.params
}
pub(crate) fn body(&self) -> &[Node] {
&self.body.statements()
}
pub(super) fn display(&self, f: &mut fmt::Formatter<'_>, indentation: usize) -> fmt::Result {
write!(f, "(")?;
join_nodes(f, &self.params)?;
f.write_str(") => ")?;
self.body.display(f, indentation)
}
}
impl fmt::Display for ArrowFunctionDecl {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.display(f, 0)
}
}
impl From<ArrowFunctionDecl> for Node {
fn from(decl: ArrowFunctionDecl) -> Self {
Self::ArrowFunctionDecl(decl)
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
pub struct ConstDeclList {
#[cfg_attr(feature = "serde", serde(flatten))]
list: Box<[ConstDecl]>,
}
impl<T> From<T> for ConstDeclList
where
T: Into<Box<[ConstDecl]>>,
{
fn from(list: T) -> Self {
Self { list: list.into() }
}
}
impl From<ConstDecl> for ConstDeclList {
fn from(decl: ConstDecl) -> Self {
Self {
list: Box::new([decl]),
}
}
}
impl AsRef<[ConstDecl]> for ConstDeclList {
fn as_ref(&self) -> &[ConstDecl] {
&self.list
}
}
impl fmt::Display for ConstDeclList {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if !self.list.is_empty() {
write!(f, "const ")?;
join_nodes(f, &self.list)
} else {
Ok(())
}
}
}
impl From<ConstDeclList> for Node {
fn from(list: ConstDeclList) -> Self {
Self::ConstDeclList(list)
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
pub struct ConstDecl {
name: Identifier,
init: Node,
}
impl fmt::Display for ConstDecl {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} = {}", self.name, self.init)
}
}
impl ConstDecl {
pub(in crate::syntax) fn new<N, I>(name: N, init: I) -> Self
where
N: Into<Identifier>,
I: Into<Node>,
{
Self {
name: name.into(),
init: init.into(),
}
}
pub fn name(&self) -> &str {
self.name.as_ref()
}
pub fn init(&self) -> &Node {
&self.init
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
pub struct LetDeclList {
#[cfg_attr(feature = "serde", serde(flatten))]
list: Box<[LetDecl]>,
}
impl<T> From<T> for LetDeclList
where
T: Into<Box<[LetDecl]>>,
{
fn from(list: T) -> Self {
Self { list: list.into() }
}
}
impl From<LetDecl> for LetDeclList {
fn from(decl: LetDecl) -> Self {
Self {
list: Box::new([decl]),
}
}
}
impl AsRef<[LetDecl]> for LetDeclList {
fn as_ref(&self) -> &[LetDecl] {
&self.list
}
}
impl fmt::Display for LetDeclList {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if !self.list.is_empty() {
write!(f, "let ")?;
join_nodes(f, &self.list)
} else {
Ok(())
}
}
}
impl From<LetDeclList> for Node {
fn from(list: LetDeclList) -> Self {
Self::LetDeclList(list)
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
pub struct LetDecl {
name: Identifier,
init: Option<Node>,
}
impl fmt::Display for LetDecl {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.name, f)?;
if let Some(ref init) = self.init {
write!(f, " = {}", init)?;
}
Ok(())
}
}
impl LetDecl {
pub(in crate::syntax) fn new<N, I>(name: N, init: I) -> Self
where
N: Into<Identifier>,
I: Into<Option<Node>>,
{
Self {
name: name.into(),
init: init.into(),
}
}
pub fn name(&self) -> &str {
self.name.as_ref()
}
pub fn init(&self) -> Option<&Node> {
self.init.as_ref()
}
}