1
1
mirror of https://github.com/github/semantic.git synced 2024-12-24 23:42:31 +03:00

lambda takes the set of free variables as a parameter.

This commit is contained in:
Rob Rix 2018-05-08 10:54:04 -04:00
parent 5a4e6cb0b0
commit d9084f9f45
5 changed files with 13 additions and 12 deletions

View File

@ -137,8 +137,11 @@ class Show value => AbstractValue location value effects where
-- | Extract the environment from any scoped object (e.g. classes, namespaces, etc).
scopedEnvironment :: value -> Evaluator location term value effects (Maybe (Environment location value))
-- | Evaluate an abstraction (a binder like a lambda or method definition).
lambda :: FreeVariables term => [Name] -> Subterm term (Evaluator location term value effects value) -> Evaluator location term value effects value
-- | Build a closure (a binder like a lambda or method definition).
lambda :: [Name] -- ^ The parameter names.
-> Set Name -- ^ The set of free variables to close over.
-> Evaluator location term value effects value -- ^ The evaluator for the body of the closure.
-> Evaluator location term value effects value
-- | Evaluate an application (like a function call).
call :: value -> [Evaluator location term value effects value] -> Evaluator location term value effects value

View File

@ -92,7 +92,7 @@ instance ( Addressable location effects
, Reducer (Type location) (Cell location (Type location))
)
=> AbstractValue location (Type location) effects where
lambda names (Subterm _ body) = do
lambda names _ body = do
(env, tvars) <- foldr (\ name rest -> do
a <- alloc name
tvar <- Var <$> raise fresh

View File

@ -349,9 +349,9 @@ instance ( Addressable location (Goto effects (Value location) ': effects)
| otherwise = throwValueError (Bitwise2Error left right)
where pair = (left, right)
lambda names (Subterm body bodyValue) = do
l <- label bodyValue
injValue . Closure names l . Env.bind (foldr Set.delete (Set.fromList (freeVariables body)) names) <$> getEnv
lambda parameters freeVariables body = do
l <- label body
injValue . Closure parameters l . Env.bind (foldr Set.delete freeVariables parameters) <$> getEnv
call op params = do
case prjValue op of

View File

@ -3,6 +3,7 @@ module Data.Syntax.Declaration where
import qualified Data.Abstract.Environment as Env
import Data.Abstract.Evaluatable
import qualified Data.Set as Set (fromList)
import Diffing.Algorithm
import Prologue
@ -22,7 +23,7 @@ instance Show1 Function where liftShowsPrec = genericLiftShowsPrec
instance Evaluatable Function where
eval Function{..} = do
name <- either (throwEvalError . FreeVariablesError) pure (freeVariable $ subterm functionName)
(v, addr) <- letrec name (lambda (paramNames functionParameters) functionBody)
(v, addr) <- letrec name (lambda (paramNames functionParameters) (Set.fromList (freeVariables functionBody)) (subtermValue functionBody))
modifyEnv (Env.insert name addr)
pure v
where paramNames = foldMap (freeVariables . subterm)
@ -46,7 +47,7 @@ instance Show1 Method where liftShowsPrec = genericLiftShowsPrec
instance Evaluatable Method where
eval Method{..} = do
name <- either (throwEvalError . FreeVariablesError) pure (freeVariable $ subterm methodName)
(v, addr) <- letrec name (lambda (paramNames methodParameters) methodBody)
(v, addr) <- letrec name (lambda (paramNames methodParameters) (Set.fromList (freeVariables methodBody)) (subtermValue methodBody))
modifyEnv (Env.insert name addr)
pure v
where paramNames = foldMap (freeVariables . subterm)

View File

@ -22,7 +22,7 @@ spec = parallel $ do
it "calls functions" $ do
(expected, _) <- evaluate $ do
identity <- lambda [name "x"] (term (variable (name "x")))
identity <- lambda [name "x"] lowerBound (variable (name "x"))
call identity [integer 123]
expected `shouldBe` Right (Value.injValue (Value.Integer (Number.Integer 123)))
@ -47,9 +47,6 @@ reassociate :: Either String (Either (SomeExc exc1) (Either (SomeExc exc2) (Eith
reassociate (Left s) = Left (SomeExc (injectSum (Const s)))
reassociate (Right (Right (Right (Right a)))) = Right a
term :: TermEvaluator Value -> Subterm Term (TermEvaluator Value)
term eval = Subterm (Term eval) eval
type TermEffects = Goto GotoEffects Value ': GotoEffects
type GotoEffects
= '[ LoopControl Value