@@ -49,6 +49,9 @@ optimize cycle (A.At region expression) =
49 Can.VarForeign home name _ ->
49 Can.VarForeign home name _ ->
50 Names.registerGlobal home name
50 Names.registerGlobal home name
52+ Can.VarCtor opts home name index _ ->
53+ Names.registerCtor home name index opts
52 Can.VarDebug home name _ ->
55 Can.VarDebug home name _ ->
53 Names.registerKernel N.debug (Opt.VarDebug name home region Nothing)
56 Names.registerKernel N.debug (Opt.VarDebug name home region Nothing)
@@ -82,9 +85,9 @@ optimize cycle (A.At region expression) =
82 return (Opt.Call optFunc [optLeft, optRight])
85 return (Opt.Call optFunc [optLeft, optRight])
84 Can.Lambda args body ->
87 Can.Lambda args body ->
85− do (argNames, defss) <- destructArgs args
88+ do (argNames, destructors) <- destructArgs args
86 obody <- optimize cycle body
89 obody <- optimize cycle body
87− pure $ Opt.Function argNames (foldr Opt.Let obody (concat defss))
90+ pure $ Opt.Function argNames (foldr Opt.Destruct obody destructors)
89 Can.Call func args ->
92 Can.Call func args ->
@@ -117,18 +120,18 @@ optimize cycle (A.At region expression) =
117 foldM (\bod def -> optimizeDef cycle def bod) obody defs
120 foldM (\bod def -> optimizeDef cycle def bod) obody defs
119 Can.LetDestruct pattern expr body ->
122 Can.LetDestruct pattern expr body ->
120− do (name, defs) <- destruct pattern
123+ do (name, destructs) <- destruct pattern
121 oexpr <- optimize cycle expr
124 oexpr <- optimize cycle expr
122 obody <- optimize cycle body
125 obody <- optimize cycle body
124− Opt.Let (Opt.Def name oexpr) (foldr Opt.Let obody defs)
127+ Opt.Let (Opt.Def name oexpr) (foldr Opt.Destruct obody destructs)
126 Can.Case expr branches ->
129 Can.Case expr branches ->
128 optimizeBranch root (Can.CaseBranch pattern branch) =
131 optimizeBranch root (Can.CaseBranch pattern branch) =
129− do defs <- destructHelp (Opt.VarLocal root) pattern []
132+ do destructors <- destructHelp (Opt.Root root) pattern []
130 obranch <- optimize cycle branch
133 obranch <- optimize cycle branch
131− pure (pattern, foldr Opt.Let obranch defs)
134+ pure (pattern, foldr Opt.Destruct obranch destructors)
133 do temp <- Names.generate
136 do temp <- Names.generate
134 oexpr <- optimize cycle expr
137 oexpr <- optimize cycle expr
@@ -190,8 +193,8 @@ optimizeDefHelp cycle name args expr body =
190 pure $ Opt.Let (Opt.Def name oexpr) body
193 pure $ Opt.Let (Opt.Def name oexpr) body
193− do (argNames, defss) <- destructArgs args
196+ do (argNames, destructors) <- destructArgs args
194− let oexpr = Opt.Function argNames (foldr Opt.Let body (concat defss))
197+ let oexpr = Opt.Function argNames (foldr Opt.Destruct body destructors)
195 pure $ Opt.Let (Opt.Def name oexpr) body
198 pure $ Opt.Let (Opt.Def name oexpr) body
@@ -199,98 +202,98 @@ optimizeDefHelp cycle name args expr body =
199-- DESTRUCTURING
202-- DESTRUCTURING
202−destructArgs :: [Can.Pattern] -> Names.Tracker ([N.Name], [[Opt.Def]])
205+destructArgs :: [Can.Pattern] -> Names.Tracker ([N.Name], [Opt.Destructor])
203destructArgs args =
206destructArgs args =
204− unzip <$> traverse destruct args
207+ do (argNames, destructorLists) <- unzip <$> traverse destruct args
208+ return (argNames, concat destructorLists)
207−destruct :: Can.Pattern -> Names.Tracker (N.Name, [Opt.Def])
211+destruct :: Can.Pattern -> Names.Tracker (N.Name, [Opt.Destructor])
208destruct pattern@(A.At _ ptrn) =
212destruct pattern@(A.At _ ptrn) =
209 case ptrn of
213 case ptrn of
210 Can.PVar name ->
214 Can.PVar name ->
211 pure (name, [])
215 pure (name, [])
213 Can.PAlias subPattern name ->
217 Can.PAlias subPattern name ->
214− do revDefs <- destructHelp (Opt.VarLocal name) subPattern []
218+ do revDs <- destructHelp (Opt.Root name) subPattern []
215− pure (name, reverse revDefs)
219+ pure (name, reverse revDs)
218 do name <- Names.generate
222 do name <- Names.generate
219− revDefs <- destructHelp (Opt.VarLocal name) pattern []
223+ revDs <- destructHelp (Opt.Root name) pattern []
220− pure (name, reverse revDefs)
224+ pure (name, reverse revDs)
223−destructHelp :: Opt.Expr -> Can.Pattern -> [Opt.Def] -> Names.Tracker [Opt.Def]
227+destructHelp :: Opt.Path -> Can.Pattern -> [Opt.Destructor] -> Names.Tracker [Opt.Destructor]
224−destructHelp root (A.At region pattern) revDefs =
228+destructHelp path (A.At region pattern) revDs =
225 case pattern of
229 case pattern of
226 Can.PAnything ->
230 Can.PAnything ->
227− pure revDefs
231+ pure revDs
229 Can.PVar name ->
233 Can.PVar name ->
230− pure (Opt.Def name root : revDefs)
234+ pure (Opt.Destructor name path : revDs)
232 Can.PRecord fields ->
236 Can.PRecord fields ->
233− let toDef name = Opt.Def name (Opt.Access root name) in
237+ let
239+ Opt.Destructor name (Opt.Field name path)
234− Names.registerFieldList fields (map toDef fields ++ revDefs)
241+ Names.registerFieldList fields (map toDestruct fields ++ revDs)
236 Can.PAlias subPattern name ->
243 Can.PAlias subPattern name ->
237− destructHelp (Opt.VarLocal name) subPattern $
244+ destructHelp (Opt.Root name) subPattern $
238− Opt.Def name root : revDefs
245+ Opt.Destructor name path : revDs
240 Can.PUnit ->
247 Can.PUnit ->
241− pure revDefs
248+ pure revDs
250+ Can.PTuple a b Nothing ->
251+ destructTwo path a b revDs
243− Can.PTuple a b maybeC ->
253+ Can.PTuple a b (Just c) ->
244 do name <- Names.generate
254 do name <- Names.generate
245− let tuple = Opt.VarLocal name
255+ let newRoot = Opt.Root name
246− let newRevDefs = Opt.Def name root : revDefs
256+ destructHelp (Opt.Index Index.first newRoot) a =<<
247− case maybeC of
257+ destructHelp (Opt.Index Index.second newRoot) b =<<
248− Nothing ->
258+ destructHelp (Opt.Index Index.third newRoot) c (Opt.Destructor name path : revDs)
249− destructHelp (Opt.Index tuple 1) b =<<
250− destructHelp (Opt.Index tuple 0) a newRevDefs
253− destructHelp (Opt.Index tuple 2) c =<<
254− destructHelp (Opt.Index tuple 1) b =<<
255− destructHelp (Opt.Index tuple 0) a newRevDefs
257 Can.PList [] ->
260 Can.PList [] ->
258− pure revDefs
261+ pure revDs
260 Can.PList (hd:tl) ->
263 Can.PList (hd:tl) ->
261− destructCons root hd (A.At region (Can.PList tl)) revDefs
264+ destructTwo path hd (A.At region (Can.PList tl)) revDs
263 Can.PCons hd tl ->
266 Can.PCons hd tl ->
264− destructCons root hd tl revDefs
267+ destructTwo path hd tl revDs
266 Can.PChr _ ->
269 Can.PChr _ ->
267− pure revDefs
270+ pure revDs
269 Can.PStr _ ->
272 Can.PStr _ ->
270− pure revDefs
273+ pure revDs
272 Can.PInt _ ->
275 Can.PInt _ ->
273− pure revDefs
276+ pure revDs
275− Can.PCtor _ _ _ _ _ _ args ->
278+ Can.PCtor _ _ _ _ _ args ->
276 do name <- Names.generate
279 do name <- Names.generate
278− (destructCtorArg (Opt.VarLocal name))
281+ (destructCtorArg (Opt.Root name))
279− (Opt.Def name root : revDefs)
282+ (Opt.Destructor name path : revDs)
283−destructCons :: Opt.Expr -> Can.Pattern -> Can.Pattern -> [Opt.Def] -> Names.Tracker [Opt.Def]
286+destructTwo :: Opt.Path -> Can.Pattern -> Can.Pattern -> [Opt.Destructor] -> Names.Tracker [Opt.Destructor]
284−destructCons root hd tl revDefs =
287+destructTwo path a b revDs =
285 do name <- Names.generate
288 do name <- Names.generate
286− let list = Opt.VarLocal name
289+ let newRoot = Opt.Root name
287− destructHelp (Opt.Index list 0) hd =<<
290+ destructHelp (Opt.Index Index.first newRoot) a =<<
288− destructHelp (Opt.Index list 1) tl (Opt.Def name root : revDefs)
291+ destructHelp (Opt.Index Index.second newRoot) b (Opt.Destructor name path : revDs)
291−destructCtorArg :: Opt.Expr -> [Opt.Def] -> Can.PatternCtorArg -> Names.Tracker [Opt.Def]
294+destructCtorArg :: Opt.Path -> [Opt.Destructor] -> Can.PatternCtorArg -> Names.Tracker [Opt.Destructor]
292−destructCtorArg root revDefs (Can.PatternCtorArg index _ arg) =
295+destructCtorArg path revDs (Can.PatternCtorArg index _ arg) =
293− destructHelp (Opt.Index root (Index.toZeroBased index)) arg revDefs
296+ destructHelp (Opt.Index index path) arg revDs
@@ -301,13 +304,13 @@ optimizePotentialTailCall :: Cycle -> Can.Def -> Names.Tracker Opt.Def
301optimizePotentialTailCall cycle def =
304optimizePotentialTailCall cycle def =
302 case def of
305 case def of
303 Can.Def (A.At _ name) args expr ->
306 Can.Def (A.At _ name) args expr ->
304− do (argNames, defss) <- destructArgs args
307+ do (argNames, destructors) <- destructArgs args
305− toTailDef name argNames defss <$>
308+ toTailDef name argNames destructors <$>
306 optimizeTail cycle name argNames expr
309 optimizeTail cycle name argNames expr
308 Can.TypedDef (A.At _ name) _ typedArgs expr _ ->
311 Can.TypedDef (A.At _ name) _ typedArgs expr _ ->
309− do (argNames, defss) <- destructArgs (map fst typedArgs)
312+ do (argNames, destructors) <- destructArgs (map fst typedArgs)
310− toTailDef name argNames defss <$>
313+ toTailDef name argNames destructors <$>
311 optimizeTail cycle name argNames expr
314 optimizeTail cycle name argNames expr
@@ -355,18 +358,18 @@ optimizeTail cycle rootName argNames locExpr@(A.At _ expression) =
355 foldM (\bod def -> optimizeDef cycle def bod) obody defs
358 foldM (\bod def -> optimizeDef cycle def bod) obody defs
357 Can.LetDestruct pattern expr body ->
360 Can.LetDestruct pattern expr body ->
358− do (dname, defs) <- destruct pattern
361+ do (dname, destructors) <- destruct pattern
359 oexpr <- optimize cycle expr
362 oexpr <- optimize cycle expr
360 obody <- optimizeTail cycle dname argNames body
363 obody <- optimizeTail cycle dname argNames body
362− Opt.Let (Opt.Def dname oexpr) (foldr Opt.Let obody defs)
365+ Opt.Let (Opt.Def dname oexpr) (foldr Opt.Destruct obody destructors)
364 Can.Case expr branches ->
367 Can.Case expr branches ->
366 optimizeBranch root (Can.CaseBranch pattern branch) =
369 optimizeBranch root (Can.CaseBranch pattern branch) =
367− do defs <- destructHelp (Opt.VarLocal root) pattern []
370+ do destructors <- destructHelp (Opt.Root root) pattern []
368 obranch <- optimizeTail cycle rootName argNames branch
371 obranch <- optimizeTail cycle rootName argNames branch
369− pure (pattern, foldr Opt.Let obranch defs)
372+ pure (pattern, foldr Opt.Destruct obranch destructors)
371 do temp <- Names.generate
374 do temp <- Names.generate
372 oexpr <- optimize cycle expr
375 oexpr <- optimize cycle expr
@@ -385,12 +388,12 @@ optimizeTail cycle rootName argNames locExpr@(A.At _ expression) =
385-- DETECT TAIL CALLS
388-- DETECT TAIL CALLS
388−toTailDef :: N.Name -> [N.Name] -> [[Opt.Def]] -> Opt.Expr -> Opt.Def
391+toTailDef :: N.Name -> [N.Name] -> [Opt.Destructor] -> Opt.Expr -> Opt.Def
389−toTailDef name argNames defss body =
392+toTailDef name argNames destructors body =
390 if hasTailCall body then
393 if hasTailCall body then
391− Opt.TailDef name argNames (foldr Opt.Let body (concat defss))
394+ Opt.TailDef name argNames (foldr Opt.Destruct body destructors)
393− Opt.Def name (Opt.Function argNames (foldr Opt.Let body (concat defss)))
396+ Opt.Def name (Opt.Function argNames (foldr Opt.Destruct body destructors))
396hasTailCall :: Opt.Expr -> Bool
399hasTailCall :: Opt.Expr -> Bool