From 1e3af751b7d92933126c8b7787f508139c832d69 Mon Sep 17 00:00:00 2001 From: Ziyang Hu Date: Wed, 18 May 2022 22:56:30 +0800 Subject: [PATCH] fn call notation --- src/data/eval.rs | 6 ++++++ src/data/expr_parser.rs | 25 ++++++++++++++++++------- src/grammar.pest | 8 +++----- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/data/eval.rs b/src/data/eval.rs index 9d65b35b..85a9d016 100644 --- a/src/data/eval.rs +++ b/src/data/eval.rs @@ -599,6 +599,12 @@ mod tests { dbg!(str2expr("switch 3 {2 => '2', 1+2 => '3', .. => 'x'}")?.partial_eval(&())?); dbg!(str2expr("null.is_null()")?.row_eval(&())?); dbg!(str2expr("null.is_null()")?.partial_eval(&())?); + dbg!(str2expr("null.not_null()")?.row_eval(&())?); + dbg!(str2expr("null.not_null()")?.partial_eval(&())?); + dbg!(str2expr("is_null(null)")?.row_eval(&())?); + dbg!(str2expr("is_null(null)")?.partial_eval(&())?); + dbg!(str2expr("is_null((null ~ 3)+2).is_null()")?.row_eval(&())?); + dbg!(str2expr("is_null((null ~ 3)+2).is_null()")?.partial_eval(&())?); Ok(()) } diff --git a/src/data/expr_parser.rs b/src/data/expr_parser.rs index 69634165..d1c2ea41 100644 --- a/src/data/expr_parser.rs +++ b/src/data/expr_parser.rs @@ -86,6 +86,13 @@ fn build_cond_expr(pair: Pair) -> Result { Ok(res) } +fn build_call_expr(pair: Pair) -> Result { + let mut pairs = pair.into_inner(); + let method = get_method(pairs.next().unwrap().as_str()); + let args = pairs.map(Expr::try_from).collect::>>()?; + Ok(Expr::Apply(method, args)) +} + fn build_switch_expr(pair: Pair) -> Result { let mut pairs = pair.into_inner(); let expr = pairs.next().unwrap(); @@ -142,12 +149,7 @@ fn build_expr_primary(pair: Pair) -> Result { } Rule::call => { let mut pairs = p.into_inner(); - let method_name = pairs.next().unwrap().as_str(); - let op: Arc = match method_name { - n if n == OpIsNull.name() => Arc::new(OpIsNull), - n if n == OpNotNull.name() => Arc::new(OpNotNull), - method_name => Arc::new(UnresolvedOp(method_name.to_string())) - }; + let op: Arc = get_method(pairs.next().unwrap().as_str()); let mut args = vec![head]; args.extend(pairs.map(Expr::try_from).collect::>>()?); head = Expr::Apply(op, args); @@ -170,7 +172,8 @@ fn build_expr_primary(pair: Pair) -> Result { Rule::if_expr => return build_if_expr(p), Rule::cond_expr => return build_cond_expr(p), Rule::switch_expr => return build_switch_expr(p), - _ => unreachable!(), + Rule::call_expr => return build_call_expr(p), + r => unreachable!("Encountered unknown op {:?}", r), }; let term = build_expr_primary(inner.next().unwrap())?; Ok(Expr::Apply(op, vec![term])) @@ -284,6 +287,14 @@ fn build_expr_primary(pair: Pair) -> Result { } } +fn get_method(name: &str) -> Arc { + match name { + n if n == OpIsNull.name() => Arc::new(OpIsNull), + n if n == OpNotNull.name() => Arc::new(OpNotNull), + method_name => Arc::new(UnresolvedOp(method_name.to_string())) + } +} + fn build_expr_infix<'a>( lhs: Result>, op: Pair, diff --git a/src/grammar.pest b/src/grammar.pest index 9d833e56..54503786 100644 --- a/src/grammar.pest +++ b/src/grammar.pest @@ -103,18 +103,16 @@ op_ge = { ">=" } op_le = { "<=" } op_pow = { "^" } -unary = { cond_expr | switch_expr | if_expr | (unary_op ~ unary) | term } +unary = { cond_expr | switch_expr | if_expr | call_expr | (unary_op ~ unary) | term } unary_op = _{ minus | negate } minus = { "-" } negate = { "!" } +call_expr = { ident ~ "(" ~ (expr ~ ",")* ~ expr? ~ ")" } term = { (grouping | literal | ident | param | list | dict) ~ (call | accessor | index_accessor)* } -call = {"." ~ ident ~ "(" ~ argument* ~ ")"} +call = {"." ~ ident ~ "(" ~ (expr ~ ",")* ~ expr? ~ ")"} accessor = {"." ~ ident} index_accessor = {"[" ~ int ~ "]"} -argument = _{(kw_arg | pos_arg)} -kw_arg = {ident ~ "=" ~ expr} -pos_arg = { expr } grouping = { "(" ~ expr ~ ")" } if_expr = { if_clause ~ ("else" ~ if_clause)* ~ else_clause? }