diff --git a/src/main.rs b/src/main.rs index 0f662e6..40f87aa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,9 +2,10 @@ mod ast; mod parser; fn main() { - let a = "hello( )"; - let (_rest, res) = parser::expr(a).unwrap(); + let a = r#"funFun("ss" + 12, true)"#; + let (rest, res) = parser::expr(a).unwrap(); dbg!(res); + dbg!(rest); println!("Hello, world!"); } diff --git a/src/parser.rs b/src/parser.rs index 3886c5b..4abeed2 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -72,13 +72,19 @@ fn parse_str<'a>(i: &'a str) -> IResult<&'a str, &'a str> { escaped(alphanumeric1, '\\', one_of("\"n\\"))(i) } -fn string<'a>(i: &'a str) -> IResult<&'a str, &'a str> { - preceded(char('\"'), cut(terminated(parse_str, char('\"'))))(i) +fn string<'a>(i: &'a str) -> IResult<&'a str, Expr> { + map( + preceded(char('\"'), cut(terminated(parse_str, char('\"')))), + |s| Expr::LStr(String::from(s)), + )(i) } -fn boolean<'a>(i: &'a str) -> IResult<&'a str, bool> { +fn boolean<'a>(i: &'a str) -> IResult<&'a str, Expr> { println!("boolean: {}", i); - alt((map(tag("true"), |_| true), map(tag("false"), |_| false)))(i) + alt(( + map(tag("true"), |_| Expr::LBool(true)), + map(tag("false"), |_| Expr::LBool(false)), + ))(i) } fn call<'a>(i: &'a str) -> IResult<&'a str, (Identifier, Vec)> { @@ -100,13 +106,13 @@ fn num(i: &str) -> IResult<&str, Expr> { println!("num: {}", i); map(double, Expr::LNum)(i) } - -fn parens_bin(i: &str) -> IResult<&str, Expr> { - delimited(space0, delimited(tag("("), expr, tag(")")), space0)(i) +fn literal(i: &str) -> IResult<&str, Expr> { + println!("literal: {}", i); + alt((num, string, map(tag("null"), |_| Expr::LNull), boolean))(i) } fn factor_bin(i: &str) -> IResult<&str, Expr> { - alt((delimited(space0, num, space0), parens_bin))(i) + alt((delimited(space0, literal, space0), expr))(i) } fn bin_less_greater(i: &str) -> IResult<&str, Expr> { @@ -178,18 +184,17 @@ fn receive<'a>(i: &'a str) -> IResult<&'a str, Expr> { pub fn expr<'a>(i: &'a str) -> IResult<&'a str, Expr> { println!("expr: {}", i); - preceded( + delimited( sc, alt(( parens(expr), map(call, |(i, v)| Expr::Call(i, v)), - map(identifier, |i| Expr::Var(i.to_string())), receive, binary, - map(tag("null"), |_| Expr::LNull), - map(string, |s| Expr::LStr(String::from(s))), - num, + literal, + map(identifier, |i| Expr::Var(i.to_string())), )), + sc, )(i) } @@ -202,7 +207,7 @@ mod tests { let a = r#""hey" "#; let (rest, res) = string(a).unwrap(); - assert_eq!(res, "hey"); + assert_eq!(res, Expr::LStr("hey".to_string())); assert_eq!(rest, " "); } @@ -225,6 +230,29 @@ mod tests { ); } + #[test] + fn can_parse_binary_op_with_str() { + let a = r#"3 +3 + 6 + "hey""#; + let (_rest, res) = binary(a).unwrap(); + + assert_eq!( + res, + Expr::Binary( + BinOp::Plus, + Box::new(Expr::Binary( + BinOp::Plus, + Box::new(Expr::Binary( + BinOp::Plus, + Box::new(Expr::LNum(3.0)), + Box::new(Expr::LNum(3.0)), + )), + Box::new(Expr::LNum(6.0)) + )), + Box::new(Expr::LStr("hey".to_string())) + ) + ); + } + #[test] fn can_parse_empty_call() { let a = "hello()"; @@ -277,7 +305,24 @@ mod tests { } #[test] - fn can_parse() { - let a = r#"let hello = ("hey" + 0.5)"#; + fn can_parse_call_with_string_binop() { + let a = r#"funFun("ss" + 12, true)"#; + let (rest, res) = expr(a).unwrap(); + + assert_eq!( + res, + Expr::Call( + "funFun".to_string(), + vec![ + Expr::Binary( + BinOp::Plus, + Box::new(Expr::LStr("ss".to_string())), + Box::new(Expr::LNum(12.0)) + ), + Expr::LBool(true) + ] + ) + ); + assert_eq!(rest, ""); } }