@@ -25,7 +25,7 @@ module Language.PureScript.CodeGen.JS
25 , mainCall
25 , mainCall
28−import Data.List ((\\), delete)
28+import Data.List ((\\), delete, intersect)
29import qualified Data.Traversable as T (traverse)
29import qualified Data.Traversable as T (traverse)
31import Control.Applicative
31import Control.Applicative
@@ -53,15 +53,17 @@ moduleToJs :: forall m mode. (Applicative m, Monad m, MonadReader (Options mode)
53moduleToJs (Module coms mn imps exps foreigns decls) = do
53moduleToJs (Module coms mn imps exps foreigns decls) = do
54 additional <- asks optionsAdditional
54 additional <- asks optionsAdditional
55 jsImports <- T.traverse importToJs . delete (ModuleName [ProperName C.prim]) . (\\ [mn]) $ imps
55 jsImports <- T.traverse importToJs . delete (ModuleName [ProperName C.prim]) . (\\ [mn]) $ imps
56− let foreigns' = [] -- TODO: Update this. mapMaybe (\(_, js, _) -> js) foreigns
57 jsDecls <- mapM bindToJs decls
56 jsDecls <- mapM bindToJs decls
58 optimized <- T.traverse (T.traverse optimize) jsDecls
57 optimized <- T.traverse (T.traverse optimize) jsDecls
59 let isModuleEmpty = null exps
58 let isModuleEmpty = null exps
60 comments <- not <$> asks optionsNoComments
59 comments <- not <$> asks optionsNoComments
61 let strict = JSStringLiteral "use strict"
60 let strict = JSStringLiteral "use strict"
62 let header = if comments && not (null coms) then JSComment coms strict else strict
61 let header = if comments && not (null coms) then JSComment coms strict else strict
63− let moduleBody = header : jsImports ++ foreigns' ++ concat optimized
62+ let moduleBody = header : jsImports ++ concat optimized
63+ let foreignExps = exps `intersect` (fst `map` foreigns)
64+ let standardExps = exps \\ foreignExps
64− let exps' = JSObjectLiteral $ map (runIdent &&& JSVar . identToJs) exps
65+ let exps' = JSObjectLiteral $ map (runIdent &&& JSVar . identToJs) standardExps
66+ ++ map (runIdent &&& foreignIdent) foreignExps
65 return $ case additional of
67 return $ case additional of
66 MakeOptions -> moduleBody ++ [JSAssignment (JSAccessor "exports" (JSVar "module")) exps']
68 MakeOptions -> moduleBody ++ [JSAssignment (JSAccessor "exports" (JSVar "module")) exps']
67 CompileOptions ns _ _ | not isModuleEmpty ->
69 CompileOptions ns _ _ | not isModuleEmpty ->
@@ -171,6 +173,12 @@ moduleToJs (Module coms mn imps exps foreigns decls) = do
171 unApp :: Expr Ann -> [Expr Ann] -> (Expr Ann, [Expr Ann])
173 unApp :: Expr Ann -> [Expr Ann] -> (Expr Ann, [Expr Ann])
172 unApp (App _ val arg) args = unApp val (arg : args)
174 unApp (App _ val arg) args = unApp val (arg : args)
173 unApp other args = (other, args)
175 unApp other args = (other, args)
176+ valueToJs (Var (_, _, _, Just IsForeign) qi@(Qualified (Just mn') ident)) =
177+ return $ if mn' == mn
178+ then foreignIdent ident
180+ valueToJs (Var (_, _, _, Just IsForeign) ident) =
181+ error $ "Encountered an unqualified reference to a foreign ident " ++ show ident
174 valueToJs (Var _ ident) =
182 valueToJs (Var _ ident) =
175 return $ varToJs ident
183 return $ varToJs ident
176 valueToJs (Case (maybeSpan, _, _, _) values binders) = do
184 valueToJs (Case (maybeSpan, _, _, _) values binders) = do
@@ -247,6 +255,9 @@ moduleToJs (Module coms mn imps exps foreigns decls) = do
247 qualifiedToJS f (Qualified (Just mn') a) | mn /= mn' = accessor (f a) (JSVar (moduleNameToJs mn'))
255 qualifiedToJS f (Qualified (Just mn') a) | mn /= mn' = accessor (f a) (JSVar (moduleNameToJs mn'))
248 qualifiedToJS f (Qualified _ a) = JSVar $ identToJs (f a)
256 qualifiedToJS f (Qualified _ a) = JSVar $ identToJs (f a)
258+ foreignIdent :: Ident -> JS
259+ foreignIdent ident = accessorString (runIdent ident) (JSVar "$foreign")
251 -- Generate code in the simplified Javascript intermediate representation for pattern match binders
262 -- Generate code in the simplified Javascript intermediate representation for pattern match binders
252 -- and guards.
263 -- and guards.