diff options
author | Joe Crayne <joe@jerkface.net> | 2019-03-23 23:17:41 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-03-23 23:17:41 -0400 |
commit | f8f3647669288b7d2b70025bef77382ce6420e37 (patch) | |
tree | d1af301e891d55da36a563d78040d5623ca28052 | |
parent | 30799e391ddfa9ca56289b3f300c373a727171d9 (diff) |
Applicative instance for Computation.
-rw-r--r-- | monkeypatch.hs | 48 |
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 | ||
162 | instance 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 | |||
162 | mkcomp :: x -> Computation x | 175 | mkcomp :: x -> Computation x |
163 | mkcomp x = Computation Map.empty Map.empty Nothing x | 176 | mkcomp 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 | } | ||
329 | grokExpression fe (CUnary CAdrOp (CVar cv0 _) _) = do | 340 | grokExpression 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 | } | ||
354 | grokExpression fe (CSizeofExpr expr _) = do | 363 | grokExpression 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 |
557 | grokStatement fe (CBlockStmt (CExpr (Just | 563 | grokStatement 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 |
567 | grokStatement fe (CBlockStmt (CExpr (Just | 575 | grokStatement fe (CBlockStmt (CExpr (Just |
568 | (CAssign CAssignOp cvarnew | 576 | (CAssign CAssignOp cvarnew |