@@ -49,6 +49,9 @@ optimize cycle (A.At region expression) =
4949 Can.VarForeign home name _ ->
5050 Names.registerGlobal home name
5151
52+ Can.VarCtor opts home name index _ ->
53+ Names.registerCtor home name index opts
54+
5255 Can.VarDebug home name _ ->
5356 Names.registerKernel N.debug (Opt.VarDebug name home region Nothing)
5457
@@ -82,9 +85,9 @@ optimize cycle (A.At region expression) =
8285 return (Opt.Call optFunc [optLeft, optRight])
8386
8487 Can.Lambda args body ->
85− do (argNames, defss) <- destructArgs args
88+ do (argNames, destructors) <- destructArgs args
8689 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)
8891
8992 Can.Call func args ->
9093 Opt.Call
@@ -117,18 +120,18 @@ optimize cycle (A.At region expression) =
117120 foldM (\bod def -> optimizeDef cycle def bod) obody defs
118121
119122 Can.LetDestruct pattern expr body ->
120− do (name, defs) <- destruct pattern
123+ do (name, destructs) <- destruct pattern
121124 oexpr <- optimize cycle expr
122125 obody <- optimize cycle body
123126 pure $
124− Opt.Let (Opt.Def name oexpr) (foldr Opt.Let obody defs)
127+ Opt.Let (Opt.Def name oexpr) (foldr Opt.Destruct obody destructs)
125128
126129 Can.Case expr branches ->
127130 let
128131 optimizeBranch root (Can.CaseBranch pattern branch) =
129− do defs <- destructHelp (Opt.VarLocal root) pattern []
132+ do destructors <- destructHelp (Opt.Root root) pattern []
130133 obranch <- optimize cycle branch
131− pure (pattern, foldr Opt.Let obranch defs)
134+ pure (pattern, foldr Opt.Destruct obranch destructors)
132135 in
133136 do temp <- Names.generate
134137 oexpr <- optimize cycle expr
@@ -190,8 +193,8 @@ optimizeDefHelp cycle name args expr body =
190193 pure $ Opt.Let (Opt.Def name oexpr) body
191194
192195 _ ->
193− do (argNames, defss) <- destructArgs args
194− let oexpr = Opt.Function argNames (foldr Opt.Let body (concat defss))
196+ do (argNames, destructors) <- destructArgs args
197+ let oexpr = Opt.Function argNames (foldr Opt.Destruct body destructors)
195198 pure $ Opt.Let (Opt.Def name oexpr) body
196199
197200
@@ -199,98 +202,98 @@ optimizeDefHelp cycle name args expr body =
199202-- DESTRUCTURING
200203
201204
202−destructArgs :: [Can.Pattern] -> Names.Tracker ([N.Name], [[Opt.Def]])
205+destructArgs :: [Can.Pattern] -> Names.Tracker ([N.Name], [Opt.Destructor])
203206destructArgs args =
204− unzip <$> traverse destruct args
207+ do (argNames, destructorLists) <- unzip <$> traverse destruct args
208+ return (argNames, concat destructorLists)
205209
206210
207−destruct :: Can.Pattern -> Names.Tracker (N.Name, [Opt.Def])
211+destruct :: Can.Pattern -> Names.Tracker (N.Name, [Opt.Destructor])
208212destruct pattern@(A.At _ ptrn) =
209213 case ptrn of
210214 Can.PVar name ->
211215 pure (name, [])
212216
213217 Can.PAlias subPattern name ->
214− do revDefs <- destructHelp (Opt.VarLocal name) subPattern []
215− pure (name, reverse revDefs)
218+ do revDs <- destructHelp (Opt.Root name) subPattern []
219+ pure (name, reverse revDs)
216220
217221 _ ->
218222 do name <- Names.generate
219− revDefs <- destructHelp (Opt.VarLocal name) pattern []
220− pure (name, reverse revDefs)
223+ revDs <- destructHelp (Opt.Root name) pattern []
224+ pure (name, reverse revDs)
221225
222226
223−destructHelp :: Opt.Expr -> Can.Pattern -> [Opt.Def] -> Names.Tracker [Opt.Def]
224−destructHelp root (A.At region pattern) revDefs =
227+destructHelp :: Opt.Path -> Can.Pattern -> [Opt.Destructor] -> Names.Tracker [Opt.Destructor]
228+destructHelp path (A.At region pattern) revDs =
225229 case pattern of
226230 Can.PAnything ->
227− pure revDefs
231+ pure revDs
228232
229233 Can.PVar name ->
230− pure (Opt.Def name root : revDefs)
234+ pure (Opt.Destructor name path : revDs)
231235
232236 Can.PRecord fields ->
233− let toDef name = Opt.Def name (Opt.Access root name) in
234− Names.registerFieldList fields (map toDef fields ++ revDefs)
237+ let
238+ toDestruct name =
239+ Opt.Destructor name (Opt.Field name path)
240+ in
241+ Names.registerFieldList fields (map toDestruct fields ++ revDs)
235242
236243 Can.PAlias subPattern name ->
237− destructHelp (Opt.VarLocal name) subPattern $
238− Opt.Def name root : revDefs
244+ destructHelp (Opt.Root name) subPattern $
245+ Opt.Destructor name path : revDs
239246
240247 Can.PUnit ->
241− pure revDefs
248+ pure revDs
249+
250+ Can.PTuple a b Nothing ->
251+ destructTwo path a b revDs
242252
243− Can.PTuple a b maybeC ->
253+ Can.PTuple a b (Just c) ->
244254 do name <- Names.generate
245− let tuple = Opt.VarLocal name
246− let newRevDefs = Opt.Def name root : revDefs
247− case maybeC of
248− Nothing ->
249− destructHelp (Opt.Index tuple 1) b =<<
250− destructHelp (Opt.Index tuple 0) a newRevDefs
251−
252− Just c ->
253− destructHelp (Opt.Index tuple 2) c =<<
254− destructHelp (Opt.Index tuple 1) b =<<
255− destructHelp (Opt.Index tuple 0) a newRevDefs
255+ let newRoot = Opt.Root name
256+ destructHelp (Opt.Index Index.first newRoot) a =<<
257+ destructHelp (Opt.Index Index.second newRoot) b =<<
258+ destructHelp (Opt.Index Index.third newRoot) c (Opt.Destructor name path : revDs)
256259
257260 Can.PList [] ->
258− pure revDefs
261+ pure revDs
259262
260263 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
262265
263266 Can.PCons hd tl ->
264− destructCons root hd tl revDefs
267+ destructTwo path hd tl revDs
265268
266269 Can.PChr _ ->
267− pure revDefs
270+ pure revDs
268271
269272 Can.PStr _ ->
270− pure revDefs
273+ pure revDs
271274
272275 Can.PInt _ ->
273− pure revDefs
276+ pure revDs
274277
275− Can.PCtor _ _ _ _ _ _ args ->
278+ Can.PCtor _ _ _ _ _ args ->
276279 do name <- Names.generate
277280 foldM
278− (destructCtorArg (Opt.VarLocal name))
279− (Opt.Def name root : revDefs)
281+ (destructCtorArg (Opt.Root name))
282+ (Opt.Destructor name path : revDs)
280283 args
281284
282285
283−destructCons :: Opt.Expr -> Can.Pattern -> Can.Pattern -> [Opt.Def] -> Names.Tracker [Opt.Def]
284−destructCons root hd tl revDefs =
286+destructTwo :: Opt.Path -> Can.Pattern -> Can.Pattern -> [Opt.Destructor] -> Names.Tracker [Opt.Destructor]
287+destructTwo path a b revDs =
285288 do name <- Names.generate
286− let list = Opt.VarLocal name
287− destructHelp (Opt.Index list 0) hd =<<
288− destructHelp (Opt.Index list 1) tl (Opt.Def name root : revDefs)
289+ let newRoot = Opt.Root name
290+ destructHelp (Opt.Index Index.first newRoot) a =<<
291+ destructHelp (Opt.Index Index.second newRoot) b (Opt.Destructor name path : revDs)
289292
290293
291−destructCtorArg :: Opt.Expr -> [Opt.Def] -> Can.PatternCtorArg -> Names.Tracker [Opt.Def]
292−destructCtorArg root revDefs (Can.PatternCtorArg index _ arg) =
293− destructHelp (Opt.Index root (Index.toZeroBased index)) arg revDefs
294+destructCtorArg :: Opt.Path -> [Opt.Destructor] -> Can.PatternCtorArg -> Names.Tracker [Opt.Destructor]
295+destructCtorArg path revDs (Can.PatternCtorArg index _ arg) =
296+ destructHelp (Opt.Index index path) arg revDs
294297
295298
296299
@@ -301,13 +304,13 @@ optimizePotentialTailCall :: Cycle -> Can.Def -> Names.Tracker Opt.Def
301304optimizePotentialTailCall cycle def =
302305 case def of
303306 Can.Def (A.At _ name) args expr ->
304− do (argNames, defss) <- destructArgs args
305− toTailDef name argNames defss <$>
307+ do (argNames, destructors) <- destructArgs args
308+ toTailDef name argNames destructors <$>
306309 optimizeTail cycle name argNames expr
307310
308311 Can.TypedDef (A.At _ name) _ typedArgs expr _ ->
309− do (argNames, defss) <- destructArgs (map fst typedArgs)
310− toTailDef name argNames defss <$>
312+ do (argNames, destructors) <- destructArgs (map fst typedArgs)
313+ toTailDef name argNames destructors <$>
311314 optimizeTail cycle name argNames expr
312315
313316
@@ -355,18 +358,18 @@ optimizeTail cycle rootName argNames locExpr@(A.At _ expression) =
355358 foldM (\bod def -> optimizeDef cycle def bod) obody defs
356359
357360 Can.LetDestruct pattern expr body ->
358− do (dname, defs) <- destruct pattern
361+ do (dname, destructors) <- destruct pattern
359362 oexpr <- optimize cycle expr
360363 obody <- optimizeTail cycle dname argNames body
361364 pure $
362− Opt.Let (Opt.Def dname oexpr) (foldr Opt.Let obody defs)
365+ Opt.Let (Opt.Def dname oexpr) (foldr Opt.Destruct obody destructors)
363366
364367 Can.Case expr branches ->
365368 let
366369 optimizeBranch root (Can.CaseBranch pattern branch) =
367− do defs <- destructHelp (Opt.VarLocal root) pattern []
370+ do destructors <- destructHelp (Opt.Root root) pattern []
368371 obranch <- optimizeTail cycle rootName argNames branch
369− pure (pattern, foldr Opt.Let obranch defs)
372+ pure (pattern, foldr Opt.Destruct obranch destructors)
370373 in
371374 do temp <- Names.generate
372375 oexpr <- optimize cycle expr
@@ -385,12 +388,12 @@ optimizeTail cycle rootName argNames locExpr@(A.At _ expression) =
385388-- DETECT TAIL CALLS
386389
387390
388−toTailDef :: N.Name -> [N.Name] -> [[Opt.Def]] -> Opt.Expr -> Opt.Def
389−toTailDef name argNames defss body =
391+toTailDef :: N.Name -> [N.Name] -> [Opt.Destructor] -> Opt.Expr -> Opt.Def
392+toTailDef name argNames destructors body =
390393 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)
392395 else
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))
394397
395398
396399hasTailCall :: Opt.Expr -> Bool