93 lines
1.9 KiB
Rust
93 lines
1.9 KiB
Rust
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<Identifier>,
|
|
}
|
|
|
|
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::<String>(),
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
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<Expr>)>),
|
|
}
|
|
|
|
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<Expr>, name: String) -> LinkedList<Expr> {
|
|
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<Expr>) -> Option<Identifier> {
|
|
exprs.back().map(|expr| expr.identifier.clone())
|
|
}
|