summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-03-23 23:17:41 -0400
committerJoe Crayne <joe@jerkface.net>2019-03-23 23:17:41 -0400
commitf8f3647669288b7d2b70025bef77382ce6420e37 (patch)
treed1af301e891d55da36a563d78040d5623ca28052
parent30799e391ddfa9ca56289b3f300c373a727171d9 (diff)
Applicative instance for Computation.
-rw-r--r--monkeypatch.hs48
1 files changed, 28 insertions, 20 deletions
diff --git a/monkeypatch.hs b/monkeypatch.hs
index d7c4282..a6c4db9 100644
--- a/monkeypatch.hs
+++ b/monkeypatch.hs
@@ -159,6 +159,19 @@ data Computation st = Computation
159 } 159 }
160 deriving (Eq,Ord,Functor) 160 deriving (Eq,Ord,Functor)
161 161
162instance Applicative Computation where
163 pure = mkcomp
164 mf <*> ma = Computation
165 { compFree = Map.union (compFree mf) (compFree ma)
166 , compIntro = Map.union (compIntro mf) (compIntro ma)
167 , compContinue = (if isJust (compContinue mf) && isJust (compContinue ma)
168 then trace "Warning: incompatible continue symbols."
169 else id)
170 $ mplus (compContinue mf) (compContinue ma)
171 , comp = comp mf $ comp ma
172 }
173
174
162mkcomp :: x -> Computation x 175mkcomp :: x -> Computation x
163mkcomp x = Computation Map.empty Map.empty Nothing x 176mkcomp x = Computation Map.empty Map.empty Nothing x
164 177
@@ -323,9 +336,7 @@ grokExpression fe (CBinary op a b _) = do
323 | otherwise = infixOp 336 | otherwise = infixOp
324 -- trace ("intros("++hop++"): "++show (foldr Map.union Map.empty $ map compIntro as)) $ return () 337 -- trace ("intros("++hop++"): "++show (foldr Map.union Map.empty $ map compIntro as)) $ return ()
325 -- TODO: Short-circuit boolean evaluation side-effects. 338 -- TODO: Short-circuit boolean evaluation side-effects.
326 return $ (,) ss $ (mkcomp $ infx (comp ca) hop (comp cb)) 339 return $ (,) ss $ infx <$> ca <*> pure hop <*> cb
327 { compFree = compFree ca `Map.union` compFree cb
328 }
329grokExpression fe (CUnary CAdrOp (CVar cv0 _) _) = do 340grokExpression fe (CUnary CAdrOp (CVar cv0 _) _) = do
330 let cv = identToString cv0 341 let cv = identToString cv0
331 hv = "p" ++ cv 342 hv = "p" ++ cv
@@ -348,9 +359,7 @@ grokExpression fe (CCond cond (Just thn) els _) = do
348 (es,e) <- grokExpression fe els 359 (es,e) <- grokExpression fe els
349 let tt = foldr applyComputation t ts 360 let tt = foldr applyComputation t ts
350 ee = foldr applyComputation e es 361 ee = foldr applyComputation e es
351 return $ (,) cs $ fmap (\cnd -> If () cnd (comp tt) (comp ee)) c 362 return $ (,) cs $ If () <$> c <*> tt <*> ee
352 { compFree = compFree ee `Map.union` compFree tt `Map.union` compFree c
353 }
354grokExpression fe (CSizeofExpr expr _) = do 363grokExpression fe (CSizeofExpr expr _) = do
355 (xs,x) <- grokExpression fe expr 364 (xs,x) <- grokExpression fe expr
356 return $ (,) xs $ fmap (App () (hsvar "sizeOf")) x 365 return $ (,) xs $ fmap (App () (hsvar "sizeOf")) x
@@ -379,16 +388,13 @@ grokExpression fe (C.CCall (CVar fn _) exps _) = do
379 gs <- mapM (grokExpression fe) exps 388 gs <- mapM (grokExpression fe) exps
380 let ss = concatMap fst gs -- TODO: resolve variable name conflicts 389 let ss = concatMap fst gs -- TODO: resolve variable name conflicts
381 hv = "r" ++ identToString fn 390 hv = "r" ++ identToString fn
382 cll = foldl (App ()) (hsvar (identToString fn)) $ map (comp . snd) gs 391 -- cll = foldl (App ()) (hsvar (identToString fn)) $ map (comp . snd) gs
383 frees = foldr Map.union (Map.singleton (identToString fn) ()) (map (compFree . snd) gs) 392 -- frees = foldr Map.union (Map.singleton (identToString fn) ()) (map (compFree . snd) gs)
384 k = uniqIdentifier "go" frees 393 fn' = identToString fn
385 s = Computation 394 cll = foldl (\f x -> App () <$> f <*> x) (mkcomp $ hsvar fn'){compFree = Map.singleton fn' ()} (map snd gs)
386 { compFree = frees 395 k = uniqIdentifier "go" (compFree s)
387 , compIntro = Map.singleton hv () 396 s = (fmap (\c -> FormalLambda k $ infixOp c ">>=" $ Lambda () [hspvar hv] (hsvar k)) cll)
388 , compContinue = Nothing 397 { compIntro = Map.singleton hv ()
389 , comp = FormalLambda k
390 $ infixOp cll ">>="
391 $ Lambda () [hspvar hv] (hsvar k)
392 } 398 }
393 return $ (,) (ss++[s]) (mkcomp $ hsvar hv) 399 return $ (,) (ss++[s]) (mkcomp $ hsvar hv)
394 { compFree = Map.singleton hv () 400 { compFree = Map.singleton hv ()
@@ -556,13 +562,15 @@ grokStatement fe (CBlockStmt (CExpr (Just
556 return $ fmap (FormalLambda k1) $ foldr applyComputation x' xs 562 return $ fmap (FormalLambda k1) $ foldr applyComputation x' xs
557grokStatement fe (CBlockStmt (CExpr (Just 563grokStatement fe (CBlockStmt (CExpr (Just
558 (C.CCall cvarfun exps _)) _)) = do 564 (C.CCall cvarfun exps _)) _)) = do
565 -- This case is technically not needed, but it makes slightly cleaner output
566 -- by avoiding a bind operation.
559 fn <- cvarName cvarfun 567 fn <- cvarName cvarfun
560 gs <- mapM (grokExpression fe) exps 568 gs <- mapM (grokExpression fe) exps
561 let k = uniqIdentifier "go" frees 569 let k = uniqIdentifier "go" (compFree s1)
562 cll = foldl (App ()) (hsvar fn) $ map (comp . snd) gs 570 cll = foldl (\f x -> App () <$> f <*> x) (mkcomp $ hsvar fn){compFree = Map.singleton fn ()} $ map snd gs
563 frees = foldr Map.union (Map.singleton fn ()) (map (compFree . snd) gs) 571 s1 = fmap (`infixOp` ">>") cll
572 s = s1 <*> mkcomp (hsvar k)
564 x = foldr applyComputation s $ concatMap fst gs 573 x = foldr applyComputation s $ concatMap fst gs
565 s = (mkcomp $ infixOp cll ">>" (hsvar k)) { compFree = frees }
566 return $ fmap (FormalLambda k) x 574 return $ fmap (FormalLambda k) x
567grokStatement fe (CBlockStmt (CExpr (Just 575grokStatement fe (CBlockStmt (CExpr (Just
568 (CAssign CAssignOp cvarnew 576 (CAssign CAssignOp cvarnew