Skip to content

Commit

Permalink
Merge 5d52b0b into f5000d5
Browse files Browse the repository at this point in the history
  • Loading branch information
andorp committed Apr 28, 2020
2 parents f5000d5 + 5d52b0b commit f72433c
Show file tree
Hide file tree
Showing 14 changed files with 998 additions and 111 deletions.
28 changes: 28 additions & 0 deletions grin/grin.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,14 @@ library
Reducer.LLVM.TypeGen
Reducer.PrimOps
Reducer.Pure
Reducer.Interpreter.Base
Reducer.Interpreter.Definitional
Reducer.Interpreter.Env
Reducer.Interpreter.Store
Reducer.Interpreter.Definitional.Instance
Reducer.Interpreter.Definitional.Internal
Reducer.Interpreter.Definitional.Cib

Test.Assertions
Test.Check
Test.Grammar
Expand Down Expand Up @@ -303,6 +311,7 @@ test-suite grin-test
, process
, bytestring
, MissingH
, recursion-schemes

other-modules:
Transformations.Simplifying.RegisterIntroductionSpec
Expand Down Expand Up @@ -356,6 +365,25 @@ test-suite grin-test
Test.EndToEnd
Test.EndToEndSpec
CLI.Lib
AbstractInterpretation.ExtendedSyntax.CreatedBySpec
AbstractInterpretation.ExtendedSyntax.EffectTrackingSpec
AbstractInterpretation.ExtendedSyntax.HptSpec
AbstractInterpretation.ExtendedSyntax.IRSpec
AbstractInterpretation.ExtendedSyntax.LiveVariableSpec
AbstractInterpretation.ExtendedSyntax.OptimiseAbstractProgramSpec
AbstractInterpretation.ExtendedSyntax.SharingSpec
ExtendedSyntax.LintSpec
ExtendedSyntax.NametableSpec
ExtendedSyntax.ParserSpec
Reducer.Interpreter.Definitional.CibSpec
Transformations.ExtendedSyntax.BindNormalisationSpec
Transformations.ExtendedSyntax.ConversionSpec
Transformations.ExtendedSyntax.MangleNamesSpec
Transformations.ExtendedSyntax.Optimising.CSESpec
Transformations.ExtendedSyntax.Optimising.CopyPropagationSpec
Transformations.ExtendedSyntax.Optimising.EvaluatedCaseEliminationSpec
Transformations.ExtendedSyntax.Optimising.TrivialCaseEliminationSpec
Transformations.ExtendedSyntax.StaticSingleAssignmentSpec
default-language: Haskell2010

test-suite grin-end-to-end-test
Expand Down
16 changes: 8 additions & 8 deletions grin/src/Pipeline/Eval.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@ import qualified Data.Text.IO as Text
import Text.Megaparsec

import Grin.Grin
import Grin.TypeCheck
import Grin.Parse
import Reducer.Base (RTVal, Statistics)
import qualified Reducer.IO
import qualified Reducer.Pure
import qualified Reducer.LLVM.JIT as LLVM
import qualified Reducer.LLVM.CodeGen as LLVM
import qualified AbstractInterpretation.HeapPointsTo.CodeGen as HPT
import qualified AbstractInterpretation.HeapPointsTo.Result as HPT
import AbstractInterpretation.Reduce (AbstractInterpretationResult(..), evalAbstractProgram)
import qualified Reducer.Interpreter.Definitional



data Reducer
= PureReducer Reducer.Pure.EvalPlugin
| IOReducer
| DefinitionalReducer Reducer.Pure.EvalPlugin

evalProgram :: Reducer -> Program -> IO (RTVal, Maybe Statistics)
evalProgram reducer program =
case reducer of
PureReducer evalPrimOp -> Reducer.Pure.reduceFun evalPrimOp program "grinMain"
IOReducer -> Reducer.IO.reduceFun program "grinMain"
PureReducer evalPrimOp
-> Reducer.Pure.reduceFun evalPrimOp program "grinMain"
IOReducer
-> Reducer.IO.reduceFun program "grinMain"
DefinitionalReducer evalPrimOp
-> (\x -> (x,Nothing)) <$> Reducer.Interpreter.Definitional.reduceFun evalPrimOp program "grinMain"
16 changes: 16 additions & 0 deletions grin/src/Pipeline/Pipeline.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module Pipeline.Pipeline
, pattern FullPrintGrin
, pattern DeadCodeElimination
, pattern PureEvalPlugin
, pattern DefinitionalInterpreter
, pipeline
, optimize
, optimizeWith
Expand Down Expand Up @@ -200,6 +201,7 @@ data PipelineStep
| PrintGrinH RenderingOption (Hidden (Doc -> Doc))
| PureEval Bool
| PureEvalPluginH (Hidden EvalPlugin) Bool
| DefinitionalInterpreterH (Hidden EvalPlugin) Bool
| JITLLVM
| PrintAST
| SaveLLVM Path
Expand Down Expand Up @@ -256,6 +258,10 @@ pattern PureEvalPlugin :: EvalPlugin -> Bool -> PipelineStep
pattern PureEvalPlugin t b <- PureEvalPluginH (H t) b
where PureEvalPlugin t b = PureEvalPluginH (H t) b

