@@ -130,14 +130,14 @@ optimize cycle (A.At region expression) =
130 obranch <- optimize cycle branch
130 obranch <- optimize cycle branch
131 pure (pattern, foldr Opt.Let obranch defs)
131 pure (pattern, foldr Opt.Let obranch defs)
133+ do temp <- Names.generate
133− do oexpr <- optimize cycle expr
134+ oexpr <- optimize cycle expr
134 case oexpr of
135 case oexpr of
135 Opt.VarLocal root ->
136 Opt.VarLocal root ->
136− Case.optimize root <$> traverse (optimizeBranch root) branches
137+ Case.optimize temp root <$> traverse (optimizeBranch root) branches
139− do root <- Names.generate
140− Case.optimize root <$> traverse (optimizeBranch root) branches
140+ Case.optimize temp temp <$> traverse (optimizeBranch temp) branches
142 Can.Accessor field ->
142 Can.Accessor field ->
143 Names.registerField field (Opt.Accessor field)
143 Names.registerField field (Opt.Accessor field)
@@ -246,13 +246,13 @@ destructHelp root (A.At region pattern) revDefs =
246 let newRevDefs = Opt.Def name root : revDefs
246 let newRevDefs = Opt.Def name root : revDefs
247 case maybeC of
247 case maybeC of
248 Nothing ->
248 Nothing ->
249− destructHelp (Opt.CtorAccess tuple Index.second) b =<<
249+ destructHelp (Opt.Index tuple 1) b =<<
250− destructHelp (Opt.CtorAccess tuple Index.first) a newRevDefs
250+ destructHelp (Opt.Index tuple 0) a newRevDefs
252 Just c ->
252 Just c ->
253− destructHelp (Opt.CtorAccess tuple Index.third) c =<<
253+ destructHelp (Opt.Index tuple 2) c =<<
254− destructHelp (Opt.CtorAccess tuple Index.second) b =<<
254+ destructHelp (Opt.Index tuple 1) b =<<
255− destructHelp (Opt.CtorAccess tuple Index.first) a newRevDefs
255+ destructHelp (Opt.Index tuple 0) a newRevDefs
257 Can.PList [] ->
257 Can.PList [] ->
258 pure revDefs
258 pure revDefs
@@ -272,7 +272,7 @@ destructHelp root (A.At region pattern) revDefs =
272 Can.PInt _ ->
272 Can.PInt _ ->
273 pure revDefs
273 pure revDefs
275− Can.PCtor _ _ _ _ _ args ->
275+ Can.PCtor _ _ _ _ _ _ args ->
276 do name <- Names.generate
276 do name <- Names.generate
278 (destructCtorArg (Opt.VarLocal name))
278 (destructCtorArg (Opt.VarLocal name))
@@ -284,13 +284,13 @@ destructCons :: Opt.Expr -> Can.Pattern -> Can.Pattern -> [Opt.Def] -> Names.Tra
284destructCons root hd tl revDefs =
284destructCons root hd tl revDefs =
285 do name <- Names.generate
285 do name <- Names.generate
286 let list = Opt.VarLocal name
286 let list = Opt.VarLocal name
287− destructHelp (Opt.CtorAccess list Index.first) hd =<<
287+ destructHelp (Opt.Index list 0) hd =<<
288− destructHelp (Opt.CtorAccess list Index.second) tl (Opt.Def name root : revDefs)
288+ destructHelp (Opt.Index list 1) tl (Opt.Def name root : revDefs)
291destructCtorArg :: Opt.Expr -> [Opt.Def] -> Can.PatternCtorArg -> Names.Tracker [Opt.Def]
291destructCtorArg :: Opt.Expr -> [Opt.Def] -> Can.PatternCtorArg -> Names.Tracker [Opt.Def]
292destructCtorArg root revDefs (Can.PatternCtorArg index _ arg) =
292destructCtorArg root revDefs (Can.PatternCtorArg index _ arg) =
293− destructHelp (Opt.CtorAccess root index) arg revDefs
293+ destructHelp (Opt.Index root (Index.toZeroBased index)) arg revDefs
@@ -312,37 +312,46 @@ optimizePotentialTailCall cycle def =
314optimizeTail :: Cycle -> N.Name -> [N.Name] -> Can.Expr -> Names.Tracker Opt.Expr
314optimizeTail :: Cycle -> N.Name -> [N.Name] -> Can.Expr -> Names.Tracker Opt.Expr
315−optimizeTail cycle name argNames locExpr@(A.At _ expression) =
315+optimizeTail cycle rootName argNames locExpr@(A.At _ expression) =
316 case expression of
316 case expression of
317− Can.Call (A.At _ (Can.VarTopLevel _ funcName)) args ->
317+ Can.Call func@(A.At _ (Can.VarTopLevel _ name)) args ->
318− if funcName == name && length args == length argNames then
318+ do oargs <- traverse (optimize cycle) args
321+ case Index.indexedZipWith (\_ a b -> (a,b)) argNames oargs of
322+ Index.LengthMatch pairs ->
319− Opt.TailCall name argNames <$> traverse (optimize cycle) args
323+ pure $ Opt.TailCall name pairs
325+ Index.LengthMismatch _ _ ->
326+ do ofunc <- optimize cycle func
327+ pure $ Opt.Call ofunc oargs
321− optimize cycle locExpr
329+ do ofunc <- optimize cycle func
330+ pure $ Opt.Call ofunc oargs
323 Can.If branches finally ->
332 Can.If branches finally ->
325 optimizeBranch (condition, branch) =
334 optimizeBranch (condition, branch) =
327 <$> optimize cycle condition
336 <$> optimize cycle condition
328− <*> optimizeTail cycle name argNames branch
337+ <*> optimizeTail cycle rootName argNames branch
331 <$> traverse optimizeBranch branches
340 <$> traverse optimizeBranch branches
332− <*> optimizeTail cycle name argNames finally
341+ <*> optimizeTail cycle rootName argNames finally
334 Can.Let def body ->
343 Can.Let def body ->
335− optimizeDef cycle def =<< optimizeTail cycle name argNames body
344+ optimizeDef cycle def =<< optimizeTail cycle rootName argNames body
337 Can.LetRec defs body ->
346 Can.LetRec defs body ->
338 case defs of
347 case defs of
341 <$> optimizePotentialTailCall cycle def
350 <$> optimizePotentialTailCall cycle def
342− <*> optimizeTail cycle name argNames body
351+ <*> optimizeTail cycle rootName argNames body
345− do obody <- optimizeTail cycle name argNames body
354+ do obody <- optimizeTail cycle rootName argNames body
346 foldM (\bod def -> optimizeDef cycle def bod) obody defs
355 foldM (\bod def -> optimizeDef cycle def bod) obody defs
348 Can.LetDestruct pattern expr body ->
357 Can.LetDestruct pattern expr body ->
@@ -356,17 +365,17 @@ optimizeTail cycle name argNames locExpr@(A.At _ expression) =
357 optimizeBranch root (Can.CaseBranch pattern branch) =
366 optimizeBranch root (Can.CaseBranch pattern branch) =
358 do defs <- destructHelp (Opt.VarLocal root) pattern []
367 do defs <- destructHelp (Opt.VarLocal root) pattern []
359− obranch <- optimizeTail cycle name argNames branch
368+ obranch <- optimizeTail cycle rootName argNames branch
360 pure (pattern, foldr Opt.Let obranch defs)
369 pure (pattern, foldr Opt.Let obranch defs)
371+ do temp <- Names.generate
362− do oexpr <- optimize cycle expr
372+ oexpr <- optimize cycle expr
363 case oexpr of
373 case oexpr of
364 Opt.VarLocal root ->
374 Opt.VarLocal root ->
365− Case.optimize root <$> traverse (optimizeBranch root) branches
375+ Case.optimize temp root <$> traverse (optimizeBranch root) branches
368− do root <- Names.generate
369− Case.optimize root <$> traverse (optimizeBranch root) branches
378+ Case.optimize temp temp <$> traverse (optimizeBranch temp) branches
372 optimize cycle locExpr
381 optimize cycle locExpr
@@ -387,7 +396,7 @@ toTailDef name argNames defss body =
387hasTailCall :: Opt.Expr -> Bool
396hasTailCall :: Opt.Expr -> Bool
388hasTailCall expression =
397hasTailCall expression =
389 case expression of
398 case expression of
390− Opt.TailCall _ _ _ ->
399+ Opt.TailCall _ _ ->
393 Opt.If branches finally ->
402 Opt.If branches finally ->
@@ -396,7 +405,7 @@ hasTailCall expression =
396 Opt.Let _ body ->
405 Opt.Let _ body ->
397 hasTailCall body
406 hasTailCall body
399− Opt.Case _ _ branches ->
408+ Opt.Case _ _ _ branches ->
400 any (hasTailCall . snd) branches
409 any (hasTailCall . snd) branches