From 4204d21ac03940c27b137ef2a66659af45f14790 Mon Sep 17 00:00:00 2001 From: Folkert Date: Thu, 14 Nov 2019 23:30:07 +0100 Subject: [PATCH 1/2] Desugar pizza into Apply --- src/can/operator.rs | 27 ++++++++++++++++++++++++++- tests/test_infer.rs | 26 +++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/can/operator.rs b/src/can/operator.rs index d16b763ade..6350912932 100644 --- a/src/can/operator.rs +++ b/src/can/operator.rs @@ -199,7 +199,32 @@ pub fn desugar<'a>(arena: &'a Bump, loc_expr: &'a Located>) -> &'a Loca let value = match loc_op.value { Pizza => { // Rewrite the Pizza operator into an Apply - panic!("TODO desugar |> operator into an Apply"); + + match &right.value { + Apply(function, arguments, _called_via) => { + let mut args = Vec::with_capacity_in(1 + arguments.len(), arena); + + args.push(*arena.alloc(left)); + + for arg in arguments { + args.push(arg); + } + + Apply(function, args, CalledVia::BinOp(Pizza)) + } + expr => { + // e.g. `1 |> (if b then (\a -> a) else (\c -> c))` + let mut args = Vec::with_capacity_in(1, arena); + args.push(*arena.alloc(left)); + + let function = arena.alloc(Located { + value: expr.clone(), + region: right.region, + }); + + Apply(function, args, CalledVia::BinOp(Pizza)) + } + } } binop => { // This is a normal binary operator like (+), so desugar it diff --git a/tests/test_infer.rs b/tests/test_infer.rs index 17898273c1..c6c8265d51 100644 --- a/tests/test_infer.rs +++ b/tests/test_infer.rs @@ -492,6 +492,31 @@ mod test_infer { ); } + #[test] + fn pizza_desugar() { + infer_eq( + indoc!( + r#" + 1 |> (\a -> a) + "# + ), + "Int", + ); + } + + #[test] + fn pizza_desugar_two_arguments() { + infer_eq( + indoc!( + r#" + always = \a b -> a + + 1 |> always "foo" + "# + ), + "Int", + ); + } // #[test] // fn identity() { // infer_eq( @@ -624,5 +649,4 @@ mod test_infer { "Int", ); } - } From 1ea0264174ce1b254aa4a2b6d71d50edf645acf3 Mon Sep 17 00:00:00 2001 From: Folkert Date: Fri, 15 Nov 2019 12:18:06 +0100 Subject: [PATCH 2/2] changes after review trust the borrow checker: reallocation of Expr is not needed --- src/can/operator.rs | 6 +++--- tests/test_infer.rs | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/can/operator.rs b/src/can/operator.rs index 6350912932..255d2b128a 100644 --- a/src/can/operator.rs +++ b/src/can/operator.rs @@ -204,7 +204,7 @@ pub fn desugar<'a>(arena: &'a Bump, loc_expr: &'a Located>) -> &'a Loca Apply(function, arguments, _called_via) => { let mut args = Vec::with_capacity_in(1 + arguments.len(), arena); - args.push(*arena.alloc(left)); + args.push(left); for arg in arguments { args.push(arg); @@ -232,8 +232,8 @@ pub fn desugar<'a>(arena: &'a Bump, loc_expr: &'a Located>) -> &'a Loca let (module_parts, name) = desugar_binop(&binop, arena); let mut args = Vec::with_capacity_in(2, arena); - args.push(*arena.alloc(left)); - args.push(*arena.alloc(right)); + args.push(left); + args.push(right); let loc_expr = arena.alloc(Located { value: Expr::Var(module_parts, name), diff --git a/tests/test_infer.rs b/tests/test_infer.rs index c6c8265d51..79165f6146 100644 --- a/tests/test_infer.rs +++ b/tests/test_infer.rs @@ -511,7 +511,7 @@ mod test_infer { r#" always = \a b -> a - 1 |> always "foo" + 1 |> always "foo" "# ), "Int", @@ -649,4 +649,5 @@ mod test_infer { "Int", ); } + }