@@ -14,6 +14,7 @@ module IRTS.JavaScript.Codegen( codegenJs
15import Idris.Core.TT
15import Idris.Core.TT
16import IRTS.CodegenCommon
16import IRTS.CodegenCommon
17import IRTS.JavaScript.AST
18import IRTS.JavaScript.AST
18import IRTS.JavaScript.LangTransforms
19import IRTS.JavaScript.LangTransforms
19import IRTS.JavaScript.Name
20import IRTS.JavaScript.Name
@@ -39,7 +40,6 @@ import System.Directory (doesFileExist)
39import System.Environment
40import System.Environment
40import System.FilePath
41import System.FilePath
43-- | Code generation stats hold information about the generated user
43-- | Code generation stats hold information about the generated user
44-- code. Based on that information we add additional code to make
44-- code. Based on that information we add additional code to make
45-- things work.
45-- things work.
@@ -98,6 +98,31 @@ isYes (Just "Y") = True
98isYes (Just "y") = True
98isYes (Just "y") = True
99isYes _ = False
99isYes _ = False
101+makeExportDecls :: Map Name LDecl -> ExportIFace -> [Text]
102+makeExportDecls defs (Export _ _ e) =
103+ concatMap makeExport e
105+ uncurryF name argTy (Just args) =
106+ if length argTy == length args then name
107+ else T.concat [ "function(){ return "
109+ , ".apply(this, Array.prototype.slice.call(arguments, 0,", T.pack $ show $ length args,"))"
110+ , T.concat $ map (\x -> T.concat ["(arguments[", T.pack $ show x , "])"]) [length args .. (length argTy - 1)]
113+ uncurryF name argTy Nothing = name
115+ addApplyForIO (FIO _) f = T.concat ["function(){ return (",f, ").apply(this,arguments)()}"]
116+ addApplyForIO _ f = f
118+ makeExport (ExportData _) =
120+ makeExport (ExportFun name (FStr exportname) retTy argTy) =
121+ [T.concat [ T.pack $ exportname
123+ , addApplyForIO retTy $ uncurryF (jsName name) argTy (getArgList' name defs)
102codegenJs :: CGConf -> CodeGenerator
127codegenJs :: CGConf -> CodeGenerator
103codegenJs conf ci =
128codegenJs conf ci =
@@ -105,7 +130,10 @@ codegenJs conf ci =
105 debug <- isYes <$> lookupEnv "IDRISJS_DEBUG"
130 debug <- isYes <$> lookupEnv "IDRISJS_DEBUG"
106 let defs' = Map.fromList $ liftDecls ci
131 let defs' = Map.fromList $ liftDecls ci
107 let defs = globlToCon defs'
132 let defs = globlToCon defs'
133+ let iface = interfaces ci
134+ let used = if iface then
135+ Map.elems $ removeDeadCode defs (getExpNames $ exportDecls ci)
108− let used = Map.elems $ removeDeadCode defs [sMN 0 "runMain"]
136+ else Map.elems $ removeDeadCode defs [sMN 0 "runMain"]
109 when debug $ do
137 when debug $ do
110 writeFile (outputFile ci ++ ".LDeclsDebug") $ (unlines $ intersperse "" $ map show used) ++ "\n\n\n"
138 writeFile (outputFile ci ++ ".LDeclsDebug") $ (unlines $ intersperse "" $ map show used) ++ "\n\n\n"
111 putStrLn $ "Finished calculating used"
139 putStrLn $ "Finished calculating used"
@@ -136,7 +164,8 @@ codegenJs conf ci =
136 , doPartials (partialApplications stats), "\n"
164 , doPartials (partialApplications stats), "\n"
137 , doHiddenClasses (hiddenClasses stats), "\n"
165 , doHiddenClasses (hiddenClasses stats), "\n"
138 , out, "\n"
166 , out, "\n"
167+ , if iface then T.concat ["module.exports = {\n", T.intercalate ",\n" $ concatMap (makeExportDecls defs) (exportDecls ci), "\n};\n"]
139− , jsName (sMN 0 "runMain"), "();\n"
168+ else jsName (sMN 0 "runMain") `T.append` "();\n"
140 , "}.call(this))"
169 , "}.call(this))"
141 , footer conf
170 , footer conf
@@ -223,13 +252,17 @@ getConsId n =
223 Just (LConstructor _ conId arity) -> pure (conId, arity)
252 Just (LConstructor _ conId arity) -> pure (conId, arity)
224 _ -> error $ "Internal JS Backend error " ++ showCG n ++ " is not a constructor."
253 _ -> error $ "Internal JS Backend error " ++ showCG n ++ " is not a constructor."
255+getArgList' :: Name -> Map Name LDecl -> Maybe [Name]
257+ case Map.lookup n defs of
258+ Just (LFun _ _ a _) -> Just a
226getArgList :: Name -> State CGBodyState (Maybe [Name])
261getArgList :: Name -> State CGBodyState (Maybe [Name])
227getArgList n =
262getArgList n =
229 st <- get
264 st <- get
230− case Map.lookup n (defs st) of
265+ pure $ getArgList' n (defs st)
231− Just (LFun _ _ a _) -> pure $ Just a
234data BodyResTarget = ReturnBT
267data BodyResTarget = ReturnBT
235 | DecBT Text
268 | DecBT Text