Skip to content

Commit

Permalink
stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
lieuwex committed Dec 8, 2023
1 parent 8b07419 commit b03d2b2
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 53 deletions.
6 changes: 2 additions & 4 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,13 @@ impl fmt::Display for BinOp {
pub enum FoldOp {
BinOp(BinOp),
Expr(Box<Expr>),
FunctionRef(String),
}

impl fmt::Display for FoldOp {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
FoldOp::BinOp(op) => write!(f, "{}", op),
FoldOp::Expr(expr) => write!(f, "{}", expr),
FoldOp::FunctionRef(fun) => write!(f, "{}", fun),
}
}
}
Expand All @@ -174,7 +172,7 @@ pub enum Expr {
Binary(Box<Expr>, BinOp, Box<Expr>),
Fold(FoldOp, Box<Expr>),
Scan(FoldOp, Box<Expr>),
Chunker(FoldOp, Box<Expr>),
Map(FoldOp, Box<Expr>),
Index(Box<Expr>, Box<Expr>), // vector, indices
Let(String, Box<Expr>, Box<Expr>), // let 0 = 1 in 2
Lambda(Vec<String>, Box<Expr>), // params, body
Expand Down Expand Up @@ -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) => {
Expand Down
17 changes: 1 addition & 16 deletions src/executor/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")),
},
}
}

Expand Down Expand Up @@ -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"),
}
}

Expand Down Expand Up @@ -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()?;
Expand Down
58 changes: 25 additions & 33 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Expr>)> {
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
Expand Down Expand Up @@ -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")));
}
}

0 comments on commit b03d2b2

Please sign in to comment.