g-machine mark 1 hooray
This commit is contained in:
38
app/Main.hs
38
app/Main.hs
@@ -10,6 +10,7 @@ import System.IO
|
|||||||
import System.Exit (exitSuccess)
|
import System.Exit (exitSuccess)
|
||||||
import Core
|
import Core
|
||||||
import TIM
|
import TIM
|
||||||
|
import GM
|
||||||
import Lens.Micro
|
import Lens.Micro
|
||||||
import Lens.Micro.Mtl
|
import Lens.Micro.Mtl
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
@@ -23,30 +24,46 @@ optParser = info (helper <*> options)
|
|||||||
|
|
||||||
options :: Parser RLPCOptions
|
options :: Parser RLPCOptions
|
||||||
options = RLPCOptions
|
options = RLPCOptions
|
||||||
|
{- --log, -l -}
|
||||||
<$> optional # strOption
|
<$> optional # strOption
|
||||||
( long "log"
|
( long "log"
|
||||||
<> short 'l'
|
<> short 'l'
|
||||||
<> metavar "FILE"
|
<> metavar "FILE"
|
||||||
<> help "output dumps to FILE. stderr is used by default"
|
<> help "output dumps to FILE. stderr is used by default"
|
||||||
)
|
)
|
||||||
-- temp. i want gcc/ghc style options
|
{- -d -}
|
||||||
<*> fmap S.fromList # many # option debugFlagReader
|
<*> fmap S.fromList # many # option debugFlagReader
|
||||||
( short 'd'
|
( short 'd'
|
||||||
<> help "dump evaluation logs"
|
<> help "dump evaluation logs"
|
||||||
<> metavar "DEBUG FLAG"
|
<> metavar "DEBUG FLAG"
|
||||||
)
|
)
|
||||||
|
{- --evaluator, -e -}
|
||||||
|
<*> option evaluatorReader
|
||||||
|
( long "evaluator"
|
||||||
|
<> short 'e'
|
||||||
|
<> metavar "gm|tim"
|
||||||
|
<> value EvaluatorGM
|
||||||
|
<> 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
|
||||||
|
|
||||||
|
evaluatorReader :: ReadM Evaluator
|
||||||
|
evaluatorReader = maybeReader $ \case
|
||||||
|
"gm" -> Just EvaluatorGM
|
||||||
|
"tim" -> Just EvaluatorTIM
|
||||||
|
_ -> Nothing
|
||||||
|
|
||||||
mmany :: (Alternative f, Monoid m) => f m -> f m
|
mmany :: (Alternative f, Monoid m) => f m -> f m
|
||||||
mmany v = liftA2 (<>) v (mmany v)
|
mmany v = liftA2 (<>) v (mmany v)
|
||||||
|
|
||||||
debugFlagReader :: ReadM DebugFlag
|
debugFlagReader :: ReadM DebugFlag
|
||||||
debugFlagReader = maybeReader $ Just . \case
|
debugFlagReader = maybeReader $ \case
|
||||||
"dump-eval" -> DDumpEval
|
"dump-eval" -> Just DDumpEval
|
||||||
"dump-opts" -> DDumpOpts
|
"dump-opts" -> Just DDumpOpts
|
||||||
|
_ -> Nothing
|
||||||
|
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -83,12 +100,21 @@ ddumpEval = whenFlag flagDDumpEval do
|
|||||||
Left e -> addFatal . CompilerError $ show e
|
Left e -> addFatal . CompilerError $ show e
|
||||||
Right (a,_) -> do
|
Right (a,_) -> do
|
||||||
log <- view rlpcLogFile
|
log <- view rlpcLogFile
|
||||||
|
dumpEval <- chooseEval
|
||||||
case log of
|
case log of
|
||||||
Just f -> void . liftIO $ withFile f WriteMode $ hdbgProg a
|
Just f -> liftIO $ withFile f WriteMode $ dumpEval a
|
||||||
Nothing -> void . liftIO $ hdbgProg a stderr
|
Nothing -> liftIO $ dumpEval a stderr
|
||||||
|
|
||||||
parseProg :: RLPCOptions
|
parseProg :: RLPCOptions
|
||||||
-> String
|
-> String
|
||||||
-> Either SrcError (Program, [SrcError])
|
-> Either SrcError (Program, [SrcError])
|
||||||
parseProg o = evalRLPC o . (lexCore >=> parseCoreProg)
|
parseProg o = evalRLPC o . (lexCore >=> parseCoreProg)
|
||||||
|
|
||||||
|
-- choose the appropriate model based on the compiler opts
|
||||||
|
chooseEval = do
|
||||||
|
ev <- view rlpcEvaluator
|
||||||
|
pure $ case ev of
|
||||||
|
EvaluatorGM -> v GM.hdbgProg
|
||||||
|
EvaluatorTIM -> v TIM.hdbgProg
|
||||||
|
where v f p h = f p h *> pure ()
|
||||||
|
|
||||||
|
|||||||
@@ -17,11 +17,13 @@ module Compiler.RLPC
|
|||||||
, addWound
|
, addWound
|
||||||
, MonadErrorful
|
, MonadErrorful
|
||||||
, Severity(..)
|
, Severity(..)
|
||||||
|
, Evaluator(..)
|
||||||
, evalRLPCT
|
, evalRLPCT
|
||||||
, evalRLPCIO
|
, evalRLPCIO
|
||||||
, evalRLPC
|
, evalRLPC
|
||||||
, rlpcLogFile
|
, rlpcLogFile
|
||||||
, rlpcDebugOpts
|
, rlpcDebugOpts
|
||||||
|
, rlpcEvaluator
|
||||||
, rlpcInputFiles
|
, rlpcInputFiles
|
||||||
, DebugFlag(..)
|
, DebugFlag(..)
|
||||||
, whenFlag
|
, whenFlag
|
||||||
@@ -80,10 +82,14 @@ evalRLPCIO o m = do
|
|||||||
data RLPCOptions = RLPCOptions
|
data RLPCOptions = RLPCOptions
|
||||||
{ _rlpcLogFile :: Maybe FilePath
|
{ _rlpcLogFile :: Maybe FilePath
|
||||||
, _rlpcDebugOpts :: DebugOpts
|
, _rlpcDebugOpts :: DebugOpts
|
||||||
|
, _rlpcEvaluator :: Evaluator
|
||||||
, _rlpcInputFiles :: [FilePath]
|
, _rlpcInputFiles :: [FilePath]
|
||||||
}
|
}
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
|
data Evaluator = EvaluatorGM | EvaluatorTIM
|
||||||
|
deriving Show
|
||||||
|
|
||||||
data Severity = Error
|
data Severity = Error
|
||||||
| Warning
|
| Warning
|
||||||
| Debug
|
| Debug
|
||||||
@@ -105,6 +111,7 @@ instance Default RLPCOptions where
|
|||||||
def = RLPCOptions
|
def = RLPCOptions
|
||||||
{ _rlpcLogFile = Nothing
|
{ _rlpcLogFile = Nothing
|
||||||
, _rlpcDebugOpts = mempty
|
, _rlpcDebugOpts = mempty
|
||||||
|
, _rlpcEvaluator = EvaluatorGM
|
||||||
, _rlpcInputFiles = []
|
, _rlpcInputFiles = []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,6 +110,13 @@ listExample3 = [coreProg|
|
|||||||
main = foldr (+#) 0 list;
|
main = foldr (+#) 0 list;
|
||||||
|]
|
|]
|
||||||
|
|
||||||
|
simple1 = [coreProg|
|
||||||
|
k a b = a;
|
||||||
|
s f g x = f x (g x);
|
||||||
|
|
||||||
|
main = s k k 3;
|
||||||
|
|]
|
||||||
|
|
||||||
corePrelude :: Module
|
corePrelude :: Module
|
||||||
corePrelude = Module (Just ("Prelude", [])) $
|
corePrelude = Module (Just ("Prelude", [])) $
|
||||||
-- non-primitive defs
|
-- non-primitive defs
|
||||||
|
|||||||
40
src/GM.hs
40
src/GM.hs
@@ -6,7 +6,7 @@ Description : The G-Machine
|
|||||||
{-# LANGUAGE ViewPatterns #-}
|
{-# LANGUAGE ViewPatterns #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
module GM
|
module GM
|
||||||
(
|
( hdbgProg
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
@@ -19,6 +19,8 @@ import Lens.Micro.TH
|
|||||||
import Text.Printf
|
import Text.Printf
|
||||||
import Text.PrettyPrint hiding ((<>))
|
import Text.PrettyPrint hiding ((<>))
|
||||||
import Text.PrettyPrint.HughesPJ (maybeParens)
|
import Text.PrettyPrint.HughesPJ (maybeParens)
|
||||||
|
import Data.Foldable (traverse_)
|
||||||
|
import System.IO (Handle, hPutStrLn)
|
||||||
import Data.Heap
|
import Data.Heap
|
||||||
import Core
|
import Core
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
@@ -72,6 +74,21 @@ pure []
|
|||||||
|
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
hdbgProg :: Program -> Handle -> IO (Node, Stats)
|
||||||
|
hdbgProg p hio = do
|
||||||
|
(renderOut . showState) `traverse_` p'
|
||||||
|
renderOut . showStats $ sts
|
||||||
|
pure (res, sts)
|
||||||
|
where
|
||||||
|
renderOut r = hPutStrLn hio $ render r ++ "\n"
|
||||||
|
|
||||||
|
p' = eval $ compile p
|
||||||
|
final = last p'
|
||||||
|
sts = final ^. gmStats
|
||||||
|
[resAddr] = final ^. gmStack
|
||||||
|
res = hLookupUnsafe resAddr h
|
||||||
|
h = final ^. gmHeap
|
||||||
|
|
||||||
eval :: GmState -> [GmState]
|
eval :: GmState -> [GmState]
|
||||||
eval st = st : rest
|
eval st = st : rest
|
||||||
where
|
where
|
||||||
@@ -139,20 +156,18 @@ step st = case head (st ^. gmCode) of
|
|||||||
s = st ^. gmStack
|
s = st ^. gmStack
|
||||||
h = st ^. gmHeap
|
h = st ^. gmHeap
|
||||||
|
|
||||||
s' = an : s
|
s' = arg : s
|
||||||
an = s !! (n+1)
|
argAp = s !! (n+1)
|
||||||
an' = getArg an
|
arg = case hLookupUnsafe argAp h of
|
||||||
|
NAp _ a -> a
|
||||||
getArg (hViewUnsafe h -> NAp _ a) = a
|
|
||||||
|
|
||||||
slide :: Int -> GmState -> GmState
|
slide :: Int -> GmState -> GmState
|
||||||
slide n st = st
|
slide n st = st
|
||||||
& gmCode %~ drop 1
|
& gmCode %~ drop 1
|
||||||
& gmStack .~ s'
|
& gmStack .~ s'
|
||||||
where
|
where
|
||||||
s = st ^. gmStack
|
(a:s) = st ^. gmStack
|
||||||
a0 = head s
|
s' = a : drop n s
|
||||||
s' = a0 : drop n s
|
|
||||||
|
|
||||||
unwind :: GmState -> GmState
|
unwind :: GmState -> GmState
|
||||||
unwind st = case hLookupUnsafe a h of
|
unwind st = case hLookupUnsafe a h of
|
||||||
@@ -162,6 +177,7 @@ 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:)
|
||||||
|
-- assumes length s < d (i.e. enough args have been supplied)
|
||||||
NGlobal d c -> st
|
NGlobal d c -> st
|
||||||
-- 'jump' to global's code by replacing our current
|
-- 'jump' to global's code by replacing our current
|
||||||
-- code with `c`
|
-- code with `c`
|
||||||
@@ -235,9 +251,6 @@ pprTabstop = 4
|
|||||||
qquotes :: Doc -> Doc
|
qquotes :: Doc -> Doc
|
||||||
qquotes d = "`" <> d <> "'"
|
qquotes d = "`" <> d <> "'"
|
||||||
|
|
||||||
showResults :: [GmState] -> String
|
|
||||||
showResults st = undefined
|
|
||||||
|
|
||||||
showStats :: Stats -> Doc
|
showStats :: Stats -> Doc
|
||||||
showStats sts = "==== Stats ============" $$ stats
|
showStats sts = "==== Stats ============" $$ stats
|
||||||
where
|
where
|
||||||
@@ -316,7 +329,8 @@ showNodeAtP p st a = case hLookup a h of
|
|||||||
where
|
where
|
||||||
g = st ^. gmEnv
|
g = st ^. gmEnv
|
||||||
name = fromMaybe "<unknown>" $ lookup a (swap <$> g)
|
name = fromMaybe "<unknown>" $ lookup a (swap <$> g)
|
||||||
Just (NAp f x) -> 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)
|
||||||
Nothing -> "<invalid address>"
|
Nothing -> "<invalid address>"
|
||||||
where h = st ^. gmHeap
|
where h = st ^. gmHeap
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user