use core::fmt; use std::{collections::LinkedList, mem}; use super::{value::Value, pattern::Pattern, Identifier}; #[derive(Debug)] pub struct Expr { pub identifier: Identifier, pub operation: Operation, pub formals: Vec, } impl fmt::Display for Expr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if let Operation::NoOp = self.operation { self.identifier.fmt(f) } else { write!(f, "{} = {:?}{}", self.identifier, self.operation, self.formals.iter() .map(|f| format!(" {f}")) .collect::(), ) } } } pub enum Operation { Add, Sub, Mul, Div, Mod, Range, Eq, NEq, LessThan, GreaterThan, LAnd, LOr, Const(Value), Call, VariantUnion, FunctionType, NoOp, Conditional(Vec<(Pattern, LinkedList)>), } impl fmt::Debug for Operation { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(match self { Self::Add => "plus", Self::Sub => "minus", Self::Mul => "times", Self::Div => "div", Self::Mod => "mod", Self::Range => "to", Self::Eq => "equals", Self::NEq => "nequals", Self::LessThan => "lessthan", Self::GreaterThan => "morethan", Self::LAnd => "and", Self::LOr => "or", Self::Const(v) => { return write!(f, "const[{v:?}]"); }, Self::Call => "call", Self::VariantUnion => "orvariant", Self::FunctionType => "yields", Self::NoOp => "noop", Self::Conditional(branches) => { return write!(f, "cond({branches:?})"); }, }) } } pub fn set_last_ident_name(mut exprs: LinkedList, name: String) -> LinkedList { if let Some(expr) = exprs.back_mut() { let mut placeholder = Identifier::ROOT; mem::swap(&mut expr.identifier, &mut placeholder); placeholder = placeholder.set_name(name); mem::swap(&mut expr.identifier, &mut placeholder); } exprs } pub fn get_last_ident(exprs: &LinkedList) -> Option { exprs.back().map(|expr| expr.identifier.clone()) }