@@ -51,8 +51,9 @@ defunctionalise nexttag defs
5151 newacons = sortBy conord $ concatMap (toConsA anames') (getFn all)
5252 eval = mkEval newecons
5353 app = mkApply newacons
54+ app2 = mkApply2 newacons
5455 condecls = declare nexttag (newecons ++ newacons) in
55− addAlist (eval : app : condecls ++ allD) emptyContext
56+ addAlist (eval : app : app2 : condecls ++ allD) emptyContext
5657 where conord (n, _, _) (n', _, _) = compare n n'
5758
5859getFn :: [(Name, LDecl)] -> [(Name, Int)]
@@ -152,6 +153,8 @@ addApps defs (n, LFun _ _ args e)
152153 = return $ chainAPPLY (DApp False n (take ar args)) (drop ar args)
153154
154155 chainAPPLY f [] = f
156+-- chainAPPLY f (a : b : as)
157+-- = chainAPPLY (DApp False (sMN 0 "APPLY2") [f, a, b]) as
155158 chainAPPLY f (a : as) = chainAPPLY (DApp False (sMN 0 "APPLY") [f, a]) as
156159
157160 -- if anything in the DExp is projected from, we'll need to evaluate it,
@@ -184,6 +187,7 @@ eEVAL x = DApp False (sMN 0 "EVAL") [x]
184187
185188data EvalApply a = EvalCase (Name -> a)
186189 | ApplyCase a
190+ | Apply2Case a
187191
188192-- For a function name, generate a list of
189193-- data constuctors, and whether to handle them in EVAL or APPLY
@@ -219,7 +223,15 @@ mkApplyCase fname n ar
219223 (DApp False (mkUnderCon fname (ar - (n + 1)))
220224 (map (DV . Glob) (take n (genArgs 0) ++
221225 [sMN 0 "arg"])))))
222− : mkApplyCase fname (n + 1) ar
226+ :
227+ if (ar - (n + 2) >=0 )
228+ then (nm, n, Apply2Case (DConCase (-1) nm (take n (genArgs 0))
229+ (DApp False (mkUnderCon fname (ar - (n + 2)))
230+ (map (DV . Glob) (take n (genArgs 0) ++
231+ [sMN 0 "arg0", sMN 0 "arg1"])))))
232+ :
233+ mkApplyCase fname (n + 1) ar
234+ else mkApplyCase fname (n + 1) ar
223235
224236mkEval :: [(Name, Int, EvalApply DAlt)] -> (Name, DDecl)
225237mkEval xs = (sMN 0 "EVAL", DFun (sMN 0 "EVAL") [sMN 0 "arg"]
@@ -243,6 +255,25 @@ mkApply xs = (sMN 0 "APPLY", DFun (sMN 0 "APPLY") [sMN 0 "fn", sMN 0 "arg"]
243255 applyCase (n, t, ApplyCase x) = Just x
244256 applyCase _ = Nothing
245257
258+mkApply2 :: [(Name, Int, EvalApply DAlt)] -> (Name, DDecl)
259+mkApply2 xs = (sMN 0 "APPLY2", DFun (sMN 0 "APPLY2") [sMN 0 "fn", sMN 0 "arg0", sMN 0 "arg1"]
260+ (case mapMaybe applyCase xs of
261+ [] -> DNothing
262+ cases ->
263+ mkBigCase (sMN 0 "APPLY") 256
264+ (DV (Glob (sMN 0 "fn")))
265+ (cases ++
266+ [DDefaultCase
267+ (DApp False (sMN 0 "APPLY")
268+ [DApp False (sMN 0 "APPLY")
269+ [DV (Glob (sMN 0 "fn")),
270+ DV (Glob (sMN 0 "arg0"))],
271+ DV (Glob (sMN 0 "arg1"))])
272+ ])))
273+ where
274+ applyCase (n, t, Apply2Case x) = Just x
275+ applyCase _ = Nothing
276+
246277
247278declare :: Int -> [(Name, Int, EvalApply DAlt)] -> [(Name, DDecl)]
248279declare t xs = dec' t xs [] where