diff --git a/src/main.rs b/src/main.rs index 40f87aa..c40c57c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ mod ast; mod parser; fn main() { - let a = r#"funFun("ss" + 12, true)"#; + let a = r#"1 + a < 9 - <- chan"#; let (rest, res) = parser::expr(a).unwrap(); dbg!(res); dbg!(rest); diff --git a/src/parser.rs b/src/parser.rs index cfa916c..adc1082 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -110,9 +110,16 @@ fn literal(i: &str) -> IResult<&str, Expr> { println!("literal: {}", i); alt((num, string, map(tag("null"), |_| Expr::LNull), boolean))(i) } +fn receive<'a>(i: &'a str) -> IResult<&'a str, Expr> { + println!("receive: {}", i); + map(tuple((sc, tag("<-"), expr)), |(_, _, expr)| { + Expr::Receive(Box::new(expr)) + })(i) +} fn factor_bin(i: &str) -> IResult<&str, Expr> { - alt((delimited(space0, term, space0), expr))(i) + println!("factor bin: {}", i); + alt((delimited(space0, alt((receive, term)), space0), expr))(i) } fn bin_less_greater(i: &str) -> IResult<&str, Expr> { @@ -176,22 +183,16 @@ fn binary<'a>(i: &'a str) -> IResult<&'a str, Expr> { }, )(i) } -fn receive<'a>(i: &'a str) -> IResult<&'a str, Expr> { - println!("receive: {}", i); - map(pair(tag("<-"), expr), |(_, expr)| { - Expr::Receive(Box::new(expr)) - })(i) -} - -pub fn expr<'a>(i: &'a str) -> IResult<&'a str, Expr> { - alt((receive, binary))(i) -} fn term<'a>(i: &'a str) -> IResult<&'a str, Expr> { println!("expr: {}", i); delimited(sc, alt((literal, call, variable, parens(expr))), sc)(i) } +pub fn expr<'a>(i: &'a str) -> IResult<&'a str, Expr> { + binary(i) +} + #[cfg(test)] mod tests { use super::*; @@ -321,7 +322,7 @@ mod tests { #[test] fn can_parse_call_with_string_binop() { - let a = r#"funFun("ss" + 12, true)"#; + let a = r#"funFun(null == "ss" + 12, true)"#; let (rest, res) = expr(a).unwrap(); assert_eq!( @@ -331,7 +332,11 @@ mod tests { vec![ Expr::Binary( BinOp::Plus, - Box::new(Expr::LStr("ss".to_string())), + Box::new(Expr::Binary( + BinOp::Equals, + Box::new(Expr::LNull), + Box::new(Expr::LStr("ss".to_string())), + )), Box::new(Expr::LNum(12.0)) ), Expr::LBool(true) @@ -340,4 +345,55 @@ mod tests { ); assert_eq!(rest, ""); } + + #[test] + fn can_parse_binop_with_receive() { + let a = r#"1 + a < 9 - <- chan"#; + let (rest, res) = expr(a).unwrap(); + + assert_eq!( + res, + Expr::Binary( + BinOp::Minus, + Box::new(Expr::Binary( + BinOp::Plus, + Box::new(Expr::LNum(1.0)), + Box::new(Expr::Binary( + BinOp::LessThan, + Box::new(Expr::Var("a".to_string())), + Box::new(Expr::LNum(9.0)), + )), + )), + Box::new(Expr::Receive(Box::new(Expr::Var("chan".to_string())))), + ) + ); + assert_eq!(rest, ""); + } + + #[test] + fn can_parse_binop_with_receive_and_fun_call() { + let a = r#"-99 - <- chan + funkyFun(a, false, "hey")"#; + let (rest, res) = expr(a).unwrap(); + + assert_eq!( + res, + Expr::Binary( + BinOp::Minus, + Box::new(Expr::LNum(-99.0)), + Box::new(Expr::Receive(Box::new(Expr::Binary( + BinOp::Plus, + Box::new(Expr::Var("chan".to_string())), + Box::new(Expr::Call( + "funkyFun".to_string(), + vec![ + Expr::Var("a".to_string()), + Expr::LBool(false), + Expr::LStr("hey".to_string()) + ] + )) + )))) + ) + ); + assert_eq!(rest, ""); + } }