Add Display implementations for abstract tree

This commit is contained in:
Jeff 2024-06-26 12:50:46 -04:00
parent 49fe4555c6
commit 822f12b44d
18 changed files with 413 additions and 4 deletions

View File

@ -1,4 +1,7 @@
use std::borrow::Borrow; use std::{
borrow::Borrow,
fmt::{self, Display, Formatter},
};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -77,3 +80,9 @@ impl AbstractNode for As {
.map(|r#type| Some(r#type)) .map(|r#type| Some(r#type))
} }
} }
impl Display for As {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{} as {}", self.expression, self.constructor)
}
}

View File

@ -1,3 +1,5 @@
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
@ -237,3 +239,27 @@ impl AbstractNode for Assignment {
Ok(None) Ok(None)
} }
} }
impl Display for Assignment {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let Assignment {
identifier,
constructor,
operator,
statement,
} = self;
write!(f, "{} ", identifier.node)?;
if let Some(constructor) = constructor {
write!(f, ": {constructor} ")?;
}
match operator {
AssignmentOperator::Assign => write!(f, "="),
AssignmentOperator::AddAssign => write!(f, "+="),
AssignmentOperator::SubAssign => write!(f, "-="),
}?;
write!(f, " {statement}")
}
}

View File

@ -1,4 +1,7 @@
use std::sync::Mutex; use std::{
fmt::{self, Display, Formatter},
sync::Mutex,
};
use rayon::prelude::*; use rayon::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -69,3 +72,15 @@ impl AbstractNode for AsyncBlock {
self.statements.last().unwrap().expected_type(_context) self.statements.last().unwrap().expected_type(_context)
} }
} }
impl Display for AsyncBlock {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "async {{")?;
for statement in &self.statements {
write!(f, "{statement}")?;
}
write!(f, "}}")
}
}

View File

@ -1,3 +1,5 @@
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
@ -62,6 +64,18 @@ impl AbstractNode for Block {
} }
} }
impl Display for Block {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{{")?;
for statement in &self.statements {
write!(f, "{statement}")?;
}
write!(f, "}}")
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::{ use crate::{

View File

@ -1,3 +1,5 @@
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
@ -90,6 +92,42 @@ impl AbstractNode for EnumDeclaration {
} }
} }
impl Display for EnumDeclaration {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let EnumDeclaration {
name,
type_parameters,
variants,
} = self;
write!(f, "enum {}", name.node)?;
if let Some(parameters) = type_parameters {
write!(f, "<")?;
for WithPosition { node, .. } in parameters {
write!(f, "{node}, ")?;
}
write!(f, ">")?;
}
for EnumVariant { name, content } in variants {
write!(f, "{}", name.node)?;
if let Some(content) = content {
write!(f, "(")?;
for constructor in content {
write!(f, "{constructor}, ")?;
}
write!(f, ")")?;
}
}
Ok(())
}
}
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct EnumVariant { pub struct EnumVariant {
pub name: WithPosition<Identifier>, pub name: WithPosition<Identifier>,

View File

@ -1,3 +1,5 @@
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
@ -138,3 +140,18 @@ impl AbstractNode for Expression {
} }
} }
} }
impl Display for Expression {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
Expression::As(inner) => write!(f, "{}", inner.node),
Expression::FunctionCall(inner) => write!(f, "{}", inner.node),
Expression::Identifier(inner) => write!(f, "{}", inner.node),
Expression::MapIndex(inner) => write!(f, "{}", inner.node),
Expression::ListIndex(inner) => write!(f, "{}", inner.node),
Expression::Logic(inner) => write!(f, "{}", inner.node),
Expression::Math(inner) => write!(f, "{}", inner.node),
Expression::Value(inner) => write!(f, "{}", inner.node),
}
}
}

View File

