diff --git a/src/ast.rs b/src/ast.rs index a5a29cf..926ac39 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -147,7 +147,6 @@ impl fmt::Display for BinOp { pub enum FoldOp { BinOp(BinOp), Expr(Box), - FunctionRef(String), } impl fmt::Display for FoldOp { @@ -155,7 +154,6 @@ impl fmt::Display for FoldOp { match self { FoldOp::BinOp(op) => write!(f, "{}", op), FoldOp::Expr(expr) => write!(f, "{}", expr), - FoldOp::FunctionRef(fun) => write!(f, "{}", fun), } } } @@ -174,7 +172,7 @@ pub enum Expr { Binary(Box, BinOp, Box), Fold(FoldOp, Box), Scan(FoldOp, Box), - Chunker(FoldOp, Box), + Map(FoldOp, Box), Index(Box, Box), // vector, indices Let(String, Box, Box), // let 0 = 1 in 2 Lambda(Vec, Box), // params, body @@ -205,7 +203,7 @@ impl fmt::Display for Expr { Expr::Binary(a, op, b) => (format!("{} {} {}", a, op, b), true), Expr::Fold(op, expr) => (format!("{}//{}", op, expr), true), Expr::Scan(op, expr) => (format!(r"{}\\{}", op, expr), true), - Expr::Chunker(op, expr) => (format!(r"{}||{}", op, expr), true), + Expr::Map(op, expr) => (format!(r"{}||{}", op, expr), true), Expr::Index(vec, indices) => (format!("{}[{}]", vec, indices), false), Expr::Let(name, expr, body) => (format!("let {name} = {expr} in {body}"), true), Expr::Lambda(variables, body) => { diff --git a/src/executor/executor.rs b/src/executor/executor.rs index e284424..3a5d220 100644 --- a/src/executor/executor.rs +++ b/src/executor/executor.rs @@ -649,18 +649,6 @@ impl<'a> Executor<'a> { Ok(res) }) } - - // TODO: remove this - FoldOp::FunctionRef(name) => match self.get_variable(&name) { - Some(Value::Function(f)) => { - apply!(|acc, item| { - let args = [acc, item]; - let res = self.call_function(&f, args.into_iter())?; - Ok(res) - }) - } - _ => return Err(Error::from("left hand side is not a function")), - }, } } @@ -728,9 +716,6 @@ impl<'a> Executor<'a> { apply!(f.params().len(), |args| self .call_function(&f, args.into_iter())) } - - // TODO: remove this - FoldOp::FunctionRef(_) => unreachable!("this can't be parsed by the parser"), } } @@ -782,7 +767,7 @@ impl<'a> Executor<'a> { Expr::Binary(a, op, b) => self.execute_binary(*op, a, b), Expr::Fold(op, expr) => self.execute_fold_scan(op.clone(), expr, true), Expr::Scan(op, expr) => self.execute_fold_scan(op.clone(), expr, false), - Expr::Chunker(op, expr) => self.execute_chunker(op.clone(), expr), + Expr::Map(op, expr) => self.execute_chunker(op.clone(), expr), Expr::Index(m, indices) => { let indices = self.execute_expr(indices)?.into_iter_shape()?; diff --git a/src/parser.rs b/src/parser.rs index a69c3a7..0ae9aaf 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -374,47 +374,39 @@ fn p_expr_9<'a>() -> Parser<'a, Expr> { ) } -/// Scan -fn p_expr_10<'a>() -> Parser<'a, Expr> { - // TODO: make scan also able to parse expressions in the left hand side, then remove - // FoldOp::FunctionRef. +fn p_foldlike<'a>(ops: &'static str) -> Parser<'a, (FoldOp, Box)> { + let op_p = binary_op().map(FoldOp::BinOp); + let op = + (op_p - symbol_both(operator(ops)) + call(p_expr)).map(|(op, expr)| (op, Box::new(expr))); - let op_p = binary_op().map(FoldOp::BinOp) | p_varname().map(FoldOp::FunctionRef); - let scan = (op_p - symbol_both(operator(r"\\")) + call(p_expr)) - .map(|(op, expr)| Expr::Scan(op, Box::new(expr))); + let expr = (call(p_expr_0) - symbol_both(operator(ops)) + call(p_expr)) + .map(|(op, expr)| (FoldOp::Expr(Box::new(op)), Box::new(expr))); - scan.name("scan") | p_expr_9() + op | expr +} + +/// Scan +fn p_expr_10<'a>() -> Parser<'a, Expr> { + (p_foldlike(r"\\") + .map(|(op, expr)| Expr::Scan(op, expr)) + .name("scan")) + | p_expr_9() } /// Fold fn p_expr_11<'a>() -> Parser<'a, Expr> { - // TODO: make fold also able to parse expressions in the left hand side, then remove - // FoldOp::FunctionRef. - - let op_p = binary_op().map(FoldOp::BinOp) | p_varname().map(FoldOp::FunctionRef); - let fold = (op_p - symbol_both(operator("//")) + call(p_expr)) - .map(|(op, expr)| Expr::Fold(op, Box::new(expr))); - - fold.name("fold") | p_expr_10() + (p_foldlike("//") + .map(|(op, expr)| Expr::Fold(op, expr)) + .name("fold")) + | p_expr_10() } -/// Chunker +/// Map fn p_expr_12<'a>() -> Parser<'a, Expr> { - fn expr<'b>() -> Parser<'b, Expr> { - right_recurse( - p_expr_8, - symbol_both(operator("||")), - p_expr_8, - "special binary", - |e1, _, e2| Expr::Chunker(FoldOp::Expr(Box::new(e1)), Box::new(e2)), - ) - } - - let op_p = binary_op().map(FoldOp::BinOp); - let fold = (op_p - symbol_both(operator("||")) + call(p_expr)) - .map(|(op, expr)| Expr::Chunker(op, Box::new(expr))); - - fold.name("chunker") | expr().name("chunker") | p_expr_11() + (p_foldlike(".") + .map(|(op, expr)| Expr::Map(op, expr)) + .name("map")) + | p_expr_11() } /// Let binding @@ -573,6 +565,6 @@ mod tests { #[test] fn test_chunker() { - assert!(is_ok_some!(parse(r"f || 1 2 3"))); + assert!(is_ok_some!(parse(r"f . 1 2 3"))); } }