oh boy (pack)
This commit is contained in:
31
app/Main.hs
31
app/Main.hs
@@ -44,7 +44,7 @@ options = RLPCOptions
|
|||||||
<> value EvaluatorGM
|
<> value EvaluatorGM
|
||||||
<> help "the intermediate layer used to model evaluation"
|
<> help "the intermediate layer used to model evaluation"
|
||||||
)
|
)
|
||||||
<*> some (argument str (metavar "FILES..."))
|
<*> some (argument str $ metavar "FILES...")
|
||||||
where
|
where
|
||||||
infixr 9 #
|
infixr 9 #
|
||||||
f # x = f x
|
f # x = f x
|
||||||
@@ -62,6 +62,7 @@ debugFlagReader :: ReadM DebugFlag
|
|||||||
debugFlagReader = maybeReader $ \case
|
debugFlagReader = maybeReader $ \case
|
||||||
"dump-eval" -> Just DDumpEval
|
"dump-eval" -> Just DDumpEval
|
||||||
"dump-opts" -> Just DDumpOpts
|
"dump-opts" -> Just DDumpOpts
|
||||||
|
"dump-ast" -> Just DDumpAST
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
|
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
@@ -79,13 +80,21 @@ main = do
|
|||||||
driver :: RLPCIO CompilerError ()
|
driver :: RLPCIO CompilerError ()
|
||||||
driver = sequence_
|
driver = sequence_
|
||||||
[ dshowFlags
|
[ dshowFlags
|
||||||
|
, ddumpAST
|
||||||
, ddumpEval
|
, ddumpEval
|
||||||
]
|
]
|
||||||
|
|
||||||
dshowFlags :: RLPCIO CompilerError ()
|
dshowFlags :: RLPCIO CompilerError ()
|
||||||
dshowFlags = whenFlag flagDDumpOpts do
|
dshowFlags = whenFlag flagDDumpOpts do
|
||||||
ask >>= liftIO . print
|
ask >>= liftIO . print
|
||||||
liftIO $ exitSuccess
|
|
||||||
|
ddumpAST :: RLPCIO CompilerError ()
|
||||||
|
ddumpAST = whenFlag flagDDumpAST $ forFiles_ \o f -> do
|
||||||
|
liftIO $ withFile f ReadMode $ \h -> do
|
||||||
|
s <- hGetContents h
|
||||||
|
case parseProg o s of
|
||||||
|
Right (a,_) -> hPutStrLn stderr $ show a
|
||||||
|
Left e -> error "todo errors lol"
|
||||||
|
|
||||||
ddumpEval :: RLPCIO CompilerError ()
|
ddumpEval :: RLPCIO CompilerError ()
|
||||||
ddumpEval = whenFlag flagDDumpEval do
|
ddumpEval = whenFlag flagDDumpEval do
|
||||||
@@ -104,11 +113,6 @@ ddumpEval = whenFlag flagDDumpEval do
|
|||||||
Just f -> liftIO $ withFile f WriteMode $ dumpEval a
|
Just f -> liftIO $ withFile f WriteMode $ dumpEval a
|
||||||
Nothing -> liftIO $ dumpEval a stderr
|
Nothing -> liftIO $ dumpEval a stderr
|
||||||
|
|
||||||
parseProg :: RLPCOptions
|
|
||||||
-> String
|
|
||||||
-> Either SrcError (Program, [SrcError])
|
|
||||||
parseProg o = evalRLPC o . (lexCore >=> parseCoreProg)
|
|
||||||
|
|
||||||
-- choose the appropriate model based on the compiler opts
|
-- choose the appropriate model based on the compiler opts
|
||||||
chooseEval = do
|
chooseEval = do
|
||||||
ev <- view rlpcEvaluator
|
ev <- view rlpcEvaluator
|
||||||
@@ -117,3 +121,16 @@ ddumpEval = whenFlag flagDDumpEval do
|
|||||||
EvaluatorTI -> v TI.hdbgProg
|
EvaluatorTI -> v TI.hdbgProg
|
||||||
where v f p h = f p h *> pure ()
|
where v f p h = f p h *> pure ()
|
||||||
|
|
||||||
|
parseProg :: RLPCOptions
|
||||||
|
-> String
|
||||||
|
-> Either SrcError (Program, [SrcError])
|
||||||
|
parseProg o = evalRLPC o . (lexCore >=> parseCoreProg)
|
||||||
|
|
||||||
|
forFiles_ :: (Monad m)
|
||||||
|
=> (RLPCOptions -> FilePath -> RLPCT e m a)
|
||||||
|
-> RLPCT e m ()
|
||||||
|
forFiles_ k = do
|
||||||
|
fs <- view rlpcInputFiles
|
||||||
|
o <- ask
|
||||||
|
forM_ fs (k o)
|
||||||
|
|
||||||
|
|||||||
@@ -103,10 +103,9 @@ Core Transition Rules
|
|||||||
& m
|
& m
|
||||||
}
|
}
|
||||||
|
|
||||||
#. If the top of the stack is in WHNF (currently this just means a number) is on
|
#. If the top of the stack is in WHNF is on top of the stack, :code:`Unwind`
|
||||||
top of the stack, :code:`Unwind` considers evaluation complete. In the case
|
considers evaluation complete. In the case where the dump is **not** empty,
|
||||||
where the dump is **not** empty, the instruction queue and stack is restored
|
the instruction queue and stack is restored from the top.
|
||||||
from the top.
|
|
||||||
|
|
||||||
.. math::
|
.. math::
|
||||||
\gmrule
|
\gmrule
|
||||||
@@ -126,6 +125,26 @@ Core Transition Rules
|
|||||||
& m
|
& m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#. Consider constructors to be in WHNF
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\gmrule
|
||||||
|
{ \mathtt{Unwind} : \nillist
|
||||||
|
& a : s
|
||||||
|
& \langle i', s' \rangle : d
|
||||||
|
& h
|
||||||
|
\begin{bmatrix}
|
||||||
|
a : \mathtt{NConstr} \; t \; v
|
||||||
|
\end{bmatrix}
|
||||||
|
& m
|
||||||
|
}
|
||||||
|
{ i'
|
||||||
|
& a : s'
|
||||||
|
& d
|
||||||
|
& h
|
||||||
|
& m
|
||||||
|
}
|
||||||
|
|
||||||
#. Bulding on the previous rule, in the case where the dump **is** empty, leave
|
#. Bulding on the previous rule, in the case where the dump **is** empty, leave
|
||||||
the machine in a halt state (i.e. with an empty instruction queue).
|
the machine in a halt state (i.e. with an empty instruction queue).
|
||||||
|
|
||||||
@@ -402,7 +421,77 @@ Core Transition Rules
|
|||||||
& m
|
& m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#. Deconstruct a constructor
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\gmrule
|
||||||
|
{ \mathtt{Split} \; n : i
|
||||||
|
& a : s
|
||||||
|
& d
|
||||||
|
& h
|
||||||
|
\begin{bmatrix}
|
||||||
|
a : \mathtt{NConstr} \; t \; [a_1,\ldots,a_n]
|
||||||
|
\end{bmatrix}
|
||||||
|
& m
|
||||||
|
}
|
||||||
|
{ i
|
||||||
|
& a_1 : \ldots a_n : s
|
||||||
|
& d
|
||||||
|
& h
|
||||||
|
& m
|
||||||
|
}
|
||||||
|
|
||||||
|
#. Allow constructors to behave as functions: look a constructor up in the
|
||||||
|
environment, and if push the address if found
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\gmrule
|
||||||
|
{ \mathtt{PushConstr} \; p_{t,n} : i
|
||||||
|
& s
|
||||||
|
& d
|
||||||
|
& h
|
||||||
|
& m
|
||||||
|
\begin{bmatrix}
|
||||||
|
p_{t,n} : a
|
||||||
|
\end{bmatrix}
|
||||||
|
}
|
||||||
|
{ i
|
||||||
|
& a : s
|
||||||
|
& d
|
||||||
|
& h
|
||||||
|
& m
|
||||||
|
}
|
||||||
|
|
||||||
|
#. Expanding upon the previous rule: in the case that no such address is found,
|
||||||
|
update the environment
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
\gmrule
|
||||||
|
{ \mathtt{PushConstr} \; p_{t,n} : i
|
||||||
|
& s
|
||||||
|
& d
|
||||||
|
& h
|
||||||
|
& m
|
||||||
|
}
|
||||||
|
{ i
|
||||||
|
& a : s
|
||||||
|
& d
|
||||||
|
& h
|
||||||
|
\begin{bmatrix}
|
||||||
|
a : g_{t,n}
|
||||||
|
\end{bmatrix}
|
||||||
|
& m
|
||||||
|
\begin{bmatrix}
|
||||||
|
p_{t,n} : a
|
||||||
|
\end{bmatrix}
|
||||||
|
\\
|
||||||
|
\SetCell[c=6]{c}
|
||||||
|
\text{where $p_{t,n}$ is a non-conflicting string rep. of
|
||||||
|
$\mathtt{Pack}\{t,n\}$,} \\
|
||||||
|
\SetCell[c=6]{c}
|
||||||
|
\text{and $g_{t,n} = \mathtt{NGlobal} \; n \;
|
||||||
|
[\mathtt{Pack} \; t \; n, \mathtt{Update} \; 0, \mathtt{Unwind}]$}
|
||||||
|
}
|
||||||
|
|
||||||
***************
|
***************
|
||||||
Extension Rules
|
Extension Rules
|
||||||
@@ -436,7 +525,7 @@ Extension Rules
|
|||||||
n' : a
|
n' : a
|
||||||
\end{bmatrix}
|
\end{bmatrix}
|
||||||
\\
|
\\
|
||||||
\SetCell[c=5]{c}
|
\SetCell[c=6]{c}
|
||||||
\text{where $n'$ is the base-10 string rep. of $n$}
|
\text{where $n'$ is the base-10 string rep. of $n$}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,10 @@ This module implements the toolset common to the entire compiler, most notably
|
|||||||
errors and the family of RLPC monads.
|
errors and the family of RLPC monads.
|
||||||
-}
|
-}
|
||||||
{-# LANGUAGE GeneralisedNewtypeDeriving, StandaloneDeriving #-}
|
{-# LANGUAGE GeneralisedNewtypeDeriving, StandaloneDeriving #-}
|
||||||
|
{-# LANGUAGE FunctionalDependencies #-}
|
||||||
{-# LANGUAGE TemplateHaskell #-}
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
-- only used for mtl instances
|
||||||
|
{-# LANGUAGE UndecidableInstances #-}
|
||||||
{-# LANGUAGE DeriveGeneric, DerivingStrategies, DerivingVia #-}
|
{-# LANGUAGE DeriveGeneric, DerivingStrategies, DerivingVia #-}
|
||||||
module Compiler.RLPC
|
module Compiler.RLPC
|
||||||
( RLPC
|
( RLPC
|
||||||
@@ -29,12 +32,15 @@ module Compiler.RLPC
|
|||||||
, whenFlag
|
, whenFlag
|
||||||
, flagDDumpEval
|
, flagDDumpEval
|
||||||
, flagDDumpOpts
|
, flagDDumpOpts
|
||||||
|
, flagDDumpAST
|
||||||
|
, def
|
||||||
)
|
)
|
||||||
|
|
||||||
where
|
where
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
import Control.Arrow ((>>>))
|
import Control.Arrow ((>>>))
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
|
import Control.Monad.State (MonadState(state))
|
||||||
import Control.Monad.Errorful
|
import Control.Monad.Errorful
|
||||||
import Data.Functor.Identity
|
import Data.Functor.Identity
|
||||||
import Data.Default.Class
|
import Data.Default.Class
|
||||||
@@ -51,10 +57,18 @@ import Lens.Micro.TH
|
|||||||
newtype RLPCT e m a = RLPCT {
|
newtype RLPCT e m a = RLPCT {
|
||||||
runRLPCT :: ReaderT RLPCOptions (ErrorfulT e m) a
|
runRLPCT :: ReaderT RLPCOptions (ErrorfulT e m) a
|
||||||
}
|
}
|
||||||
|
-- TODO: incorrect ussage of MonadReader. RLPC should have its own
|
||||||
|
-- environment access functions
|
||||||
deriving (Functor, Applicative, Monad, MonadReader RLPCOptions)
|
deriving (Functor, Applicative, Monad, MonadReader RLPCOptions)
|
||||||
|
|
||||||
deriving instance (MonadIO m) => MonadIO (RLPCT e m)
|
deriving instance (MonadIO m) => MonadIO (RLPCT e m)
|
||||||
|
|
||||||
|
instance MonadTrans (RLPCT e) where
|
||||||
|
lift = RLPCT . lift . lift
|
||||||
|
|
||||||
|
instance (MonadState s m) => MonadState s (RLPCT e m) where
|
||||||
|
state = lift . state
|
||||||
|
|
||||||
type RLPC e = RLPCT e Identity
|
type RLPC e = RLPCT e Identity
|
||||||
|
|
||||||
type RLPCIO e = RLPCT e IO
|
type RLPCIO e = RLPCT e IO
|
||||||
@@ -119,6 +133,7 @@ type DebugOpts = HashSet DebugFlag
|
|||||||
|
|
||||||
data DebugFlag = DDumpEval
|
data DebugFlag = DDumpEval
|
||||||
| DDumpOpts
|
| DDumpOpts
|
||||||
|
| DDumpAST
|
||||||
deriving (Show, Eq, Generic)
|
deriving (Show, Eq, Generic)
|
||||||
|
|
||||||
-- deriving (Hashable)
|
-- deriving (Hashable)
|
||||||
@@ -143,3 +158,6 @@ flagDDumpEval = flagGetter DDumpEval
|
|||||||
flagDDumpOpts :: SimpleGetter RLPCOptions Bool
|
flagDDumpOpts :: SimpleGetter RLPCOptions Bool
|
||||||
flagDDumpOpts = flagGetter DDumpOpts
|
flagDDumpOpts = flagGetter DDumpOpts
|
||||||
|
|
||||||
|
flagDDumpAST :: SimpleGetter RLPCOptions Bool
|
||||||
|
flagDDumpAST = flagGetter DDumpAST
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ $octit = 0-7
|
|||||||
$hexit = [0-9 A-F a-f]
|
$hexit = [0-9 A-F a-f]
|
||||||
$namechar = [$alpha $digit \' \#]
|
$namechar = [$alpha $digit \' \#]
|
||||||
$symchar = [$symbol \:]
|
$symchar = [$symbol \:]
|
||||||
|
$nonwhite = $printable # $white
|
||||||
$nl = [\n\r]
|
$nl = [\n\r]
|
||||||
$white_no_nl = $white # $nl
|
$white_no_nl = $white # $nl
|
||||||
|
|
||||||
@@ -68,6 +69,7 @@ rlp :-
|
|||||||
"}" { constTok TokenRBrace }
|
"}" { constTok TokenRBrace }
|
||||||
";" { constTok TokenSemicolon }
|
";" { constTok TokenSemicolon }
|
||||||
"," { constTok TokenComma }
|
"," { constTok TokenComma }
|
||||||
|
"{-#" { constTok TokenLPragma `andBegin` pragma }
|
||||||
|
|
||||||
"let" { constTok TokenLet }
|
"let" { constTok TokenLet }
|
||||||
"letrec" { constTok TokenLetrec }
|
"letrec" { constTok TokenLetrec }
|
||||||
@@ -94,6 +96,19 @@ rlp :-
|
|||||||
\n { skip }
|
\n { skip }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<pragma>
|
||||||
|
{
|
||||||
|
"#-}" { constTok TokenRPragma `andBegin` 0 }
|
||||||
|
"{" { constTok TokenLBrace }
|
||||||
|
"}" { constTok TokenRBrace }
|
||||||
|
";" { constTok TokenSemicolon }
|
||||||
|
|
||||||
|
$white { skip }
|
||||||
|
\n { skip }
|
||||||
|
|
||||||
|
$nonwhite+ { lexWith TokenWord }
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
data Located a = Located Int Int Int a
|
data Located a = Located Int Int Int a
|
||||||
deriving Show
|
deriving Show
|
||||||
@@ -123,6 +138,9 @@ data CoreToken = TokenLet
|
|||||||
| TokenLBrace
|
| TokenLBrace
|
||||||
| TokenRBrace
|
| TokenRBrace
|
||||||
| TokenSemicolon
|
| TokenSemicolon
|
||||||
|
| TokenLPragma
|
||||||
|
| TokenRPragma
|
||||||
|
| TokenWord String
|
||||||
| TokenEOF
|
| TokenEOF
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
@@ -135,6 +153,7 @@ data SrcError = SrcError
|
|||||||
|
|
||||||
data SrcErrorType = SrcErrLexical String
|
data SrcErrorType = SrcErrLexical String
|
||||||
| SrcErrParse
|
| SrcErrParse
|
||||||
|
| SrcErrUnknownPragma Name
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
type Lexer = AlexInput -> Int -> Alex (Located CoreToken)
|
type Lexer = AlexInput -> Int -> Alex (Located CoreToken)
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import Data.Default.Class (def)
|
|||||||
varsym { Located _ _ _ (TokenVarSym $$) }
|
varsym { Located _ _ _ (TokenVarSym $$) }
|
||||||
conname { Located _ _ _ (TokenConName $$) }
|
conname { Located _ _ _ (TokenConName $$) }
|
||||||
consym { Located _ _ _ (TokenConSym $$) }
|
consym { Located _ _ _ (TokenConSym $$) }
|
||||||
|
word { Located _ _ _ (TokenWord $$) }
|
||||||
'λ' { Located _ _ _ TokenLambda }
|
'λ' { Located _ _ _ TokenLambda }
|
||||||
'->' { Located _ _ _ TokenArrow }
|
'->' { Located _ _ _ TokenArrow }
|
||||||
'=' { Located _ _ _ TokenEquals }
|
'=' { Located _ _ _ TokenEquals }
|
||||||
@@ -51,6 +52,8 @@ import Data.Default.Class (def)
|
|||||||
')' { Located _ _ _ TokenRParen }
|
')' { Located _ _ _ TokenRParen }
|
||||||
'{' { Located _ _ _ TokenLBrace }
|
'{' { Located _ _ _ TokenLBrace }
|
||||||
'}' { Located _ _ _ TokenRBrace }
|
'}' { Located _ _ _ TokenRBrace }
|
||||||
|
'{-#' { Located _ _ _ TokenLPragma }
|
||||||
|
'#-}' { Located _ _ _ TokenRPragma }
|
||||||
';' { Located _ _ _ TokenSemicolon }
|
';' { Located _ _ _ TokenSemicolon }
|
||||||
eof { Located _ _ _ TokenEOF }
|
eof { Located _ _ _ TokenEOF }
|
||||||
|
|
||||||
@@ -122,8 +125,16 @@ Expr1 :: { Expr }
|
|||||||
Expr1 : litint { IntE $1 }
|
Expr1 : litint { IntE $1 }
|
||||||
| Id { Var $1 }
|
| Id { Var $1 }
|
||||||
| PackCon { $1 }
|
| PackCon { $1 }
|
||||||
|
| ExprPragma { $1 }
|
||||||
| '(' Expr ')' { $2 }
|
| '(' Expr ')' { $2 }
|
||||||
|
|
||||||
|
ExprPragma :: { Expr }
|
||||||
|
ExprPragma : '{-#' Words '#-}' {% exprPragma $2 }
|
||||||
|
|
||||||
|
Words :: { [String] }
|
||||||
|
Words : word Words { $1 : $2 }
|
||||||
|
| word { [$1] }
|
||||||
|
|
||||||
PackCon :: { Expr }
|
PackCon :: { Expr }
|
||||||
PackCon : pack '{' litint ',' litint '}' { Con $3 $5 }
|
PackCon : pack '{' litint ',' litint '}' { Con $3 $5 }
|
||||||
|
|
||||||
@@ -148,6 +159,7 @@ Con : '(' consym ')' { $2 }
|
|||||||
| conname { $1 }
|
| conname { $1 }
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
parseError :: [Located CoreToken] -> RLPC SrcError a
|
parseError :: [Located CoreToken] -> RLPC SrcError a
|
||||||
parseError (Located y x l _ : _) = addFatal err
|
parseError (Located y x l _ : _) = addFatal err
|
||||||
where err = SrcError
|
where err = SrcError
|
||||||
@@ -165,5 +177,17 @@ parseTmp = do
|
|||||||
where
|
where
|
||||||
parse = evalRLPC def . (lexCore >=> parseCore)
|
parse = evalRLPC def . (lexCore >=> parseCore)
|
||||||
|
|
||||||
|
exprPragma :: [String] -> RLPC SrcError Expr
|
||||||
|
exprPragma ("AST" : e) = astPragma e
|
||||||
|
exprPragma _ = addFatal err
|
||||||
|
where err = SrcError
|
||||||
|
{ _errSpan = (0,0,0) -- TODO: span
|
||||||
|
, _errSeverity = Warning
|
||||||
|
, _errDiagnostic = SrcErrUnknownPragma "" -- TODO: missing pragma
|
||||||
|
}
|
||||||
|
|
||||||
|
astPragma :: [String] -> RLPC SrcError Expr
|
||||||
|
astPragma = pure . read . unwords
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ data Expr = Var Name
|
|||||||
| Lam [Name] Expr
|
| Lam [Name] Expr
|
||||||
| App Expr Expr
|
| App Expr Expr
|
||||||
| IntE Int
|
| IntE Int
|
||||||
deriving (Show, Lift, Eq)
|
deriving (Show, Read, Lift, Eq)
|
||||||
|
|
||||||
infixl 2 :$
|
infixl 2 :$
|
||||||
pattern (:$) :: Expr -> Expr -> Expr
|
pattern (:$) :: Expr -> Expr -> Expr
|
||||||
@@ -47,7 +47,7 @@ pattern f :$ x = App f x
|
|||||||
{-# COMPLETE Binding :: Binding #-}
|
{-# COMPLETE Binding :: Binding #-}
|
||||||
{-# COMPLETE (:=) :: Binding #-}
|
{-# COMPLETE (:=) :: Binding #-}
|
||||||
data Binding = Binding Name Expr
|
data Binding = Binding Name Expr
|
||||||
deriving (Show, Lift, Eq)
|
deriving (Show, Read, Lift, Eq)
|
||||||
|
|
||||||
infixl 1 :=
|
infixl 1 :=
|
||||||
pattern (:=) :: Name -> Expr -> Binding
|
pattern (:=) :: Name -> Expr -> Binding
|
||||||
@@ -55,10 +55,10 @@ pattern k := v = Binding k v
|
|||||||
|
|
||||||
data Rec = Rec
|
data Rec = Rec
|
||||||
| NonRec
|
| NonRec
|
||||||
deriving (Show, Eq, Lift)
|
deriving (Show, Read, Eq, Lift)
|
||||||
|
|
||||||
data Alter = Alter Tag [Name] Expr
|
data Alter = Alter Tag [Name] Expr
|
||||||
deriving (Show, Lift, Eq)
|
deriving (Show, Read, Lift, Eq)
|
||||||
|
|
||||||
type Name = String
|
type Name = String
|
||||||
type Tag = Int
|
type Tag = Int
|
||||||
|
|||||||
47
src/GM.hs
47
src/GM.hs
@@ -163,8 +163,18 @@ step st = case head (st ^. gmCode) of
|
|||||||
Mul -> mulI
|
Mul -> mulI
|
||||||
Div -> divI
|
Div -> divI
|
||||||
Split n -> splitI n
|
Split n -> splitI n
|
||||||
|
Pack t n -> packI t n
|
||||||
where
|
where
|
||||||
|
|
||||||
|
packI :: Tag -> Int -> GmState
|
||||||
|
packI t n = st
|
||||||
|
& advanceCode
|
||||||
|
& gmStack %~ (a:)
|
||||||
|
& gmHeap .~ h'
|
||||||
|
where
|
||||||
|
(as,s) = splitAt n (st ^. gmStack)
|
||||||
|
(h',a) = alloc (st ^. gmHeap) $ NConstr t as
|
||||||
|
|
||||||
pushGlobalI :: Name -> GmState
|
pushGlobalI :: Name -> GmState
|
||||||
pushGlobalI k = st
|
pushGlobalI k = st
|
||||||
& advanceCode
|
& advanceCode
|
||||||
@@ -178,7 +188,23 @@ step st = case head (st ^. gmCode) of
|
|||||||
& fromMaybe (error $ "undefined var: " <> show k)
|
& fromMaybe (error $ "undefined var: " <> show k)
|
||||||
|
|
||||||
pushConstrI :: Tag -> Int -> GmState
|
pushConstrI :: Tag -> Int -> GmState
|
||||||
pushConstrI = undefined
|
pushConstrI t n = st
|
||||||
|
& advanceCode
|
||||||
|
& gmStack %~ (a:)
|
||||||
|
& gmEnv .~ m'
|
||||||
|
& gmHeap .~ h'
|
||||||
|
where
|
||||||
|
s = st ^. gmStack
|
||||||
|
m = st ^. gmEnv
|
||||||
|
h = st ^. gmHeap
|
||||||
|
(a,m',h') = case lookupC t n m of
|
||||||
|
-- address found in env; no need to update env or heap
|
||||||
|
Just aa -> (aa,m,h)
|
||||||
|
Nothing -> (aa,mm,hh)
|
||||||
|
where
|
||||||
|
(hh,aa) = alloc h (NGlobal n c)
|
||||||
|
c = [Pack t n, Update 0, Unwind]
|
||||||
|
mm = (ConstrKey t n, aa) : m
|
||||||
|
|
||||||
-- Extension Rules 1,2 (sharing)
|
-- Extension Rules 1,2 (sharing)
|
||||||
pushIntI :: Int -> GmState
|
pushIntI :: Int -> GmState
|
||||||
@@ -339,6 +365,19 @@ step st = case head (st ^. gmCode) of
|
|||||||
-- leave the stack as is
|
-- leave the stack as is
|
||||||
[] -> ([], s, [])
|
[] -> ([], s, [])
|
||||||
|
|
||||||
|
NConstr t n -> st
|
||||||
|
& gmCode .~ i'
|
||||||
|
& gmStack .~ s'
|
||||||
|
& gmDump .~ d'
|
||||||
|
where
|
||||||
|
(i',s',d') = case st ^. gmDump of
|
||||||
|
-- if the dump is non-empty, restore the instruction
|
||||||
|
-- queue and stack, and pop the dump
|
||||||
|
((ii,ss):d) -> (ii,a:ss,d)
|
||||||
|
-- if the dump is empty, clear the instruction queue and
|
||||||
|
-- leave the stack as is
|
||||||
|
[] -> ([], s, [])
|
||||||
|
|
||||||
NAp f _ -> st
|
NAp f _ -> st
|
||||||
-- leave the Unwind instr; continue unwinding
|
-- leave the Unwind instr; continue unwinding
|
||||||
& gmStack %~ (f:)
|
& gmStack %~ (f:)
|
||||||
@@ -537,8 +576,7 @@ buildInitialHeap (Program ss) = mapAccumL allocateSc mempty compiledScs
|
|||||||
compileBinder (_ := v, a) = compileC g' v <> [Update a]
|
compileBinder (_ := v, a) = compileC g' v <> [Update a]
|
||||||
|
|
||||||
-- kinda evil; better system eventually
|
-- kinda evil; better system eventually
|
||||||
compileC g (Con t n) = [PushGlobal p]
|
compileC g (Con t n) = [PushConstr t n]
|
||||||
where p = idPack t n
|
|
||||||
|
|
||||||
compileC _ _ = error "yet to be implemented!"
|
compileC _ _ = error "yet to be implemented!"
|
||||||
|
|
||||||
@@ -729,11 +767,14 @@ showNodeAtP p st a = case hLookup a h of
|
|||||||
g = st ^. gmEnv
|
g = st ^. gmEnv
|
||||||
name = case lookup a (swap <$> g) of
|
name = case lookup a (swap <$> g) of
|
||||||
Just (NameKey n) -> n
|
Just (NameKey n) -> n
|
||||||
|
Just (ConstrKey t n) -> idPack t n
|
||||||
_ -> errTxtInvalidAddress
|
_ -> errTxtInvalidAddress
|
||||||
Just (NAp f x) -> pprec $ showNodeAtP (p+1) st f <+> showNodeAtP (p+1) st x
|
Just (NAp f x) -> pprec $ showNodeAtP (p+1) st f <+> showNodeAtP (p+1) st x
|
||||||
where pprec = maybeParens (p > 0)
|
where pprec = maybeParens (p > 0)
|
||||||
Just (NInd a') -> pprec $ "NInd -> " <> showNodeAtP (p+1) st a'
|
Just (NInd a') -> pprec $ "NInd -> " <> showNodeAtP (p+1) st a'
|
||||||
where pprec = maybeParens (p > 0)
|
where pprec = maybeParens (p > 0)
|
||||||
|
Just (NConstr t as) -> pprec $ "NConstr" <+> int t <+> text (show as)
|
||||||
|
where pprec = maybeParens (p > 0)
|
||||||
Just NUninitialised -> "<uninitialised>"
|
Just NUninitialised -> "<uninitialised>"
|
||||||
Nothing -> errTxtInvalidAddress
|
Nothing -> errTxtInvalidAddress
|
||||||
where h = st ^. gmHeap
|
where h = st ^. gmHeap
|
||||||
|
|||||||
Reference in New Issue
Block a user