diff options
author | Joe Crayne <joe@jerkface.net> | 2019-03-23 18:17:22 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-03-23 18:17:22 -0400 |
commit | 86d43ec094cec3a88491258d17434b7e9ee7c1c9 (patch) | |
tree | 1e80efced140e815e95400324f504031ee3a7b5c | |
parent | 56b8d9316dcb37aedf5a7727f05b6cd81f9f0f19 (diff) |
grok assignment expression.
-rw-r--r-- | monkeypatch.hs | 76 |
1 files changed, 50 insertions, 26 deletions
diff --git a/monkeypatch.hs b/monkeypatch.hs index 352a0f5..e47cb37 100644 --- a/monkeypatch.hs +++ b/monkeypatch.hs | |||
@@ -252,8 +252,8 @@ transpileBinOp = \case | |||
252 | CAndOp -> ".&." | 252 | CAndOp -> ".&." |
253 | CXorOp -> "xor" | 253 | CXorOp -> "xor" |
254 | COrOp -> ".|." | 254 | COrOp -> ".|." |
255 | CLndOp -> "and" | 255 | CLndOp -> "&&" |
256 | CLorOp -> "or" | 256 | CLorOp -> "||" |
257 | 257 | ||
258 | -- This function decides whether to treat an identifier as a constant or as a | 258 | -- This function decides whether to treat an identifier as a constant or as a |
259 | -- pointer that must be peeked. | 259 | -- pointer that must be peeked. |
@@ -417,6 +417,21 @@ grokExpression fe (CStatExpr (CCompound idents xs _) _) = do | |||
417 | , compIntro = Map.empty | 417 | , compIntro = Map.empty |
418 | , comp = hsvar hv | 418 | , comp = hsvar hv |
419 | } | 419 | } |
420 | grokExpression fe (CAssign CAssignOp cvar expr _) = do | ||
421 | v <- cvarName cvar | ||
422 | (ss,x) <- grokExpression fe expr | ||
423 | let k = uniqIdentifier "go" (Map.insert v () $ foldr (\s m -> compFree s `Map.union` compIntro s `Map.union` m) Map.empty ss) | ||
424 | s = x | ||
425 | { compIntro = Map.singleton v () | ||
426 | , comp = Lambda () [hspvar k] | ||
427 | $ infixOp (App () (hsvar "return") (comp x)) ">>=" | ||
428 | $ Lambda () [hspvar v] (hsvar k) | ||
429 | } | ||
430 | return $ (,) (ss ++ [s]) Computation | ||
431 | { compFree = Map.empty | ||
432 | , compIntro = Map.empty | ||
433 | , comp = hsvar v | ||
434 | } | ||
420 | grokExpression fe _ = Nothing | 435 | grokExpression fe _ = Nothing |
421 | 436 | ||
422 | 437 | ||
@@ -493,6 +508,30 @@ grokStatement fe (CBlockStmt (CReturn (Just exp) _)) = do | |||
493 | let k = uniqIdentifier "go" (compFree x `Map.union` compIntro x) | 508 | let k = uniqIdentifier "go" (compFree x `Map.union` compIntro x) |
494 | x' = fmap (\y -> App () (hsvar "return") $ promote (fnArgs fe) y) x | 509 | x' = fmap (\y -> App () (hsvar "return") $ promote (fnArgs fe) y) x |
495 | return $ fmap (\y -> Lambda () [hspvar k] y) $ foldr applyComputation x' xs | 510 | return $ fmap (\y -> Lambda () [hspvar k] y) $ foldr applyComputation x' xs |
511 | grokStatement fe (CBlockStmt (CIf exp thn els _)) = do | ||
512 | (xs,x) <- grokExpression fe exp | ||
513 | let mkif0 = If () (comp x) | ||
514 | (mkif,stmts) <- case (thn,els) of | ||
515 | |||
516 | (CCompound [] stmts _, Nothing ) -> Just (mkif0, stmts) | ||
517 | (CCompound [] stmts _, Just (CExpr Nothing _) ) -> Just (mkif0, stmts) | ||
518 | (CCompound [] stmts _, Just (CCompound [] [ CBlockStmt (CExpr Nothing _) ] _)) -> Just (mkif0, stmts) | ||
519 | |||
520 | (CExpr Nothing _ ,Just (CCompound [] stmts _)) -> Just (flip mkif0, stmts) | ||
521 | (CCompound [] [CBlockStmt (CExpr Nothing _)] _,Just (CCompound [] stmts _)) -> Just (flip mkif0, stmts) | ||
522 | (CExpr Nothing _ ,Just e@(CExpr (Just _) _)) -> Just (flip mkif0, [CBlockStmt e]) | ||
523 | (CCompound [] [CBlockStmt (CExpr Nothing _)] _,Just e@(CExpr (Just _) _)) -> Just (flip mkif0, [CBlockStmt e]) | ||
524 | |||
525 | _ -> Nothing -- TODO | ||
526 | |||
527 | ss <- sequence $ map (grokStatement fe) stmts | ||
528 | let s = foldr applyComputation (Computation Map.empty Map.empty (hsvar k)) ss | ||
529 | k = uniqIdentifier "go" (Map.union (compFree x) (compFree s)) | ||
530 | return $ flip (foldr applyComputation) xs Computation | ||
531 | { compFree = compFree x `Map.union` compFree s | ||
532 | , compIntro = compIntro s | ||
533 | , comp = Lambda () [hspvar k] $ mkif (comp s) (hsvar k) | ||
534 | } | ||
496 | grokStatement fe (CBlockStmt (CExpr (Just (C.CCall (CVar (C.Ident "__assert_fail" _ _) _) xs _)) _)) = do | 535 | grokStatement fe (CBlockStmt (CExpr (Just (C.CCall (CVar (C.Ident "__assert_fail" _ _) _) xs _)) _)) = do |
497 | x <- case xs of | 536 | x <- case xs of |
498 | (CConst (CStrConst msg _):_) -> let s = getCString msg | 537 | (CConst (CStrConst msg _):_) -> let s = getCString msg |
@@ -544,30 +583,6 @@ grokStatement fe (CBlockStmt (CExpr (Just | |||
544 | $ infixOp (hsvar fn) ">>=" | 583 | $ infixOp (hsvar fn) ">>=" |
545 | $ Lambda () [hspvar v] (hsvar k) | 584 | $ Lambda () [hspvar v] (hsvar k) |
546 | } | 585 | } |
547 | grokStatement fe (CBlockStmt (CIf exp thn els _)) = do | ||
548 | (xs,x) <- grokExpression fe exp | ||
549 | let mkif0 = If () (comp x) | ||
550 | (mkif,stmts) <- case (thn,els) of | ||
551 | |||
552 | (CCompound [] stmts _, Nothing ) -> Just (mkif0, stmts) | ||
553 | (CCompound [] stmts _, Just (CExpr Nothing _) ) -> Just (mkif0, stmts) | ||
554 | (CCompound [] stmts _, Just (CCompound [] [ CBlockStmt (CExpr Nothing _) ] _)) -> Just (mkif0, stmts) | ||
555 | |||
556 | (CExpr Nothing _ ,Just (CCompound [] stmts _)) -> Just (flip mkif0, stmts) | ||
557 | (CCompound [] [CBlockStmt (CExpr Nothing _)] _,Just (CCompound [] stmts _)) -> Just (flip mkif0, stmts) | ||
558 | (CExpr Nothing _ ,Just e@(CExpr (Just _) _)) -> Just (flip mkif0, [CBlockStmt e]) | ||
559 | (CCompound [] [CBlockStmt (CExpr Nothing _)] _,Just e@(CExpr (Just _) _)) -> Just (flip mkif0, [CBlockStmt e]) | ||
560 | |||
561 | _ -> Nothing -- TODO | ||
562 | |||
563 | ss <- sequence $ map (grokStatement fe) stmts | ||
564 | let s = foldr applyComputation (Computation Map.empty Map.empty (hsvar k)) ss | ||
565 | k = uniqIdentifier "go" (Map.union (compFree x) (compFree s)) | ||
566 | return $ flip (foldr applyComputation) xs Computation | ||
567 | { compFree = compFree x `Map.union` compFree s | ||
568 | , compIntro = compIntro s | ||
569 | , comp = Lambda () [hspvar k] $ mkif (comp s) (hsvar k) | ||
570 | } | ||
571 | grokStatement fe (CBlockStmt (CExpr (Just (CUnary CPostIncOp (CMember (CVar cv0 _) fld True _) _)) _)) = do | 586 | grokStatement fe (CBlockStmt (CExpr (Just (CUnary CPostIncOp (CMember (CVar cv0 _) fld True _) _)) _)) = do |
572 | let k1 = uniqIdentifier "go" (varmap [fieldlbl,v]) | 587 | let k1 = uniqIdentifier "go" (varmap [fieldlbl,v]) |
573 | fieldlbl = identToString fld | 588 | fieldlbl = identToString fld |
@@ -582,6 +597,15 @@ grokStatement fe (CBlockStmt (CExpr (Just (CUnary CPostIncOp (CMember (CVar cv0 | |||
582 | (hsvar v)) | 597 | (hsvar v)) |
583 | (hsvar "succ")) ">>" (hsvar k1) | 598 | (hsvar "succ")) ">>" (hsvar k1) |
584 | } | 599 | } |
600 | {- | ||
601 | -- TODO: Are any above cases CBlockStmt (CExpr ...) neccessary? | ||
602 | -- XXX In next case after this, mexpr is always Nothing | ||
603 | grokStatement fe (CBlockStmt (CExpr (Just expr) _)) = do | ||
604 | (ss,x) <- grokExpression fe expr | ||
605 | let k = uniqIdentifier "go" $ foldr Map.union Map.empty $ map compFree ss ++ map compIntro ss | ||
606 | g = Computation Map.empty Map.empty (hsvar k) | ||
607 | return $ fmap (Lambda () [hspvar k]) $ foldr applyComputation g ss | ||
608 | -} | ||
585 | grokStatement fe (CBlockStmt (CExpr mexpr _)) = do | 609 | grokStatement fe (CBlockStmt (CExpr mexpr _)) = do |
586 | (ss,pre) <- maybe (Just $ (,) [] $ Computation Map.empty Map.empty id) | 610 | (ss,pre) <- maybe (Just $ (,) [] $ Computation Map.empty Map.empty id) |
587 | (fmap (second (fmap (\e -> infixFn e "seq"))) . grokExpression fe) mexpr | 611 | (fmap (second (fmap (\e -> infixFn e "seq"))) . grokExpression fe) mexpr |