fn call notation

main
Ziyang Hu 2 years ago
parent c0f2618278
commit 1e3af751b7

@ -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(())
}

@ -86,6 +86,13 @@ fn build_cond_expr(pair: Pair) -> Result<Expr> {
Ok(res)
}
fn build_call_expr(pair: Pair) -> Result<Expr> {
let mut pairs = pair.into_inner();
let method = get_method(pairs.next().unwrap().as_str());
let args = pairs.map(Expr::try_from).collect::<Result<Vec<_>>>()?;
Ok(Expr::Apply(method, args))
}
fn build_switch_expr(pair: Pair) -> Result<Expr> {
let mut pairs = pair.into_inner();
let expr = pairs.next().unwrap();
@ -142,12 +149,7 @@ fn build_expr_primary(pair: Pair) -> Result<Expr> {
}
Rule::call => {
let mut pairs = p.into_inner();
let method_name = pairs.next().unwrap().as_str();
let op: Arc<dyn Op + Send + Sync> = 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<dyn Op + Send + Sync> = get_method(pairs.next().unwrap().as_str());
let mut args = vec![head];
args.extend(pairs.map(Expr::try_from).collect::<Result<Vec<_>>>()?);
head = Expr::Apply(op, args);
@ -170,7 +172,8 @@ fn build_expr_primary(pair: Pair) -> Result<Expr> {
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<Expr> {
}
}
fn get_method(name: &str) -> Arc<dyn Op + Send + Sync> {
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<Expr<'a>>,
op: Pair,

@ -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? }

Loading…
Cancel
Save