Skip to content

Commit 518600b

Browse files
committed
Improving support for diverted variables by the compiler.
1 parent bb005b7 commit 518600b

File tree

2 files changed

+41
-18
lines changed

2 files changed

+41
-18
lines changed

hs-src/Language/Scheme/Compiler.hs

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -214,15 +214,29 @@ compile env (List [Atom "expand", _body]) copts = do
214214
val <- Language.Scheme.Macro.expand env False _body Language.Scheme.Core.apply
215215
compileScalar (" return $ " ++ astToHaskellStr val) copts
216216

217-
compile env (List (Atom "let-syntax" : List _bindings : _body)) copts = do
217+
compile env (List (Atom "let-syntax" : List _bindings : _body)) copts@(CompileOptions tfnc uvar uargs nfnc) = do
218218
-- TODO: check if let-syntax has been rebound?
219219
bodyEnv <- liftIO $ extendEnv env []
220220
_ <- Language.Scheme.Macro.loadMacros env bodyEnv Nothing False _bindings
221221
-- Expand whole body as a single continuous macro, to ensure hygiene
222222
expanded <- Language.Scheme.Macro.expand bodyEnv False (List _body) Language.Scheme.Core.apply
223-
case expanded of
224-
List e -> compile bodyEnv (List $ Atom "begin" : e) copts
225-
e -> compile bodyEnv e copts
223+
224+
-- TODO: should be able to consolidate with the one from macroEval
225+
-- also, need to use for the other 'expand' call below
226+
vars <- Language.Scheme.Macro.getDivertedVars bodyEnv
227+
case vars of
228+
[] -> func bodyEnv expanded copts
229+
_ -> do
230+
Atom symNext <- _gensym "afterDivert"
231+
diverted <- compileDivertedVars symNext bodyEnv vars copts
232+
rest <- func bodyEnv expanded $ CompileOptions symNext uvar uargs nfnc
233+
return $ [diverted] ++ rest
234+
235+
where
236+
func bodyEnv' expanded' copts' = do
237+
case expanded' of
238+
List e -> compile bodyEnv' (List $ Atom "begin" : e) copts'
239+
e -> compile bodyEnv' e copts'
226240

227241
compile env (List (Atom "letrec-syntax" : List _bindings : _body)) copts = do
228242
-- TODO: check if let-syntax has been rebound?
@@ -649,19 +663,14 @@ mfunc env lisp func copts@(CompileOptions tfnc uvar uargs nfnc) = do
649663

650664
transformed <- Language.Scheme.Macro.macroEval env lisp Language.Scheme.Core.apply
651665

652-
-- TESTING
653-
-- TODO: need to refactor this into a common function, and use it here as well
654-
-- as for expand below. Also, it would be nice if all the details for
655-
-- "diverted" could be contained in the macro module
656-
List tmp <- getNamespacedVar env " " "diverted"
657-
case tmp of
666+
vars <- Language.Scheme.Macro.getDivertedVars env
667+
case vars of
658668
[] -> func env transformed copts
659-
_ -> do -- TODO: call a function to process diverted vars
660-
Atom symNext <- _gensym "afterDivert"
661-
diverted <- compileDivertedVars symNext env tmp copts
662-
rest <- func env transformed $ CompileOptions symNext uvar uargs nfnc --copts
663-
return $ [diverted] ++ rest
664-
-- END
669+
_ -> do
670+
Atom symNext <- _gensym "afterDivert"
671+
diverted <- compileDivertedVars symNext env vars copts
672+
rest <- func env transformed $ CompileOptions symNext uvar uargs nfnc
673+
return $ [diverted] ++ rest
665674

666675
-- |Take a list of variables diverted into env at compile time, and
667676
-- divert them into the env at runtime

hs-src/Language/Scheme/Macro.hs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ module Language.Scheme.Macro
4545
expand
4646
, macroEval
4747
, loadMacros
48+
, getDivertedVars
4849
) where
4950
import Language.Scheme.Types
5051
import Language.Scheme.Variables
@@ -101,6 +102,19 @@ import Data.Array
101102
--needToExtendEnv (List [Atom "define-syntax", Atom _, (List (Atom "syntax-rules" : (List _ : _)))]) = True
102103
--needToExtendEnv _ = False
103104

105+
-- |Get a list of variables that the macro hygiene
106+
-- subsystem diverted back into the calling environment.
107+
--
108+
-- This is a specialized function that is only
109+
-- mean to be used by the husk compiler.
110+
getDivertedVars :: Env -> IOThrowsError [LispVal]
111+
getDivertedVars env = do
112+
List tmp <- getNamespacedVar env " " "diverted"
113+
return tmp
114+
115+
clearDivertedVars :: Env -> IOThrowsError LispVal
116+
clearDivertedVars env = defineNamespacedVar env " " "diverted" $ List []
117+
104118
-- |Examines the input AST to see if it is a macro call.
105119
-- If a macro call is found, the code is expanded.
106120
-- Otherwise the input is returned unchanged.
@@ -122,7 +136,7 @@ macroEval :: Env -- ^Current environment for the AST
122136
-}
123137
macroEval env lisp@(List (Atom x : _)) apply = do
124138
-- Keep track of diverted variables
125-
_ <- defineNamespacedVar env " " "diverted" (List [])
139+
_ <- clearDivertedVars env
126140
_macroEval env lisp apply
127141
macroEval env lisp apply = _macroEval env lisp apply
128142

@@ -608,7 +622,7 @@ expand env dim code apply = do
608622
--
609623

610624
-- Keep track of diverted variables
611-
_ <- defineNamespacedVar env " " "diverted" (List [])
625+
_ <- clearDivertedVars env
612626
walkExpanded env env env renameEnv cleanupEnv dim True False (List []) code apply
613627

614628
-- |Walk expanded code per Clinger's algorithm from Macros That Work

0 commit comments

Comments
 (0)