/// This program contains list of valid AST nodes that can be constructed and also evaluates an AST to compute a value // Standard lib use std::error; //structs // List of allowed AST nodes that can be constructed by Parser // Tokens can be arithmetic operators or a Number #[derive(Debug, Clone, PartialEq)] pub enum Node { Add(Box, Box), Subtract(Box, Box), Multiply(Box, Box), Divide(Box, Box), Caret(Box, Box), Negative(Box), Number(f64), } // Given an AST, calculate the numeric value. pub fn eval(expr: Node) -> Result> { use self::Node::*; match expr { Number(i) => Ok(i), Add(expr1, expr2) => Ok(eval(*expr1)? + eval(*expr2)?), Subtract(expr1, expr2) => Ok(eval(*expr1)? - eval(*expr2)?), Multiply(expr1, expr2) => Ok(eval(*expr1)? * eval(*expr2)?), Divide(expr1, expr2) => Ok(eval(*expr1)? / eval(*expr2)?), Negative(expr1) => Ok(-(eval(*expr1)?)), Caret(expr1, expr2) => Ok(eval(*expr1)?.powf(eval(*expr2)?)), } } //Unit tests #[cfg(test)] mod tests { use super::*; #[test] fn test_expr1() { use crate::parsemath::parser::Parser; let ast = Parser::new("1+2-3").unwrap().parse().unwrap(); let value = eval(ast).unwrap(); assert_eq!(value, 0.0); } #[test] fn test_expr2() { use crate::parsemath::parser::Parser; let ast = Parser::new("3+2-1*5/4").unwrap().parse().unwrap(); let value = eval(ast).unwrap(); assert_eq!(value, 3.75); } }