eval cons
This commit is contained in:
+41
-12
@@ -12,7 +12,7 @@ module Gyehoek.CPS.Eval
|
|||||||
import Gyehoek.CPS.Syntax hiding (Hob(..), Obj(..), cont)
|
import Gyehoek.CPS.Syntax hiding (Hob(..), Obj(..), cont)
|
||||||
import Gyehoek.Sexp qualified as S
|
import Gyehoek.Sexp qualified as S
|
||||||
import Control.Lens hiding (assign)
|
import Control.Lens hiding (assign)
|
||||||
import Data.Maybe (fromMaybe)
|
import Data.Maybe (fromMaybe, isJust)
|
||||||
import Text.Show.Functions ()
|
import Text.Show.Functions ()
|
||||||
import qualified Data.HashMap.Strict as H
|
import qualified Data.HashMap.Strict as H
|
||||||
import Gyehoek.Prelude hiding (assign)
|
import Gyehoek.Prelude hiding (assign)
|
||||||
@@ -116,6 +116,13 @@ data Mutability
|
|||||||
wrong :: Text -> M Answer a
|
wrong :: Text -> M Answer a
|
||||||
wrong s = ContT \_ -> pure . AnswerError . EvalError $ s
|
wrong s = ContT \_ -> pure . AnswerError . EvalError $ s
|
||||||
|
|
||||||
|
orWrong
|
||||||
|
:: Getting (First a) s a
|
||||||
|
-> s -> Text -> (a -> M Answer c) -> M Answer c
|
||||||
|
orWrong p s msg f = case getFirst . getConst $ p (Const . First . Just) s of
|
||||||
|
Nothing -> wrong msg
|
||||||
|
Just x -> f x
|
||||||
|
|
||||||
bind :: Name -> Loc -> Env
|
bind :: Name -> Loc -> Env
|
||||||
bind k = MkEnv . H.singleton k
|
bind k = MkEnv . H.singleton k
|
||||||
|
|
||||||
@@ -139,9 +146,9 @@ data E
|
|||||||
| EUndefined
|
| EUndefined
|
||||||
| EUnspecified
|
| EUnspecified
|
||||||
| ENull
|
| ENull
|
||||||
| EPair Loc Loc Mutability
|
| EPair Mutability Loc Loc
|
||||||
| EVec (List Loc) Mutability
|
| EVec Mutability (List Loc)
|
||||||
| EString (List Loc) Mutability
|
| EString Mutability (List Loc)
|
||||||
| EProcedure Procedure
|
| EProcedure Procedure
|
||||||
deriving stock (Show, Generic)
|
deriving stock (Show, Generic)
|
||||||
|
|
||||||
@@ -159,24 +166,30 @@ eGrammar st = S.partialOsi (const . Left $ mempty) go
|
|||||||
EUndefined -> S.Unreadable "#<undefined>"
|
EUndefined -> S.Unreadable "#<undefined>"
|
||||||
EUnspecified -> S.Unreadable "#<unspecified>"
|
EUnspecified -> S.Unreadable "#<unspecified>"
|
||||||
ENull -> S.List []
|
ENull -> S.List []
|
||||||
EPair car cdr _mut -> S.DotList [gofetch car] (gofetch cdr)
|
EPair _mut car cdr -> S.DotList [gofetch car] (gofetch cdr)
|
||||||
EVec xs _mut -> S.Vector . fmap gofetch $ xs
|
EVec _mut xs -> S.Vector . fmap gofetch $ xs
|
||||||
EString xs _mut -> S.String _
|
EString _mut xs -> S.String _
|
||||||
|
|
||||||
data DynPoints = MkDynPoints
|
data DynPoints = MkDynPoints
|
||||||
deriving (Generic, Data)
|
deriving (Generic, Data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
truthy :: E -> Bool
|
||||||
|
truthy (EBool False) = False
|
||||||
|
truthy _ = True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
evalVal :: Env -> Val -> M Answer E
|
evalVal :: Env -> Val -> M Answer E
|
||||||
|
|
||||||
evalVal g (ValVar x) = var g x >>= fetch
|
evalVal g (ValVar x) = var g x >>= fetch
|
||||||
|
|
||||||
evalVal g (ValImm imm) = pure case imm of
|
evalVal g (ValImm imm) = case imm of
|
||||||
ImmLabel l -> error [i|#{l}|]
|
ImmLabel (MkLabel l) -> var g l >>= fetch
|
||||||
ImmInt n -> EInt n
|
ImmInt n -> pure $ EInt n
|
||||||
ImmBool b -> EBool b
|
ImmBool b -> pure $ EBool b
|
||||||
ImmUndefined -> EUndefined
|
ImmUndefined -> pure EUndefined
|
||||||
|
|
||||||
evalKexp :: Env -> Kexp -> M Answer E
|
evalKexp :: Env -> Kexp -> M Answer E
|
||||||
evalKexp g (KexpVar x) = var g x >>= fetch
|
evalKexp g (KexpVar x) = var g x >>= fetch
|
||||||
@@ -218,6 +231,13 @@ eval g dps (ExpPrim p k) = do
|
|||||||
EProcedure fp -> fp p' dps
|
EProcedure fp -> fp p' dps
|
||||||
_ -> wrong [i|prim(#{p})의 계속을 나쁘다|]
|
_ -> wrong [i|prim(#{p})의 계속을 나쁘다|]
|
||||||
|
|
||||||
|
eval g dps (ExpIf c t f) = do
|
||||||
|
c' <- evalVal g c
|
||||||
|
let b = if truthy c' then t else f
|
||||||
|
var g b >>= fetch >>= \case
|
||||||
|
EProcedure fp -> fp [] dps
|
||||||
|
_ -> wrong [i|if의 계속을 나쁘다|]
|
||||||
|
|
||||||
eval g dps e = error [i|unimplemented #{e}|]
|
eval g dps e = error [i|unimplemented #{e}|]
|
||||||
|
|
||||||
evalPrim :: Env -> Prim E -> M Answer (List E)
|
evalPrim :: Env -> Prim E -> M Answer (List E)
|
||||||
@@ -226,11 +246,20 @@ evalPrim g = \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
|
||||||
|
PrimZeroP x -> pure [EBool . isJust $ x ^? #EInt . only 0]
|
||||||
|
PrimCons x y -> do
|
||||||
|
(x',y') <- traverseOf both new' (x,y)
|
||||||
|
pure [EPair Mut x' y']
|
||||||
|
PrimCar p -> cr p _2
|
||||||
|
PrimCdr p -> cr p _3
|
||||||
PrimValues xs -> pure xs
|
PrimValues xs -> pure xs
|
||||||
p -> wrong [i|prim(#{p})은 벌써 나지 않다|]
|
p -> wrong [i|prim(#{p})은 벌써 나지 않다|]
|
||||||
where
|
where
|
||||||
arith2 f (EInt x) (EInt y) = pure [EInt $ f x y]
|
arith2 f (EInt x) (EInt y) = pure [EInt $ f x y]
|
||||||
arith2 f x y = wrong [i|나쁜 인자: #{x}, #{y}|]
|
arith2 f x y = wrong [i|나쁜 인자: #{x}, #{y}|]
|
||||||
|
cr p l = orWrong (#_EPair . l) p
|
||||||
|
[i|car/cdr는 pair을 받지 않다|]
|
||||||
|
(fmap (:[]) . fetch)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user