@@ -34,6 +34,7 @@ import qualified Data.Traversable as T (traverse)
35import Control.Arrow ((&&&))
35import Control.Arrow ((&&&))
36import Control.Monad (replicateM, forM)
36import Control.Monad (replicateM, forM)
37+import Control.Monad.Error.Class (MonadError(..))
37import Control.Monad.Reader (MonadReader, asks)
38import Control.Monad.Reader (MonadReader, asks)
38import Control.Monad.Supply.Class
39import Control.Monad.Supply.Class
@@ -43,6 +44,7 @@ import Language.PureScript.CodeGen.JS.AST as AST
43import Language.PureScript.CodeGen.JS.Common as Common
44import Language.PureScript.CodeGen.JS.Common as Common
44import Language.PureScript.CoreFn
45import Language.PureScript.CoreFn
45import Language.PureScript.Names
46import Language.PureScript.Names
47+import Language.PureScript.Errors
46import Language.PureScript.CodeGen.JS.Optimizer
48import Language.PureScript.CodeGen.JS.Optimizer
47import Language.PureScript.Options
49import Language.PureScript.Options
48import Language.PureScript.Traversals (sndM)
50import Language.PureScript.Traversals (sndM)
@@ -54,22 +56,23 @@ import System.FilePath.Posix ((</>))
54-- Generate code in the simplified Javascript intermediate representation for all declarations in a
56-- Generate code in the simplified Javascript intermediate representation for all declarations in a
57−moduleToJs :: forall m. (Applicative m, Monad m, MonadReader Options m, MonadSupply m)
59+moduleToJs :: forall m. (Applicative m, Monad m, MonadReader Options m, MonadSupply m, MonadError MultipleErrors m)
58 => Module Ann -> Maybe JS -> m [JS]
60 => Module Ann -> Maybe JS -> m [JS]
59−moduleToJs (Module coms mn imps exps foreigns decls) foreign_ = do
61+moduleToJs (Module coms mn imps exps foreigns decls) foreign_ =
62+ rethrow (addHint (ErrorInModule mn)) $ do
60− jsImports <- T.traverse importToJs . delete (ModuleName [ProperName C.prim]) . (\\ [mn]) $ imps
63+ jsImports <- T.traverse importToJs . delete (ModuleName [ProperName C.prim]) . (\\ [mn]) $ imps
61− jsDecls <- mapM bindToJs decls
64+ jsDecls <- mapM bindToJs decls
62− optimized <- T.traverse (T.traverse optimize) jsDecls
65+ optimized <- T.traverse (T.traverse optimize) jsDecls
63− comments <- not <$> asks optionsNoComments
66+ comments <- not <$> asks optionsNoComments
64− let strict = JSStringLiteral "use strict"
67+ let strict = JSStringLiteral "use strict"
65− let header = if comments && not (null coms) then JSComment coms strict else strict
68+ let header = if comments && not (null coms) then JSComment coms strict else strict
66− let foreign' = [JSVariableIntroduction "$foreign" foreign_ | not $ null foreigns || isNothing foreign_]
69+ let foreign' = [JSVariableIntroduction "$foreign" foreign_ | not $ null foreigns || isNothing foreign_]
67− let moduleBody = header : foreign' ++ jsImports ++ concat optimized
70+ let moduleBody = header : foreign' ++ jsImports ++ concat optimized
68− let foreignExps = exps `intersect` (fst `map` foreigns)
71+ let foreignExps = exps `intersect` (fst `map` foreigns)
69− let standardExps = exps \\ foreignExps
72+ let standardExps = exps \\ foreignExps
70− let exps' = JSObjectLiteral $ map (runIdent &&& JSVar . identToJs) standardExps
73+ let exps' = JSObjectLiteral $ map (runIdent &&& JSVar . identToJs) standardExps
71− ++ map (runIdent &&& foreignIdent) foreignExps
74+ ++ map (runIdent &&& foreignIdent) foreignExps
72− return $ moduleBody ++ [JSAssignment (JSAccessor "exports" (JSVar "module")) exps']
75+ return $ moduleBody ++ [JSAssignment (JSAccessor "exports" (JSVar "module")) exps']
@@ -129,8 +132,8 @@ moduleToJs (Module coms mn imps exps foreigns decls) foreign_ = do
129 -- Generate code in the simplified Javascript intermediate representation for a value or expression.
132 -- Generate code in the simplified Javascript intermediate representation for a value or expression.
131 valueToJs :: Expr Ann -> m JS
134 valueToJs :: Expr Ann -> m JS
132− valueToJs (Literal _ l) =
135+ valueToJs (Literal (pos, _, _, _) l) =
133− literalToValueJS l
136+ maybe id rethrowWithPosition pos $ literalToValueJS l
134 valueToJs (Var (_, _, _, Just (IsConstructor _ [])) name) =
137 valueToJs (Var (_, _, _, Just (IsConstructor _ [])) name) =
135 return $ JSAccessor "value" $ qualifiedToJS id name
138 return $ JSAccessor "value" $ qualifiedToJS id name
136 valueToJs (Var (_, _, _, Just (IsConstructor _ _)) name) =
139 valueToJs (Var (_, _, _, Just (IsConstructor _ _)) name) =
@@ -207,7 +210,13 @@ moduleToJs (Module coms mn imps exps foreigns decls) foreign_ = do
207 iife v exprs = JSApp (JSFunction Nothing [] (JSBlock $ exprs ++ [JSReturn $ JSVar v])) []
210 iife v exprs = JSApp (JSFunction Nothing [] (JSBlock $ exprs ++ [JSReturn $ JSVar v])) []
209 literalToValueJS :: Literal (Expr Ann) -> m JS
212 literalToValueJS :: Literal (Expr Ann) -> m JS
210− literalToValueJS (NumericLiteral n) = return $ JSNumericLiteral n
213+ literalToValueJS (NumericLiteral (Left i)) =
214+ let minInt = -2147483648
216+ in if i < minInt || i > maxInt
217+ then throwError . errorMessage $ IntOutOfRange i "JavaScript" minInt maxInt
218+ else return $ JSNumericLiteral (Left i)
219+ literalToValueJS (NumericLiteral (Right n)) = return $ JSNumericLiteral (Right n)
211 literalToValueJS (StringLiteral s) = return $ JSStringLiteral s
220 literalToValueJS (StringLiteral s) = return $ JSStringLiteral s
212 literalToValueJS (CharLiteral c) = return $ JSStringLiteral [c]
221 literalToValueJS (CharLiteral c) = return $ JSStringLiteral [c]
213 literalToValueJS (BooleanLiteral b) = return $ JSBooleanLiteral b
222 literalToValueJS (BooleanLiteral b) = return $ JSBooleanLiteral b
@@ -275,10 +284,10 @@ moduleToJs (Module coms mn imps exps foreigns decls) foreign_ = do
275 go _ _ _ = internalError "Invalid arguments to bindersToJs"
284 go _ _ _ = internalError "Invalid arguments to bindersToJs"
277 failedPatternError :: [String] -> JS
286 failedPatternError :: [String] -> JS
278− failedPatternError names = JSUnary JSNew $ JSApp (JSVar "Error") [JSBinary Add (JSStringLiteral errorMessage) (JSArrayLiteral $ zipWith valueError names vals)]
287+ failedPatternError names = JSUnary JSNew $ JSApp (JSVar "Error") [JSBinary Add (JSStringLiteral failedPatternMessage) (JSArrayLiteral $ zipWith valueError names vals)]
280− errorMessage :: String
289+ failedPatternMessage :: String
281− errorMessage = "Failed pattern match" ++ maybe "" (((" at " ++ runModuleName mn ++ " ") ++) . displayStartEndPos) maybeSpan ++ ": "
290+ failedPatternMessage = "Failed pattern match" ++ maybe "" (((" at " ++ runModuleName mn ++ " ") ++) . displayStartEndPos) maybeSpan ++ ": "
283 valueError :: String -> JS -> JS
292 valueError :: String -> JS -> JS
284 valueError _ l@(JSNumericLiteral _) = l
293 valueError _ l@(JSNumericLiteral _) = l