@@ -7,6 +7,9 @@ import Data.Maybe
7
7
import Text.Parsec
8
8
import Data.Functor.Identity (Identity )
9
9
import System.IO (hSetEncoding , stdin , stdout , utf8 )
10
+ import Data.IORef ( newIORef , readIORef )
11
+ import GHC.IORef ( IORef (IORef ) )
12
+ import GHC.Base ( IO (IO ) )
10
13
11
14
12
15
type Parser = Parsec String ()
@@ -126,23 +129,23 @@ fun opt (sapp(sapp(scomb S,sapp(scomb K,e)),scomb I)) = (e : snode)
126
129
-- graph allocation
127
130
type Pointer = Int
128
131
129
- data Graph =
132
+ data Graph =
130
133
Node Pointer Pointer
131
134
| Comb String
132
- | Num Integer
135
+ | Num Integer
133
136
deriving Show
134
137
135
- allocate :: Expr -> [(Pointer , Graph )]
136
- allocate expr =
137
- alloc expr 1 []
138
+ allocate :: Expr -> [(Pointer , Graph )]
139
+ allocate expr =
140
+ alloc expr 1 []
138
141
where
139
142
maxPointer :: [(Pointer , Graph )] -> Pointer
140
143
maxPointer x = maximum $ map fst x
141
144
142
145
alloc :: Expr -> Int -> [(Int , Graph )] -> [(Int , Graph )]
143
146
alloc (Var name) pointer memMap = (pointer, Comb name) : memMap
144
147
alloc (Int val) pointer memMap = (pointer, Num val) : memMap
145
- alloc (l :@ r) pointer memMap =
148
+ alloc (l :@ r) pointer memMap =
146
149
let pointerL = pointer+ 1
147
150
allocL = alloc l pointerL []
148
151
maxL = maxPointer allocL
@@ -163,6 +166,37 @@ spine g@(Node l r) mm stack = spine (getNode l mm) mm (g:stack)
163
166
Nothing -> error $ " deref " ++ show p ++ " in " ++ show mm
164
167
Just g -> g
165
168
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
+
166
200
167
201
-- parse a lambda expression
168
202
toSK :: String -> Either ParseError Expr
@@ -179,9 +213,9 @@ getSK _ = Var "error"
179
213
red :: Expr -> Expr
180
214
red i@ (Int _i) = i
181
215
red (Var " i" :@ x) = x
182
- red (Var " i" :@ x :@ y) = x :@ y
216
+ red (Var " i" :@ x :@ y) = x :@ y
183
217
red (Var " k" :@ x :@ _) = x
184
- red (Var " k" :@ x :@ _ :@ z) = x :@ z
218
+ red (Var " k" :@ x :@ _ :@ z) = x :@ z
185
219
red (Var " s" :@ f :@ g :@ x) = f :@ x :@ (g :@ x)
186
220
red (Var " s" :@ f :@ g :@ x :@ z) = f :@ x :@ (g :@ x) :@ z
187
221
red (Var " c" :@ f :@ g :@ x) = f :@ x :@ g
0 commit comments