67 lines
1.9 KiB
Rust
67 lines
1.9 KiB
Rust
|
use egg::{RecExpr, Id};
|
||
|
use crate::language::EquationLanguage;
|
||
|
|
||
|
// there is already a Display implementation generated by define_langauge!
|
||
|
// but we want an alternative string conversion
|
||
|
pub fn print_term(expr: &RecExpr<EquationLanguage>) -> String {
|
||
|
let root_id = Id::from(expr.as_ref().len()-1);
|
||
|
print_term_inner(expr, root_id).0
|
||
|
}
|
||
|
|
||
|
// the second result is the precedence of the top level op: 1 = '+-', 2 = '*/', 3 = '^', 4 = primitive
|
||
|
fn print_term_inner(expr: &RecExpr<EquationLanguage>, id: Id) -> (String, usize) {
|
||
|
match &expr[id] {
|
||
|
EquationLanguage::Num(c) => {
|
||
|
(format!("{}", c), if c.denom == 1 { 4 } else { 2 })
|
||
|
},
|
||
|
EquationLanguage::Neg([a]) => {
|
||
|
(print_unary(expr, *a, "-", 1), 1)
|
||
|
},
|
||
|
EquationLanguage::Add([a,b]) => {
|
||
|
(print_binary(expr, *a, *b, "+", 1), 1)
|
||
|
},
|
||
|
EquationLanguage::Sub([a,b]) => {
|
||
|
(print_binary(expr, *a, *b, "-", 1), 1)
|
||
|
},
|
||
|
EquationLanguage::Mul([a,b]) => {
|
||
|
(print_binary(expr, *a, *b, "*", 2), 2)
|
||
|
},
|
||
|
EquationLanguage::Div([a,b]) => {
|
||
|
(print_binary(expr, *a, *b, "/", 2), 2)
|
||
|
},
|
||
|
EquationLanguage::Power([a,b]) => {
|
||
|
(print_binary(expr, *a, *b, "^", 3), 3)
|
||
|
},
|
||
|
_ => unimplemented!()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn print_unary(expr: &RecExpr<EquationLanguage>, a: Id, op: &str, precedence: usize) -> String {
|
||
|
let (astr, aprec) = print_term_inner(expr, a);
|
||
|
|
||
|
if aprec > precedence {
|
||
|
format!("{}{}", op, astr)
|
||
|
} else {
|
||
|
format!("{}({})", op, astr)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn print_binary(expr: &RecExpr<EquationLanguage>, a: Id, b: Id, op: &str, precedence: usize) -> String {
|
||
|
let (astr, aprec) = print_term_inner(expr, a);
|
||
|
let (bstr, bprec) = print_term_inner(expr, b);
|
||
|
|
||
|
if aprec > precedence {
|
||
|
if bprec > precedence {
|
||
|
format!("{} {} {}", astr, op, bstr)
|
||
|
} else {
|
||
|
format!("{} {} ({})", astr, op, bstr)
|
||
|
}
|
||
|
} else {
|
||
|
if bprec > precedence {
|
||
|
format!("({}) {} {}", astr, op, bstr)
|
||
|
} else {
|
||
|
format!("({}) {} ({})", astr, op, bstr)
|
||
|
}
|
||
|
}
|
||
|
}
|