Finish Lambda Lifter
This commit is contained in:
parent
1f47288fcf
commit
7a2404cf74
3 changed files with 74 additions and 13 deletions
4
basic-2
Normal file
4
basic-2
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
add x = \y. x + y;
|
||||||
|
|
||||||
|
main = (\z. z + z) ((add 4) 6);
|
||||||
|
|
||||||
|
|
@ -3,12 +3,12 @@
|
||||||
{-# LANGUAGE PatternSynonyms #-}
|
{-# LANGUAGE PatternSynonyms #-}
|
||||||
|
|
||||||
|
|
||||||
module LambdaLifter (lambdaLift, freeVars, abstract) where
|
module LambdaLifter (lambdaLift, freeVars, abstract, rename, collectScs) where
|
||||||
|
|
||||||
import Data.List (mapAccumL)
|
import Data.List (mapAccumL)
|
||||||
import Data.Map (Map)
|
import Data.Map (Map)
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import Data.Maybe (fromJust)
|
import Data.Maybe (fromMaybe)
|
||||||
import Data.Set (Set, (\\))
|
import Data.Set (Set, (\\))
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
import Data.Tuple.Extra (uncurry3)
|
import Data.Tuple.Extra (uncurry3)
|
||||||
|
|
@ -21,7 +21,7 @@ pattern Sc n xs e = ScDef (Bind n xs e)
|
||||||
|
|
||||||
|
|
||||||
lambdaLift :: Program -> Program
|
lambdaLift :: Program -> Program
|
||||||
lambdaLift = rename . abstract . freeVars
|
lambdaLift = collectScs . rename . abstract . freeVars
|
||||||
|
|
||||||
|
|
||||||
-- Annotate free variables
|
-- Annotate free variables
|
||||||
|
|
@ -94,7 +94,7 @@ abstractExp (free, exp) = case exp of
|
||||||
e' = foldr EAbs (abstractExp e) (fvList ++ [n])
|
e' = foldr EAbs (abstractExp e) (fvList ++ [n])
|
||||||
sc = ELet [bind] (EId (Ident "sc"))
|
sc = ELet [bind] (EId (Ident "sc"))
|
||||||
|
|
||||||
-- rename pass
|
-- Rename
|
||||||
|
|
||||||
rename :: Program -> Program
|
rename :: Program -> Program
|
||||||
rename (Program ds) = Program $ map (uncurry3 Sc) tuples
|
rename (Program ds) = Program $ map (uncurry3 Sc) tuples
|
||||||
|
|
@ -108,9 +108,7 @@ rename (Program ds) = Program $ map (uncurry3 Sc) tuples
|
||||||
renameExp :: Map Ident Ident -> Int -> Exp -> (Int, Exp)
|
renameExp :: Map Ident Ident -> Int -> Exp -> (Int, Exp)
|
||||||
renameExp env i = \case
|
renameExp env i = \case
|
||||||
|
|
||||||
|
EId n -> (i, EId . fromMaybe n $ Map.lookup n env)
|
||||||
EId n -> (i, maybe (error "no") EId $ Map.lookup n env)
|
|
||||||
|
|
||||||
|
|
||||||
EInt i1 -> (i, EInt i1)
|
EInt i1 -> (i, EInt i1)
|
||||||
|
|
||||||
|
|
@ -157,6 +155,70 @@ getNames i ns = (i + length ss, zipWith makeName ss [i..])
|
||||||
makeName :: String -> Int -> Ident
|
makeName :: String -> Int -> Ident
|
||||||
makeName prefix i = Ident (prefix ++ "_" ++ show i)
|
makeName prefix i = Ident (prefix ++ "_" ++ show i)
|
||||||
|
|
||||||
|
|
||||||
|
-- Collect supercombinators
|
||||||
|
|
||||||
|
collectScs :: Program -> Program
|
||||||
|
collectScs (Program ds) = Program $ concatMap collect_one_sc ds
|
||||||
|
where
|
||||||
|
collect_one_sc (Sc n xs e) = Sc n xs e' : scs
|
||||||
|
where (scs, e') = collectScsExp e
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
collectScsExp :: Exp -> ([ScDef], Exp)
|
||||||
|
collectScsExp = \case
|
||||||
|
|
||||||
|
EId n -> ([], EId n)
|
||||||
|
|
||||||
|
EInt i -> ([], EInt i)
|
||||||
|
|
||||||
|
EApp e1 e2 -> (scs1 ++ scs2, EApp e1' e2')
|
||||||
|
where
|
||||||
|
(scs1, e1') = collectScsExp e1
|
||||||
|
(scs2, e2') = collectScsExp e2
|
||||||
|
|
||||||
|
EAdd e1 e2 -> (scs1 ++ scs2, EAdd e1' e2')
|
||||||
|
where
|
||||||
|
(scs1, e1') = collectScsExp e1
|
||||||
|
(scs2, e2') = collectScsExp e2
|
||||||
|
|
||||||
|
EAbs x e -> (scs, EAbs x e')
|
||||||
|
where
|
||||||
|
(scs, e') = collectScsExp e
|
||||||
|
|
||||||
|
ELet bs e -> (rhss_scs ++ e_scs ++ local_scs, mkEAbs non_scs' e')
|
||||||
|
where
|
||||||
|
(rhss_scs, bs') = mapAccumL collectScs_d [] bs
|
||||||
|
scs' = [ Sc n xs rhs | Sc n xs rhs <- bs', isEAbs rhs]
|
||||||
|
non_scs' = [ Bind n xs rhs | Sc n xs rhs <- bs', not $ isEAbs rhs]
|
||||||
|
local_scs = map peelLambda scs'
|
||||||
|
-- local_scs = [ Sc n (xs ++ [x]) e1 | Sc n xs (EAbs x e1) <- scs']
|
||||||
|
(e_scs, e') = collectScsExp e
|
||||||
|
|
||||||
|
collectScs_d scs (Bind n xs rhs) = (scs ++ rhs_scs1, Sc n xs rhs')
|
||||||
|
where
|
||||||
|
(rhs_scs1, rhs') = collectScsExp rhs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
peelLambda :: ScDef -> ScDef
|
||||||
|
peelLambda sc@(Sc n xs e) = case e of
|
||||||
|
EAbs x e1 -> peelLambda (Sc n (xs ++ [x]) e1)
|
||||||
|
_ -> sc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
isEAbs :: Exp -> Bool
|
||||||
|
isEAbs = \case
|
||||||
|
EAbs {} -> True
|
||||||
|
_ -> False
|
||||||
|
|
||||||
|
mkEAbs :: [Bind] -> Exp -> Exp
|
||||||
|
mkEAbs [] e = e
|
||||||
|
mkEAbs bs e = ELet bs e
|
||||||
|
|
||||||
|
|
||||||
-- Annotated AST
|
-- Annotated AST
|
||||||
|
|
||||||
type AnnProgram = [(Ident, [Ident], AnnExp)]
|
type AnnProgram = [(Ident, [Ident], AnnExp)]
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ module Main where
|
||||||
|
|
||||||
import Grammar.Par (myLexer, pProgram)
|
import Grammar.Par (myLexer, pProgram)
|
||||||
import Grammar.Print (printTree)
|
import Grammar.Print (printTree)
|
||||||
import LambdaLifter (abstract, freeVars, lambdaLift)
|
import LambdaLifter (abstract, freeVars, lambdaLift, rename)
|
||||||
import System.Environment (getArgs)
|
import System.Environment (getArgs)
|
||||||
import System.Exit (exitFailure, exitSuccess)
|
import System.Exit (exitFailure, exitSuccess)
|
||||||
|
|
||||||
|
|
@ -21,11 +21,6 @@ main = getArgs >>= \case
|
||||||
putStrLn "-- Parser"
|
putStrLn "-- Parser"
|
||||||
putStrLn $ printTree prg
|
putStrLn $ printTree prg
|
||||||
putStrLn "\n--Lamda lifter"
|
putStrLn "\n--Lamda lifter"
|
||||||
putStrLn "\n--freevars"
|
|
||||||
print $ freeVars prg
|
|
||||||
putStrLn "\n--abstract"
|
|
||||||
putStrLn . printTree $ (abstract . freeVars) prg
|
|
||||||
putStrLn "\n--renamed"
|
|
||||||
putStrLn . printTree $ lambdaLift prg
|
putStrLn . printTree $ lambdaLift prg
|
||||||
exitSuccess
|
exitSuccess
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue