@@ -20,132 +20,207 @@ module Language.PureScript.Pretty.Values (
21import Data.Maybe (fromMaybe)
21import Data.Maybe (fromMaybe)
22import Data.List (intercalate)
22import Data.List (intercalate)
23−import Control.Arrow ((<+>))
24+import Control.Arrow ((<+>), runKleisli)
24import Control.PatternArrows
25import Control.PatternArrows
26+import Control.Monad.State
27+import Control.Applicative
26−import Language.PureScript.Types
27import Language.PureScript.Declarations
29import Language.PureScript.Declarations
28import Language.PureScript.Pretty.Common
30import Language.PureScript.Pretty.Common
29−import Language.PureScript.Pretty.Types
31+import Language.PureScript.Pretty.Types (prettyPrintType)
31−literals :: Pattern () Value String
33+literals :: Pattern PrinterState Value String
32−literals = mkPattern match
34+literals = mkPattern' match
36+ match :: Value -> StateT PrinterState Maybe String
34− match (NumericLiteral n) = Just $ either show show n
37+ match (NumericLiteral n) = return $ either show show n
35− match (StringLiteral s) = Just $ show s
38+ match (StringLiteral s) = return $ show s
36− match (BooleanLiteral True) = Just "true"
39+ match (BooleanLiteral True) = return "true"
37− match (BooleanLiteral False) = Just "false"
40+ match (BooleanLiteral False) = return "false"
38− match (ArrayLiteral xs) = Just $ "[" ++ intercalate ", " (map prettyPrintValue xs) ++ "]"
41+ match (ArrayLiteral xs) = fmap concat $ sequence
43+ , withIndent $ prettyPrintMany prettyPrintValue' xs
46+ match (ObjectLiteral []) = return "{}"
47+ match (ObjectLiteral ps) = fmap concat $ sequence
39− match (ObjectLiteral ps) = Just $ "{" ++ intercalate ", " (map (uncurry prettyPrintObjectProperty) ps) ++ "}"
49+ , withIndent $ prettyPrintMany prettyPrintObjectProperty ps
40− match (Constructor name) = Just $ show name
53+ match (Constructor name) = return $ show name
41− match (Case values binders) = Just $ "case " ++ unwords (map prettyPrintValue values) ++
54+ match (Case values binders) = fmap concat $ sequence
56+ , unwords <$> forM values prettyPrintValue'
42− " of { " ++ intercalate " ; " (map prettyPrintCaseAlternative binders) ++ " }"
58+ , withIndent $ prettyPrintMany prettyPrintCaseAlternative binders
61+ match (Let ds val) = fmap concat $ sequence
63+ , withIndent $ prettyPrintMany prettyPrintDeclaration ds
43− match (Let _ val) = Just $ "let ... in " ++ prettyPrintValue val
67+ , prettyPrintValue' val
44− match (Var ident) = Just $ show ident
69+ match (Var ident) = return $ show ident
70+ match (Do els) = fmap concat $ sequence
45− match (Do els) = Just $ " do { " ++ intercalate "; " (map prettyPrintDoNotationElement els) ++ " }"
72+ , withIndent $ prettyPrintMany prettyPrintDoNotationElement els
46 match (TypeClassDictionary _ _) = error "Type class dictionary was not replaced"
75 match (TypeClassDictionary _ _) = error "Type class dictionary was not replaced"
47− match _ = Nothing
76+ match (TypedValue _ val _) = prettyPrintValue' val
48−
77+ match (PositionedValue _ val) = prettyPrintValue' val
80+prettyPrintDeclaration :: Declaration -> StateT PrinterState Maybe String
81+prettyPrintDeclaration (TypeDeclaration ident ty) = return $ show ident ++ " :: " ++ prettyPrintType ty
82+prettyPrintDeclaration (ValueDeclaration ident _ [] Nothing val) = fmap concat $ sequence
83+ [ return $ show ident ++ " = "
84+ , prettyPrintValue' val
86+prettyPrintDeclaration (PositionedDeclaration _ d) = prettyPrintDeclaration d
87+prettyPrintDeclaration _ = error "Invalid argument to prettyPrintDeclaration"
49−prettyPrintCaseAlternative :: CaseAlternative -> String
89+prettyPrintCaseAlternative :: CaseAlternative -> StateT PrinterState Maybe String
50prettyPrintCaseAlternative (CaseAlternative binders grd val) =
90prettyPrintCaseAlternative (CaseAlternative binders grd val) =
91+ fmap concat $ sequence
51− "(" ++ intercalate ", " (map prettyPrintBinder binders) ++ ") " ++
92+ [ intercalate ", " <$> forM binders prettyPrintBinder'
52− maybe "" (("| " ++) . prettyPrintValue) grd ++ " -> " ++ prettyPrintValue val
93+ , maybe (return "") (fmap ("| " ++) . prettyPrintValue') grd
95+ , prettyPrintValue' val
98+prettyPrintDoNotationElement :: DoNotationElement -> StateT PrinterState Maybe String
99+prettyPrintDoNotationElement (DoNotationValue val) =
100+ prettyPrintValue' val
101+prettyPrintDoNotationElement (DoNotationBind binder val) =
102+ fmap concat $ sequence
103+ [ prettyPrintBinder' binder
105+ , prettyPrintValue' val
107+prettyPrintDoNotationElement (DoNotationLet binder val) =
108+ fmap concat $ sequence
110+ , prettyPrintBinder' binder
112+ , prettyPrintValue' val
114+prettyPrintDoNotationElement (PositionedDoNotationElement _ el) = prettyPrintDoNotationElement el
54−ifThenElse :: Pattern () Value ((Value, Value), Value)
116+ifThenElse :: Pattern PrinterState Value ((Value, Value), Value)
55ifThenElse = mkPattern match
117ifThenElse = mkPattern match
57 match (IfThenElse cond th el) = Just ((th, el), cond)
119 match (IfThenElse cond th el) = Just ((th, el), cond)
58 match _ = Nothing
120 match _ = Nothing
60−accessor :: Pattern () Value (String, Value)
122+accessor :: Pattern PrinterState Value (String, Value)
61accessor = mkPattern match
123accessor = mkPattern match
63 match (Accessor prop val) = Just (prop, val)
125 match (Accessor prop val) = Just (prop, val)
64 match _ = Nothing
126 match _ = Nothing
66−objectUpdate :: Pattern () Value ([String], Value)
128+objectUpdate :: Pattern PrinterState Value ([String], Value)
67objectUpdate = mkPattern match
129objectUpdate = mkPattern match
69 match (ObjectUpdate o ps) = Just (flip map ps $ \(key, val) -> key ++ " = " ++ prettyPrintValue val, o)
131 match (ObjectUpdate o ps) = Just (flip map ps $ \(key, val) -> key ++ " = " ++ prettyPrintValue val, o)
70 match _ = Nothing
132 match _ = Nothing
72−app :: Pattern () Value (String, Value)
134+app :: Pattern PrinterState Value (String, Value)
73app = mkPattern match
135app = mkPattern match
75 match (App val arg) = Just (prettyPrintValue arg, val)
137 match (App val arg) = Just (prettyPrintValue arg, val)
76 match _ = Nothing
138 match _ = Nothing
78−lam :: Pattern () Value (String, Value)
140+lam :: Pattern PrinterState Value (String, Value)
79lam = mkPattern match
141lam = mkPattern match
81 match (Abs (Left arg) val) = Just (show arg, val)
143 match (Abs (Left arg) val) = Just (show arg, val)
82 match _ = Nothing
144 match _ = Nothing
84−typed :: Pattern () Value (Type, Value)
85−typed = mkPattern match
87− match (TypedValue _ val ty) = Just (ty, val)
90−prettyPrintDoNotationElement :: DoNotationElement -> String
91−prettyPrintDoNotationElement (DoNotationValue val) = prettyPrintValue val
92−prettyPrintDoNotationElement (DoNotationBind binder val) = prettyPrintBinder binder ++ " <- " ++ prettyPrintValue val
93−prettyPrintDoNotationElement (DoNotationLet binder val) = "let " ++ prettyPrintBinder binder ++ " = " ++ prettyPrintValue val
96−-- Generate a pretty-printed string representing a Value
147+-- Generate a pretty-printed string representing an expression
98prettyPrintValue :: Value -> String
149prettyPrintValue :: Value -> String
99−prettyPrintValue = fromMaybe (error "Incomplete pattern") . pattern matchValue ()
150+prettyPrintValue = fromMaybe (error "Incomplete pattern") . flip evalStateT (PrinterState 0) . prettyPrintValue'
152+prettyPrintValue' :: Value -> StateT PrinterState Maybe String
153+prettyPrintValue' = runKleisli $ runPattern matchValue
101− matchValue :: Pattern () Value String
155+ matchValue :: Pattern PrinterState Value String
102 matchValue = buildPrettyPrinter operators (literals <+> fmap parens matchValue)
156 matchValue = buildPrettyPrinter operators (literals <+> fmap parens matchValue)
103− operators :: OperatorTable () Value String
157+ operators :: OperatorTable PrinterState Value String
104 operators =
158 operators =
105 OperatorTable [ [ Wrap accessor $ \prop val -> val ++ "." ++ prop ]
159 OperatorTable [ [ Wrap accessor $ \prop val -> val ++ "." ++ prop ]
106 , [ Wrap objectUpdate $ \ps val -> val ++ "{ " ++ intercalate ", " ps ++ " }" ]
160 , [ Wrap objectUpdate $ \ps val -> val ++ "{ " ++ intercalate ", " ps ++ " }" ]
107 , [ Wrap app $ \arg val -> val ++ "(" ++ arg ++ ")" ]
161 , [ Wrap app $ \arg val -> val ++ "(" ++ arg ++ ")" ]
108 , [ Split lam $ \arg val -> "\\" ++ arg ++ " -> " ++ prettyPrintValue val ]
162 , [ Split lam $ \arg val -> "\\" ++ arg ++ " -> " ++ prettyPrintValue val ]
109 , [ Wrap ifThenElse $ \(th, el) cond -> "if " ++ cond ++ " then " ++ prettyPrintValue th ++ " else " ++ prettyPrintValue el ]
163 , [ Wrap ifThenElse $ \(th, el) cond -> "if " ++ cond ++ " then " ++ prettyPrintValue th ++ " else " ++ prettyPrintValue el ]
110− , [ Wrap typed $ \ty val -> val ++ " :: " ++ prettyPrintType ty ]
113−prettyPrintBinderAtom :: Pattern () Binder String
166+prettyPrintBinderAtom :: Pattern PrinterState Binder String
114−prettyPrintBinderAtom = mkPattern match
167+prettyPrintBinderAtom = mkPattern' match
116− match :: Binder -> Maybe String
169+ match :: Binder -> StateT PrinterState Maybe String
117− match NullBinder = Just "_"
170+ match NullBinder = return "_"
118− match (StringBinder str) = Just $ show str
171+ match (StringBinder str) = return $ show str
119− match (NumberBinder num) = Just $ either show show num
172+ match (NumberBinder num) = return $ either show show num
120− match (BooleanBinder True) = Just "true"
173+ match (BooleanBinder True) = return "true"
121− match (BooleanBinder False) = Just "false"
174+ match (BooleanBinder False) = return "false"
122− match (VarBinder ident) = Just $ show ident
175+ match (VarBinder ident) = return $ show ident
123− match (ConstructorBinder ctor args) = Just $ show ctor ++ " " ++ unwords (map (parens . prettyPrintBinder) args)
176+ match (ConstructorBinder ctor args) = fmap concat $ sequence
177+ [ return $ show ctor ++ " "
178+ , unwords <$> forM args match
180+ match (ObjectBinder bs) = fmap concat $ sequence
124− match (ObjectBinder bs) = Just $ "{ " ++ intercalate ", " (map (uncurry prettyPrintObjectPropertyBinder) bs) ++ " }"
182+ , withIndent $ prettyPrintMany prettyPrintObjectPropertyBinder bs
186+ match (ArrayBinder bs) = fmap concat $ sequence
125− match (ArrayBinder bs) = Just $ "[ " ++ intercalate ", " (map prettyPrintBinder bs) ++ " ]"
188+ , unwords <$> mapM prettyPrintBinder' bs
126− match (NamedBinder ident binder) = Just $ show ident ++ "@" ++ prettyPrintBinder binder
191+ match (NamedBinder ident binder) = ((show ident ++ "@") ++) <$> prettyPrintBinder' binder
127− match _ = Nothing
192+ match (PositionedBinder _ binder) = prettyPrintBinder' binder
130-- Generate a pretty-printed string representing a Binder
196-- Generate a pretty-printed string representing a Binder
132prettyPrintBinder :: Binder -> String
198prettyPrintBinder :: Binder -> String
133−prettyPrintBinder = fromMaybe (error "Incomplete pattern") . pattern matchBinder ()
199+prettyPrintBinder = fromMaybe (error "Incomplete pattern") . flip evalStateT (PrinterState 0) . prettyPrintBinder'
201+prettyPrintBinder' :: Binder -> StateT PrinterState Maybe String
202+prettyPrintBinder' = runKleisli $ runPattern matchBinder
135− matchBinder :: Pattern () Binder String
204+ matchBinder :: Pattern PrinterState Binder String
136 matchBinder = buildPrettyPrinter operators (prettyPrintBinderAtom <+> fmap parens matchBinder)
205 matchBinder = buildPrettyPrinter operators (prettyPrintBinderAtom <+> fmap parens matchBinder)
137− operators :: OperatorTable () Binder String
206+ operators :: OperatorTable PrinterState Binder String
138 operators =
207 operators =
139 OperatorTable [ [ AssocR matchConsBinder (\b1 b2 -> b1 ++ " : " ++ b2) ] ]
208 OperatorTable [ [ AssocR matchConsBinder (\b1 b2 -> b1 ++ " : " ++ b2) ] ]
141−matchConsBinder :: Pattern () Binder (Binder, Binder)
210+matchConsBinder :: Pattern PrinterState Binder (Binder, Binder)
142matchConsBinder = mkPattern match'
211matchConsBinder = mkPattern match'
144 match' (ConsBinder b1 b2) = Just (b1, b2)
213 match' (ConsBinder b1 b2) = Just (b1, b2)
145 match' _ = Nothing
214 match' _ = Nothing
147−prettyPrintObjectPropertyBinder :: String -> Binder -> String
216+prettyPrintObjectPropertyBinder :: (String, Binder) -> StateT PrinterState Maybe String
148−prettyPrintObjectPropertyBinder key binder = key ++ ": " ++ prettyPrintBinder binder
217+prettyPrintObjectPropertyBinder (key, binder) = fmap concat $ sequence
149−
218+ [ return $ key ++ ": "
219+ , prettyPrintBinder' binder
150−prettyPrintObjectProperty :: String -> Value -> String
222+prettyPrintObjectProperty :: (String, Value) -> StateT PrinterState Maybe String
151−prettyPrintObjectProperty key value = key ++ ": " ++ prettyPrintValue value
223+prettyPrintObjectProperty (key, value) = fmap concat $ sequence
224+ [ return $ key ++ ": "
225+ , prettyPrintValue' value