home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 2
/
DATAFILE_PDCD2.iso
/
utilities
/
_gofer
/
!Gofer
/
archives
/
Demos
/
Modular
/
LambdaLift
< prev
next >
Wrap
Text File
|
1993-02-12
|
5KB
|
126 lines
------------------------------------------------------------------------------
--The files in this directory are based on the programs described in:
--
-- A Modular fully-lazy lambda lifter in Haskell
-- Simon L. Peyton Jones and David Lester
-- Software -- Practice and Experience
-- Vol 21(5), pp.479-506
-- MAY 1991
--
--See the Readme file for more details.
------------------------------------------------------------------------------
-- 3.3 A data type for compilation -- a happy ending:
data Constant = CNum Int | CBool Bool | CFun Name
type Name = String
data Expr binder = EVar Name |
EConst Constant |
EAp (Expr binder) (Expr binder) |
ELet IsRec [Defn binder] (Expr binder) |
ELam [binder] (Expr binder)
type Defn binder = (binder, Expr binder)
type Expression = Expr Name
type IsRec = Bool
recursive = True
nonRecursive = False
type AnnExpr binder a = (a, AnnExpr' binder a)
data AnnExpr' binder a = AVar Name |
AConst Constant |
AAp (AnnExpr binder a) (AnnExpr binder a) |
ALet IsRec [AnnDefn binder a] (AnnExpr binder a) |
ALam [binder] (AnnExpr binder a)
type AnnDefn binder a = (binder, AnnExpr binder a)
bindersOf :: [(binder,rhs)] -> [binder]
bindersOf defns = [ binder | (binder,rhs) <- defns ]
rhssOf :: [(binder,rhs)] -> [rhs]
rhssOf defns = [ rhs | (binder, rhs) <- defns ]
-- 4 Lambda lifting:
lambdaLift :: Expression -> [SCDefn]
lambdaLift = collectSCs . abstract . freeVars
type SCDefn = (Name, [Name], Expression)
-- 4.2 Free variables:
freeVars :: Expression -> AnnExpr Name (Set Name)
freeVars (EConst k) = (setEmpty, AConst k)
freeVars (EVar v) = (setSingleton v, AVar v)
freeVars (EAp e1 e2) = (setUnion (freeVarsOf e1') (freeVarsOf e2'),AAp e1' e2')
where e1' = freeVars e1
e2' = freeVars e2
freeVars (ELam args body)
= (setDifference (freeVarsOf body') (setFromList args), ALam args body')
where body' = freeVars body
freeVars (ELet isRec defns body)
= (setUnion defnsFree bodyFree, ALet isRec defns' body')
where binders = bindersOf defns
binderSet = setFromList binders
values' = map freeVars (rhssOf defns)
defns' = zip binders values'
freeInValues = foldr setUnion setEmpty (map freeVarsOf values')
defnsFree
| isRec = setDifference freeInValues binderSet
| not isRec = freeInValues
body' = freeVars body
bodyFree = setDifference (freeVarsOf body') binderSet
freeVarsOf :: AnnExpr Name (Set Name) -> Set Name
freeVarsOf (freeVars, expr) = freeVars
-- 4.3 Generating supercombinators:
abstract :: AnnExpr Name (Set Name) -> Expression
abstract (_, AVar v) = EVar v
abstract (_, AConst k) = EConst k
abstract (_, AAp e1 e2) = EAp (abstract e1) (abstract e2)
abstract (free, ALam args body)
= foldl EAp sc (map EVar fvList)
where fvList = setToList free
sc = ELam (fvList++args) (abstract body)
abstract (_,ALet isRec defns body)
= ELet isRec
[(name,abstract body) | (name,body) <- defns]
(abstract body)
-- 4.4 Collecting supercombinators:
collectSCs :: Expression -> [SCDefn]
collectSCs e = [("$main",[],e')] ++ bagToList scs
where (_, scs, e') = collectSCs_e initialNameSupply e
collectSCs_e :: NameSupply -> Expression -> (NameSupply,Bag SCDefn,Expression)
collectSCs_e ns (EConst k) = (ns, bagEmpty, EConst k)
collectSCs_e ns (EVar v) = (ns, bagEmpty, EVar v)
collectSCs_e ns (EAp e1 e2) = (ns'', bagUnion scs1 scs2, EAp e1' e2')
where (ns', scs1, e1') = collectSCs_e ns e1
(ns'', scs2, e2') = collectSCs_e ns' e2
collectSCs_e ns (ELam args body)
= (ns'', bagInsert (name,args,body') bodySCs, EConst (CFun name))
where (ns', bodySCs,body') = collectSCs_e ns body
(ns'',name) = newName ns' "SC"
collectSCs_e ns (ELet isRec defns body)
= (ns'', scs, ELet isRec defns' body')
where ((ns'',scs),defns') = mapAccuml collectSCs_d (ns',bodySCs) defns
(ns', bodySCs, body') = collectSCs_e ns body
collectSCs_d (ns,scs) (name,value)
= ((ns',bagUnion scs scs'), (name, value'))
where (ns',scs',value') = collectSCs_e ns value