strict arith

This commit is contained in:
crumbtoo
2023-12-04 13:50:48 -07:00
parent a3a38cb256
commit 5c3b7c2c30
3 changed files with 87 additions and 6 deletions

View File

@@ -147,6 +147,29 @@ Core Transition Rules
& m & m
} }
#. Again, building on the previous rules, this rule makes the machine consider
unapplied supercombinators to be in WHNF
.. math::
\gmrule
{ \mathtt{Unwind} : \nillist
& a_0 : \ldots : a_n : \nillist
& \langle i, s \rangle : d
& h
\begin{bmatrix}
a_0 : \mathtt{NGlobal} \; k \; c
\end{bmatrix}
& m
}
{ i
& a_n : s
& d
& h
& m \\
\SetCell[c=2]{c}
\text{when $n < k$}
}
#. If an application is on top of the stack, :code:`Unwind` continues unwinding #. If an application is on top of the stack, :code:`Unwind` continues unwinding
.. math:: .. math::
@@ -339,7 +362,7 @@ Core Transition Rules
\end{bmatrix} \end{bmatrix}
& m & m
} }
*************** ***************
Extension Rules Extension Rules
*************** ***************

View File

@@ -37,14 +37,14 @@ data Expr = Var Name
| Lam [Name] Expr | Lam [Name] Expr
| App Expr Expr | App Expr Expr
| IntE Int | IntE Int
deriving (Show, Lift) deriving (Show, Lift, Eq)
infixl 2 :$ infixl 2 :$
pattern (:$) :: Expr -> Expr -> Expr pattern (:$) :: Expr -> Expr -> Expr
pattern f :$ x = App f x pattern f :$ x = App f x
data Binding = Binding Name Expr data Binding = Binding Name Expr
deriving (Show, Lift) deriving (Show, Lift, Eq)
infixl 1 := infixl 1 :=
pattern (:=) :: Name -> Expr -> Binding pattern (:=) :: Name -> Expr -> Binding
@@ -55,12 +55,12 @@ data Rec = Rec
deriving (Show, Eq, Lift) deriving (Show, Eq, Lift)
data Alter = Alter Int [Name] Expr data Alter = Alter Int [Name] Expr
deriving (Show, Lift) deriving (Show, Lift, Eq)
type Name = String type Name = String
data ScDef = ScDef Name [Name] Expr data ScDef = ScDef Name [Name] Expr
deriving (Show, Lift) deriving (Show, Lift, Eq)
data Module = Module (Maybe (Name, [Name])) Program data Module = Module (Maybe (Name, [Name])) Program
deriving (Show, Lift) deriving (Show, Lift)

View File

@@ -310,6 +310,15 @@ step st = case head (st ^. gmCode) of
NAp f x -> st NAp f x -> st
-- leave the Unwind instr; continue unwinding -- leave the Unwind instr; continue unwinding
& gmStack %~ (f:) & gmStack %~ (f:)
NGlobal k c
| n < k -> st
& gmCode .~ i
& gmStack .~ s
& gmDump .~ d
where
((i,s) : d) = st ^. gmDump
n = st ^. gmStack & length
-- assumes length s < d (i.e. enough args have been supplied) -- assumes length s < d (i.e. enough args have been supplied)
NGlobal n c -> st NGlobal n c -> st
-- 'jump' to global's code by replacing our current -- 'jump' to global's code by replacing our current
@@ -348,6 +357,7 @@ primitive1 box unbox f st
& f & f
& box (st & gmStack .~ s) & box (st & gmStack .~ s)
& advanceCode & advanceCode
& gmStats . stsPrimReductions %~ succ
where where
putNewStack = gmStack .~ s putNewStack = gmStack .~ s
(a:s) = st ^. gmStack (a:s) = st ^. gmStack
@@ -361,6 +371,7 @@ primitive2 :: (GmState -> b -> GmState) -- boxing function
primitive2 box unbox f st primitive2 box unbox f st
= st' = st'
& advanceCode & advanceCode
& gmStats . stsPrimReductions %~ succ
where where
(ax:ay:s) = st ^. gmStack (ax:ay:s) = st ^. gmStack
putNewStack = gmStack .~ s putNewStack = gmStack .~ s
@@ -434,10 +445,11 @@ buildInitialHeap (Program ss) = mapAccumL allocateSc mempty compiledScs
-- << [ref/compileSc] -- << [ref/compileSc]
compileR :: Env -> Expr -> Code compileR :: Env -> Expr -> Code
compileR g e = compileC g e <> [Update d, Pop d, Unwind] compileR g e = compileE g e <> [Update d, Pop d, Unwind]
where where
d = length g d = length g
-- compile an expression in a lazy context
compileC :: Env -> Expr -> Code compileC :: Env -> Expr -> Code
compileC g (Var k) compileC g (Var k)
| k `elem` domain = [Push n] | k `elem` domain = [Push n]
@@ -483,6 +495,52 @@ buildInitialHeap (Program ss) = mapAccumL allocateSc mempty compiledScs
compileBinder :: (Binding, Int) -> Code compileBinder :: (Binding, Int) -> Code
compileBinder (k := v, a) = compileC g' v <> [Update a] compileBinder (k := v, a) = compileC g' v <> [Update a]
-- compile an expression in a strict context such that a pointer to the
-- expression is left on top of the stack in WHNF
compileE :: Env -> Expr -> Code
compileE g (IntE n) = [PushInt n]
compileE g (Let NonRec bs e) =
-- we use compileE instead of compileC
mconcat binders <> compileE g' e <> [Slide d]
where
d = length bs
(g',binders) = mapAccumL compileBinder (argOffset d g) addressed
-- kinda gross. revisit this
addressed = bs `zip` reverse [0 .. d-1]
compileBinder :: Env -> (Binding, Int) -> (Env, Code)
compileBinder m (k := v, a) = (m',c)
where
m' = (k,a) : m
-- make note that we use m rather than m'!
c = compileC m v
compileE g (Let Rec bs e) =
Alloc d : initialisers <> body <> [Slide d]
where
d = length bs
g' = fmap toEnv addressed ++ argOffset d g
toEnv (k := _, a) = (k,a)
-- kinda gross. revisit this
addressed = bs `zip` reverse [0 .. d-1]
initialisers = mconcat $ compileBinder <$> addressed
-- we use compileE instead of compileC
body = compileE g' e
-- we use compileE instead of compileC
compileBinder :: (Binding, Int) -> Code
compileBinder (k := v, a) = compileC g' v <> [Update a]
-- special cases for prim functions
compileE g ("negate#" :$ a) = compileE g a <> [Neg]
compileE g ("+#" :$ a :$ b) = compileE g a <> compileE g b <> [Add]
compileE g ("-#" :$ a :$ b) = compileE g a <> compileE g b <> [Sub]
compileE g ("*#" :$ a :$ b) = compileE g a <> compileE g b <> [Mul]
compileE g ("/#" :$ a :$ b) = compileE g a <> compileE g b <> [Div]
compileE g e = compileC g e ++ [Eval]
-- | offset each address in the environment by n -- | offset each address in the environment by n
argOffset :: Int -> Env -> Env argOffset :: Int -> Env -> Env
argOffset n = each . _2 %~ (+n) argOffset n = each . _2 %~ (+n)