Cleaned up closure stuff in the transfer interpreter.

This commit is contained in:
bringert
2005-11-28 19:12:15 +00:00
parent e74fc3a3b5
commit 101f43dcd4

View File

@@ -13,7 +13,7 @@ data Value = VStr String
| VInt Integer | VInt Integer
| VType | VType
| VRec [(CIdent,Value)] | VRec [(CIdent,Value)]
| VClos Env PatternVariable Exp | VClos Env Exp
| VCons CIdent [Value] | VCons CIdent [Value]
| VPrim (Value -> Value) | VPrim (Value -> Value)
deriving (Show) deriving (Show)
@@ -71,10 +71,11 @@ builtin =
toBool b = VCons (CIdent (if b then "True" else "False")) [] toBool b = VCons (CIdent (if b then "True" else "False")) []
appInt1 f x = case x of appInt1 f x = case x of
VInt n -> f n VInt n -> f n
_ -> error $ printValue x ++ " is not an integer" -- VCons c [x] _ -> error $ printValue x ++ " is not an integer"
appInt2 f x y = case (x,y) of appInt2 f x y = case (x,y) of
(VInt n,VInt m) -> f n m (VInt n,VInt m) -> f n m
_ -> error $ printValue x ++ " and " ++ printValue y ++ " are not both integers" -- VCons c [x,y] _ -> error $ printValue x ++ " and " ++ printValue y
++ " are not both integers"
addModuleEnv :: Env -> Module -> Env addModuleEnv :: Env -> Module -> Env
addModuleEnv env (Module ds) = addModuleEnv env (Module ds) =
@@ -101,24 +102,28 @@ eval env x = case x of
Nothing -> error $ "No pattern matched " ++ printValue v Nothing -> error $ "No pattern matched " ++ printValue v
Just (e,bs) -> eval (bs `addToEnv` env) e Just (e,bs) -> eval (bs `addToEnv` env) e
in v `seq` r in v `seq` r
EAbs id exp -> VClos env id $! exp EAbs _ _ -> VClos env $! x
-- FIXME: what to do? EPi _ _ _ -> VClos env $! x
-- EPi id _ exp -> VClos env id $! exp EApp exp1 exp2 ->
EApp exp1 exp2 -> let v1 = eval env exp1 let v1 = eval env exp1
v2 = eval env exp2 v2 = eval env exp2
in case v1 of in case v1 of
VClos env' id e -> eval (bind id v2 `addToEnv` env') e VClos env' (EAbs id e) -> eval (bind id v2 `addToEnv` env') e
VPrim f -> f $! v2 VPrim f -> f $! v2
VCons c vs -> (VCons $! c) $! ((++) $! vs) $! [v2] VCons c vs -> (VCons $! c) $! ((++) $! vs) $! [v2]
_ -> error $ "Bad application (" ++ printValue v1 ++ ") (" ++ printValue v2 ++ ")" _ -> error $ "Bad application (" ++ printValue v1
++ ") (" ++ printValue v2 ++ ")"
EProj exp id -> let v = eval env exp EProj exp id -> let v = eval env exp
in case v of in case v of
VRec fs -> recLookup id fs VRec fs -> recLookup id fs
_ -> error $ printValue v ++ " is not a record, cannot get field " ++ printTree id _ -> error $ printValue v ++ " is not a record, "
++ "cannot get field " ++ printTree id
EEmptyRec -> VRec [] EEmptyRec -> VRec []
ERecType fts -> VRec $! deepSeqList $! [ v `seq` (f,v) | FieldType f e <- fts, let v = eval env e] ERecType fts -> VRec $! deepSeqList $! [v `seq` (f,v) | FieldType f e <- fts,
ERec fvs -> VRec $! deepSeqList $! [ v `seq` (f,v) | FieldValue f e <- fvs, let v = eval env e] let v = eval env e]
ERec fvs -> VRec $! deepSeqList $! [v `seq` (f,v) | FieldValue f e <- fvs,
let v = eval env e]
EVar id -> lookupEnv env id EVar id -> lookupEnv env id
EType -> VType EType -> VType
EStr str -> VStr str EStr str -> VStr str
@@ -176,9 +181,7 @@ valueToExp v =
VInt i -> EInt i VInt i -> EInt i
VType -> EType VType -> EType
VRec fs -> ERec [ FieldValue f (valueToExp v) | (f,v) <- fs] VRec fs -> ERec [ FieldValue f (valueToExp v) | (f,v) <- fs]
VClos _ id e -> EAbs id e VClos env e -> e
-- FIXME: what do we do with VPi?
-- VPi id e -> EPi id (EVar (CIdent "_")) e -- FIXME: should be a meta variable or something
VCons c vs -> foldl EApp (EVar c) (map valueToExp vs) VCons c vs -> foldl EApp (EVar c) (map valueToExp vs)
VPrim _ -> EVar (CIdent "<<primitive>>") -- FIXME: what to return here? VPrim _ -> EVar (CIdent "<<primitive>>") -- FIXME: what to return here?
@@ -188,31 +191,3 @@ valueToExp v =
printValue :: Value -> String printValue :: Value -> String
printValue v = printTree (valueToExp v) printValue v = printTree (valueToExp v)
{-
prValue 0 0 v ""
where
prValue p n v = case v of
VStr s -> shows s
VInt i -> shows i
VType -> showString "Type"
VRec cs -> showChar '{' . joinS (showChar ';')
(map prField cs) . showChar '}'
VAbs id e -> showString "<<function>>"
-- let x = "$"++show n
-- in showChar '\\' . showString (x++" -> ")
-- . prValue 0 (n+1) (f (VCons (CIdent x) [])) -- hacky to use VCons
VPi f -> showString "<<function type>>"
VCons c [] -> showIdent c
VCons c vs -> parenth (showIdent c . concatS (map (\v -> spaceS . prValue 1 n v) vs))
VPrim _ -> "<<primitive>>"
where prField (i,v) = showIdent i . showChar '=' . prValue 0 n v
parenth s = if p > 0 then showChar '(' . s . showChar ')' else s
showIdent (CIdent i) = showString i
-}
spaceS :: ShowS
spaceS = showChar ' '
joinS :: ShowS -> [ShowS] -> ShowS
joinS glue = concatS . intersperse glue