This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
(let ((p (cons 123 456)))
|
||||||
|
(cons (cdr p) (car p)))
|
||||||
@@ -31,7 +31,6 @@ close1 = \case
|
|||||||
(each . _2)
|
(each . _2)
|
||||||
(freeWithBound' boundNames')
|
(freeWithBound' boundNames')
|
||||||
& nub
|
& nub
|
||||||
pTraceShowM frees
|
|
||||||
env_cont_l <- gensym' @Name "env-cont"
|
env_cont_l <- gensym' @Name "env-cont"
|
||||||
e_l <- gensym' @Name "letrec-body-cont"
|
e_l <- gensym' @Name "letrec-body-cont"
|
||||||
bs' <- for bs \(f,ab) -> do
|
bs' <- for bs \(f,ab) -> do
|
||||||
|
|||||||
@@ -49,12 +49,15 @@ convert (Scm.ExpLit l) k = k . one . ValImm $ case l of
|
|||||||
convert (Scm.ExpPrim p) k =
|
convert (Scm.ExpPrim p) k =
|
||||||
telescope (convert1 @es) p \p' -> do
|
telescope (convert1 @es) p \p' -> do
|
||||||
r_l <- gensym' "r"
|
r_l <- gensym' "r"
|
||||||
k_l <- gensym' @Name "prim-k"
|
-- k_l <- gensym' @Name "prim-k"
|
||||||
m <- k [ValVar r_l]
|
m <- k [ValVar r_l]
|
||||||
pure [cps|
|
pure [cps|
|
||||||
(letrec ((#{k_l} (κ (#{r_l}) #{m})))
|
(prim #{p'} (κ (#{r_l}) #{m}))
|
||||||
(prim #{p'} #{k_l}))
|
|
||||||
|]
|
|]
|
||||||
|
-- pure [cps|
|
||||||
|
-- (letrec ((#{k_l} (κ (#{r_l}) #{m})))
|
||||||
|
-- (prim #{p'} #{k_l}))
|
||||||
|
-- |]
|
||||||
|
|
||||||
convert (Scm.ExpLambda xs e) k = do
|
convert (Scm.ExpLambda xs e) k = do
|
||||||
f <- gensym' "lambda-body"
|
f <- gensym' "lambda-body"
|
||||||
|
|||||||
+32
-17
@@ -18,6 +18,8 @@ import Control.Monad.Cont qualified as Cont
|
|||||||
import Gyehoek.Sexp qualified as S
|
import Gyehoek.Sexp qualified as S
|
||||||
import GHC.Generics (Generically(..))
|
import GHC.Generics (Generically(..))
|
||||||
import Gyehoek.Sexp ((:-)(..))
|
import Gyehoek.Sexp ((:-)(..))
|
||||||
|
import Data.List (nub)
|
||||||
|
import Data.HashSet.Lens (setOf)
|
||||||
|
|
||||||
|
|
||||||
data Env = MkEnv
|
data Env = MkEnv
|
||||||
@@ -40,7 +42,7 @@ data Obj
|
|||||||
|
|
||||||
-- | a heap object.
|
-- | a heap object.
|
||||||
data Hob
|
data Hob
|
||||||
= HobClosure { code :: Abs, env :: Env}
|
= HobClosure { code :: Abs, env :: List Obj }
|
||||||
-- should a continuation have a label, or an Obj?
|
-- should a continuation have a label, or an Obj?
|
||||||
| HobPair Obj Obj
|
| HobPair Obj Obj
|
||||||
deriving stock (Show, Generic, Data, Eq)
|
deriving stock (Show, Generic, Data, Eq)
|
||||||
@@ -59,7 +61,7 @@ instance S.DatumIso Hob where
|
|||||||
where
|
where
|
||||||
conspair = S.dottedList (S.el S.datumIso) S.datumIso
|
conspair = S.dottedList (S.el S.datumIso) S.datumIso
|
||||||
-- closures can be printed, but not parsed.
|
-- closures can be printed, but not parsed.
|
||||||
closure :: S.G (S.Datum :- t) (Env :- Abs :- t)
|
closure :: S.G (S.Datum :- t) (List Obj :- Abs :- t)
|
||||||
closure = S.Flip $ S.PartialIso
|
closure = S.Flip $ S.PartialIso
|
||||||
(\(_:-_:-t) -> S.Unreadable [i|\#<procedure>|] :- t)
|
(\(_:-_:-t) -> S.Unreadable [i|\#<procedure>|] :- t)
|
||||||
(const . Left $ mempty)
|
(const . Left $ mempty)
|
||||||
@@ -82,18 +84,23 @@ eval
|
|||||||
=> Env -> Exp
|
=> Env -> Exp
|
||||||
-> Eff es (List Obj)
|
-> Eff es (List Obj)
|
||||||
|
|
||||||
eval g (ExpLetRec bs e) = eval g' e
|
eval g (ExpLetRec bs e) = do
|
||||||
where
|
let boundNames = bs ^.. each . _1
|
||||||
g' = g <> foldMap
|
let boundNames' = setOf each boundNames
|
||||||
(\(f,ab) -> mempty & #store . at f ?~
|
let frees = bs
|
||||||
ObjHob (HobClosure ab g'))
|
& foldMapOf
|
||||||
bs
|
(each . _2)
|
||||||
|
(freeWithBound' boundNames')
|
||||||
|
& nub
|
||||||
|
let g' = g & #store <>~ foldMap
|
||||||
|
_
|
||||||
|
bs
|
||||||
|
eval g' e
|
||||||
|
|
||||||
eval g (Halt rs) = traverse (evalVal g) rs
|
eval g (Halt rs) = traverse (evalVal g) rs
|
||||||
|
|
||||||
eval g (ExpContinue k xs) =
|
eval g (ExpContinue k xs) = case k of
|
||||||
case k of
|
ValVar x -> continueWith g (KexpVar x) =<< traverse (evalVal g) xs
|
||||||
ValVar x -> continueWith g (KexpVar x) xs
|
|
||||||
|
|
||||||
eval g (ExpApply f xs ktail) = do
|
eval g (ExpApply f xs ktail) = do
|
||||||
f' <- evalVal g f
|
f' <- evalVal g f
|
||||||
@@ -112,21 +119,29 @@ eval g (ExpPrim p k) = traverse (evalVal g) p >>= \case
|
|||||||
PrimMul x y -> arith2 (*) x y
|
PrimMul x y -> arith2 (*) x y
|
||||||
PrimSub x y -> arith2 (-) x y
|
PrimSub x y -> arith2 (-) x y
|
||||||
PrimDiv x y -> arith2 div x y
|
PrimDiv x y -> arith2 div x y
|
||||||
|
PrimCons car cdr -> ret1 . ObjHob $ HobPair car cdr
|
||||||
|
PrimCar p -> case p of
|
||||||
|
ObjHob (HobPair x _) -> ret1 x
|
||||||
|
_ -> err "car"
|
||||||
|
PrimCdr p -> case p of
|
||||||
|
ObjHob (HobPair _ y) -> ret1 y
|
||||||
|
_ -> err "cdr"
|
||||||
|
p -> err [i|unimplemented prim #{p}|]
|
||||||
where
|
where
|
||||||
|
ret1 = continueWith g k . (:[])
|
||||||
arith2 f (ObjImm (ImmInt x)) (ObjImm (ImmInt y)) =
|
arith2 f (ObjImm (ImmInt x)) (ObjImm (ImmInt y)) =
|
||||||
pure1 . ObjImm . ImmInt $ f x y
|
ret1 . ObjImm . ImmInt $ f x y
|
||||||
|
|
||||||
eval g e = err [i|unimplemented exp: #{S.encodeOrShow' @Text S.datumIso e}|]
|
eval g e = err [i|unimplemented exp: #{S.encodeOrShow' @Text S.datumIso e}|]
|
||||||
|
|
||||||
continueWith :: Jalmot :> es => Env -> Kexp -> List Val -> Eff es (List Obj)
|
continueWith :: Jalmot :> es => Env -> Kexp -> List Obj -> Eff es (List Obj)
|
||||||
continueWith g kexp xs = do
|
continueWith g kexp xs =
|
||||||
xs' <- traverse (evalVal g) xs
|
|
||||||
evalKexp g kexp >>= \case
|
evalKexp g kexp >>= \case
|
||||||
ObjImm (ImmLabel "halt") -> traverse (evalVal g) xs
|
ObjImm (ImmLabel "halt") -> pure xs
|
||||||
ObjHob (HobClosure {code,env}) -> eval env' e
|
ObjHob (HobClosure {code,env}) -> eval env' e
|
||||||
where
|
where
|
||||||
MkAbs bxs bktail e = code
|
MkAbs bxs bktail e = code
|
||||||
env' = env & #store <>~ H.fromList (zip bxs xs')
|
env' = env & #store <>~ H.fromList (zip bxs xs)
|
||||||
|
|
||||||
evalKexp :: Jalmot :> es => Env -> Kexp -> Eff es Obj
|
evalKexp :: Jalmot :> es => Env -> Kexp -> Eff es Obj
|
||||||
evalKexp g = \case
|
evalKexp g = \case
|
||||||
|
|||||||
+14
-3
@@ -1,5 +1,5 @@
|
|||||||
module Gyehoek.Driver
|
module Gyehoek.Driver
|
||||||
(main, lower_e2e, convert_e2e, parse_e2e, readScm, eval_e2e, eval_cps_e2e)
|
(main, lower_e2e, convert_e2e, parse_e2e, readScm, eval_e2e, eval_cps_e2e, eval_cps2_e2e)
|
||||||
where
|
where
|
||||||
|
|
||||||
import Gyehoek.Options
|
import Gyehoek.Options
|
||||||
@@ -123,10 +123,10 @@ driver opts = do
|
|||||||
S.writeDatum cps
|
S.writeDatum cps
|
||||||
closedCps <- closeProgram cps
|
closedCps <- closeProgram cps
|
||||||
when opts.dumpClosed do
|
when opts.dumpClosed do
|
||||||
S.writeData closedCps
|
S.writeDatum closedCps
|
||||||
hoistedCps <- hoistProgram closedCps
|
hoistedCps <- hoistProgram closedCps
|
||||||
when opts.dumpHoisted do
|
when opts.dumpHoisted do
|
||||||
S.writeData hoistedCps
|
S.writeDatum hoistedCps
|
||||||
-- contifiedCps <- contifyProgram hoistedCps
|
-- contifiedCps <- contifyProgram hoistedCps
|
||||||
-- when opts.dumpContified do
|
-- when opts.dumpContified do
|
||||||
-- hPutStrLn FS.stdout =<< S.encodeWith S.datumIso contifiedCps
|
-- hPutStrLn FS.stdout =<< S.encodeWith S.datumIso contifiedCps
|
||||||
@@ -137,6 +137,9 @@ driver opts = do
|
|||||||
(eval >=> fmap writeObj
|
(eval >=> fmap writeObj
|
||||||
>>> T.unwords
|
>>> T.unwords
|
||||||
>>> hPutStrLn FS.stdout)
|
>>> hPutStrLn FS.stdout)
|
||||||
|
when (rt_is #HigherOrderCPS) do
|
||||||
|
CPS.evalProgram cps
|
||||||
|
>>= S.writeData
|
||||||
when (rt_is #CPS) do
|
when (rt_is #CPS) do
|
||||||
CPS.evalProgram closedCps
|
CPS.evalProgram closedCps
|
||||||
>>= S.writeData
|
>>= S.writeData
|
||||||
@@ -166,6 +169,14 @@ eval_e2e fp = runJalmotIO . runFileSystem . runGenSym $ do
|
|||||||
|
|
||||||
eval_cps_e2e :: FilePath -> IO Text
|
eval_cps_e2e :: FilePath -> IO Text
|
||||||
eval_cps_e2e fp = runJalmotIO . runFileSystem . runGenSym $
|
eval_cps_e2e fp = runJalmotIO . runFileSystem . runGenSym $
|
||||||
|
readScm fp
|
||||||
|
>>= convertProgram
|
||||||
|
>>= closeProgram
|
||||||
|
>>= CPS.evalProgram
|
||||||
|
>>= pure . S.encodeOrShowData' S.dataIso
|
||||||
|
|
||||||
|
eval_cps2_e2e :: FilePath -> IO Text
|
||||||
|
eval_cps2_e2e fp = runJalmotIO . runFileSystem . runGenSym $
|
||||||
readScm fp
|
readScm fp
|
||||||
>>= convertProgram
|
>>= convertProgram
|
||||||
-- >>= closeProgram
|
-- >>= closeProgram
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import Data.Foldable
|
|||||||
import Gyehoek.Prelude hiding (argument)
|
import Gyehoek.Prelude hiding (argument)
|
||||||
|
|
||||||
|
|
||||||
data Runtime = Stackify | Wasm | CPS
|
data Runtime = Stackify | Wasm | CPS | HigherOrderCPS
|
||||||
deriving (Show, Generic, Eq)
|
deriving (Show, Generic, Eq)
|
||||||
|
|
||||||
data Language
|
data Language
|
||||||
@@ -55,6 +55,7 @@ runtimeReader = maybeReader \case
|
|||||||
"stackify" -> Just (Just Stackify)
|
"stackify" -> Just (Just Stackify)
|
||||||
"wasm" -> Just (Just Wasm)
|
"wasm" -> Just (Just Wasm)
|
||||||
"cps" -> Just (Just CPS)
|
"cps" -> Just (Just CPS)
|
||||||
|
("cps2";"higher-order-cps") -> Just (Just CPS)
|
||||||
"none" -> Just Nothing
|
"none" -> Just Nothing
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
|
|
||||||
@@ -75,9 +76,9 @@ parser = do
|
|||||||
runtime <- option runtimeReader . fold $
|
runtime <- option runtimeReader . fold $
|
||||||
[ long "runtime"
|
[ long "runtime"
|
||||||
, short 'R'
|
, short 'R'
|
||||||
, value (Just CPS)
|
, value (Just HigherOrderCPS)
|
||||||
, completeWith runtimeValues
|
, completeWith runtimeValues
|
||||||
, showDefaultWith $ const "cps"
|
, showDefaultWith $ const "higher-order-cps"
|
||||||
, metavar "RUNTIME"
|
, metavar "RUNTIME"
|
||||||
]
|
]
|
||||||
sourceLanguage <- option languageReader . fold $
|
sourceLanguage <- option languageReader . fold $
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ encodeOrShow' g x = fromString $
|
|||||||
|
|
||||||
encodeOrShow :: (IsString s, Show a) => DatumGrammar a -> a -> s
|
encodeOrShow :: (IsString s, Show a) => DatumGrammar a -> a -> s
|
||||||
encodeOrShow g x = fromString $
|
encodeOrShow g x = fromString $
|
||||||
case runPureEff . runJalmot . encodeWith' g $ x of
|
case runPureEff . runJalmot . encodeWith g $ x of
|
||||||
Left _ -> show x
|
Left _ -> show x
|
||||||
Right t -> T.unpack t
|
Right t -> T.unpack t
|
||||||
|
|
||||||
|
|||||||
@@ -56,12 +56,15 @@ test_eval :: IO TestTree
|
|||||||
test_eval = do
|
test_eval = do
|
||||||
cs <- listDirectory "golden/exec"
|
cs <- listDirectory "golden/exec"
|
||||||
<&> fmap ("golden/exec" </>)
|
<&> fmap ("golden/exec" </>)
|
||||||
pure $ testGroup "cps interpreter" $ cpsCase <$> cs
|
pure $ testGroup "cps interpreter"
|
||||||
|
[ testGroup "higher-order" $ cpsCase Driver.eval_cps2_e2e <$> cs
|
||||||
|
, testGroup "first-order" $ cpsCase Driver.eval_cps_e2e <$> cs
|
||||||
|
]
|
||||||
|
|
||||||
maybeBroken name broken = applyWhen (name `elem` broken) expectFail
|
maybeBroken name broken = applyWhen (name `elem` broken) expectFail
|
||||||
|
|
||||||
cpsCase :: FilePath -> TestTree
|
cpsCase :: (FilePath -> IO Text) -> FilePath -> TestTree
|
||||||
cpsCase test =
|
cpsCase f test =
|
||||||
maybeBroken testName brokenEvalTests $
|
maybeBroken testName brokenEvalTests $
|
||||||
goldenVsAction testName resultFile action printProcResult
|
goldenVsAction testName resultFile action printProcResult
|
||||||
where
|
where
|
||||||
@@ -69,7 +72,7 @@ cpsCase test =
|
|||||||
resultFile = test </> "exec"
|
resultFile = test </> "exec"
|
||||||
sourceFile = test </> "source.scm"
|
sourceFile = test </> "source.scm"
|
||||||
action = catch @SomeException
|
action = catch @SomeException
|
||||||
(do r <- Driver.eval_cps_e2e sourceFile
|
(do r <- f sourceFile
|
||||||
pure $!! ( ExitSuccess
|
pure $!! ( ExitSuccess
|
||||||
, r
|
, r
|
||||||
, "" ))
|
, "" ))
|
||||||
|
|||||||
Reference in New Issue
Block a user