Skip to content

Commit

Permalink
support multis in lam, app, let (#6)
Browse files Browse the repository at this point in the history
this allows us to write

----
(lam [x y] y)

(f x y)

(let ([x 1]
      [y 2])
  y)
----

these desugar into multiple applications of the singular Expr
constructors. since we support currying this works nicely.
  • Loading branch information
mhuesch authored Nov 1, 2020
1 parent e78f512 commit 08131be
Showing 1 changed file with 26 additions and 11 deletions.
37 changes: 26 additions & 11 deletions src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,37 @@ where
let p_eql = res_str("==").map(|_| PrimOp::Eql);
let prim_op = choice((p_add, p_sub, p_mul, p_eql)).map(|v| Expr::Prim(v));

let app = (expr(), expr()).map(|t| Expr::App(Box::new(t.0), Box::new(t.1)));

let lam = (res_str("lam"), lex_char('['), name(), lex_char(']'), expr())
.map(|t| Expr::Lam(t.2, Box::new(t.4)));
let app = (expr(), many1::<Vec<_>, _, _>(expr())).map(|t| {
let applicator = |fun, arg: Expr| Expr::App(Box::new(fun), Box::new(arg));
t.1.into_iter().fold(t.0, applicator)
});

let let_ = (
res_str("let"),
lex_char('('),
let lam = (
res_str("lam"),
lex_char('['),
name(),
expr(),
many1::<Vec<_>, _, _>(name()),
lex_char(']'),
lex_char(')'),
expr(),
)
.map(|t| Expr::Let(t.3, Box::new(t.4), Box::new(t.7)));
.map(|t| {
let applicator = |bd, nm: Name| Expr::Lam(nm, Box::new(bd));
t.2.into_iter().rev().fold(t.4, applicator)
});

let let_ = {
let binder = (lex_char('['), name(), expr(), lex_char(']')).map(|t| (t.1, t.2));
(
res_str("let"),
lex_char('('),
many1::<Vec<_>, _, _>(binder),
lex_char(')'),
expr(),
)
.map(|t| {
let applicator = |bd, (nm, e)| Expr::Let(nm, Box::new(e), Box::new(bd));
t.2.into_iter().rev().fold(t.4, applicator)
})
};

let if_ = (res_str("if"), expr(), expr(), expr())
.map(|t| Expr::If(Box::new(t.1), Box::new(t.2), Box::new(t.3)));
Expand Down

0 comments on commit 08131be

Please sign in to comment.