git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge branch 'srcpos'
commit516f24c43f5e7b4f83a61a354eea626f2ed1ba2c authorPhil Freeman <paf31@cantab.net> dateFri 28 Mar 2014, 18:15 (13 years ago) parentfd9dca2c7f8746
22 files changed+364−143
docgen/Main.hs+3 src/Language/PureScript.hs+1 src/Language/PureScript/CodeGen/Externs.hs+1 src/Language/PureScript/CodeGen/JS.hs+3 src/Language/PureScript/DeadCodeElimination.hs+5 src/Language/PureScript/Declarations.hs+45−4 src/Language/PureScript/ModuleDependencies.hs+1 src/Language/PureScript/Parser/Common.hs+1 src/Language/PureScript/Parser/Declarations.hs+13−4 src/Language/PureScript/Pretty/Common.hs+38 src/Language/PureScript/Pretty/JS.hs−26 src/Language/PureScript/Pretty/Values.hs+142−67 src/Language/PureScript/Sugar/BindingGroups.hs+14−7 src/Language/PureScript/Sugar/CaseDeclarations.hs+9 src/Language/PureScript/Sugar/DoNotation.hs+3 src/Language/PureScript/Sugar/Names.hs+8−4 src/Language/PureScript/Sugar/Operators.hs+1 src/Language/PureScript/Sugar/TypeClasses.hs+11 src/Language/PureScript/Sugar/TypeDeclarations.hs+14−2 src/Language/PureScript/TypeChecker.hs+6 src/Language/PureScript/TypeChecker/Monad.hs+35−28 src/Language/PureScript/TypeChecker/Types.hs+10−1
docgen/Main.hs+3
@@ -84,6 +84,7 @@ renderModule (P.Module moduleName ds exps) =
8484isExported :: Maybe [P.DeclarationRef] -> P.Declaration -> Bool
8585isExported Nothing _ = True
8686isExported _ (P.TypeInstanceDeclaration _ _ _ _ _) = True
87+isExported exps (P.PositionedDeclaration _ d) = isExported exps d
8788isExported (Just exps) decl = any (matches decl) exps
8889 where
8990 matches (P.TypeDeclaration ident _) (P.ValueRef ident') = ident == ident'
@@ -130,6 +131,8 @@ renderDeclaration n _ (P.TypeInstanceDeclaration name constraints className tys
130131 [] -> ""
131132 cs -> "(" ++ intercalate ", " (map (\(pn, tys') -> show pn ++ " " ++ unwords (map P.prettyPrintTypeAtom tys')) cs) ++ ") => "
132133 atIndent n $ "instance " ++ show name ++ " :: " ++ constraintsText ++ show className ++ " " ++ unwords (map P.prettyPrintTypeAtom tys)
134+renderDeclaration n exps (P.PositionedDeclaration _ d) =
135+ renderDeclaration n exps d
133136renderDeclaration _ _ _ = return ()
134137
135138getName :: P.Declaration -> String
src/Language/PureScript.hs+1
@@ -248,5 +248,6 @@ importPrelude m@(Module mn decls exps) =
248248 where
249249 prelude = ModuleName [ProperName C.prelude]
250250 isPreludeImport (ImportDeclaration (ModuleName [ProperName mn']) _ _) | mn' == C.prelude = True
251+ isPreludeImport (PositionedDeclaration _ d) = isPreludeImport d
251252 isPreludeImport _ = False
252253 preludeImport = ImportDeclaration prelude Nothing Nothing
src/Language/PureScript/CodeGen/Externs.hs+1
@@ -45,6 +45,7 @@ moduleToPs (Module moduleName ds (Just exts)) env = intercalate "\n" . execWrite
4545 fixityToPs :: Declaration -> Writer [String] ()
4646 fixityToPs (FixityDeclaration (Fixity assoc prec) ident) =
4747 tell [ unwords [ show assoc, show prec, ident ] ]
48+ fixityToPs (PositionedDeclaration _ d) = fixityToPs d
4849 fixityToPs _ = return ()
4950
5051 exportToPs :: DeclarationRef -> Writer [String] ()
src/Language/PureScript/CodeGen/JS.hs+3
@@ -82,6 +82,7 @@ declToJs _ mp (DataDeclaration _ _ ctors) _ =
8282 (JSBlock [JSReturn (go pn (index + 1) tys' (JSVar ("value" ++ show index) : values))])
8383declToJs opts mp (DataBindingGroupDeclaration ds) e = Just $ concat $ mapMaybe (flip (declToJs opts mp) e) ds
8484declToJs _ _ (ExternDeclaration _ _ (Just js) _) _ = Just [js]
85+declToJs opts mp (PositionedDeclaration _ d) e = declToJs opts mp d e
8586declToJs _ _ _ _ = Nothing
8687
8788-- |
@@ -307,6 +308,8 @@ binderToJs m e varName done (ConsBinder headBinder tailBinder) = do
307308binderToJs m e varName done (NamedBinder ident binder) = do
308309 js <- binderToJs m e varName done binder
309310 return (JSVariableIntroduction (identToJs ident) (Just (JSVar varName)) : js)
311+binderToJs m e varName done (PositionedBinder _ binder) =
312+ binderToJs m e varName done binder
310313
311314-- |
312315-- Checks whether a data constructor is the only constructor for that type, used to simplify the
src/Language/PureScript/DeadCodeElimination.hs+5
@@ -50,11 +50,13 @@ eliminateDeadCode entryPoints ms = map go ms
5050 valueExists name (ValueDeclaration name' _ _ _ _) = name == name'
5151 valueExists name (ExternDeclaration _ name' _ _) = name == name'
5252 valueExists name (BindingGroupDeclaration decls) = any (\(name', _, _) -> name == name') decls
53+ valueExists name (PositionedDeclaration _ d) = valueExists name d
5354 valueExists _ _ = False
5455
5556 typeExists :: ProperName -> Declaration -> Bool
5657 typeExists name (DataDeclaration name' _ _) = name == name'
5758 typeExists name (DataBindingGroupDeclaration decls) = any (typeExists name) decls
59+ typeExists name (PositionedDeclaration _ d) = typeExists name d
5860 typeExists _ _ = False
5961
6062type Key = (ModuleName, Either Ident ProperName)
@@ -68,6 +70,7 @@ declarationsByModule (Module moduleName ds _) = concatMap go ds
6870 go (ExternDeclaration _ name _ _) = [((moduleName, Left name), [])]
6971 go d@(BindingGroupDeclaration names') = map (\(name, _, _) -> ((moduleName, Left name), dependencies moduleName d)) names'
7072 go (DataBindingGroupDeclaration ds') = concatMap go ds'
73+ go (PositionedDeclaration _ d) = go d
7174 go _ = []
7275
7376dependencies :: (Data d) => ModuleName -> d -> [Key]
@@ -94,4 +97,6 @@ isUsed moduleName graph vertexFor entryPointVertices (BindingGroupDeclaration ds
9497 in any (\v -> path graph v v') entryPointVertices) ds
9598isUsed moduleName graph vertexFor entryPointVertices (DataBindingGroupDeclaration ds) =
9699 any (isUsed moduleName graph vertexFor entryPointVertices) ds
100+isUsed moduleName graph vertexFor entryPointVertices (PositionedDeclaration _ d) =
101+ isUsed moduleName graph vertexFor entryPointVertices d
97102isUsed _ _ _ _ _ = True
src/Language/PureScript/Declarations.hs+45−4
@@ -41,6 +41,24 @@ instance Show Associativity where
4141 show Infixr = "infixr"
4242 show Infix = "infix"
4343
44+-- |
45+-- Source position information
46+--
47+data SourcePos = SourcePos
48+ {
49+ -- |
50+ -- Line number
51+ --
52+ sourcePosLine :: Int
53+ -- |
54+ -- Column number
55+ --
56+ , sourcePosColumn :: Int
57+ } deriving (D.Data, D.Typeable)
58+
59+instance Show SourcePos where
60+ show sp = "line " ++ show (sourcePosLine sp) ++ ", column " ++ show (sourcePosColumn sp)
61+
4462-- |
4563-- Fixity data for infix operators
4664--
@@ -132,6 +150,10 @@ data Declaration
132150 -- declarations)
133151 --
134152 | TypeInstanceDeclaration Ident [(Qualified ProperName, [Type])] (Qualified ProperName) [Type] [Declaration]
153+ -- |
154+ -- A declaration with source position information
155+ --
156+ | PositionedDeclaration SourcePos Declaration
135157 deriving (Show, D.Data, D.Typeable)
136158
137159-- |
@@ -139,6 +161,7 @@ data Declaration
139161--
140162isValueDecl :: Declaration -> Bool
141163isValueDecl ValueDeclaration{} = True
164+isValueDecl (PositionedDeclaration _ d) = isValueDecl d
142165isValueDecl _ = False
143166
144167-- |
@@ -147,6 +170,7 @@ isValueDecl _ = False
147170isDataDecl :: Declaration -> Bool
148171isDataDecl DataDeclaration{} = True
149172isDataDecl TypeSynonymDeclaration{} = True
173+isDataDecl (PositionedDeclaration _ d) = isDataDecl d
150174isDataDecl _ = False
151175
152176-- |
@@ -154,6 +178,7 @@ isDataDecl _ = False
154178--
155179isImportDecl :: Declaration -> Bool
156180isImportDecl ImportDeclaration{} = True
181+isImportDecl (PositionedDeclaration _ d) = isImportDecl d
157182isImportDecl _ = False
158183
159184-- |
@@ -161,6 +186,7 @@ isImportDecl _ = False
161186--
162187isExternDataDecl :: Declaration -> Bool
163188isExternDataDecl ExternDataDeclaration{} = True
189+isExternDataDecl (PositionedDeclaration _ d) = isExternDataDecl d
164190isExternDataDecl _ = False
165191
166192-- |
@@ -168,6 +194,7 @@ isExternDataDecl _ = False
168194--
169195isExternInstanceDecl :: Declaration -> Bool
170196isExternInstanceDecl ExternInstanceDeclaration{} = True
197+isExternInstanceDecl (PositionedDeclaration _ d) = isExternInstanceDecl d
171198isExternInstanceDecl _ = False
172199
173200-- |
@@ -175,6 +202,7 @@ isExternInstanceDecl _ = False
175202--
176203isFixityDecl :: Declaration -> Bool
177204isFixityDecl FixityDeclaration{} = True
205+isFixityDecl (PositionedDeclaration _ d) = isFixityDecl d
178206isFixityDecl _ = False
179207
180208-- |
@@ -182,6 +210,7 @@ isFixityDecl _ = False
182210--
183211isExternDecl :: Declaration -> Bool
184212isExternDecl ExternDeclaration{} = True
213+isExternDecl (PositionedDeclaration _ d) = isExternDecl d
185214isExternDecl _ = False
186215
187216-- |
@@ -190,6 +219,7 @@ isExternDecl _ = False
190219isTypeClassDeclaration :: Declaration -> Bool
191220isTypeClassDeclaration TypeClassDeclaration{} = True
192221isTypeClassDeclaration TypeInstanceDeclaration{} = True
222+isTypeClassDeclaration (PositionedDeclaration _ d) = isTypeClassDeclaration d
193223isTypeClassDeclaration _ = False
194224
195225-- |
@@ -286,7 +316,11 @@ data Value
286316 -- can be evaluated at runtime. The constructor arguments represent (in order): the type class name and
287317 -- instance type, and the type class dictionaries in scope.
288318 --
289− | TypeClassDictionary (Qualified ProperName, [Type]) [TypeClassDictionaryInScope] deriving (Show, D.Data, D.Typeable)
319+ | TypeClassDictionary (Qualified ProperName, [Type]) [TypeClassDictionaryInScope]
320+ -- |
321+ -- A value with source position information
322+ --
323+ | PositionedValue SourcePos Value deriving (Show, D.Data, D.Typeable)
290324
291325-- |
292326-- An alternative in a case statement
@@ -328,7 +362,11 @@ data DoNotationElement
328362 -- |
329363 -- A let statement, i.e. a pure value with a binder
330364 --
331− | DoNotationLet Binder Value deriving (Show, D.Data, D.Typeable)
365+ | DoNotationLet Binder Value
366+ -- |
367+ -- A do notation element with source position information
368+ --
369+ | PositionedDoNotationElement SourcePos DoNotationElement deriving (Show, D.Data, D.Typeable)
332370
333371-- |
334372-- Data type for binders
@@ -373,8 +411,11 @@ data Binder
373411 -- |
374412 -- A binder which binds its input to an identifier
375413 --
376− | NamedBinder Ident Binder deriving (Show, D.Data, D.Typeable)
377−
414+ | NamedBinder Ident Binder
415+ -- |
416+ -- A binder with source position information
417+ --
418+ | PositionedBinder SourcePos Binder deriving (Show, D.Data, D.Typeable)
378419
379420-- |
380421-- Collect all names introduced in binders in an expression
src/Language/PureScript/ModuleDependencies.hs+1
@@ -56,6 +56,7 @@ usedModules = nub . everything (++) (mkQ [] qualifiedIdents `extQ` qualifiedProp
5656 qualifiedProperNames _ = []
5757 imports :: Declaration -> [ModuleName]
5858 imports (ImportDeclaration mn _ _) = [mn]
59+ imports (PositionedDeclaration _ d) = imports d
5960 imports _ = []
6061
6162getModuleName :: Module -> ModuleName
src/Language/PureScript/Parser/Common.hs+1
@@ -369,3 +369,4 @@ same = checkIndentation (==) P.<?> "no indentation"
369369--
370370runIndentParser :: FilePath -> P.Parsec String ParseState a -> String -> Either P.ParseError a
371371runIndentParser filePath p = P.runParser p (ParseState 0) filePath
372+
src/Language/PureScript/Parser/Declarations.hs+13−4
@@ -38,6 +38,14 @@ import qualified Language.PureScript.Parser.Common as C
3838import qualified Text.Parsec as P
3939import qualified Text.Parsec.Expr as P
4040
41+-- |
42+-- Read source position information
43+--
44+sourcePos :: P.Parsec s u SourcePos
45+sourcePos = toSourcePos <$> P.getPosition
46+ where
47+ toSourcePos p = SourcePos (P.sourceLine p) (P.sourceColumn p)
48+
4149parseDataDeclaration :: P.Parsec String ParseState Declaration
4250parseDataDeclaration = do
4351 reserved "data"
@@ -162,7 +170,7 @@ parseTypeInstanceDeclaration = do
162170-- Parse a single declaration
163171--
164172parseDeclaration :: P.Parsec String ParseState Declaration
165−parseDeclaration = P.choice
173+parseDeclaration = PositionedDeclaration <$> sourcePos <*> P.choice
166174 [ parseDataDeclaration
167175 , parseTypeDeclaration
168176 , parseTypeSynonymDeclaration
@@ -175,7 +183,7 @@ parseDeclaration = P.choice
175183 ] P.<?> "declaration"
176184
177185parseLocalDeclaration :: P.Parsec String ParseState Declaration
178−parseLocalDeclaration = P.choice
186+parseLocalDeclaration = PositionedDeclaration <$> sourcePos <*> P.choice
179187 [ parseTypeDeclaration
180188 , parseValueDeclaration
181189 ] P.<?> "local declaration"
@@ -313,7 +321,7 @@ parseDoNotationElement = P.choice
313321-- Parse a value
314322--
315323parseValue :: P.Parsec String ParseState Value
316−parseValue =
324+parseValue = PositionedValue <$> sourcePos <*>
317325 (P.buildExpressionParser operators
318326 . C.buildPostfixParser postfixTable2
319327 $ indexersAndAccessors) P.<?> "expression"
@@ -373,7 +381,8 @@ parseIdentifierAndBinder = do
373381-- Parse a binder
374382--
375383parseBinder :: P.Parsec String ParseState Binder
376−parseBinder = P.buildExpressionParser operators parseBinderAtom P.<?> "expression"
384+parseBinder = PositionedBinder <$> sourcePos <*>
385+ P.buildExpressionParser operators parseBinderAtom P.<?> "expression"
377386 where
378387 operators = [ [ P.Infix ( C.lexeme (P.try $ C.indented *> C.reservedOp ":") >> return ConsBinder) P.AssocRight ] ]
379388 parseBinderAtom :: P.Parsec String ParseState Binder
src/Language/PureScript/Pretty/Common.hs+38
@@ -15,8 +15,46 @@
1515
1616module Language.PureScript.Pretty.Common where
1717
18+import Control.Monad.State
19+import Data.List (intercalate)
20+
1821-- |
1922-- Wrap a string in parentheses
2023--
2124parens :: String -> String
2225parens s = ('(':s) ++ ")"
26+
27+newtype PrinterState = PrinterState { indent :: Int } deriving (Show, Eq, Ord)
28+
29+-- |
30+-- Number of characters per identation level
31+--
32+blockIndent :: Int
33+blockIndent = 4
34+
35+-- |
36+-- Pretty print with a new indentation level
37+--
38+withIndent :: StateT PrinterState Maybe String -> StateT PrinterState Maybe String
39+withIndent action = do
40+ modify $ \st -> st { indent = indent st + blockIndent }
41+ result <- action
42+ modify $ \st -> st { indent = indent st - blockIndent }
43+ return result
44+
45+-- |
46+-- Get the current indentation level
47+--
48+currentIndent :: StateT PrinterState Maybe String
49+currentIndent = do
50+ current <- get
51+ return $ replicate (indent current) ' '
52+
53+-- |
54+-- Print many lines
55+--
56+prettyPrintMany :: (a -> StateT PrinterState Maybe String) -> [a] -> StateT PrinterState Maybe String
57+prettyPrintMany f xs = do
58+ ss <- mapM f xs
59+ indentString <- currentIndent
60+ return $ intercalate "\n" $ map (indentString ++) ss
src/Language/PureScript/Pretty/JS.hs−26
@@ -29,32 +29,6 @@ import Control.Applicative
2929import Control.Monad.State
3030import Numeric
3131
32−newtype PrinterState = PrinterState { indent :: Int } deriving (Show, Eq, Ord)
33−
34−-- |
35−-- Number of characters per identation level
36−--
37−blockIndent :: Int
38−blockIndent = 4
39−
40−-- |
41−-- Pretty print with a new indentation level
42−--
43−withIndent :: StateT PrinterState Maybe String -> StateT PrinterState Maybe String
44−withIndent action = do
45− modify $ \st -> st { indent = indent st + blockIndent }
46− result <- action
47− modify $ \st -> st { indent = indent st - blockIndent }
48− return result
49−
50−-- |
51−-- Get the current indentation level
52−--
53−currentIndent :: StateT PrinterState Maybe String
54−currentIndent = do
55− current <- get
56− return $ replicate (indent current) ' '
57−
5832literals :: Pattern PrinterState JS String
5933literals = mkPattern' match
6034 where
src/Language/PureScript/Pretty/Values.hs+142−67
@@ -20,132 +20,207 @@ module Language.PureScript.Pretty.Values (
2020
2121import Data.Maybe (fromMaybe)
2222import Data.List (intercalate)
23−import Control.Arrow ((<+>))
23+
24+import Control.Arrow ((<+>), runKleisli)
2425import Control.PatternArrows
26+import Control.Monad.State
27+import Control.Applicative
2528
26−import Language.PureScript.Types
2729import Language.PureScript.Declarations
2830import Language.PureScript.Pretty.Common
29−import Language.PureScript.Pretty.Types
31+import Language.PureScript.Pretty.Types (prettyPrintType)
3032
31−literals :: Pattern () Value String
32−literals = mkPattern match
33+literals :: Pattern PrinterState Value String
34+literals = mkPattern' match
3335 where
34− match (NumericLiteral n) = Just $ either show show n
35− match (StringLiteral s) = Just $ show s
36− match (BooleanLiteral True) = Just "true"
37− match (BooleanLiteral False) = Just "false"
38− match (ArrayLiteral xs) = Just $ "[" ++ intercalate ", " (map prettyPrintValue xs) ++ "]"
39− match (ObjectLiteral ps) = Just $ "{" ++ intercalate ", " (map (uncurry prettyPrintObjectProperty) ps) ++ "}"
40− match (Constructor name) = Just $ show name
41− match (Case values binders) = Just $ "case " ++ unwords (map prettyPrintValue values) ++
42− " of { " ++ intercalate " ; " (map prettyPrintCaseAlternative binders) ++ " }"
43− match (Let _ val) = Just $ "let ... in " ++ prettyPrintValue val
44− match (Var ident) = Just $ show ident
45− match (Do els) = Just $ " do { " ++ intercalate "; " (map prettyPrintDoNotationElement els) ++ " }"
36+ match :: Value -> StateT PrinterState Maybe String
37+ match (NumericLiteral n) = return $ either show show n
38+ match (StringLiteral s) = return $ show s
39+ match (BooleanLiteral True) = return "true"
40+ match (BooleanLiteral False) = return "false"
41+ match (ArrayLiteral xs) = fmap concat $ sequence
42+ [ return "[ "
43+ , withIndent $ prettyPrintMany prettyPrintValue' xs
44+ , return " ]"
45+ ]
46+ match (ObjectLiteral []) = return "{}"
47+ match (ObjectLiteral ps) = fmap concat $ sequence
48+ [ return "{\n"
49+ , withIndent $ prettyPrintMany prettyPrintObjectProperty ps
50+ , currentIndent
51+ , return "}"
52+ ]
53+ match (Constructor name) = return $ show name
54+ match (Case values binders) = fmap concat $ sequence
55+ [ return "case "
56+ , unwords <$> forM values prettyPrintValue'
57+ , return " of\n"
58+ , withIndent $ prettyPrintMany prettyPrintCaseAlternative binders
59+ , currentIndent
60+ ]
61+ match (Let ds val) = fmap concat $ sequence
62+ [ return "let\n"
63+ , withIndent $ prettyPrintMany prettyPrintDeclaration ds
64+ , return "\n"
65+ , currentIndent
66+ , return "in "
67+ , prettyPrintValue' val
68+ ]
69+ match (Var ident) = return $ show ident
70+ match (Do els) = fmap concat $ sequence
71+ [ return "do "
72+ , withIndent $ prettyPrintMany prettyPrintDoNotationElement els
73+ , currentIndent
74+ ]
4675 match (TypeClassDictionary _ _) = error "Type class dictionary was not replaced"
47− match _ = Nothing
48−
49−prettyPrintCaseAlternative :: CaseAlternative -> String
76+ match (TypedValue _ val _) = prettyPrintValue' val
77+ match (PositionedValue _ val) = prettyPrintValue' val
78+ match _ = mzero
79+
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
85+ ]
86+prettyPrintDeclaration (PositionedDeclaration _ d) = prettyPrintDeclaration d
87+prettyPrintDeclaration _ = error "Invalid argument to prettyPrintDeclaration"
88+
89+prettyPrintCaseAlternative :: CaseAlternative -> StateT PrinterState Maybe String
5090prettyPrintCaseAlternative (CaseAlternative binders grd val) =
51− "(" ++ intercalate ", " (map prettyPrintBinder binders) ++ ") " ++
52− maybe "" (("| " ++) . prettyPrintValue) grd ++ " -> " ++ prettyPrintValue val
53−
54−ifThenElse :: Pattern () Value ((Value, Value), Value)
91+ fmap concat $ sequence
92+ [ intercalate ", " <$> forM binders prettyPrintBinder'
93+ , maybe (return "") (fmap ("| " ++) . prettyPrintValue') grd
94+ , return " -> "
95+ , prettyPrintValue' val
96+ ]
97+
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
104+ , return " <- "
105+ , prettyPrintValue' val
106+ ]
107+prettyPrintDoNotationElement (DoNotationLet binder val) =
108+ fmap concat $ sequence
109+ [ return "let "
110+ , prettyPrintBinder' binder
111+ , return " = "
112+ , prettyPrintValue' val
113+ ]
114+prettyPrintDoNotationElement (PositionedDoNotationElement _ el) = prettyPrintDoNotationElement el
115+
116+ifThenElse :: Pattern PrinterState Value ((Value, Value), Value)
55117ifThenElse = mkPattern match
56118 where
57119 match (IfThenElse cond th el) = Just ((th, el), cond)
58120 match _ = Nothing
59121
60−accessor :: Pattern () Value (String, Value)
122+accessor :: Pattern PrinterState Value (String, Value)
61123accessor = mkPattern match
62124 where
63125 match (Accessor prop val) = Just (prop, val)
64126 match _ = Nothing
65127
66−objectUpdate :: Pattern () Value ([String], Value)
128+objectUpdate :: Pattern PrinterState Value ([String], Value)
67129objectUpdate = mkPattern match
68130 where
69131 match (ObjectUpdate o ps) = Just (flip map ps $ \(key, val) -> key ++ " = " ++ prettyPrintValue val, o)
70132 match _ = Nothing
71133
72−app :: Pattern () Value (String, Value)
134+app :: Pattern PrinterState Value (String, Value)
73135app = mkPattern match
74136 where
75137 match (App val arg) = Just (prettyPrintValue arg, val)
76138 match _ = Nothing
77139
78−lam :: Pattern () Value (String, Value)
140+lam :: Pattern PrinterState Value (String, Value)
79141lam = mkPattern match
80142 where
81143 match (Abs (Left arg) val) = Just (show arg, val)
82144 match _ = Nothing
83145
84−typed :: Pattern () Value (Type, Value)
85−typed = mkPattern match
86− where
87− match (TypedValue _ val ty) = Just (ty, val)
88− match _ = Nothing
89−
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
94−
95146-- |
96−-- Generate a pretty-printed string representing a Value
147+-- Generate a pretty-printed string representing an expression
97148--
98149prettyPrintValue :: Value -> String
99−prettyPrintValue = fromMaybe (error "Incomplete pattern") . pattern matchValue ()
150+prettyPrintValue = fromMaybe (error "Incomplete pattern") . flip evalStateT (PrinterState 0) . prettyPrintValue'
151+
152+prettyPrintValue' :: Value -> StateT PrinterState Maybe String
153+prettyPrintValue' = runKleisli $ runPattern matchValue
100154 where
101− matchValue :: Pattern () Value String
155+ matchValue :: Pattern PrinterState Value String
102156 matchValue = buildPrettyPrinter operators (literals <+> fmap parens matchValue)
103− operators :: OperatorTable () Value String
157+ operators :: OperatorTable PrinterState Value String
104158 operators =
105159 OperatorTable [ [ Wrap accessor $ \prop val -> val ++ "." ++ prop ]
106160 , [ Wrap objectUpdate $ \ps val -> val ++ "{ " ++ intercalate ", " ps ++ " }" ]
107161 , [ Wrap app $ \arg val -> val ++ "(" ++ arg ++ ")" ]
108162 , [ Split lam $ \arg val -> "\\" ++ arg ++ " -> " ++ prettyPrintValue val ]
109163 , [ Wrap ifThenElse $ \(th, el) cond -> "if " ++ cond ++ " then " ++ prettyPrintValue th ++ " else " ++ prettyPrintValue el ]
110− , [ Wrap typed $ \ty val -> val ++ " :: " ++ prettyPrintType ty ]
111164 ]
112165
113−prettyPrintBinderAtom :: Pattern () Binder String
114−prettyPrintBinderAtom = mkPattern match
166+prettyPrintBinderAtom :: Pattern PrinterState Binder String
167+prettyPrintBinderAtom = mkPattern' match
115168 where
116− match :: Binder -> Maybe String
117− match NullBinder = Just "_"
118− match (StringBinder str) = Just $ show str
119− match (NumberBinder num) = Just $ either show show num
120− match (BooleanBinder True) = Just "true"
121− match (BooleanBinder False) = Just "false"
122− match (VarBinder ident) = Just $ show ident
123− match (ConstructorBinder ctor args) = Just $ show ctor ++ " " ++ unwords (map (parens . prettyPrintBinder) args)
124− match (ObjectBinder bs) = Just $ "{ " ++ intercalate ", " (map (uncurry prettyPrintObjectPropertyBinder) bs) ++ " }"
125− match (ArrayBinder bs) = Just $ "[ " ++ intercalate ", " (map prettyPrintBinder bs) ++ " ]"
126− match (NamedBinder ident binder) = Just $ show ident ++ "@" ++ prettyPrintBinder binder
127− match _ = Nothing
169+ match :: Binder -> StateT PrinterState Maybe String
170+ match NullBinder = return "_"
171+ match (StringBinder str) = return $ show str
172+ match (NumberBinder num) = return $ either show show num
173+ match (BooleanBinder True) = return "true"
174+ match (BooleanBinder False) = return "false"
175+ match (VarBinder ident) = return $ show ident
176+ match (ConstructorBinder ctor args) = fmap concat $ sequence
177+ [ return $ show ctor ++ " "
178+ , unwords <$> forM args match
179+ ]
180+ match (ObjectBinder bs) = fmap concat $ sequence
181+ [ return "{\n"
182+ , withIndent $ prettyPrintMany prettyPrintObjectPropertyBinder bs
183+ , currentIndent
184+ , return "}"
185+ ]
186+ match (ArrayBinder bs) = fmap concat $ sequence
187+ [ return "["
188+ , unwords <$> mapM prettyPrintBinder' bs
189+ , return "]"
190+ ]
191+ match (NamedBinder ident binder) = ((show ident ++ "@") ++) <$> prettyPrintBinder' binder
192+ match (PositionedBinder _ binder) = prettyPrintBinder' binder
193+ match _ = mzero
128194
129195-- |
130196-- Generate a pretty-printed string representing a Binder
131197--
132198prettyPrintBinder :: Binder -> String
133−prettyPrintBinder = fromMaybe (error "Incomplete pattern") . pattern matchBinder ()
199+prettyPrintBinder = fromMaybe (error "Incomplete pattern") . flip evalStateT (PrinterState 0) . prettyPrintBinder'
200+
201+prettyPrintBinder' :: Binder -> StateT PrinterState Maybe String
202+prettyPrintBinder' = runKleisli $ runPattern matchBinder
134203 where
135− matchBinder :: Pattern () Binder String
204+ matchBinder :: Pattern PrinterState Binder String
136205 matchBinder = buildPrettyPrinter operators (prettyPrintBinderAtom <+> fmap parens matchBinder)
137− operators :: OperatorTable () Binder String
206+ operators :: OperatorTable PrinterState Binder String
138207 operators =
139208 OperatorTable [ [ AssocR matchConsBinder (\b1 b2 -> b1 ++ " : " ++ b2) ] ]
140209
141−matchConsBinder :: Pattern () Binder (Binder, Binder)
210+matchConsBinder :: Pattern PrinterState Binder (Binder, Binder)
142211matchConsBinder = mkPattern match'
143212 where
144213 match' (ConsBinder b1 b2) = Just (b1, b2)
145214 match' _ = Nothing
146215
147−prettyPrintObjectPropertyBinder :: String -> Binder -> String
148−prettyPrintObjectPropertyBinder key binder = key ++ ": " ++ prettyPrintBinder binder
149−
150−prettyPrintObjectProperty :: String -> Value -> String
151−prettyPrintObjectProperty key value = key ++ ": " ++ prettyPrintValue value
216+prettyPrintObjectPropertyBinder :: (String, Binder) -> StateT PrinterState Maybe String
217+prettyPrintObjectPropertyBinder (key, binder) = fmap concat $ sequence
218+ [ return $ key ++ ": "
219+ , prettyPrintBinder' binder
220+ ]
221+
222+prettyPrintObjectProperty :: (String, Value) -> StateT PrinterState Maybe String
223+prettyPrintObjectProperty (key, value) = fmap concat $ sequence
224+ [ return $ key ++ ": "
225+ , prettyPrintValue' value
226+ ]
src/Language/PureScript/Sugar/BindingGroups.hs+14−7
@@ -26,7 +26,7 @@ import Data.Graph
2626import Data.Generics
2727import Data.Generics.Extras
2828import Data.List (nub, intersect)
29−import Data.Maybe (mapMaybe)
29+import Data.Maybe (isJust, mapMaybe)
3030import Control.Applicative ((<$>), (<*>), pure)
3131
3232import Language.PureScript.Declarations
@@ -82,6 +82,7 @@ collapseBindingGroups = everywhere (mkT collapseBindingGroupsForValue) . concatM
8282 where
8383 go (DataBindingGroupDeclaration ds) = ds
8484 go (BindingGroupDeclaration ds) = map (\(ident, nameKind, val) -> ValueDeclaration ident nameKind [] Nothing val) ds
85+ go (PositionedDeclaration pos d) = map (PositionedDeclaration pos) $ go d
8586 go other = [other]
8687
8788collapseBindingGroupsForValue :: Value -> Value
@@ -109,11 +110,13 @@ usedProperNames moduleName = nub . everything (++) (mkQ [] usedNames)
109110
110111getIdent :: Declaration -> Ident
111112getIdent (ValueDeclaration ident _ _ _ _) = ident
113+getIdent (PositionedDeclaration _ d) = getIdent d
112114getIdent _ = error "Expected ValueDeclaration"
113115
114116getProperName :: Declaration -> ProperName
115117getProperName (DataDeclaration pn _ _) = pn
116118getProperName (TypeSynonymDeclaration pn _ _) = pn
119+getProperName (PositionedDeclaration _ d) = getProperName d
117120getProperName _ = error "Expected DataDeclaration"
118121
119122toBindingGroup :: SCC Declaration -> Declaration
@@ -123,16 +126,20 @@ toBindingGroup (CyclicSCC ds') = BindingGroupDeclaration $ map fromValueDecl ds'
123126
124127toDataBindingGroup :: SCC Declaration -> Either String Declaration
125128toDataBindingGroup (AcyclicSCC d) = return d
126−toDataBindingGroup (CyclicSCC [TypeSynonymDeclaration pn _ _]) = Left $ "Cycle in type synonym " ++ show pn
127−toDataBindingGroup (CyclicSCC [d]) = return d
129+toDataBindingGroup (CyclicSCC [d]) = case isTypeSynonym d of
130+ Just pn -> Left $ "Cycle in type synonym " ++ show pn
131+ _ -> return d
128132toDataBindingGroup (CyclicSCC ds')
129− | all isTypeSynonym ds' = Left "Cycle in type synonyms"
133+ | all (isJust . isTypeSynonym) ds' = Left "Cycle in type synonyms"
130134 | otherwise = return $ DataBindingGroupDeclaration ds'
131− where
132− isTypeSynonym TypeSynonymDeclaration{} = True
133− isTypeSynonym _ = False
135+
136+isTypeSynonym :: Declaration -> Maybe ProperName
137+isTypeSynonym (TypeSynonymDeclaration pn _ _) = Just pn
138+isTypeSynonym (PositionedDeclaration _ d) = isTypeSynonym d
139+isTypeSynonym _ = Nothing
134140
135141fromValueDecl :: Declaration -> (Ident, NameKind, Value)
136142fromValueDecl (ValueDeclaration ident nameKind [] Nothing val) = (ident, nameKind, val)
137143fromValueDecl ValueDeclaration{} = error "Binders should have been desugared"
144+fromValueDecl (PositionedDeclaration _ d) = fromValueDecl d
138145fromValueDecl _ = error "Expected ValueDeclaration"
src/Language/PureScript/Sugar/CaseDeclarations.hs+9
@@ -62,11 +62,16 @@ desugarCases = desugarRest <=< fmap join . mapM toDecls . groupBy inSameGroup
6262 where
6363 go (Let ds val') = Let <$> desugarCases ds <*> pure val'
6464 go other = return other
65+ desugarRest (PositionedDeclaration pos d : ds) = do
66+ (d' : ds') <- desugarRest (d : ds)
67+ return (PositionedDeclaration pos d' : ds')
6568 desugarRest (d : ds) = (:) d <$> desugarRest ds
6669 desugarRest [] = pure []
6770
6871inSameGroup :: Declaration -> Declaration -> Bool
6972inSameGroup (ValueDeclaration ident1 _ _ _ _) (ValueDeclaration ident2 _ _ _ _) = ident1 == ident2
73+inSameGroup (PositionedDeclaration _ d1) d2 = inSameGroup d1 d2
74+inSameGroup d1 (PositionedDeclaration _ d2) = inSameGroup d1 d2
7075inSameGroup _ _ = False
7176
7277toDecls :: [Declaration] -> Either String [Declaration]
@@ -79,6 +84,9 @@ toDecls ds@(ValueDeclaration ident _ bs _ _ : _) = do
7984 unless (all ((== length bs) . length . fst) tuples) $
8085 throwError $ "Argument list lengths differ in declaration " ++ show ident
8186 return [makeCaseDeclaration ident tuples]
87+toDecls (PositionedDeclaration pos d : ds) = do
88+ (d' : ds') <- toDecls (d : ds)
89+ return (PositionedDeclaration pos d' : ds')
8290toDecls ds = return ds
8391
8492isVarBinder :: Binder -> Bool
@@ -87,6 +95,7 @@ isVarBinder _ = False
8795
8896toTuple :: Declaration -> ([Binder], (Maybe Guard, Value))
8997toTuple (ValueDeclaration _ _ bs g val) = (bs, (g, val))
98+toTuple (PositionedDeclaration _ d) = toTuple d
9099toTuple _ = error "Not a value declaration"
91100
92101makeCaseDeclaration :: Ident -> [([Binder], (Maybe Guard, Value))] -> Declaration
src/Language/PureScript/Sugar/DoNotation.hs+3
@@ -27,6 +27,8 @@ import Language.PureScript.Declarations
2727
2828import qualified Language.PureScript.Constants as C
2929
30+import Control.Applicative
31+
3032-- |
3133-- Replace all @DoNotationBind@ and @DoNotationValue@ constructors with applications of the Prelude.(>>=) function,
3234-- and all @DoNotationLet@ constructors with let expressions.
@@ -60,3 +62,4 @@ desugarDo = everywhereM (mkM replace)
6062 go (DoNotationLet binder val : rest) = do
6163 rest' <- go rest
6264 return $ Case [val] [CaseAlternative [binder] Nothing rest']
65+ go (PositionedDoNotationElement pos el : rest) = PositionedValue pos <$> go (el : rest)
src/Language/PureScript/Sugar/Names.hs+8−4
@@ -216,6 +216,7 @@ renameInModule imports exports (Module mn decls exps) =
216216
217217 letBoundVariable :: Declaration -> Ident
218218 letBoundVariable (ValueDeclaration ident _ _ _ _) = ident
219+ letBoundVariable (PositionedDeclaration _ d) = letBoundVariable d
219220 letBoundVariable _ = error "Invalid argument to letBoundVariable"
220221 go (ValueDeclaration name _ _ _ _) = error $ "Binders should have been desugared in " ++ show name
221222 go (ExternDeclaration fit name js ty) =
@@ -223,6 +224,7 @@ renameInModule imports exports (Module mn decls exps) =
223224 go (BindingGroupDeclaration decls') = do
224225 BindingGroupDeclaration <$> mapM go' decls'
225226 where go' = \(name, nk, value) -> rethrowFor "declaration" name $ (,,) <$> pure name <*> pure nk <*> updateAll value
227+ go (PositionedDeclaration pos d) = PositionedDeclaration pos <$> go d
226228 go d = updateAll d
227229
228230 rethrowFor :: (Show a) => String -> a -> Either String b -> Either String b
@@ -230,20 +232,20 @@ renameInModule imports exports (Module mn decls exps) =
230232
231233 updateAll :: Data d => d -> Either String d
232234 updateAll = everywhereM (mkM updateType `extM` updateValue `extM` updateBinder)
233−
235+
234236 updateValue (Constructor name) = Constructor <$> updateDataConstructorName name
235237 updateValue v = return v
236−
238+
237239 updateBinder (ConstructorBinder name b) = ConstructorBinder <$> updateDataConstructorName name <*> pure b
238240 updateBinder v = return v
239−
241+
240242 updateType (TypeConstructor name) = TypeConstructor <$> updateTypeName name
241243 updateType (SaturatedTypeSynonym name tys) = SaturatedTypeSynonym <$> updateTypeName name <*> mapM updateType tys
242244 updateType (ConstrainedType cs t) = ConstrainedType <$> updateConstraints cs <*> pure t
243245 updateType t = return t
244246 updateType' :: Data d => d -> Either String d
245247 updateType' = everywhereM (mkM updateType)
246−
248+
247249 updateConstraints = mapM (\(name, ts) -> (,) <$> updateClassName name <*> pure ts)
248250
249251 updateTypeName = update "type" importedTypes (\mes -> isJust . (`lookup` (exportedTypes mes)))
@@ -299,6 +301,7 @@ findExports = foldM addModule $ M.singleton (ModuleName [ProperName "Prim"]) pri
299301 addDecl mn env (ExternDataDeclaration tn _) = addType env mn tn []
300302 addDecl mn env (ValueDeclaration name _ _ _ _) = addValue env mn name
301303 addDecl mn env (ExternDeclaration _ name _ _) = addValue env mn name
304+ addDecl mn env (PositionedDeclaration _ d) = addDecl mn env d
302305 addDecl _ env _ = return env
303306
304307-- |
@@ -365,6 +368,7 @@ findImports :: [Declaration] -> M.Map ModuleName (Maybe ExplicitImports, Maybe M
365368findImports = foldl findImports' M.empty
366369 where
367370 findImports' result (ImportDeclaration mn expl qual) = M.insert mn (expl, qual) result
371+ findImports' result (PositionedDeclaration _ d) = findImports' result d
368372 findImports' result _ = result
369373
370374-- |
src/Language/PureScript/Sugar/Operators.hs+1
@@ -76,6 +76,7 @@ collectFixities :: Module -> [(Qualified Ident, Fixity)]
7676collectFixities (Module moduleName ds _) = concatMap collect ds
7777 where
7878 collect :: Declaration -> [(Qualified Ident, Fixity)]
79+ collect (PositionedDeclaration _ d) = collect d
7980 collect (FixityDeclaration fixity name) = [(Qualified (Just moduleName) (Op name), fixity)]
8081 collect _ = []
8182
src/Language/PureScript/Sugar/TypeClasses.hs+11
@@ -99,10 +99,14 @@ desugarDecl mn d@(TypeInstanceDeclaration name deps className ty members) = do
9999 entries <- mapM (typeInstanceDictionaryEntryDeclaration name mn deps className ty) desugared
100100 dictDecl <- typeInstanceDictionaryDeclaration name mn deps className ty desugared
101101 return $ (Just $ TypeInstanceRef name, d : entries ++ [dictDecl])
102+desugarDecl mn (PositionedDeclaration pos d) = do
103+ (dr, ds) <- desugarDecl mn d
104+ return (dr, map (PositionedDeclaration pos) ds)
102105desugarDecl _ other = return (Nothing, [other])
103106
104107memberToNameAndType :: Declaration -> (String, Type)
105108memberToNameAndType (TypeDeclaration ident ty) = (identToJs ident, ty)
109+memberToNameAndType (PositionedDeclaration _ d) = memberToNameAndType d
106110memberToNameAndType _ = error "Invalid declaration in type class definition"
107111
108112typeClassDictionaryDeclaration :: ProperName -> [String] -> [Declaration] -> Declaration
@@ -114,6 +118,8 @@ typeClassMemberToDictionaryAccessor mn name args (TypeDeclaration ident ty) =
114118 ExternDeclaration TypeClassAccessorImport ident
115119 (Just (JSFunction (Just $ identToJs ident) ["dict"] (JSBlock [JSReturn (JSAccessor (identToJs ident) (JSVar "dict"))])))
116120 (quantify (ConstrainedType [(Qualified (Just mn) name, map TypeVar args)] ty))
121+typeClassMemberToDictionaryAccessor mn name args (PositionedDeclaration pos d) =
122+ PositionedDeclaration pos $ typeClassMemberToDictionaryAccessor mn name args d
117123typeClassMemberToDictionaryAccessor _ _ _ _ = error "Invalid declaration in type class definition"
118124
119125typeInstanceDictionaryDeclaration :: Ident -> ModuleName -> [(Qualified ProperName, [Type])] -> Qualified ProperName -> [Type] -> [Declaration] -> Desugar Declaration
@@ -143,6 +149,9 @@ typeInstanceDictionaryDeclaration name mn deps className tys decls = do
143149 return (identToJs ident, TypedValue False
144150 (foldl App (Var (Qualified Nothing memberName)) (map (\n -> Var (Qualified Nothing (Ident ('_' : show n)))) [1..length deps]))
145151 (quantify memberType))
152+ memberToNameAndValue tys' (PositionedDeclaration pos d) = do
153+ (ident, val) <- memberToNameAndValue tys' d
154+ return (ident, PositionedValue pos val)
146155 memberToNameAndValue _ _ = error "Invalid declaration in type instance definition"
147156
148157typeInstanceDictionaryEntryDeclaration :: Ident -> ModuleName -> [(Qualified ProperName, [Type])] -> Qualified ProperName -> [Type] -> Declaration -> Desugar Declaration
@@ -157,6 +166,8 @@ typeInstanceDictionaryEntryDeclaration name mn deps className tys (ValueDeclarat
157166 where
158167 lookupTypeClass m = maybe (Left $ "Type class " ++ show className ++ " is undefined. Type class names must be qualified.") Right $ M.lookup (qualify mn className) m
159168 lookupIdent members = maybe (Left $ "Type class " ++ show className ++ " does not have method " ++ show ident) Right $ lookup (identToJs ident) members
169+typeInstanceDictionaryEntryDeclaration name mn deps className tys (PositionedDeclaration pos d) =
170+ PositionedDeclaration pos <$> typeInstanceDictionaryEntryDeclaration name mn deps className tys d
160171typeInstanceDictionaryEntryDeclaration _ _ _ _ _ _ = error "Invalid declaration in type instance definition"
161172
162173-- |
src/Language/PureScript/Sugar/TypeDeclarations.hs+14−2
@@ -27,6 +27,8 @@ import Control.Monad.Error.Class
2727import Control.Monad (forM)
2828
2929import Language.PureScript.Declarations
30+import Language.PureScript.Names
31+import Language.PureScript.Environment
3032
3133-- |
3234-- Replace all top level type declarations in a module with type annotations
@@ -38,9 +40,19 @@ desugarTypeDeclarationsModule ms = forM ms $ \(Module name ds exps) -> Module na
3840-- Replace all top level type declarations with type annotations
3941--
4042desugarTypeDeclarations :: [Declaration] -> Either String [Declaration]
41−desugarTypeDeclarations (TypeDeclaration name ty : ValueDeclaration name' nameKind [] Nothing val : rest) | name == name' =
43+desugarTypeDeclarations (PositionedDeclaration pos d : ds) = do
44+ (d' : ds') <- desugarTypeDeclarations (d : ds)
45+ return (PositionedDeclaration pos d' : ds')
46+desugarTypeDeclarations (TypeDeclaration name ty : d : rest) = do
47+ (_, nameKind, val) <- fromValueDeclaration d
4248 desugarTypeDeclarations (ValueDeclaration name nameKind [] Nothing (TypedValue True val ty) : rest)
43−desugarTypeDeclarations (TypeDeclaration name _ : _) = throwError $ "Orphan type declaration for " ++ show name
49+ where
50+ fromValueDeclaration :: Declaration -> Either String (Ident, NameKind, Value)
51+ fromValueDeclaration (ValueDeclaration name' nameKind [] Nothing val) | name == name' = return (name', nameKind, val)
52+ fromValueDeclaration (PositionedDeclaration pos d') = do
53+ (ident, nameKind, val) <- fromValueDeclaration d'
54+ return (ident, nameKind, PositionedValue pos val)
55+ fromValueDeclaration _ = throwError $ "Orphan type declaration for " ++ show name
4456desugarTypeDeclarations (ValueDeclaration name nameKind bs g val : rest) = do
4557 (:) <$> (ValueDeclaration name nameKind bs g <$> everywhereM' (mkM go) val) <*> desugarTypeDeclarations rest
4658 where
src/Language/PureScript/TypeChecker.hs+6
@@ -124,8 +124,10 @@ typeCheckAll mainModuleName moduleName (d@(DataBindingGroupDeclaration tys) : re
124124 return $ d : ds
125125 where
126126 toTypeSynonym (TypeSynonymDeclaration nm args ty) = Just (nm, args, ty)
127+ toTypeSynonym (PositionedDeclaration _ d') = toTypeSynonym d'
127128 toTypeSynonym _ = Nothing
128129 toDataDecl (DataDeclaration nm args dctors) = Just (nm, args, dctors)
130+ toDataDecl (PositionedDeclaration _ d') = toDataDecl d'
129131 toDataDecl _ = Nothing
130132typeCheckAll mainModuleName moduleName (d@(TypeSynonymDeclaration name args ty) : rest) = do
131133 rethrow (strMsg ("Error in type synonym " ++ show name) <>) $ do
@@ -194,3 +196,7 @@ typeCheckAll mainModuleName moduleName (d@(ExternInstanceDeclaration dictName de
194196 addTypeClassDictionaries [TypeClassDictionaryInScope (Qualified (Just moduleName) dictName) className tys (Just deps) TCDRegular]
195197 ds <- typeCheckAll mainModuleName moduleName rest
196198 return $ d : ds
199+typeCheckAll mainModuleName moduleName (PositionedDeclaration pos d : rest) =
200+ rethrowWithPosition pos $ do
201+ (d' : rest') <- typeCheckAll mainModuleName moduleName (d : rest)
202+ return (PositionedDeclaration pos d' : rest')
src/Language/PureScript/TypeChecker/Monad.hs+35−28
@@ -63,6 +63,10 @@ data UnifyError = UnifyError {
6363 -- The value where the error occurred
6464 --
6565 , unifyErrorValue :: Maybe UnifyErrorSource
66+ -- |
67+ -- Optional source position information
68+ --
69+ , unifyErrorPosition :: Maybe SourcePos
6670 } deriving (Show)
6771
6872-- |
@@ -71,42 +75,39 @@ data UnifyError = UnifyError {
7175newtype UnifyErrorStack = UnifyErrorStack { runUnifyErrorStack :: [UnifyError] } deriving (Show, Monoid)
7276
7377instance Error UnifyErrorStack where
74− strMsg s = UnifyErrorStack [UnifyError s Nothing]
78+ strMsg s = UnifyErrorStack [UnifyError s Nothing Nothing]
7579 noMsg = UnifyErrorStack []
7680
7781prettyPrintUnifyErrorStack :: Options -> UnifyErrorStack -> String
78−prettyPrintUnifyErrorStack opts (UnifyErrorStack es) | optionsVerboseErrors opts = intercalate "\n" (map showError es)
79−prettyPrintUnifyErrorStack _ (UnifyErrorStack es) =
80− let
81− errorsWithValues = filter (isJust . unifyErrorValue) es
82− mostSpecificError = last es
83− in case (length errorsWithValues, isJust (unifyErrorValue mostSpecificError)) of
84− (0, _) -> showError mostSpecificError
85− (1, True) -> showError mostSpecificError
86− (1, False) ->
87− let errorWithValue = head errorsWithValues
88− in showError errorWithValue ++ "\n" ++
89− showError mostSpecificError
90− (_, True) ->
91− let errorWithValue = head errorsWithValues
92− in showError errorWithValue ++ "\n" ++
93− showError mostSpecificError
94− (_, False) ->
82+prettyPrintUnifyErrorStack opts (UnifyErrorStack es) =
83+ case mconcat $ map (Last . unifyErrorPosition) es of
84+ Last (Just sourcePos) -> "Error at " ++ show sourcePos ++ ": \n" ++ prettyPrintUnifyErrorStack'
85+ _ -> prettyPrintUnifyErrorStack'
86+ where
87+ prettyPrintUnifyErrorStack' :: String
88+ prettyPrintUnifyErrorStack'
89+ | optionsVerboseErrors opts =
90+ intercalate "\n" (map showError (filter isErrorNonEmpty es))
91+ | otherwise =
9592 let
96− leastSpecificErrorWithValue = head errorsWithValues
97− mostSpecificErrorWithValue = last errorsWithValues
98− in
99− showError leastSpecificErrorWithValue ++ "\n" ++
100− showError mostSpecificErrorWithValue ++ "\n" ++
101− showError mostSpecificError
93+ es' = filter isErrorNonEmpty es
94+ in case length es' of
95+ 1 -> showError (head es')
96+ _ -> showError (head es') ++ "\n" ++ showError (last es')
97+
98+isErrorNonEmpty :: UnifyError -> Bool
99+isErrorNonEmpty = not . null . unifyErrorMessage
102100
103101showError :: UnifyError -> String
104−showError (UnifyError msg Nothing) = msg
105−showError (UnifyError msg (Just (ValueError val))) = "Error in value " ++ prettyPrintValue val ++ ": \n" ++ msg
106−showError (UnifyError msg (Just (TypeError ty))) = "Error in type " ++ prettyPrintType ty ++ ": \n" ++ msg
102+showError (UnifyError msg Nothing _) = msg
103+showError (UnifyError msg (Just (ValueError val)) _) = "Error in value " ++ prettyPrintValue val ++ "\n" ++ msg
104+showError (UnifyError msg (Just (TypeError ty)) _) = "Error in type " ++ prettyPrintType ty ++ "\n" ++ msg
107105
108106mkUnifyErrorStack :: String -> Maybe UnifyErrorSource -> UnifyErrorStack
109−mkUnifyErrorStack msg t = UnifyErrorStack [UnifyError msg t]
107+mkUnifyErrorStack msg t = UnifyErrorStack [UnifyError msg t Nothing]
108+
109+positionError :: SourcePos -> UnifyErrorStack
110+positionError pos = UnifyErrorStack [UnifyError "" Nothing (Just pos)]
110111
111112-- |
112113-- Temporarily bind a collection of names to values
@@ -254,6 +255,12 @@ guardWith e False = throwError e
254255rethrow :: (MonadError e m) => (e -> e) -> m a -> m a
255256rethrow f = flip catchError $ \e -> throwError (f e)
256257
258+-- |
259+-- Rethrow an error with source position information
260+--
261+rethrowWithPosition :: (MonadError UnifyErrorStack m) => SourcePos -> m a -> m a
262+rethrowWithPosition pos = rethrow (positionError pos <>)
263+
257264-- |
258265-- Generate new type class dictionary name
259266--
src/Language/PureScript/TypeChecker/Types.hs+10−1
@@ -238,6 +238,7 @@ typeForBindingGroupElement moduleName e@(_, (val, _)) dict untypedDict = do
238238isFunction :: Value -> Bool
239239isFunction (Abs _ _) = True
240240isFunction (TypedValue _ val _) = isFunction val
241+isFunction (PositionedValue _ val) = isFunction val
241242isFunction _ = False
242243
243244-- |
@@ -576,6 +577,7 @@ infer' (TypedValue checkType val ty) = do
576577 ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms $ ty
577578 val' <- if checkType then check val ty' else return val
578579 return $ TypedValue True val' ty'
580+infer' (PositionedValue pos val) = rethrowWithPosition pos $ infer' val
579581infer' _ = error "Invalid argument to infer"
580582
581583inferLetBinding :: [Declaration] -> [Declaration] -> Value -> (Value -> UnifyT Type Check Value) -> UnifyT Type Check ([Declaration], Value)
@@ -593,7 +595,10 @@ inferLetBinding seen (BindingGroupDeclaration ds : rest) ret j = do
593595 (ident, (val', _)) <- typeForBindingGroupElement moduleName e dict untypedDict
594596 return $ (ident, LocalVariable, val')
595597 bindNames dict $ inferLetBinding (seen ++ [BindingGroupDeclaration ds']) rest ret j
596−inferLetBinding _ _ _ _ = error "Invalid argument to fromValueDeclaration"
598+inferLetBinding seen (PositionedDeclaration pos d : ds) ret j = do
599+ ((d' : ds'), val') <- inferLetBinding seen (d : ds) ret j
600+ return (PositionedDeclaration pos d' : ds', val')
601+inferLetBinding _ _ _ _ = error "Invalid argument to inferLetBinding"
597602
598603-- |
599604-- Infer the type of a property inside a record with a given type
@@ -662,6 +667,8 @@ inferBinder val (ConsBinder headBinder tailBinder) = do
662667inferBinder val (NamedBinder name binder) = do
663668 m <- inferBinder val binder
664669 return $ M.insert name val m
670+inferBinder val (PositionedBinder pos binder) =
671+ rethrowWithPosition pos $ inferBinder val binder
665672
666673-- |
667674-- Check the types of the return values in a set of binders in a case statement
@@ -826,6 +833,8 @@ check' (Let ds val) ty = do
826833check' val ty | containsTypeSynonyms ty = do
827834 ty' <- introduceSkolemScope <=< expandAllTypeSynonyms $ ty
828835 check val ty'
836+check' (PositionedValue pos val) ty =
837+ rethrowWithPosition pos $ check val ty
829838check' val ty = throwError $ mkUnifyErrorStack ("Value does not have type " ++ prettyPrintType ty) (Just (ValueError val))
830839
831840containsTypeSynonyms :: Type -> Bool