-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Inline top level aliases at their call sites
- Loading branch information
Showing
37 changed files
with
506 additions
and
322 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
module Pukeko.Language.AliasInliner | ||
( inlineModule | ||
) where | ||
|
||
import Control.Lens hiding (indices) | ||
import Control.Monad.ST | ||
import qualified Data.Array as A | ||
import qualified Data.Array.ST as A | ||
import Data.Foldable | ||
import qualified Data.Map as Map | ||
import Data.Maybe (mapMaybe) | ||
import Data.Monoid | ||
import qualified Data.Set as Set | ||
|
||
import Pukeko.Language.AST.Std | ||
import Pukeko.Language.AST.Classes | ||
import qualified Pukeko.Language.Ident as Id | ||
|
||
inlineModule :: Module st -> Module st | ||
inlineModule (MkModule info tops0) = | ||
let ls = mapMaybe topLink tops0 | ||
uf = unionFind ls | ||
tops1 = over (traverse . top2eval) (\x -> Map.findWithDefault x x uf) tops0 | ||
in MkModule info tops1 | ||
|
||
topLink :: TopLevel st -> Maybe (Id.EVar, Id.EVar) | ||
topLink = \case | ||
TLDef (MkDefn b (EVal _ x)) -> Just (b^.lhs, x) | ||
TLSup _ z vs _ xs (EVal _ x) | ||
| null vs && null xs -> Just (z, x) | ||
_ -> Nothing | ||
|
||
data UnionFind st a = UnionFind | ||
{ indices :: Map.Map a Int | ||
, names :: A.Array Int a | ||
, links :: A.STArray st Int Int | ||
} | ||
|
||
newUnionFind :: Ord a => Set.Set a -> ST s (UnionFind s a) | ||
newUnionFind xs = do | ||
let is = Map.fromList (zip (toList xs) [0..]) | ||
let bnds = (0, Map.size is - 1) | ||
let ns = A.array bnds (map (\(x, i) -> (i, x)) (Map.toList is)) | ||
ls <- A.newListArray bnds [0..] | ||
pure (UnionFind is ns ls) | ||
|
||
root :: UnionFind s a -> Int -> ST s Int | ||
root uf i = do | ||
j <- A.readArray (links uf) i | ||
if i /= j | ||
then do | ||
k <- A.readArray (links uf) j | ||
A.writeArray (links uf) i k | ||
root uf j | ||
else | ||
pure i | ||
|
||
join' :: UnionFind s a -> Int -> Int -> ST s () | ||
join' uf i j = do | ||
l <- root uf j | ||
A.writeArray (links uf) i l | ||
|
||
join :: Ord a => UnionFind s a -> a -> a -> ST s () | ||
join uf x y = join' uf (indices uf Map.! x) (indices uf Map.! y) | ||
|
||
unionFind :: Ord a => [(a, a)] -> Map.Map a a | ||
unionFind xys = runST $ do | ||
let xs = foldMap (\(x, y) -> Set.singleton x <> Set.singleton y) xys | ||
uf <- newUnionFind xs | ||
for_ xys (uncurry (join uf)) | ||
traverse (\i -> (names uf A.!) <$> root uf i) (indices uf) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
module Pukeko.Language.Prettifier | ||
( prettifyModule | ||
) where | ||
|
||
import Control.Lens | ||
import qualified Data.Map as Map | ||
import qualified Data.Set as Set | ||
import qualified Data.Set.Lens as Set | ||
|
||
import Pukeko.Language.AST.Std | ||
import Pukeko.Language.AST.Stage | ||
import Pukeko.Language.AST.ModuleInfo (info2funs) | ||
import qualified Pukeko.Language.Ident as Id | ||
|
||
prettifyModule :: (HasTLTyp st ~ 'False, HasTLVal st ~ 'False) => Module st -> Module st | ||
prettifyModule (MkModule info0 tops0) = | ||
let xs = Set.setOf (traverse . top2lhs) tops0 | ||
mp = cluster xs | ||
rename x = Map.findWithDefault x x mp | ||
info1 = over info2funs (Map.mapKeys rename) info0 | ||
tops1 = over (traverse . top2lhs) rename tops0 | ||
tops2 = over (traverse . top2eval) rename tops1 | ||
in MkModule info1 tops2 | ||
|
||
cluster :: Set.Set Id.EVar -> Map.Map Id.EVar Id.EVar | ||
cluster xs0 = | ||
let mp = | ||
foldl | ||
(\acc x -> Map.insertWith Set.union (Id.stripPart x) (Set.singleton x) acc) | ||
Map.empty xs0 | ||
f y xs1 | ||
| not (y `Set.member` xs1) = Map.singleton (Set.findMax xs1) y | ||
| otherwise = Map.empty | ||
in ifoldMap f mp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
g_declare_cafs gm$cons_0_0, main | ||
g_declare_main main | ||
|
||
g_globstart gm$cons_0_0, 0 | ||
g_updcons 0, 0, 1 | ||
g_return | ||
|
||
g_globstart gm$return, 2 | ||
g_updcons 0, 2, 1 | ||
g_return | ||
|
||
g_globstart h, 1 | ||
g_update 1 | ||
g_unwind | ||
|
||
g_globstart main, 0 | ||
g_pushglobal gm$cons_0_0, 0 | ||
g_pushglobal h, 1 | ||
g_mkap 1 | ||
g_pushglobal h, 1 | ||
g_mkap 1 | ||
g_pushglobal gm$return, 2 | ||
g_updap 1, 1 | ||
g_unwind |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
external return : ∀a. a -> IO a = "return" | ||
let h : ∀a. a -> a = fun @a -> fun (u : a) -> u | ||
let main : IO Unit = return @Unit (h @Unit (h @Unit Unit)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
val h : c -> c | ||
let h z = (fun u -> u) z | ||
|
||
val g : b -> b | ||
let g y = (fun z -> h z) y | ||
|
||
val f1 : a -> a | ||
let f1 = h | ||
|
||
val f2 : a -> a | ||
let f2 x = g x | ||
|
||
val main : IO Unit | ||
let main = return (f1 (f2 Unit)) |
Oops, something went wrong.