pattern DefinitionalInterpreter :: EvalPlugin -> Bool -> PipelineStep
pattern DefinitionalInterpreter t b <- DefinitionalInterpreterH (H t) b
where DefinitionalInterpreter t b = DefinitionalInterpreterH (H t) b

data PipelineOpts = PipelineOpts
{ _poOutputDir :: FilePath
, _poFailOnLint :: Bool
Expand Down Expand Up @@ -480,6 +486,7 @@ pipelineStep p = do
DebugPipelineState -> debugPipelineState
PureEval showStatistics -> pureEval (EvalPlugin evalPrimOp) showStatistics
PureEvalPlugin evalPlugin showStatistics -> pureEval evalPlugin showStatistics
DefinitionalInterpreter evalPlugin showStatistics -> definionalInterpreterEval evalPlugin showStatistics
after <- use psExp
let eff = if before == after then None else ExpChanged
showMS :: Rational -> String
Expand Down Expand Up @@ -669,6 +676,15 @@ pureEval evalPlugin showStatistics = do
when showStatistics $ pipelineLog $ show $ pretty stat
pipelineLog $ show $ pretty val

definionalInterpreterEval :: EvalPlugin -> Bool -> PipelineM ()
definionalInterpreterEval evalPlugin showStatistics = do
e <- use psExp
(val, stat) <- liftIO $ do
hSetBuffering stdout NoBuffering
evalProgram (DefinitionalReducer evalPlugin) e
when showStatistics $ pipelineLog $ show $ pretty stat
pipelineLog $ show $ pretty val

printGrinM :: RenderingOption -> (Doc -> Doc) -> PipelineM ()
printGrinM r color = do
p <- use psExp
Expand Down
4 changes: 3 additions & 1 deletion grin/src/Reducer/IO.hs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ evalSimpleExp exts env = \case
go a (x:xs) (y:ys) = go (Map.insert x y a) xs ys
go _ x y = error $ "invalid pattern for function: " ++ show (n,x,y)
if isExternalName exts n
then evalPrimOp n [] args
then do
let Just evalPrimOpFun = Map.lookup n evalPrimOp
evalPrimOpFun args
else do
Def _ vars body <- (Map.findWithDefault (error $ "unknown function: " ++ unpackName n) n) <$> getProg
evalExp exts (go env vars args) body
Expand Down
152 changes: 152 additions & 0 deletions grin/src/Reducer/Interpreter/Base.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
{-# LANGUAGE EmptyCase #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
module Reducer.Interpreter.Base
( module Reducer.Interpreter.Base
) where

import Control.Monad.Fail
import Control.Monad.Trans (MonadIO)
import Data.Function (fix)
import Data.Map.Strict (Map, fromList)
import Grin.ExtendedSyntax.Syntax hiding (Val)
import Data.Functor.Foldable
import Reducer.Interpreter.Env (Env)
import Data.Functor.Sum

import qualified Reducer.Interpreter.Env as Env
import qualified Grin.ExtendedSyntax.Syntax as Grin (Val)


-- * Interpreter

eval :: (Interpreter m, MonadIO m, Show v, v ~ Val m)
=> (forall a . Expr m a -> m v)
-> Fix (Sum ExpF (Expr m)) -> m v
eval ev = fix (baseEval ev)

-- Open recursion and monadic interpreter.
baseEval :: (MonadIO m, Interpreter m, a ~ Addr m, v ~ Val m, Show v)
=> (forall b . Expr m b -> m v)
-> (Fix (Sum ExpF (Expr m)) -> m (Val m))
-> Fix (Sum ExpF (Expr m)) -> m (Val m)
baseEval evExpr ev0 = \case
Fix (InL (SReturnF (Var n))) -> do
p <- getEnv
pure $ Env.lookup p n

-- TODO: Separate value and variable in the GRIN expressions
Fix (InL (SReturnF v)) -> value v

Fix (InL (SAppF fn ps)) -> do
p <- getEnv
vs <- pure $ map (Env.lookup p) ps
ex <- isExternal fn
if ex
then callExternal fn vs
else do
(env, body) <- functionCall fn vs
localEnv env $ ev0 body

Fix (InL (SFetchF n)) -> do
p <- getEnv
let v = Env.lookup p n
a <- valToAddr v
n <- fetch a
nodeToVal n

Fix (InL (SUpdateF nl nn)) -> do
p <- getEnv
let vl = Env.lookup p nl
let vn = Env.lookup p nn
a <- valToAddr vl
n <- valToNode vn
update a n
unit

Fix (InL (ECaseF n alts)) -> do
p <- getEnv
v <- pure $ Env.lookup p n
(env, alt) <- matchingVal v alts
localEnv (Env.insertEnv p env) (ev0 alt)

Fix (InL (EBindF (Fix (InL (SStoreF n))) (VarPat l) rhs)) -> do
p <- getEnv
let v = Env.lookup p n
a <- store l
n <- valToNode v
update a n
va <- addrToVal a
let p' = Env.insert l va p
localEnv p' (ev0 rhs)

Fix (InL (EBindF lhs (VarPat n) rhs)) -> do
v <- ev0 lhs
p <- getEnv
let p' = Env.insert n v p
localEnv p' (ev0 rhs)

Fix (InL (EBindF lhs (AsPat t@(Tag{}) vs n) rhs)) -> do
v <- ev0 lhs
p <- getEnv
p' <- flip Env.inserts p <$> bindPattern v (t,vs)
let p'' = Env.insert n v p'
localEnv p'' (ev0 rhs)

Fix (InL (AltF _name _pat body)) -> do
ev0 body

(Fix (InR e)) -> evExpr e

_overGenerative -> error "overGenerative"

-- Type class

class (Monad m, MonadFail m) => Interpreter m where
type Expr m :: * -> *

type Val m :: * -- Values that can be placed in registers/variables
type Node m :: * -- Values for the Store, Fetch, Update parameters
type Addr m :: * -- A type to represent an Address

-- Conversions, but m type is needed for type inference
value :: Grin.Val -> m (Val m) -- Value of the given literal: Only applicable to ConstTagNode, Unit and Lit
valToAddr :: Val m -> m (Addr m)
addrToVal :: Addr m -> m (Val m)
nodeToVal :: Node m -> m (Val m)
valToNode :: Val m -> m (Node m)
unit :: m (Val m) -- The unit value
bindPattern :: Val m -> (Tag, [Name]) -> m [(Name, Val m)]

-- Environment
getEnv :: m (Env (Val m))
localEnv :: Env (Val m) -> m (Val m) -> m (Val m)

-- Function call
isExternal :: Name -> m Bool
callExternal :: Name -> [Val m] -> m (Val m)
functionCall :: Name -> [Val m] -> m (Env (Val m), Fix (Sum ExpF (Expr m)))

-- Case
matchingVal :: Val m -> [Fix (Sum ExpF (Expr m))] -> m (Env (Val m), Fix (Sum ExpF (Expr m)))

-- Heap
store :: Name -> m (Addr m)
fetch :: Addr m -> m (Node m)
update :: Addr m -> Node m -> m ()

-- * Helpers

toExprF :: Exp -> Fix (Sum ExpF e)
toExprF = cata (Fix . InL)

programToDefs :: (Fix (Sum ExpF e)) -> Map Name (Fix (Sum ExpF e))
programToDefs = \case
(Fix (InL (ProgramF _ defs))) -> fromList ((\d@(Fix (InL (DefF n _ _))) -> (n,d)) <$> defs)
_ -> mempty

data Void a

instance Functor Void where
fmap _ = \case
29 changes: 29 additions & 0 deletions grin/src/Reducer/Interpreter/Definitional.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{-# LANGUAGE TypeApplications, LambdaCase, EmptyCase #-}
module Reducer.Interpreter.Definitional
( reduceFun
) where

import Control.Monad.IO.Class (MonadIO(..))
import Reducer.Interpreter.Base (Void, toExprF)
import Reducer.Interpreter.Definitional.Internal
import Reducer.Interpreter.Definitional.Instance
import Reducer.Base (RTVal(..))
import Reducer.Pure (EvalPlugin(..))
import Transformations.ExtendedSyntax.Conversion (convertToNew)
import qualified Grin.Syntax as SyntaxV1 (Exp, Name(..))


import qualified Data.Map as Map

reduceFun :: EvalPlugin -> SyntaxV1.Exp -> SyntaxV1.Name -> IO RTVal
reduceFun (EvalPlugin evalPrimOps) expV1 mainName = do
(Left dval, _)
<- evalDefinitional
(DefinitionalTContext @Void @() @NoHeapInfo)
(\case)
(Map.map convertPrimOp $ Map.mapKeys nameV1toV2 evalPrimOps)
(nameV1toV2 mainName)
(toExprF $ convertToNew expV1)
pure $ dValToRtVal dval
where
convertPrimOp f args = liftIO $ fmap rtValToDVal $ f $ map dValToRtVal args

0 comments on commit f72433c

Please sign in to comment.