@@ -48,6 +48,7 @@ emptyStats :: CGStats
4848emptyStats = CGStats {usedWriteStr = False}
4949
5050data CGConf = CGConf { header :: Text
51+ , footer :: Text
5152 , initialization :: CGStats -> Text
5253 , writeStrTemplate :: Text
5354 }
@@ -81,7 +82,7 @@ codegenJs conf ci =
8182 used `deepseq` if debug then
8283 do
8384 putStrLn $ "Finished calculating used"
84− writeFile (outputFile ci ++ ".LDecls") $ (unlines $ intersperse "" $ map show used) ++ "\n\n\n"
85+ writeFile (outputFile ci ++ ".LDeclsDebug") $ (unlines $ intersperse "" $ map show used) ++ "\n\n\n"
8586 else pure ()
8687
8788 let (out, stats) = doCodegen conf defs used --T.intercalate "\n" $ map (doCodegen conf defs) used
@@ -94,8 +95,10 @@ codegenJs conf ci =
9495 , includes, "\n"
9596 , js_aux_defs, "\n"
9697 , out, "\n"
97− , "\n\n"
98+ , "\n"
99+ , jsName (sMN 0 "runMain"), "();\n\n"
98100 , "\n}())"
101+ , footer conf
99102 ]
100103
101104jsName :: Name -> Text
@@ -136,20 +139,43 @@ getNewCGName =
136139 put $ st {lastIntName = v}
137140 return $ T.pack $ "cgIdris_" ++ show v
138141
142+getNewCGNames :: Int -> State CGBodyState [Text]
143+getNewCGNames n =
144+ mapM (\_ -> getNewCGName) [1..n]
145+
139146getConsId :: Name -> State CGBodyState Int
140147getConsId n =
141148 do
142149 st <- get
143150 case lookupCtxtExact n (defs st) of
144151 Just (LConstructor _ conId _) -> pure conId
145− _ -> error $ "ups " ++ showCG n
152+ _ -> error $ "Internal JS Backend error " ++ showCG n ++ " is not a constructor."
146153
154+getArgList :: Name -> State CGBodyState (Maybe [Name])
155+getArgList n =
156+ do
157+ st <- get
158+ case lookupCtxtExact n (defs st) of
159+ Just (LFun _ _ a _) -> pure $ Just a
160+ _ -> pure Nothing
147161
148162data BodyResTarget = ReturnBT
149− | DecVarBT Text
150− | SetVarBT Text
163+ | DecBT Text
164+ | SetBT Text
165+ | DecConstBT Text
151166 | GetExpBT
152167
168+replaceVarsByProj :: JsAST -> Map Text Int -> JsAST -> JsAST
169+replaceVarsByProj n d z =
170+ transform f z
171+ where
172+ f :: JsAST -> JsAST
173+ f (JsVar x) =
174+ case Map.lookup x d of
175+ Nothing -> (JsVar x)
176+ Just i -> JsArrayProj (JsInt i) n
177+ f x = x
178+
153179cgFun :: CGConf -> LDefs -> Name -> [Name] -> LExp -> (JsAST, CGStats)
154180cgFun cnf dfs n args def =
155181 let
@@ -165,9 +191,15 @@ cgFun cnf dfs n args def =
165191 , usedWrite = False
166192 }
167193 )
168− body = if isTailRec st then JsWhileTrue $ (seqJs decs) `JsSeq` res `JsSeq` JsBreak
194+ body = if isTailRec st then
195+ JsFor (JsLetList [("cgArgs", JsApp "Array.prototype.slice.call" [JsVar "arguments"]), ("cgArgs2", JsNull) ] , JsTrue, JsSetVar "cgArgs" (JsVar "cgArgs2") ) $
196+ --JsSeq (JsDecVar "cgArgs" $ JsApp "Array.prototype.slice.call" [JsVar "arguments"]) $ JsWhileTrue $
197+ replaceVarsByProj
198+ (JsVar "cgArgs")
199+ (Map.fromList $ zip argNames [0..])
200+ ((seqJs decs) `JsSeq` res)
169201 else JsSeq (seqJs decs) res
170− in (JsCurryFun fnName argNames $ body, CGStats {usedWriteStr = usedWrite st})
202+ in (JsFun fnName argNames $ body, CGStats {usedWriteStr = usedWrite st})
171203
172204getSwitchJs :: JsAST -> [LAlt] -> JsAST
173205getSwitchJs x alts =
@@ -178,30 +210,61 @@ getSwitchJs x alts =
178210
179211addRT :: BodyResTarget -> JsAST -> JsAST
180212addRT ReturnBT x = JsReturn x
181−addRT (DecVarBT n) x = JsDecVar n x
182−addRT (SetVarBT n) x = JsSetVar n x
213+addRT (DecBT n) x = JsLet n x
214+addRT (SetBT n) x = JsSetVar n x
215+addRT (DecConstBT n) x = JsConst n x
183216addRT GetExpBT x = x
184217
185218cgBody :: BodyResTarget -> LExp -> State CGBodyState ([JsAST], JsAST)
186219cgBody rt (LV (Glob n)) =
187− pure $ ([], addRT rt $ JsVar $ jsName n)
188−cgBody rt (LApp _ (LV (Glob fn)) args) =
220+ do
221+ argsFn <- getArgList n
222+ case argsFn of
223+ Just [] ->
224+ pure $ ([], addRT rt $ JsApp (jsName n) [])
225+ Just a ->
226+ do
227+ newNames <- getNewCGNames $ length a
228+ pure ([], addRT rt $ JsCurryLambda newNames (JsApp (jsName n) (map JsVar newNames)))
229+ Nothing ->
230+ pure $ ([], addRT rt $ JsVar $ jsName n)
231+cgBody rt (LApp tailcall (LV (Glob fn)) args) =
189232 do
190233 let fname = jsName fn
191234 st <- get
192235 let (currFn, argN) = currentFnNameAndArgs st
193236 z <- mapM (cgBody GetExpBT) args
237+ let argVals = map snd z
194238 let preDecs = concat $ map fst z
195− case (fname == currFn, rt) of
239+ case (fname == currFn && (length args) == (length argN), rt) of
196240 (True, ReturnBT) ->
197241 do
198− put $ st {isTailRec = True}
199− vars <- sequence $ map (\_->getNewCGName) argN
200− let calcs = map (\(n,v) -> JsDecVar n v) (zip vars (map snd z))
201− let calcsToArgs = map (\(n,v) -> JsSetVar n (JsVar v)) (zip argN vars)
202− pure (preDecs ++ calcs ++ calcsToArgs, JsContinue)
242+ modify (\x-> x {isTailRec = True})
243+ --vars <- getNewCGNames $ length argN --sequence $ map (\_->getNewCGName) argN
244+ let refreshArgs = JsSetVar "cgArgs2" (JsArray argVals)
245+ --let calcs = map (\(n,v) -> JsDecVar n v) (zip vars argVals)
246+ --let calcsToArgs = map (\(n,v) -> JsSetVar n (JsVar v)) (zip argN vars)
247+ pure (preDecs, refreshArgs)
203248 _ ->
204− pure $ (preDecs, addRT rt $ JsCurryApp (JsVar fname) (map snd z))
249+ do
250+ argsFn <- getArgList fn
251+ case argsFn of
252+ Nothing ->
253+ pure (preDecs, addRT rt $ JsCurryApp (JsVar fname) argVals )
254+ Just agFn ->
255+ do
256+ let lenAgFn = length agFn
257+ let lenArgs = length args
258+ case compare lenAgFn lenArgs of
259+ EQ ->
260+ pure (preDecs, addRT rt $ JsApp fname argVals)
261+ LT ->
262+ pure (preDecs, addRT rt $ JsCurryApp (JsApp fname (take lenAgFn argVals )) (drop lenAgFn argVals) )
263+ GT ->
264+ do
265+ newNames <- getNewCGNames $ lenAgFn - lenArgs
266+ pure (preDecs, addRT rt $ JsCurryLambda newNames (JsApp fname (argVals ++ (map JsVar newNames) ) ) )
267+
205268cgBody rt (LForce (LLazyApp n args)) = cgBody rt (LApp False (LV (Glob n)) args)
206269cgBody rt (LLazyApp n args) =
207270 do
@@ -213,7 +276,7 @@ cgBody rt (LForce e) =
213276 pure (d, addRT rt $ JsForce v)
214277cgBody rt (LLet n v sc) =
215278 do
216− (d1, v1) <- cgBody (DecVarBT $ jsName n) v
279+ (d1, v1) <- cgBody (DecConstBT $ jsName n) v
217280 (d2, v2) <- cgBody rt sc
218281 pure $ ((d1 ++ v1 : d2), v2 )
219282cgBody rt (LProj e i) =
@@ -230,17 +293,19 @@ cgBody rt (LCase _ e alts) =
230293 resName <- getNewCGName
231294 swName <- getNewCGName
232295 (altsJs,def) <- cgAlts rt resName (JsVar swName) alts
233− let decSw = JsDecVar swName v
296+ let decSw = JsConst swName v
234297 let sw = JsSwitchCase (getSwitchJs (JsVar swName) alts) altsJs def
235298 case rt of
236299 ReturnBT ->
237300 pure (d ++ [decSw], sw)
238− (DecVarBT nvar) ->
239− pure (d ++ [decSw, JsDecVar nvar JsNull], sw)
240− (SetVarBT nvar) ->
301+ (DecBT nvar) ->
302+ pure (d ++ [decSw, JsLet nvar JsNull], sw)
303+ (SetBT nvar) ->
241304 pure (d ++ [decSw], sw)
242305 GetExpBT ->
243− pure (d ++ [decSw, JsDecVar resName JsNull, sw], JsVar resName)
306+ pure (d ++ [decSw, JsLet resName JsNull, sw], JsVar resName)
307+ (DecConstBT nvar) ->
308+ pure (d ++ [decSw, JsLet nvar JsNull], sw)
244309cgBody rt (LConst c) = pure ([], (addRT rt) $ cgConst c)
245310cgBody rt (LOp op args) =
246311 do
@@ -256,22 +321,12 @@ cgBody rt x@(LForeign dres (FStr code) args ) =
256321 pure $ (concat $ map fst z, addRT rt $ cgForeignRes dres $ JsForeign (T.pack code) jsArgs)
257322cgBody _ x = error $ "Instruction " ++ show x ++ " not compilable yet"
258323
259−replaceMatchVars :: JsAST -> Map Text Int -> JsAST -> JsAST
260−replaceMatchVars n d z =
261− transform f z
262− where
263− f :: JsAST -> JsAST
264− f (JsVar x) =
265− case Map.lookup x d of
266− Nothing -> (JsVar x)
267− Just i -> JsArrayProj (JsInt i) n
268− f x = x
269−
270324altsRT :: Text -> BodyResTarget -> BodyResTarget
271325altsRT rn ReturnBT = ReturnBT
272−altsRT rn (DecVarBT n) = SetVarBT n
273−altsRT rn (SetVarBT n) = SetVarBT n
274−altsRT rn GetExpBT = SetVarBT rn
326+altsRT rn (DecBT n) = SetBT n
327+altsRT rn (SetBT n) = SetBT n
328+altsRT rn (DecConstBT n) = SetBT n
329+altsRT rn GetExpBT = SetBT rn
275330
276331cgAlts :: BodyResTarget -> Text -> JsAST -> [LAlt] -> State CGBodyState ([(JsAST, JsAST)], Maybe JsAST)
277332cgAlts rt resName scrvar ((LConstCase t exp):r) =
@@ -289,7 +344,7 @@ cgAlts rt resName scrvar ((LConCase _ n args exp):r) =
289344 (ar, def) <- cgAlts rt resName scrvar r
290345 conId <- getConsId n
291346 -- let branchBody = JsSeq (conCaseToProjs 1 scrvar args) $ JsSeq (seqJs d) v
292− let replace = replaceMatchVars scrvar (Map.fromList $ zip (map jsName args) [1..])
347+ let replace = replaceVarsByProj scrvar (Map.fromList $ zip (map jsName args) [1..])
293348 let branchBody = JsSeq (seqJs $ map replace d) (replace v)
294349 pure ((JsInt conId, branchBody) : ar, def)
295350cgAlts _ _ _ [] =