diff --git a/Program.fs b/Program.fs index 5ba72ba..16cd2ca 100644 --- a/Program.fs +++ b/Program.fs @@ -91,10 +91,9 @@ let testTransform parse transform = [] let main argv = - // testTransform - // "let { a = { b = b } } = { a = { b = 1 } } in b" - // "let _var0 = { a = { b = 1 } } in let _var1 = _var0.a in let b = _var1.b in b" - // "let _var0 = { a = (:b 1) } in match _var0.a { :b b -> b }" + testTransform + "match x { { a = 1 } -> 1 }" + "match x { { a = _var0 } when _var0 = 1 -> (let _var0 = x.a in 1) }" // let input = "let (a: int) = 1 in a" // test input @@ -111,17 +110,17 @@ let main argv = // runRepl () - [ - "let yfact fact n =" - " if n > 0 then" - " n * fact(n-1)" - " else" - " 1" - "in" - "let fact = fix yfact in" - "print (fact 5)" - ] - |> String.concat "\n" - |> testEmitter "10" + // [ + // "let yfact fact n =" + // " if n > 0 then" + // " n * fact(n-1)" + // " else" + // " 1" + // "in" + // "let fact = fix yfact in" + // "print (fact 5)" + // ] + // |> String.concat "\n" + // |> testEmitter "10" 0 // return an integer exit code diff --git a/TestTransform.fs b/TestTransform.fs index a0297bf..b2da2eb 100644 --- a/TestTransform.fs +++ b/TestTransform.fs @@ -102,16 +102,16 @@ let ``Fun record multiple fields`` () = let ``Extract guards in record`` () = testTransform "match x { { a = 1 } -> 1 }" - "match x { { a = _var0 } when _var0 = 1 -> 1 }" + "match x { { a = _var0 } when _var0 = 1 -> (let _var0 = x.a in 1) }" [] let ``Extract guards in variant`` () = testTransform "match x { :a 1 -> 1 }" - "match x { :a _var0 when _var0 = 1 -> 1 }" + "match x { :a _var0 when _var0 = 1 -> (match x { :a _var0 -> 1 }) }" [] let ``Transform does not mess with functions`` () = testTransform "let add a b = a + b" - "let add a b = a + b" \ No newline at end of file + "let add a b = a + b" diff --git a/Transform.fs b/Transform.fs index 6d476da..8b736c5 100644 --- a/Transform.fs +++ b/Transform.fs @@ -3,16 +3,6 @@ module Transform open Error open Expr -// Before -// let { a = 1 } = { a = 1 } in 1 -// After -// let _var0 = { a = 1 } in let _var1 = _var0.a in if a = 1 then 1 else error "bad match" - -// Before -// match a { :a 1 -> 1 } -// After -// - let currentId = ref 0 let nextId () = @@ -107,10 +97,19 @@ let rec transformExpr expr = EFun (EVar var, body) | _ -> raise (genericError (InvalidPattern pattern)) | ELet (pattern, value, body) when isRowType pattern -> - let var = getNewVar () + let var = + match value with + | EVar var -> var + | _ -> getNewVar () let body = transformRowBinding var body pattern - ELet (EVar var, value, body) + match value with + | EVar _ -> body + | _ -> ELet (EVar var, value, body) | ECase (value, cases, oDefault) -> + let var = + match value with + | EVar name -> name + | _ -> getNewVar () let fixedCases = cases |> List.map (fun (pattern, body, oGuard) -> @@ -129,9 +128,14 @@ let rec transformExpr expr = EBinOp (state, BinOp.And, guard) ) |> Some + let body = + ELet (pattern, EVar var, body) + |> transformExpr pattern, body, oGuard ) - ECase (value, fixedCases, oDefault) + match value with + | EVar name -> ECase (value, fixedCases, oDefault) + | _ -> ELet (EVar var, value, ECase (EVar var, fixedCases, oDefault)) | _ -> expr let transform expr =