use super::Node;
use crate::syntax::ast::op;
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 Assign {
lhs: Box<Node>,
rhs: Box<Node>,
}
impl Assign {
pub(in crate::syntax) fn new<L, R>(lhs: L, rhs: R) -> Self
where
L: Into<Node>,
R: Into<Node>,
{
Self {
lhs: Box::new(lhs.into()),
rhs: Box::new(rhs.into()),
}
}
pub fn lhs(&self) -> &Node {
&self.lhs
}
pub fn rhs(&self) -> &Node {
&self.rhs
}
}
impl fmt::Display for Assign {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} = {}", self.lhs, self.rhs)
}
}
impl From<Assign> for Node {
fn from(op: Assign) -> Self {
Self::Assign(op)
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
pub struct BinOp {
op: op::BinOp,
lhs: Box<Node>,
rhs: Box<Node>,
}
impl BinOp {
pub(in crate::syntax) fn new<O, L, R>(op: O, lhs: L, rhs: R) -> Self
where
O: Into<op::BinOp>,
L: Into<Node>,
R: Into<Node>,
{
Self {
op: op.into(),
lhs: Box::new(lhs.into()),
rhs: Box::new(rhs.into()),
}
}
pub fn op(&self) -> op::BinOp {
self.op
}
pub fn lhs(&self) -> &Node {
&self.lhs
}
pub fn rhs(&self) -> &Node {
&self.rhs
}
}
impl fmt::Display for BinOp {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} {} {}", self.lhs, self.op, self.rhs)
}
}
impl From<BinOp> for Node {
fn from(op: BinOp) -> Self {
Self::BinOp(op)
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
pub struct UnaryOp {
op: op::UnaryOp,
target: Box<Node>,
}
impl UnaryOp {
pub(in crate::syntax) fn new<V>(op: op::UnaryOp, target: V) -> Self
where
V: Into<Node>,
{
Self {
op,
target: Box::new(target.into()),
}
}
pub fn op(&self) -> op::UnaryOp {
self.op
}
pub fn target(&self) -> &Node {
self.target.as_ref()
}
}
impl fmt::Display for UnaryOp {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}{}", self.op, self.target)
}
}
impl From<UnaryOp> for Node {
fn from(op: UnaryOp) -> Self {
Self::UnaryOp(op)
}
}