shared closures maybe
This commit is contained in:
@@ -9,6 +9,9 @@
|
|||||||
. (progn (defun apply-cabal-fmt-h ()
|
. (progn (defun apply-cabal-fmt-h ()
|
||||||
(haskell-mode-buffer-apply-command "cabal-fmt"))
|
(haskell-mode-buffer-apply-command "cabal-fmt"))
|
||||||
(add-hook 'before-save-hook #'apply-cabal-fmt-h nil t)))))
|
(add-hook 'before-save-hook #'apply-cabal-fmt-h nil t)))))
|
||||||
|
(scheme-mode
|
||||||
|
. ((eval . (dolist (s '(kappa κ prim))
|
||||||
|
(put s 'scheme-indent-function 1)))))
|
||||||
(nil
|
(nil
|
||||||
. ((eval
|
. ((eval
|
||||||
. (progn (defun display-ansi ()
|
. (progn (defun display-ansi ()
|
||||||
|
|||||||
@@ -132,3 +132,34 @@ multiple ~env-ref~ calls could probably be replaced with a primitive that loads
|
|||||||
$code)
|
$code)
|
||||||
1))))
|
1))))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
** example
|
||||||
|
|
||||||
|
#+begin_src scheme
|
||||||
|
(λ (n m ktail)
|
||||||
|
(letrec ((f (λ (x ktail-0) (+ x n ktail-0)))
|
||||||
|
(g (λ (y ktail-1) (+ y g ktail-1))))
|
||||||
|
(prim (cons f g) ktail)))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src scheme
|
||||||
|
(λ (n m ktail)
|
||||||
|
(letrec ((f-code (λ (x ktail-0)
|
||||||
|
(prim (env-get 2)
|
||||||
|
(κ (n)
|
||||||
|
(+ x n ktail-0)))))
|
||||||
|
(g-code (λ (y ktail-1)
|
||||||
|
(prim (env-get 3)
|
||||||
|
(κ (m)
|
||||||
|
(+ y m ktail-1))))))
|
||||||
|
(letrec ((with-closure-code
|
||||||
|
(κ (f g)
|
||||||
|
(prim (get-env 0)
|
||||||
|
(κ (ktail)
|
||||||
|
(prim cons f g ktail))))))
|
||||||
|
(prim (make-shared-closure (with-closure-code)
|
||||||
|
ktail)
|
||||||
|
(κ (with-closure)
|
||||||
|
(prim (make-shared-closure (f-code g-code) n m)
|
||||||
|
with-closure))))))
|
||||||
|
#+end_src
|
||||||
|
|||||||
+56
-17
@@ -16,38 +16,77 @@ import Data.Traversable
|
|||||||
genCodeName :: GenSym :> es => Name -> Eff es Name
|
genCodeName :: GenSym :> es => Name -> Eff es Name
|
||||||
genCodeName f = gensym' @Name $ f ^. _Wrapped' . to (<> "-code")
|
genCodeName f = gensym' @Name $ f ^. _Wrapped' . to (<> "-code")
|
||||||
|
|
||||||
bindEnv :: Name -> List Name -> Exp -> Exp
|
bindEnv :: List Name -> Exp -> Exp
|
||||||
bindEnv l frees m = [cps|
|
bindEnv frees m = [cps|
|
||||||
(letrec ((#{l} (κ #{frees} #{m})))
|
(prim (get-env) (κ #{frees} #{m}))
|
||||||
(prim (get-env) #{l}))
|
|
||||||
|]
|
|]
|
||||||
|
|
||||||
close :: forall es. GenSym :> es => Exp -> Eff es Exp
|
close1 :: forall es. GenSym :> es => Exp -> Eff es Exp
|
||||||
close = transformM \case
|
close1 = \case
|
||||||
ExpLetRec bs e -> do
|
lr@(ExpLetRec bs e) -> do
|
||||||
let boundNames = bs ^.. each . _1
|
let boundNames = bs ^.. each . _1
|
||||||
|
let boundNames' = setOf each boundNames
|
||||||
let frees = bs
|
let frees = bs
|
||||||
& foldMapOf
|
& foldMapOf
|
||||||
(each . _2 . absBody)
|
(each . _2)
|
||||||
(freeWithBound' $ setOf (each . _1) bs)
|
(freeWithBound' boundNames')
|
||||||
& nub
|
& nub
|
||||||
|
pTraceShowM frees
|
||||||
env_cont_l <- gensym' @Name "env-cont"
|
env_cont_l <- gensym' @Name "env-cont"
|
||||||
e_l <- gensym' @Name "letrec-body-cont"
|
e_l <- gensym' @Name "letrec-body-cont"
|
||||||
-- let ab' = ab & absBody .~ m'
|
|
||||||
bs' <- for bs \(f,ab) -> do
|
bs' <- for bs \(f,ab) -> do
|
||||||
f_code_l <- genCodeName f
|
f_code_l <- genCodeName f
|
||||||
pure
|
pure ( f_code_l
|
||||||
( f_code_l
|
, ab & absBody %~ bindEnv (boundNames ++ frees)
|
||||||
, ab & absBody %~ bindEnv f_code_l (boundNames ++ frees)
|
)
|
||||||
)
|
let codes = bs' ^.. each . _1 . to MkLabel
|
||||||
pure [cps|
|
pure [cps|
|
||||||
(letrec #{bs'}
|
(letrec #{bs'}
|
||||||
(letrec ((#{e_l} (κ #{boundNames} #{e})))
|
(prim (make-shared-closure #{codes} #{frees})
|
||||||
(prim (make-shared-closure #{boundNames} #{frees})
|
(κ #{boundNames}
|
||||||
#{e_l})))
|
#{e})))
|
||||||
|]
|
|]
|
||||||
|
|
||||||
e -> pure e
|
e -> pure e
|
||||||
|
|
||||||
|
close :: forall es. GenSym :> es => Exp -> Eff es Exp
|
||||||
|
close = transformM close1
|
||||||
|
|
||||||
closeProgram :: GenSym :> es => Program -> Eff es Program
|
closeProgram :: GenSym :> es => Program -> Eff es Program
|
||||||
closeProgram = traverseOf (#body . #body) close
|
closeProgram = traverseOf (#body . #body) close
|
||||||
|
|
||||||
|
prog :: Program
|
||||||
|
prog = [cps|
|
||||||
|
(λ (start-ktail0)
|
||||||
|
(letrec ((fac
|
||||||
|
(λ (n lambda-tail1)
|
||||||
|
(letrec ((prim-k3
|
||||||
|
(κ (r2)
|
||||||
|
(letrec ((truthy-cont4
|
||||||
|
(κ ()
|
||||||
|
(continue lambda-tail1 1)))
|
||||||
|
(falsey-cont5
|
||||||
|
(κ ()
|
||||||
|
(letrec ((prim-k7
|
||||||
|
(κ (r6)
|
||||||
|
(letrec
|
||||||
|
((r8
|
||||||
|
(κ (x9)
|
||||||
|
(letrec
|
||||||
|
((prim-k11
|
||||||
|
(κ (r10)
|
||||||
|
(continue
|
||||||
|
lambda-tail1
|
||||||
|
r10))))
|
||||||
|
(prim
|
||||||
|
(* n x9)
|
||||||
|
prim-k11)))))
|
||||||
|
(fac r6 r8)))))
|
||||||
|
(prim (- n 1) prim-k7)))))
|
||||||
|
(if r2
|
||||||
|
truthy-cont4
|
||||||
|
falsey-cont5)))))
|
||||||
|
(prim (zero? n) prim-k3)))))
|
||||||
|
(letrec ((r12 (κ (x13) (continue start-ktail0 x13))))
|
||||||
|
(fac 20 r12))))
|
||||||
|
|]
|
||||||
|
|||||||
Reference in New Issue
Block a user