use crate::{Identifier, Node, NodeID};
use leo_span::Span;
use serde::{Deserialize, Serialize};
use std::fmt;
mod access;
pub use access::*;
mod array;
pub use array::*;
mod binary;
pub use binary::*;
mod call;
pub use call::*;
mod cast;
pub use cast::*;
mod struct_init;
pub use struct_init::*;
mod err;
pub use err::*;
mod ternary;
pub use ternary::*;
mod tuple;
pub use tuple::*;
mod unary;
pub use unary::*;
mod unit;
pub use unit::*;
mod literal;
pub use literal::*;
pub mod locator;
pub use locator::*;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Expression {
Access(AccessExpression),
Array(ArrayExpression),
Binary(BinaryExpression),
Call(CallExpression),
Cast(CastExpression),
Err(ErrExpression),
Identifier(Identifier),
Literal(Literal),
Locator(LocatorExpression),
Struct(StructExpression),
Ternary(TernaryExpression),
Tuple(TupleExpression),
Unary(UnaryExpression),
Unit(UnitExpression),
}
impl Default for Expression {
fn default() -> Self {
Expression::Err(Default::default())
}
}
impl Node for Expression {
fn span(&self) -> Span {
use Expression::*;
match self {
Access(n) => n.span(),
Array(n) => n.span(),
Binary(n) => n.span(),
Call(n) => n.span(),
Cast(n) => n.span(),
Err(n) => n.span(),
Identifier(n) => n.span(),
Literal(n) => n.span(),
Locator(n) => n.span(),
Struct(n) => n.span(),
Ternary(n) => n.span(),
Tuple(n) => n.span(),
Unary(n) => n.span(),
Unit(n) => n.span(),
}
}
fn set_span(&mut self, span: Span) {
use Expression::*;
match self {
Access(n) => n.set_span(span),
Array(n) => n.set_span(span),
Binary(n) => n.set_span(span),
Call(n) => n.set_span(span),
Cast(n) => n.set_span(span),
Identifier(n) => n.set_span(span),
Literal(n) => n.set_span(span),
Locator(n) => n.set_span(span),
Err(n) => n.set_span(span),
Struct(n) => n.set_span(span),
Ternary(n) => n.set_span(span),
Tuple(n) => n.set_span(span),
Unary(n) => n.set_span(span),
Unit(n) => n.set_span(span),
}
}
fn id(&self) -> NodeID {
use Expression::*;
match self {
Access(n) => n.id(),
Array(n) => n.id(),
Binary(n) => n.id(),
Call(n) => n.id(),
Cast(n) => n.id(),
Identifier(n) => n.id(),
Literal(n) => n.id(),
Locator(n) => n.id(),
Err(n) => n.id(),
Struct(n) => n.id(),
Ternary(n) => n.id(),
Tuple(n) => n.id(),
Unary(n) => n.id(),
Unit(n) => n.id(),
}
}
fn set_id(&mut self, id: NodeID) {
use Expression::*;
match self {
Access(n) => n.set_id(id),
Array(n) => n.set_id(id),
Binary(n) => n.set_id(id),
Call(n) => n.set_id(id),
Cast(n) => n.set_id(id),
Identifier(n) => n.set_id(id),
Literal(n) => n.set_id(id),
Locator(n) => n.set_id(id),
Err(n) => n.set_id(id),
Struct(n) => n.set_id(id),
Ternary(n) => n.set_id(id),
Tuple(n) => n.set_id(id),
Unary(n) => n.set_id(id),
Unit(n) => n.set_id(id),
}
}
}
impl fmt::Display for Expression {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use Expression::*;
match &self {
Access(n) => n.fmt(f),
Array(n) => n.fmt(f),
Binary(n) => n.fmt(f),
Call(n) => n.fmt(f),
Cast(n) => n.fmt(f),
Err(n) => n.fmt(f),
Identifier(n) => n.fmt(f),
Literal(n) => n.fmt(f),
Locator(n) => n.fmt(f),
Struct(n) => n.fmt(f),
Ternary(n) => n.fmt(f),
Tuple(n) => n.fmt(f),
Unary(n) => n.fmt(f),
Unit(n) => n.fmt(f),
}
}
}
#[derive(Clone, Copy, Eq, PartialEq)]
pub(crate) enum Associativity {
Left,
Right,
None,
}
impl Expression {
pub(crate) fn precedence(&self) -> u32 {
use Expression::*;
match self {
Binary(e) => e.precedence(),
Cast(_) => 12,
Ternary(_) => 14,
Access(_) | Array(_) | Call(_) | Err(_) | Identifier(_) | Literal(_) | Locator(_) | Struct(_)
| Tuple(_) | Unary(_) | Unit(_) => 20,
}
}
pub(crate) fn associativity(&self) -> Associativity {
if let Expression::Binary(bin) = self { bin.associativity() } else { Associativity::None }
}
}