This commit is contained in:
+34
-28
@@ -17,6 +17,7 @@ import Data.Text qualified as T
|
||||
import Gyehoek.Prelude
|
||||
import Debug.Pretty.Simple
|
||||
import qualified Gyehoek.Sexp as S
|
||||
import Data.Monoid
|
||||
|
||||
|
||||
data BlockBuilder
|
||||
@@ -29,35 +30,33 @@ buildBlock = go [] where
|
||||
go acc (Code xs bb) = go (acc ++ xs) bb
|
||||
go acc (Tail t) = Stk.MkBlock acc t
|
||||
|
||||
stackify
|
||||
:: forall es. (GenSym :> es)
|
||||
=> Env -> Exp -> Eff es BlockBuilder
|
||||
|
||||
stackify _ e = error [i|unimplemented exp: #{e}|]
|
||||
|
||||
-- affine
|
||||
_ValName :: Traversal' Val Name
|
||||
_ValName = failing #_ValVar (#_ValImm . #_ImmLabel . #_MkLabel)
|
||||
|
||||
stackifyAbs
|
||||
:: (GenSym :> es)
|
||||
=> Env -> Abs
|
||||
-> Eff es Stk.Routine
|
||||
stackify
|
||||
:: forall es. (GenSym :> es)
|
||||
=> Env -> Exp -> Eff es BlockBuilder
|
||||
|
||||
stackifyAbs g (MkAbs xs _ _) = _
|
||||
stackify _ (ExpContinue (ValVar k) xs) =
|
||||
Code [ ] _
|
||||
|
||||
stackifyVal :: Env -> Val -> Stk.Val
|
||||
stackifyVal g = \case
|
||||
ValImm imm -> Stk.ValImm imm
|
||||
ValVar v -> case regOf g v of
|
||||
Just r -> Stk.ValReg r
|
||||
Nothing -> Stk.ValLabel (MkLabel v)
|
||||
v -> error [i|unimplemented val: #{v}|]
|
||||
stackify _ (ExpPrim p k) = _
|
||||
|
||||
regOf :: Env -> Name -> Maybe Reg
|
||||
regOf g x
|
||||
| x `elem` g.bound || x == g.tail = Just . MkReg $ x
|
||||
| otherwise = Nothing
|
||||
stackify _ e = error [i|unimplemented exp: #{e}|]
|
||||
|
||||
stackifyAbs :: (GenSym :> es) => Env -> Label -> Abs -> Eff es Stk.Routine
|
||||
|
||||
stackifyAbs g lbl (MkAbs xs mtail e) =
|
||||
Stk.MkRoutine lbl . buildBlock . preamble <$> stackify g e
|
||||
where
|
||||
preamble = Code (popArgs $ (mtail ^.. _Just) ++ xs)
|
||||
|
||||
popArgs :: List Name -> List Stk.Instr
|
||||
popArgs = fmap (Stk.Pop . MkReg) . reverse
|
||||
|
||||
pushArgs :: List Name -> List Stk.Instr
|
||||
pushArgs = _
|
||||
|
||||
|
||||
|
||||
@@ -73,12 +72,19 @@ emptyEnv = MkEnv
|
||||
|
||||
|
||||
|
||||
stackifyProgram :: GenSym :> es => HoistedProgram -> Eff es Stk.Program
|
||||
stackifyProgram p = do
|
||||
let liveness = _
|
||||
let g = emptyEnv
|
||||
(_,p') <- runStackify $ emitRoutine =<< stackifyLambda g "start" e
|
||||
pure p'
|
||||
stackifyProgram
|
||||
:: forall es. GenSym :> es
|
||||
=> HoistedProgram -> Eff es Stk.Program
|
||||
stackifyProgram p = p
|
||||
& ifoldMapOf
|
||||
((#bindings . itraversed)
|
||||
<> (#body . to (H.singleton "start" . AbsLambda) . itraversed))
|
||||
(\l -> Ap . stackifyBinding l)
|
||||
& getAp
|
||||
where
|
||||
g = emptyEnv
|
||||
stackifyBinding lbl ab =
|
||||
Stk.MkProgram . H.singleton lbl <$> stackifyAbs @es g lbl ab
|
||||
|
||||
p :: HoistedProgram
|
||||
p = [cps|
|
||||
|
||||
@@ -76,7 +76,7 @@ data Instr
|
||||
= Pop Reg
|
||||
| Push Val
|
||||
| Load Reg Int
|
||||
| Prim (Prim Val)
|
||||
| Prim Reg (Prim Val)
|
||||
deriving stock (Show, Generic, Data)
|
||||
deriving anyclass (NFData)
|
||||
|
||||
@@ -99,7 +99,7 @@ instance S.DatumIso Instr where
|
||||
$ S.With (S.headTagged1 "pop!" S.datumIso >>>)
|
||||
$ S.With (S.headTagged1 "push!" S.datumIso >>>)
|
||||
$ S.With (S.headTagged2 "load" S.datumIso S.datumIso >>>)
|
||||
$ S.With (S.headTagged1 "prim" S.datumIso >>>)
|
||||
$ S.With (S.headTagged2 "prim" S.datumIso S.datumIso >>>)
|
||||
$ S.End
|
||||
where
|
||||
|
||||
|
||||
Reference in New Issue
Block a user