@@ -14,6 +14,7 @@ data Endianness = Native | BE | LE deriving (Show, Eq)
14data LVar = Loc Int | Glob Name
14data LVar = Loc Int | Glob Name
15 deriving (Show, Eq)
15 deriving (Show, Eq)
17+-- ASSUMPTION: All variable bindings have unique names here
17data LExp = LV LVar
18data LExp = LV LVar
18 | LApp Bool LExp [LExp] -- True = tail call
19 | LApp Bool LExp [LExp] -- True = tail call
19 | LLazyApp Name [LExp] -- True = tail call
20 | LLazyApp Name [LExp] -- True = tail call
@@ -217,57 +218,56 @@ nextN = do i <- get
217doInline :: LDefs -> LDecl -> LDecl
218doInline :: LDefs -> LDecl -> LDecl
218doInline defs d@(LConstructor _ _ _) = d
219doInline defs d@(LConstructor _ _ _) = d
219doInline defs (LFun opts topn args exp)
220doInline defs (LFun opts topn args exp)
220− = let res = evalState (inlineWith (map (\n -> (n, LV (Glob n))) args) exp) 0 in
221+ = let res = evalState (inlineWith [topn] (map (\n -> (n, LV (Glob n))) args) exp) 0 in
221 LFun opts topn args res
222 LFun opts topn args res
223− inlineWith :: [(Name, LExp)] -> LExp -> State Int LExp
224+ inlineWith :: [Name] -> [(Name, LExp)] -> LExp -> State Int LExp
224− inlineWith env var@(LV (Glob n)) = case lookup n env of
225+ inlineWith done env var@(LV (Glob n))
226+ = case lookup n env of
225 Just t -> return t
227 Just t -> return t
226 Nothing -> return var
228 Nothing -> return var
227− inlineWith env (LLazyApp n es) = LLazyApp n <$> (mapM (inlineWith env) es)
229+ inlineWith done env (LLazyApp n es) = LLazyApp n <$> (mapM (inlineWith done env) es)
228− inlineWith env (LForce e) = LForce <$> inlineWith env e
230+ inlineWith done env (LForce e) = LForce <$> inlineWith done env e
229− inlineWith env (LLazyExp e) = LLazyExp <$> inlineWith env e
231+ inlineWith done env (LLazyExp e) = LLazyExp <$> inlineWith done env e
230 -- Extend the environment for Let and Lam so that bound names aren't
232 -- Extend the environment for Let and Lam so that bound names aren't
231 -- expanded with any top level argument definitions they shadow
233 -- expanded with any top level argument definitions they shadow
232− inlineWith env (LLet n val sc)
234+ inlineWith done env (LLet n val sc)
233 = do n' <- nextN
235 = do n' <- nextN
234− LLet n' <$> inlineWith env val <*>
236+ LLet n' <$> inlineWith done env val <*>
235− inlineWith ((n, LV (Glob n')) : env) sc
237+ inlineWith done ((n, LV (Glob n')) : env) sc
236− inlineWith env (LLam args sc)
238+ inlineWith done env (LLam args sc)
237 = do ns' <- mapM (\n -> do n' <- nextN
239 = do ns' <- mapM (\n -> do n' <- nextN
238 return (n, n')) args
240 return (n, n')) args
239 LLam (map snd ns') <$>
241 LLam (map snd ns') <$>
240− inlineWith (map (\ (n,n') -> (n, LV (Glob n'))) ns' ++ env) sc
242+ inlineWith done (map (\ (n,n') -> (n, LV (Glob n'))) ns' ++ env) sc
241− inlineWith env (LProj exp i) = LProj <$> inlineWith env exp <*> return i
243+ inlineWith done env (LProj exp i) = LProj <$> inlineWith done env exp <*> return i
242− inlineWith env (LCon loc i n es)
244+ inlineWith done env (LCon loc i n es)
243− = LCon loc i n <$> mapM (inlineWith env) es
245+ = LCon loc i n <$> mapM (inlineWith done env) es
244− inlineWith env (LCase ty e alts)
246+ inlineWith done env (LCase ty e alts)
245− = LCase ty <$> inlineWith env e <*> mapM (inlineWithAlt env) alts
247+ = LCase ty <$> inlineWith done env e <*> mapM (inlineWithAlt done env) alts
246− inlineWith env (LOp f es) = LOp f <$> mapM (inlineWith env) es
248+ inlineWith done env (LOp f es) = LOp f <$> mapM (inlineWith done env) es
247 -- the interesting case!
249 -- the interesting case!
248− inlineWith env (LApp t (LV (Glob n)) es)
250+ inlineWith done env (LApp t (LV (Glob n)) es)
249− | [LFun opts _ args body] <- lookupCtxt n defs,
252+ [LFun opts _ args body] <- lookupCtxt n defs,
250 Inline `elem` opts,
253 Inline `elem` opts,
251 length es == length args
254 length es == length args
252− = do es' <- mapM (inlineWith env) es
255+ = do es' <- mapM (inlineWith done env) es
253− inlineWith (zip args es' ++ env) body
256+ inlineWith (n : done) (zip args es' ++ env) body
256−-- (substLExp (zip args es) body)
257− inlineWith env (LApp t f es)
257+ inlineWith done env (LApp t f es)
258− = LApp t <$> inlineWith env f <*> mapM (inlineWith env) es
258+ = LApp t <$> inlineWith done env f <*> mapM (inlineWith done env) es
259− inlineWith env (LForeign l t s args)
259+ inlineWith done env (LForeign l t s args)
260− = LForeign l t s <$> mapM (\(t, e) -> do e' <- inlineWith env e
260+ = LForeign l t s <$> mapM (\(t, e) -> do e' <- inlineWith done env e
261 return (t, e')) args
261 return (t, e')) args
262− inlineWith env t = return t
262+ inlineWith done env t = return t
264− inlineWithAlt env (LConCase i n es rhs)
264+ inlineWithAlt done env (LConCase i n es rhs)
265 = do ns' <- mapM (\n -> do n' <- nextN
265 = do ns' <- mapM (\n -> do n' <- nextN
266 return (n, n')) es
266 return (n, n')) es
267 LConCase i n (map snd ns') <$>
267 LConCase i n (map snd ns') <$>
268− inlineWith (map (\ (n,n') -> (n, LV (Glob n'))) ns' ++ env) rhs
268+ inlineWith done (map (\ (n,n') -> (n, LV (Glob n'))) ns' ++ env) rhs
269− inlineWithAlt env (LConstCase c e) = LConstCase c <$> inlineWith env e
269+ inlineWithAlt done env (LConstCase c e) = LConstCase c <$> inlineWith done env e
270− inlineWithAlt env (LDefaultCase e) = LDefaultCase <$> inlineWith env e
270+ inlineWithAlt done env (LDefaultCase e) = LDefaultCase <$> inlineWith done env e
272-- substLExp :: [(Name, LExp)] -> LExp -> LExp
272-- substLExp :: [(Name, LExp)] -> LExp -> LExp
273-- substLExp env (LV (Glob n)) | Just t <- lookup n env = t
273-- substLExp env (LV (Glob n)) | Just t <- lookup n env = t