@@ -7,6 +7,9 @@ import Data.Maybe
77import Text.Parsec
88import Data.Functor.Identity (Identity )
99import System.IO (hSetEncoding , stdin , stdout , utf8 )
10+ import Data.IORef ( newIORef , readIORef )
11+ import GHC.IORef ( IORef (IORef ) )
12+ import GHC.Base ( IO (IO ) )
1013
1114
1215type Parser = Parsec String ()
@@ -126,23 +129,23 @@ fun opt (sapp(sapp(scomb S,sapp(scomb K,e)),scomb I)) = (e : snode)
126129-- graph allocation
127130type Pointer = Int
128131
129- data Graph =
132+ data Graph =
130133 Node Pointer Pointer
131134 | Comb String
132- | Num Integer
135+ | Num Integer
133136 deriving Show
134137
135- allocate :: Expr -> [(Pointer , Graph )]
136- allocate expr =
137- alloc expr 1 []
138+ allocate :: Expr -> [(Pointer , Graph )]
139+ allocate expr =
140+ alloc expr 1 []
138141 where
139142 maxPointer :: [(Pointer , Graph )] -> Pointer
140143 maxPointer x = maximum $ map fst x
141144
142145 alloc :: Expr -> Int -> [(Int , Graph )] -> [(Int , Graph )]
143146 alloc (Var name) pointer memMap = (pointer, Comb name) : memMap
144147 alloc (Int val) pointer memMap = (pointer, Num val) : memMap
145- alloc (l :@ r) pointer memMap =
148+ alloc (l :@ r) pointer memMap =
146149 let pointerL = pointer+ 1
147150 allocL = alloc l pointerL []
148151 maxL = maxPointer allocL
@@ -163,6 +166,37 @@ spine g@(Node l r) mm stack = spine (getNode l mm) mm (g:stack)
163166 Nothing -> error $ " deref " ++ show p ++ " in " ++ show mm
164167 Just g -> g
165168
169+ --- allocation with IORefs
170+ data Graf =
171+ Nod (IO (IORef Graf )) (IO (IORef Graf ))
172+ | Com String
173+ | Numb Integer
174+
175+
176+ alloc :: Expr -> IO (IORef Graf )
177+ alloc expr = newIORef(allocate expr)
178+ where
179+ allocate (Var name) = Com name
180+ allocate (Int val) = Numb val
181+ allocate (l :@ r) =
182+ let refL = newIORef (allocate l)
183+ refR = newIORef (allocate r)
184+ in Nod refL refR
185+ allocate _ = error $ " all lambdas must be abstracted first: " ++ show expr
186+
187+ dealloc :: IO (IORef Graf ) -> IO Expr
188+ dealloc graphRef = do
189+ gRef <- graphRef
190+ payload <- readIORef gRef
191+ case payload of
192+ (Com c) -> return $ Var c
193+ (Numb n) -> return $ Int n
194+ (Nod l r) -> do
195+ rExpr <- dealloc r
196+ lExpr <- dealloc l
197+ return (lExpr :@ rExpr)
198+
199+
166200
167201-- parse a lambda expression
168202toSK :: String -> Either ParseError Expr
@@ -179,9 +213,9 @@ getSK _ = Var "error"
179213red :: Expr -> Expr
180214red i@ (Int _i) = i
181215red (Var " i" :@ x) = x
182- red (Var " i" :@ x :@ y) = x :@ y
216+ red (Var " i" :@ x :@ y) = x :@ y
183217red (Var " k" :@ x :@ _) = x
184- red (Var " k" :@ x :@ _ :@ z) = x :@ z
218+ red (Var " k" :@ x :@ _ :@ z) = x :@ z
185219red (Var " s" :@ f :@ g :@ x) = f :@ x :@ (g :@ x)
186220red (Var " s" :@ f :@ g :@ x :@ z) = f :@ x :@ (g :@ x) :@ z
187221red (Var " c" :@ f :@ g :@ x) = f :@ x :@ g
0 commit comments