Fakultas Ilmu Komputer UI

Commit ff34b261 authored by Sean Gillespie's avatar Sean Gillespie
Browse files

Update `subGlobals` logic

Try to avoid creating captures
parent c8ab7d2d
...@@ -15,18 +15,23 @@ evalExpr :: (Eq n, Ord n) ...@@ -15,18 +15,23 @@ evalExpr :: (Eq n, Ord n)
-> (LambdaExpr n, Map.Map n (LambdaExpr n)) -> (LambdaExpr n, Map.Map n (LambdaExpr n))
evalExpr globals uniqs (Let name expr) evalExpr globals uniqs (Let name expr)
= (Let name expr', Map.insert name expr' globals) = (Let name expr', Map.insert name expr' globals)
where expr' = evalExpr' uniqs (subGlobals globals expr) where expr' = evalExpr' uniqs (subGlobals globals uniqs expr)
evalExpr globals uniqs expr = (evalExpr' uniqs expr', globals) evalExpr globals uniqs expr = (evalExpr' uniqs expr', globals)
where expr' = subGlobals globals expr where expr' = subGlobals globals uniqs expr
subGlobals :: (Eq n, Ord n) subGlobals :: (Eq n, Ord n)
=> Map.Map n (LambdaExpr n) -- ^ globals => Map.Map n (LambdaExpr n) -- ^ globals
-> [n] -- ^ unique supply
-> LambdaExpr n -- ^ the expression -> LambdaExpr n -- ^ the expression
-> LambdaExpr n -> LambdaExpr n
subGlobals g e@(Var x) = Map.findWithDefault e x g subGlobals globals uniqs expr@(Var x) = Map.findWithDefault expr x globals
subGlobals g (App e1 e2) = App (subGlobals g e1) (subGlobals g e2) subGlobals globals uniqs (App e1 e2) = App (subGlobals globals uniqs e1)
subGlobals g (Abs n expr) = Abs n (subGlobals g expr) (subGlobals globals uniqs e2)
subGlobals _ expr = expr subGlobals globals uniqs (Abs n expr) = Abs n expr'
where expr' | Map.member n globals = expr
| otherwise = subGlobals globals uniqs expr
fvs = freeVarsOf expr
subGlobals _ _ expr = expr
-- | Evaluate an expression; does not support `let` -- | Evaluate an expression; does not support `let`
evalExpr' :: Eq n evalExpr' :: Eq n
......
module Language.Lambda.EvalSpec where module Language.Lambda.EvalSpec where
import Data.Map (empty, insert) import Data.Map (fromList, empty, insert)
import Test.Hspec import Test.Hspec
import Language.Lambda import Language.Lambda
...@@ -46,6 +46,21 @@ spec = do ...@@ -46,6 +46,21 @@ spec = do
fst (evalExpr globals uniques expr) fst (evalExpr globals uniques expr)
`shouldBe` Var "x" `shouldBe` Var "x"
describe "subGlobals" $ do
let globals = fromList [("w", Var "x")]
subGlobals' = subGlobals globals ["a"]
it "subs simple variables" $
subGlobals' (Var "w") `shouldBe` Var "x"
it "does not sub shadowed bindings" $ do
let expr = Abs "w" (Var "w")
subGlobals' expr `shouldBe` expr
xit "does not capture globals" $ do
let expr = Abs "x" (Var "w")
subGlobals' expr `shouldBe` Abs "a" (Var "x")
describe "betaReduce" $ do describe "betaReduce" $ do
let betaReduce' = betaReduce [] let betaReduce' = betaReduce []
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment