home *** CD-ROM | disk | FTP | other *** search
- ------------------------------------------------------------------------------
- --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
-
-