Fix first unnecessary supercombinator
This commit is contained in:
parent
7a2404cf74
commit
ce31e4d490
10 changed files with 66 additions and 51 deletions
|
|
@ -1,12 +1,6 @@
|
||||||
|
|
||||||
|
|
||||||
Program. Program ::= [ScDef];
|
Program. Program ::= [Bind];
|
||||||
|
|
||||||
ScDef. ScDef ::= Bind;
|
|
||||||
separator ScDef ";";
|
|
||||||
|
|
||||||
separator Ident " ";
|
|
||||||
|
|
||||||
|
|
||||||
EId. Exp3 ::= Ident;
|
EId. Exp3 ::= Ident;
|
||||||
EInt. Exp3 ::= Integer;
|
EInt. Exp3 ::= Integer;
|
||||||
|
|
@ -17,6 +11,7 @@ EAbs. Exp ::= "\\" Ident "." Exp;
|
||||||
|
|
||||||
Bind. Bind ::= Ident [Ident] "=" Exp;
|
Bind. Bind ::= Ident [Ident] "=" Exp;
|
||||||
separator Bind ";";
|
separator Bind ";";
|
||||||
|
separator Ident " ";
|
||||||
|
|
||||||
coercions Exp 3;
|
coercions Exp 3;
|
||||||
|
|
||||||
|
|
|
||||||
4
basic-2
4
basic-2
|
|
@ -1,4 +0,0 @@
|
||||||
add x = \y. x + y;
|
|
||||||
|
|
||||||
main = (\z. z + z) ((add 4) 6);
|
|
||||||
|
|
||||||
2
sample-programs/basic-1
Normal file
2
sample-programs/basic-1
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
f = \x. x+1;
|
||||||
4
sample-programs/basic-2
Normal file
4
sample-programs/basic-2
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
add x = \y. x+y;
|
||||||
|
|
||||||
|
main = (\z. z+z) ((add 4) 6);
|
||||||
|
|
||||||
2
sample-programs/basic-3
Normal file
2
sample-programs/basic-3
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
main = (\x. x+x+3) ((\x. x) 2)
|
||||||
2
sample-programs/basic-4
Normal file
2
sample-programs/basic-4
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
f x = let g = (\y. y+1) in g (g x)
|
||||||
9
sample-programs/basic-5
Normal file
9
sample-programs/basic-5
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
id x = x;
|
||||||
|
|
||||||
|
add x y = x + y;
|
||||||
|
|
||||||
|
double n = n + n;
|
||||||
|
|
||||||
|
apply f x = \y -> f x y;
|
||||||
|
|
||||||
|
main = apply (id add) ((\x. x + 1) 1) (double 3);
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
{-# LANGUAGE LambdaCase #-}
|
{-# LANGUAGE LambdaCase #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE PatternSynonyms #-}
|
|
||||||
|
|
||||||
|
|
||||||
module LambdaLifter (lambdaLift, freeVars, abstract, rename, collectScs) where
|
module LambdaLifter (lambdaLift, freeVars, abstract, rename, collectScs) where
|
||||||
|
|
@ -15,20 +14,14 @@ import Data.Tuple.Extra (uncurry3)
|
||||||
import Grammar.Abs
|
import Grammar.Abs
|
||||||
import Prelude hiding (exp)
|
import Prelude hiding (exp)
|
||||||
|
|
||||||
pattern Sc :: Ident -> [Ident] -> Exp -> ScDef
|
|
||||||
pattern Sc n xs e = ScDef (Bind n xs e)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
lambdaLift :: Program -> Program
|
lambdaLift :: Program -> Program
|
||||||
lambdaLift = collectScs . rename . abstract . freeVars
|
lambdaLift = collectScs . rename . abstract . freeVars
|
||||||
|
|
||||||
|
|
||||||
-- Annotate free variables
|
-- Annotate free variables
|
||||||
|
|
||||||
freeVars :: Program -> AnnProgram
|
freeVars :: Program -> AnnProgram
|
||||||
freeVars (Program ds) = [ (n, xs, freeVarsExp (Set.fromList xs) e)
|
freeVars (Program ds) = [ (n, xs, freeVarsExp (Set.fromList xs) e)
|
||||||
| Sc n xs e <- ds
|
| Bind n xs e <- ds
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -64,7 +57,6 @@ freeVarsExp lv = \case
|
||||||
freeInValues = foldr1 Set.union (map freeVarsOf es')
|
freeInValues = foldr1 Set.union (map freeVarsOf es')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
freeVarsOf :: AnnExp -> Set Ident
|
freeVarsOf :: AnnExp -> Set Ident
|
||||||
freeVarsOf = fst
|
freeVarsOf = fst
|
||||||
|
|
||||||
|
|
@ -74,10 +66,21 @@ fromBinders bs = unzip3 [ (n, xs, e) | Bind n xs e <- bs ]
|
||||||
-- Lift lambda expression into let with binder "sc"
|
-- Lift lambda expression into let with binder "sc"
|
||||||
|
|
||||||
abstract :: AnnProgram -> Program
|
abstract :: AnnProgram -> Program
|
||||||
abstract p = Program
|
abstract prog = Program $ map f prog
|
||||||
[ Sc sc_name xs $ abstractExp rhs
|
where
|
||||||
| (sc_name, xs, rhs) <- p
|
f :: (Ident, [Ident], AnnExp) -> Bind
|
||||||
]
|
f (name, pars, rhs@(_, e)) =
|
||||||
|
case e of
|
||||||
|
AAbs par body -> Bind name (snoc par pars) $ abstractExp body
|
||||||
|
_ -> Bind name pars $ abstractExp rhs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- [ case rhs of
|
||||||
|
-- EAbs par body -> Bind name (snoc par pars) body
|
||||||
|
-- _ -> Bind name pars rhs
|
||||||
|
--
|
||||||
|
-- | (name, pars, rhs) <- prog
|
||||||
|
|
||||||
|
|
||||||
abstractExp :: AnnExp -> Exp
|
abstractExp :: AnnExp -> Exp
|
||||||
|
|
@ -94,13 +97,17 @@ 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"))
|
||||||
|
|
||||||
|
|
||||||
|
snoc :: a -> [a] -> [a]
|
||||||
|
snoc x xs = xs ++ [x]
|
||||||
|
|
||||||
-- Rename
|
-- Rename
|
||||||
|
|
||||||
rename :: Program -> Program
|
rename :: Program -> Program
|
||||||
rename (Program ds) = Program $ map (uncurry3 Sc) tuples
|
rename (Program ds) = Program $ map (uncurry3 Bind) tuples
|
||||||
where
|
where
|
||||||
tuples = snd (mapAccumL renameSc 0 ds)
|
tuples = snd (mapAccumL renameSc 0 ds)
|
||||||
renameSc i (Sc n xs e) = (i2, (n, xs', e'))
|
renameSc i (Bind n xs e) = (i2, (n, xs', e'))
|
||||||
where
|
where
|
||||||
(i1, xs', env) = newNames i xs
|
(i1, xs', env) = newNames i xs
|
||||||
(i2, e') = renameExp env i1 e
|
(i2, e') = renameExp env i1 e
|
||||||
|
|
@ -159,14 +166,23 @@ makeName prefix i = Ident (prefix ++ "_" ++ show i)
|
||||||
-- Collect supercombinators
|
-- Collect supercombinators
|
||||||
|
|
||||||
collectScs :: Program -> Program
|
collectScs :: Program -> Program
|
||||||
collectScs (Program ds) = Program $ concatMap collect_one_sc ds
|
collectScs (Program ds) = Program $ concatMap collectOneSc ds
|
||||||
where
|
where
|
||||||
collect_one_sc (Sc n xs e) = Sc n xs e' : scs
|
collectOneSc (Bind name args rhs) = Bind name args rhs' : scs
|
||||||
where (scs, e') = collectScsExp e
|
where (scs, rhs') = collectScsExp rhs
|
||||||
|
{-
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
collectScsExp :: Exp -> ([ScDef], Exp)
|
Bind (Ident "f") []
|
||||||
|
|
||||||
|
(ELet [Bind (Ident "sc") [] (EAbs (Ident "x") (EAdd (EId (Ident "x")) (EInt 1)))] (EId (Ident "sc")))
|
||||||
|
|
||||||
|
|
||||||
|
-}
|
||||||
|
|
||||||
|
|
||||||
|
collectScsExp :: Exp -> ([Bind], Exp)
|
||||||
collectScsExp = \case
|
collectScsExp = \case
|
||||||
|
|
||||||
EId n -> ([], EId n)
|
EId n -> ([], EId n)
|
||||||
|
|
@ -190,25 +206,15 @@ collectScsExp = \case
|
||||||
ELet bs e -> (rhss_scs ++ e_scs ++ local_scs, mkEAbs non_scs' e')
|
ELet bs e -> (rhss_scs ++ e_scs ++ local_scs, mkEAbs non_scs' e')
|
||||||
where
|
where
|
||||||
(rhss_scs, bs') = mapAccumL collectScs_d [] bs
|
(rhss_scs, bs') = mapAccumL collectScs_d [] bs
|
||||||
scs' = [ Sc n xs rhs | Sc n xs rhs <- bs', isEAbs rhs]
|
scs' = [ Bind n xs rhs | Bind n xs rhs <- bs', isEAbs rhs]
|
||||||
non_scs' = [ Bind n xs rhs | Sc n xs rhs <- bs', not $ isEAbs rhs]
|
non_scs' = [ Bind n xs rhs | Bind n xs rhs <- bs', not $ isEAbs rhs]
|
||||||
local_scs = map peelLambda scs'
|
local_scs = [ Bind n (xs ++ [x]) e1 | Bind n xs (EAbs x e1) <- scs']
|
||||||
-- local_scs = [ Sc n (xs ++ [x]) e1 | Sc n xs (EAbs x e1) <- scs']
|
|
||||||
(e_scs, e') = collectScsExp e
|
(e_scs, e') = collectScsExp e
|
||||||
|
|
||||||
collectScs_d scs (Bind n xs rhs) = (scs ++ rhs_scs1, Sc n xs rhs')
|
collectScs_d scs (Bind n xs rhs) = (scs ++ rhs_scs1, Bind n xs rhs')
|
||||||
where
|
where
|
||||||
(rhs_scs1, rhs') = collectScsExp rhs
|
(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 :: Exp -> Bool
|
||||||
isEAbs = \case
|
isEAbs = \case
|
||||||
EAbs {} -> True
|
EAbs {} -> True
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,12 @@ main = getArgs >>= \case
|
||||||
putStrLn err
|
putStrLn err
|
||||||
exitFailure
|
exitFailure
|
||||||
Right prg -> do
|
Right prg -> do
|
||||||
putStrLn "-- Parser"
|
putStrLn "-- Parse"
|
||||||
putStrLn $ printTree prg
|
putStrLn $ printTree prg
|
||||||
|
putStrLn "\n-- Abstract"
|
||||||
|
putStrLn . printTree $ (abstract . freeVars) prg
|
||||||
|
putStrLn "\n-- Rename"
|
||||||
|
putStrLn . printTree $ (rename . abstract . freeVars) prg
|
||||||
putStrLn "\n-- Lamda lifter"
|
putStrLn "\n-- Lamda lifter"
|
||||||
putStrLn . printTree $ lambdaLift prg
|
putStrLn . printTree $ lambdaLift prg
|
||||||
exitSuccess
|
exitSuccess
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
main = (\x. x + x + 3) ((\x. x) 2)
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue