Guest User

Untitled

a guest
Dec 18th, 2017
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.71 KB | None | 0 0
  1. {-# LANGUAGE NamedFieldPuns #-}
  2. {-# LANGUAGE ViewPatterns #-}
  3. import Grammar (BinOp, Identifier, Type, HashMap)
  4. import Typed
  5. import Control.Comonad
  6. import Control.Applicative (liftA2)
  7.  
  8. data Expression t
  9. = BinOp {lhs :: Expression t, op :: BinOp, rhs :: Expression t, typ :: t}
  10. | MethodCall (Expression t) Identifier [Expression t] t
  11. | LitInt Int t
  12. | LitString String t
  13. | LitTrue t
  14. | LitFalse t
  15. | Identifier {id :: Identifier, typ :: t}
  16. | LitThis t
  17. | LitNull t
  18. | New {obj ::Identifier, typ :: t}
  19. | Not {expr :: (Expression t), typ :: t}
  20. | Block [Expression t] t
  21. | If { predicate :: Expression t
  22. , body :: Expression t
  23. , elseBody :: (Maybe (Expression t))
  24. , typ :: t
  25. }
  26. | While { predicate :: Expression t, body :: Expression t, typ :: t }
  27. | Println { expr :: Expression t, typ :: t }
  28. | Assign { var :: Identifier, expr :: Expression t, typ :: t }
  29. | Lambda { var :: Identifier
  30. , argType :: Type
  31. , expr :: Expression t
  32. , returnType :: (Maybe Type)
  33. , typ :: t
  34. }
  35. | Closure { free :: (HashMap Identifier ())
  36. , var :: Identifier
  37. , argType :: Type
  38. , expr :: Expression t
  39. , returnType :: (Maybe Type)
  40. , typ :: t
  41. }
  42. deriving (Eq, Show)
  43.  
  44. instance Functor Expression where
  45. fmap = liftW
  46.  
  47. instance Comonad Expression where
  48. extract (MethodCall _ _ _ t) = t
  49. extract (LitInt _ t) = t
  50. extract (LitString _ t) = t
  51. extract (LitTrue t) = t
  52. extract (LitFalse t) = t
  53. extract (LitThis t) = t
  54. extract (LitNull t) = t
  55. extract (Block _ t) = t
  56. extract exp = typ exp
  57.  
  58. extend f exp@(MethodCall object iden params t) = MethodCall (extend f object) iden (fmap (extend f) params) (f exp)
  59. extend f exp@(LitInt x _) = LitInt x (f exp)
  60. extend f exp@(LitString x _) = LitString x (f exp)
  61. extend f exp@(LitTrue _) = LitTrue (f exp)
  62. extend f exp@(LitFalse _) = LitFalse (f exp)
  63. extend f exp@(LitThis _) = LitThis (f exp)
  64. extend f exp@(LitNull _) = LitNull (f exp)
  65. extend f exp@(Block x _) = Block (fmap (extend f) x) (f exp)
  66. extend f (Not exp t) = Not (extend f exp) (f $ Not exp t)
  67. extend f exp@(If pred body elseB _) = If (e pred) (e body) (fmap e elseB) (f exp)
  68. where e = extend f
  69. extend f exp@While{predicate,body} = While (e predicate) (e body) (f exp)
  70. where e = extend f
  71. extend f exp@Println{expr} = exp {expr = extend f expr, typ = f exp}
  72. extend f exp@Assign{expr} = exp {expr = extend f expr, typ = f exp}
  73. extend f exp@Lambda{expr} = exp {expr = extend f expr, typ = f exp}
  74. extend f exp@Closure{expr} = exp {expr = extend f expr, typ = f exp}
  75. extend f exp@BinOp{lhs,rhs} = exp {lhs = extend f lhs, rhs = extend f rhs, typ = f exp}
  76. extend f exp@(Identifier i _) = Identifier i (f exp)
  77. extend f exp@(New o _) = New o (f exp)
  78.  
  79. isLeaf exp = case exp of
  80. LitInt _ t -> True
  81. LitString _ t -> True
  82. LitTrue t -> True
  83. LitFalse t -> True
  84. Identifier _ t -> True
  85. LitThis t -> True
  86. LitNull t -> True
  87. New _ t -> True
  88. _ -> False
  89.  
  90. extractSimple exp = case exp of
  91. Not{expr,typ} -> Just (expr,typ)
  92. Println{expr,typ} -> Just (expr,typ)
  93. Assign{expr,typ} -> Just (expr,typ)
  94. Lambda{expr,typ} -> Just (expr,typ)
  95. Closure{expr,typ} -> Just (expr,typ)
  96. _ -> Nothing
  97.  
  98.  
  99. instance ComonadApply Expression where
  100. fxp@(extract -> f) <@> exp@(extract -> x) | isLeaf exp = exp $> f x
  101. (BinOp lf _ rf f) <@> (BinOp lx o rx x) = BinOp (lf <@> lx) o (rf <@> rx) (f x)
  102. (MethodCall fo _ fp f) <@> (MethodCall xo iden xp x) = MethodCall (fo <@> xo) iden (zipWith (<@>) fp xp) (f x)
  103. (Not fe f) <@> (Not xe x) = Not (fe <@> xe) (f x)
  104. (Block fe f) <@> (Block xe x) = Block (zipWith (<@>) fe xe) (f x)
  105. (If fp fb fe f) <@> (If xp xb xe x) = If (fp <@> xp) (fb <@> xb) (liftA2 (<@>) fe xe) (f x)
  106. (While fp fb f) <@> (While xp xb x) = While (fp <@> xp) (fb <@> xb) (f x)
  107. (extractSimple -> Just (fe,f)) <@> (Not xe x) = Not (fe <@> xe) (f x)
  108. (extractSimple -> Just (fe,f)) <@> (Println xe x) = Println (fe <@> xe) (f x)
  109. (extractSimple -> Just (fe,f)) <@> (Assign var xe x) = Assign var (fe <@> xe) (f x)
  110. (extractSimple -> Just (fe,f)) <@> exp@Lambda{expr,typ} = exp {expr = fe <@> expr, typ = f typ}
  111. (extractSimple -> Just (fe,f)) <@> exp@Closure{expr,typ} = exp {expr = fe <@> expr, typ = f typ}
  112.  
  113. types :: Expression String -> Expression TType -> TType
  114. types LitInt{} = const TInt
  115. types Not{} = const TBool
  116. types While{} = \(While _ xb _) -> extract xb
  117. types LitTrue{} = const TBool
  118. types (LitThis klass) = const (TClass klass)
  119.  
  120. types' :: Expression TType -> TType
  121. types' LitInt{} = TInt
  122. types' Not{} = TBool
  123. types' (While _ xb _) = extract xb
  124. types' LitTrue{} = TBool
  125.  
  126. -- ComonadInject (TM) där man kan byta översta elementet.
  127. class Comonad w => ComonadInject w where
  128. inject :: a -> w a -> w a
  129.  
  130. instance ComonadInject Expression where
  131. inject x e | isLeaf e = x <$ e
  132. inject x (Not e _) = Not e x
  133. inject x e = e {typ = x}
  134.  
  135. --kfix :: ComonadApply w => w (w a -> a) -> w a
  136. --kfix w = fix $ \u -> w <@> duplicate u
  137.  
  138. --kfix (extend types $ (LitInt 1 ())) :: Expression (Expression TType -> TType) =
  139. -- fix $ \u :: Expression TType -> (extend types $ (LitInt 1 ())) <@> duplicate u
  140.  
  141. fix f = f (fix f)
  142.  
  143. -- kfix med 0 sharing.
  144. pfix :: Comonad w => w (w a -> a) -> w a
  145. pfix = fmap wfix . duplicate
  146.  
  147. bfix :: ComonadApply w => w (w a -> a) -> w a
  148. bfix w = w <@> extend bfix w
  149.  
  150. bfix2 :: (ComonadApply w, ComonadInject w) => w (w a -> a) -> w a
  151. bfix2 w = let x = w <@> inject undefined (extend bfix2 w) in x
  152.  
  153. fixtend :: ComonadApply w => (w a -> w b -> b) -> w a -> w b
  154. fixtend f = bfix . extend f
  155.  
  156. deepen w = While w w (extract w)
Add Comment
Please, Sign In to add comment