@ -1,4 +1,7 @@
use std::cmp::Ordering; use std::{
cmp::Ordering,
fmt::{self, Display, Formatter},
};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -291,6 +294,41 @@ impl AbstractNode for FunctionCall {
} }
} }
impl Display for FunctionCall {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let FunctionCall {
function_expression,
type_arguments,
value_arguments,
context,
} = self;
write!(f, "{function_expression}")?;
if let Some(type_arguments) = type_arguments {
write!(f, "::<")?;
for constructor in type_arguments {
write!(f, "{constructor}, ")?;
}
write!(f, ">")?;
}
write!(f, "(")?;
if let Some(value_arguments) = value_arguments {
for expression in value_arguments {
write!(f, "{expression}, ")?;
}
}
write!(f, ")")?;
Ok(())
}
}
impl Eq for FunctionCall {} impl Eq for FunctionCall {}
impl PartialEq for FunctionCall { impl PartialEq for FunctionCall {

View File

@ -1,3 +1,5 @@
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
@ -177,6 +179,31 @@ impl AbstractNode for IfElse {
} }
} }
impl Display for IfElse {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let IfElse {
if_expression,
if_block,
else_ifs,
else_block,
} = self;
write!(f, "if {if_expression} {}", if_block.node)?;
if let Some(else_ifs) = else_ifs {
for (expression, block) in else_ifs {
write!(f, "else if {expression} {}", block.node)?;
}
}
if let Some(else_block) = else_block {
write!(f, "{}", else_block.node)?;
}
Ok(())
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::{ use crate::{

View File

@ -1,3 +1,5 @@
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
@ -148,3 +150,11 @@ impl AbstractNode for ListIndex {
} }
} }
} }
impl Display for ListIndex {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let ListIndex { collection, index } = self;
write!(f, "{collection}[{index}]")
}
}

View File

@ -1,3 +1,5 @@
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
@ -257,6 +259,22 @@ impl AbstractNode for Logic {
} }
} }
impl Display for Logic {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
Logic::Equal(left, right) => write!(f, "{left} == {right}"),
Logic::NotEqual(left, right) => write!(f, "{left} != {right}"),
Logic::Greater(left, right) => write!(f, "{left} > {right}"),
Logic::Less(left, right) => write!(f, "{left} < {right}"),
Logic::GreaterOrEqual(left, right) => write!(f, "{left} >= {right}"),
Logic::LessOrEqual(left, right) => write!(f, "{left} <= {right}"),
Logic::And(left, right) => write!(f, "{left} && {right}"),
Logic::Or(left, right) => write!(f, "{left} || {right}"),
Logic::Not(expression) => write!(f, "!{expression}"),
}
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::abstract_tree::{ValueNode, WithPos}; use crate::abstract_tree::{ValueNode, WithPos};

View File

@ -1,3 +1,5 @@
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
@ -21,6 +23,7 @@ impl Loop {
self.statements.last().unwrap() self.statements.last().unwrap()
} }
} }
impl AbstractNode for Loop { impl AbstractNode for Loop {
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> { fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
for statement in &self.statements { for statement in &self.statements {
@ -58,3 +61,15 @@ impl AbstractNode for Loop {
self.last_statement().expected_type(_context) self.last_statement().expected_type(_context)
} }
} }
impl Display for Loop {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "loop {{ ")?;
for statement in &self.statements {
write!(f, "{statement}")?;
}
write!(f, " }}")
}
}

View File

@ -1,3 +1,5 @@
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
@ -175,3 +177,11 @@ impl AbstractNode for MapIndex {
}) })
} }
} }
impl Display for MapIndex {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let MapIndex { collection, index } = self;
write!(f, "{collection}.{index}")
}
}

View File

@ -1,3 +1,5 @@
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
@ -360,3 +362,15 @@ impl AbstractNode for Math {
} }
} }
} }
impl Display for Math {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
Math::Add(left, right) => write!(f, "{left} + {right}"),
Math::Subtract(left, right) => write!(f, "{left} - {right}"),
Math::Multiply(left, right) => write!(f, "{left} * {right}"),
Math::Divide(left, right) => write!(f, "{left} / {right}"),
Math::Modulo(left, right) => write!(f, "{left} % {right}"),
}
}
}

View File

