gm + gmPrep wiring
This commit is contained in:
@@ -25,6 +25,7 @@ module Core.Syntax
|
|||||||
, Alter'
|
, Alter'
|
||||||
, Binding'
|
, Binding'
|
||||||
, HasRHS(_rhs)
|
, HasRHS(_rhs)
|
||||||
|
, HasLHS(_lhs)
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
@@ -132,3 +133,16 @@ instance HasRHS (Binding b) b where
|
|||||||
(\ (_ := e) -> e)
|
(\ (_ := e) -> e)
|
||||||
(\ (k := _) e' -> k := e')
|
(\ (k := _) e' -> k := e')
|
||||||
|
|
||||||
|
class HasLHS s a | s -> a where
|
||||||
|
_lhs :: Lens' s a
|
||||||
|
|
||||||
|
instance HasLHS (Alter b) (AltCon, [b]) where
|
||||||
|
_lhs = lens
|
||||||
|
(\ (Alter a bs _) -> (a,bs))
|
||||||
|
(\ (Alter _ _ e) (a',bs') -> Alter a' bs' e)
|
||||||
|
|
||||||
|
instance HasLHS (ScDef b) (b, [b]) where
|
||||||
|
_lhs = lens
|
||||||
|
(\ (ScDef n as _) -> (n,as))
|
||||||
|
(\ (ScDef _ _ e) (n',as') -> (ScDef n' as' e))
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ module Core2Core
|
|||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
import Data.Functor.Foldable
|
import Data.Functor.Foldable
|
||||||
import Data.Maybe (fromJust)
|
import Data.Maybe (fromJust)
|
||||||
|
import Data.Set (Set)
|
||||||
import Data.Set qualified as S
|
import Data.Set qualified as S
|
||||||
import Data.List
|
import Data.List
|
||||||
import Control.Monad.Writer
|
import Control.Monad.Writer
|
||||||
@@ -30,10 +31,13 @@ gmPrep p = p' <> Program caseScs
|
|||||||
where
|
where
|
||||||
rhss :: Applicative f => (Expr z -> f (Expr z)) -> Program z -> f (Program z)
|
rhss :: Applicative f => (Expr z -> f (Expr z)) -> Program z -> f (Program z)
|
||||||
rhss = programScDefs . each . _rhs
|
rhss = programScDefs . each . _rhs
|
||||||
|
globals = p ^.. programScDefs . each . _lhs . _1
|
||||||
|
& S.fromList
|
||||||
|
|
||||||
-- i kinda don't like that we're calling floatNonStrictCases twice tbh
|
-- i kinda don't like that we're calling floatNonStrictCases twice tbh
|
||||||
p' = p & rhss %~ fst . runFloater . floatNonStrictCases
|
p' = p & rhss %~ fst . runFloater . floatNonStrictCases globals
|
||||||
caseScs = (p ^.. rhss)
|
caseScs = (p ^.. rhss)
|
||||||
<&> snd . runFloater . floatNonStrictCases
|
<&> snd . runFloater . floatNonStrictCases globals
|
||||||
& mconcat
|
& mconcat
|
||||||
|
|
||||||
-- | Auxilary type used in @floatNonSrictCases@
|
-- | Auxilary type used in @floatNonSrictCases@
|
||||||
@@ -47,8 +51,8 @@ runFloater = flip evalStateT ns >>> runWriter
|
|||||||
|
|
||||||
-- TODO: formally define a "strict context" and reference that here
|
-- TODO: formally define a "strict context" and reference that here
|
||||||
-- the returned ScDefs are guaranteed to be free of non-strict cases.
|
-- the returned ScDefs are guaranteed to be free of non-strict cases.
|
||||||
floatNonStrictCases :: Expr' -> Floater Expr'
|
floatNonStrictCases :: Set Name -> Expr' -> Floater Expr'
|
||||||
floatNonStrictCases = goE
|
floatNonStrictCases g = goE
|
||||||
where
|
where
|
||||||
goE :: Expr' -> Floater Expr'
|
goE :: Expr' -> Floater Expr'
|
||||||
goE (Var k) = pure (Var k)
|
goE (Var k) = pure (Var k)
|
||||||
@@ -64,7 +68,7 @@ floatNonStrictCases = goE
|
|||||||
-- Writer, and finally return an expression appropriately calling the sc
|
-- Writer, and finally return an expression appropriately calling the sc
|
||||||
goC p@(Case e as) = do
|
goC p@(Case e as) = do
|
||||||
n <- name
|
n <- name
|
||||||
let (e',sc) = floatCase n p
|
let (e',sc) = floatCase g n p
|
||||||
altBodies = (\(Alter _ _ b) -> b) <$> as
|
altBodies = (\(Alter _ _ b) -> b) <$> as
|
||||||
tell [sc]
|
tell [sc]
|
||||||
goE e
|
goE e
|
||||||
@@ -75,6 +79,7 @@ floatNonStrictCases = goE
|
|||||||
where bs' = travBs goC bs
|
where bs' = travBs goC bs
|
||||||
goC (LitE l) = pure (LitE l)
|
goC (LitE l) = pure (LitE l)
|
||||||
goC (Var k) = pure (Var k)
|
goC (Var k) = pure (Var k)
|
||||||
|
goC (Con t as) = pure (Con t as)
|
||||||
|
|
||||||
name = state (fromJust . uncons)
|
name = state (fromJust . uncons)
|
||||||
|
|
||||||
@@ -88,10 +93,10 @@ floatNonStrictCases = goE
|
|||||||
-- when provided with a case expr, floatCase will float the case into a
|
-- when provided with a case expr, floatCase will float the case into a
|
||||||
-- supercombinator of its free variables. the sc is returned along with an
|
-- supercombinator of its free variables. the sc is returned along with an
|
||||||
-- expression that calls the sc with the necessary arguments
|
-- expression that calls the sc with the necessary arguments
|
||||||
floatCase :: Name -> Expr' -> (Expr', ScDef')
|
floatCase :: Set Name -> Name -> Expr' -> (Expr', ScDef')
|
||||||
floatCase n c@(Case e as) = (e', sc)
|
floatCase g n c@(Case e as) = (e', sc)
|
||||||
where
|
where
|
||||||
sc = ScDef n caseFrees c
|
sc = ScDef n caseFrees c
|
||||||
caseFrees = S.toList $ freeVariables c
|
caseFrees = S.toList $ freeVariables c `S.difference` g
|
||||||
e' = foldl App (Var n) (Var <$> caseFrees)
|
e' = foldl App (Var n) (Var <$> caseFrees)
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import System.IO (Handle, hPutStrLn)
|
|||||||
import Data.String (IsString)
|
import Data.String (IsString)
|
||||||
import Data.Heap
|
import Data.Heap
|
||||||
import Debug.Trace
|
import Debug.Trace
|
||||||
|
import Core2Core
|
||||||
import Core
|
import Core
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -551,9 +552,10 @@ pop [] = []
|
|||||||
compile :: Program' -> GmState
|
compile :: Program' -> GmState
|
||||||
compile p = GmState c [] [] h g sts
|
compile p = GmState c [] [] h g sts
|
||||||
where
|
where
|
||||||
|
p' = gmPrep p
|
||||||
-- find the entry point and evaluate it
|
-- find the entry point and evaluate it
|
||||||
c = [PushGlobal "main", Eval]
|
c = [PushGlobal "main", Eval]
|
||||||
(h,g) = buildInitialHeap p
|
(h,g) = buildInitialHeap p'
|
||||||
sts = def
|
sts = def
|
||||||
|
|
||||||
type CompiledSC = (Name, Int, Code)
|
type CompiledSC = (Name, Int, Code)
|
||||||
|
|||||||
Reference in New Issue
Block a user