use trivet::errors::syntax_error;
use trivet::errors::ParseResult;
use trivet::parse_from_stdin;
use trivet::Parser;
pub fn parse_number_ws(parser: &mut Parser) -> ParseResult<f64> {
parser.parse_f64_ws()
}
pub fn parse_primitive_ws(parser: &mut Parser) -> ParseResult<f64> {
let is_neg = parser.peek_and_consume('-');
let value = if parser.peek_and_consume('(') {
let value = parse_top_expr_ws(parser)?;
if !parser.peek_and_consume_ws(')') {
return Err(syntax_error(parser.loc(), "Missing closing parenthesis."));
}
value
} else {
parse_number_ws(parser)?
};
Ok(if is_neg { -value } else { value })
}
pub fn parse_exp_expr_ws(parser: &mut Parser) -> ParseResult<f64> {
let mut left = parse_primitive_ws(parser)?;
loop {
left = if parser.peek_and_consume_str_ws("**") {
let right = parse_primitive_ws(parser)?;
left.powf(right)
} else {
break;
}
}
Ok(left)
}
pub fn parse_product_expr_ws(parser: &mut Parser) -> ParseResult<f64> {
let mut left = parse_exp_expr_ws(parser)?;
loop {
left = if parser.peek_and_consume_ws('*') {
left * parse_exp_expr_ws(parser)?
} else if parser.peek_and_consume_ws('/') {
left / parse_exp_expr_ws(parser)?
} else {
break;
}
}
Ok(left)
}
pub fn parse_top_expr_ws(parser: &mut Parser) -> ParseResult<f64> {
let mut left = parse_product_expr_ws(parser)?;
loop {
left = if parser.peek_and_consume_ws('+') {
left + parse_product_expr_ws(parser)?
} else if parser.peek_and_consume_ws('-') {
left - parse_product_expr_ws(parser)?
} else {
break;
};
}
Ok(left)
}
pub fn main() -> ParseResult<()> {
let mut parser = parse_from_stdin();
parser.consume_ws();
while !parser.is_at_eof() {
let number = parse_top_expr_ws(&mut parser)?;
println!(" {}", number);
}
Ok(())
}