Amo/src/ir/expr.rs

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())
}