@ -1,3 +1,5 @@
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
@ -144,3 +146,21 @@ impl AbstractNode for Statement {
} }
} }
} }
impl Display for Statement {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
Statement::Assignment(inner) => write!(f, "{}", inner.node),
Statement::AsyncBlock(inner) => write!(f, "{}", inner.node),
Statement::Block(inner) => write!(f, "{}", inner.node),
Statement::Break(_) => write!(f, "break"),
Statement::IfElse(inner) => write!(f, "{}", inner.node),
Statement::Loop(inner) => write!(f, "{}", inner.node),
Statement::StructureDefinition(inner) => write!(f, "{}", inner.node),
Statement::TypeAlias(inner) => write!(f, "{}", inner.node),
Statement::EnumDeclaration(inner) => write!(f, "{}", inner.node),
Statement::Expression(expression) => write!(f, "{expression}"),
Statement::While(inner) => write!(f, "{}", inner.node),
}
}
}

View File

@ -1,3 +1,5 @@
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
@ -71,3 +73,17 @@ impl AbstractNode for StructureDefinition {
Ok(None) Ok(None)
} }
} }
impl Display for StructureDefinition {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let StructureDefinition { name, fields } = self;
write!(f, "struct {name} {{ ")?;
for (identifer, constructor) in fields {
write!(f, "{identifer}: {constructor}, ")?;
}
write!(f, " }}")
}
}

View File

@ -1,3 +1,5 @@
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
@ -44,3 +46,14 @@ impl AbstractNode for TypeAlias {
Ok(None) Ok(None)
} }
} }
impl Display for TypeAlias {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let TypeAlias {
identifier,
constructor,
} = self;
write!(f, "type {} = {constructor}", identifier.node)
}
}

View File

@ -1,4 +1,9 @@
use std::{cmp::Ordering, collections::BTreeMap, ops::Range}; use std::{
cmp::Ordering,
collections::BTreeMap,
fmt::{self, Display, Formatter},
ops::Range,
};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -622,6 +627,96 @@ impl Ord for ValueNode {
} }
} }
impl Display for ValueNode {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
ValueNode::Boolean(boolean) => write!(f, "{boolean}"),
ValueNode::BuiltInFunction(built_in_function) => write!(f, "{built_in_function}"),
ValueNode::EnumInstance {
type_name,
variant,
content,
} => {
write!(f, "{}::{}", type_name.node, variant.node)?;
if let Some(content) = content {
for expression in content {
write!(f, "{expression}")?;
}
}
Ok(())
}
ValueNode::Float(float) => write!(f, "{float}"),
ValueNode::Integer(integer) => write!(f, "{integer}"),
ValueNode::List(expressions) => {
for expression in expressions {
write!(f, "{expression}")?;
}
Ok(())
}
ValueNode::Map(fields) => {
write!(f, "{{ ")?;
for (identifier, type_option, expression) in fields {
write!(f, "{identifier}")?;
if let Some(r#type) = type_option {
write!(f, ": {type}")?;
}
write!(f, " = {expression}")?;
}
write!(f, " }}")
}
ValueNode::Range(range) => write!(f, "{}..{}", range.start, range.end),
ValueNode::String(string) => write!(f, "{string}"),
ValueNode::Structure { name, fields } => {
write!(f, "{}", name.node)?;
for (identifier, expression) in fields {
write!(f, "{} = {expression},", identifier.node)?;
}
Ok(())
}
ValueNode::Function(FunctionNode {
type_parameters,
value_parameters,
return_type,
body,
context_template,
}) => {
write!(f, "fn ")?;
if let Some(type_parameters) = type_parameters {
write!(f, "(")?;
for identifier in type_parameters {
write!(f, "{identifier}")?;
}
write!(f, ")")?;
}
if let Some(value_parameters) = value_parameters {
write!(f, "(")?;
for (identifier, constructor) in value_parameters {
write!(f, "{identifier}: {constructor}")?;
}
write!(f, ")")?;
}
write!(f, "{}", body.node)
}
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct FunctionNode { pub struct FunctionNode {
type_parameters: Option<Vec<Identifier>>, type_parameters: Option<Vec<Identifier>>,

View File

@ -1,3 +1,5 @@
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
@ -83,3 +85,15 @@ impl AbstractNode for While {
self.statements.last().unwrap().expected_type(_context) self.statements.last().unwrap().expected_type(_context)
} }
} }
impl Display for While {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "while {} {{", self.expression)?;
for statement in &self.statements {
write!(f, "{statement}")?;
}
write!(f, "}}")
}
}