1
1
mirror of https://github.com/github/semantic.git synced 2024-12-15 01:51:39 +03:00

Store names as params in Closure

Co-Authored-By: Rick Winfrey <rick.winfrey@gmail.com>
This commit is contained in:
joshvera 2018-11-26 19:53:58 -05:00
parent 0186178ce1
commit af0184a195
6 changed files with 38 additions and 44 deletions

View File

@ -72,14 +72,14 @@ instance ( Carrier sig m
| Just e <- prj op = wrap $ case handleCoercible e of
Call callName params k -> Evaluator . k =<< do
case callName of
Closure _ _ name' paramNames _ _ -> do
Closure _ _ name' paramNames _ scope parentFrame -> do
let bindings = foldr (uncurry Map.insert) lowerBound (zip paramNames params)
let asStrings = asArray >=> traverse asString
if name "find_packages" == name' then do
if Just (name "find_packages") == name' then do
as <- maybe (pure mempty) (fmap (fmap stripQuotes) . asStrings) (Map.lookup (name "exclude") bindings)
put (FindPackages as)
else if name "setup" == name' then do
else if Just (name "setup") == name' then do
packageState <- get
if packageState == Unknown then do
as <- maybe (pure mempty) (fmap (fmap stripQuotes) . asStrings) (Map.lookup (name "packages") bindings)

View File

@ -69,7 +69,7 @@ data Comparator
--
-- In the concrete domain, introductions & eliminations respectively construct & pattern match against values, while in abstract domains they respectively construct & project finite sets of discrete observations of abstract values. For example, an abstract domain modelling integers as a sign (-, 0, or +) would introduce abstract values by mapping integers to their sign and eliminate them by mapping signs back to some canonical integer, e.g. - -> -1, 0 -> 0, + -> 1.
function :: (Member (Function term address value) sig, Carrier sig m) => Name -> [term] -> term -> Evaluator term address value m (ValueRef address value)
function :: (Member (Function term address value) sig, Carrier sig m) => Name -> [Name] -> term -> Evaluator term address value m (ValueRef address value)
function name params body = sendFunction (Function name params body ret)
data BuiltIn
@ -77,7 +77,7 @@ data BuiltIn
| Show
deriving (Eq, Ord, Show, Generic, NFData)
builtIn :: (Member (Function term address value) sig, Carrier sig m) => Name -> BuiltIn -> Evaluator term address value m (ValueRef address value)
builtIn :: (Member (Function term address value) sig, Carrier sig m) => Name -> BuiltIn -> Evaluator term address value m value
builtIn name = sendFunction . flip (BuiltIn name) ret
call :: (Member (Function term address value) sig, Carrier sig m) => value -> [value] -> Evaluator term address value m (ValueRef address value)
@ -87,8 +87,8 @@ sendFunction :: (Member (Function term address value) sig, Carrier sig m) => Fun
sendFunction = send
data Function term address value (m :: * -> *) k
= Function Name [term] term (ValueRef address value -> k)
| BuiltIn Name BuiltIn (ValueRef address value -> k)
= Function Name [Name] term (ValueRef address value -> k)
| BuiltIn Name BuiltIn (value -> k)
| Call value [value] (ValueRef address value -> k)
deriving (Functor)

View File

@ -111,7 +111,8 @@ instance HasPrelude 'PHP
instance HasPrelude 'Python where
definePrelude _ =
void $ builtIn (X.name "print") Print
void . withLexicalScopeAndFrame $
define (Declaration $ X.name "print") (builtIn (X.name "print") Print)
instance HasPrelude 'Ruby where
definePrelude _ = do

View File

@ -49,11 +49,8 @@ instance ( Member (Allocator address) sig
_ <- withScope scope $ do
for_ params $ \param -> do
name <- maybeM (throwEvalError NoNameError) (declaredName param)
-- Eval param in order to update (State Span) to the Span of the param.
span <- (runFunction (Evaluator . eval) (Evaluator (eval param))) >> get @Span
declare (Declaration name) span Nothing
functionSpan <- ask @Span
declare (Declaration param) functionSpan Nothing
-- TODO: Ask @robrix if we should evaluate the body under Abstract semantics
catchReturn (runFunction (Evaluator . eval) (Evaluator (eval body)))
@ -62,7 +59,7 @@ instance ( Member (Allocator address) sig
assign address Abstract
Evaluator $ runFunctionC (k (LvalMember address)) eval
BuiltIn _ _ k -> runFunctionC (k (Rval Abstract)) eval
BuiltIn _ _ k -> runFunctionC (k Abstract) eval
Call _ _ k -> runEvaluator $ do
rvalBox Abstract >>= Evaluator . flip runFunctionC eval . k) op)

View File

@ -28,7 +28,7 @@ import Prologue
import qualified Data.Map.Strict as Map
data Value term address
= Closure PackageInfo ModuleInfo Name [Name] (Either BuiltIn term) address -- TODO: Remove this address since it's a scope address
= Closure PackageInfo ModuleInfo (Maybe Name) [Name] (Either BuiltIn term) address (Maybe address)
| Unit
| Boolean Bool
| Integer (Number.Number Integer)
@ -51,7 +51,7 @@ data Value term address
instance Ord address => ValueRoots address (Value term address) where
valueRoots v
| Closure _ _ _ _ _ _ <- v = undefined -- Env.addresses env
| Closure _ _ _ _ _ _ _ <- v = undefined -- Env.addresses env
| otherwise = mempty
@ -88,45 +88,43 @@ instance ( FreeVariables term
-- TODO: Declare all params
currentScope' <- currentScope
let lexicalEdges = maybe mempty (Map.singleton Lexical . pure) currentScope'
scope <- newScope lexicalEdges
associatedScope <- newScope lexicalEdges
-- TODO: Fix this if we find a solution to declaring names of functions without throwing a lookupPathError.
-- declare (Declaration name) span (Just scope)
putDeclarationScope (Declaration name) scope
putDeclarationScope (Declaration name) associatedScope
names <- withScope scope . for params $ \param -> do
-- Leave it up to the Evaluatable instance of param to declare the name
_ <- runFunction (Evaluator . eval) (Evaluator (eval param))
maybeM (throwEvalError NoNameError) (declaredName param)
functionSpan <- ask @Span
names <- withScope associatedScope . for params $ \param ->
param <$ declare (Declaration param) functionSpan Nothing
address <- lookupDeclaration @(Value term address) (Declaration name)
let closure = Closure packageInfo moduleInfo name names (Right body) scope
currentFrame' <- currentFrame
let closure = Closure packageInfo moduleInfo (Just name) names (Right body) associatedScope currentFrame'
assign address closure
Evaluator $ runFunctionC (k (Rval closure)) eval
Abstract.BuiltIn name builtIn k -> runEvaluator $ do
packageInfo <- currentPackage
moduleInfo <- currentModule
span <- ask @Span -- TODO: This is probably wrong.
currentScope' <- currentScope
currentFrame' <- currentFrame @(Value term address)
let lexicalEdges = maybe mempty (Map.singleton Lexical . pure) currentScope'
scope <- newScope lexicalEdges
declare (Declaration name) span (Just scope)
-- TODO: Store the name of the BuiltIn in Abstract.BuiltIn, showing the builtIn name is wrong.
address <- lookupDeclaration @(Value term address) (Declaration name)
assign address (Closure packageInfo moduleInfo name [] (Left builtIn) scope)
Evaluator $ runFunctionC (k (LvalMember address)) eval
associatedScope <- newScope lexicalEdges
let closure = Closure packageInfo moduleInfo Nothing [] (Left builtIn) associatedScope currentFrame'
Evaluator $ runFunctionC (k closure) eval
Abstract.Call op params k -> runEvaluator $ do
boxed <- case op of
Closure _ _ _ _ (Left Print) _ -> traverse (trace . show) params *> rvalBox Unit
Closure _ _ name _ (Left Show) _ -> pure name >>= rvalBox . String . pack . show
Closure packageInfo moduleInfo name names (Right body) scope -> do
Closure _ _ _ _ (Left Print) _ _ -> traverse (trace . show) params *> rvalBox Unit
Closure _ _ _ _ (Left Show) _ _ -> rvalBox . String . pack $ show params
Closure packageInfo moduleInfo _ names (Right body) associatedScope parentFrame -> do
-- Evaluate the bindings and body with the closures package/module info in scope in order to
-- charge them to the closure's origin.
withCurrentPackage packageInfo . withCurrentModule moduleInfo $ do
declarationScope <- lookupDeclarationScope (Declaration name)
declarationFrame <- lookupDeclarationFrame (Declaration name)
let frameEdges = Map.singleton Lexical (Map.singleton declarationScope declarationFrame)
frameAddress <- newFrame scope frameEdges
parentScope <- traverse scopeLookup parentFrame
let frameEdges = case (parentScope, parentFrame) of
(Just scope, Just frame) -> Map.singleton Lexical (Map.singleton scope frame)
_ -> mempty
frameAddress <- newFrame associatedScope frameEdges
withScopeAndFrame frameAddress $ do
for_ (zip names params) $ \(name, param) -> do
addr <- lookupDeclaration (Declaration name)

View File

@ -270,12 +270,10 @@ instance ( Member (Allocator address) sig
let value = withLexicalScopeAndFrame $ do
(_, tvars) <- foldr (\ param rest -> do
tvar <- Var <$> fresh
name <- maybeM (throwEvalError NoNameError) (declaredName param)
-- Eval param in order to set the Span state correctly
span <- (runFunction (Evaluator . eval) (Evaluator (eval param))) >> get @Span
declare (Declaration name) span Nothing
address <- lookupDeclaration (Declaration name)
functionSpan <- ask @Span
declare (Declaration param) functionSpan Nothing
address <- lookupDeclaration (Declaration param)
-- assign tvar values to names in the frame of the function?
assign address tvar
bimap id (tvar :) <$> rest) (pure (undefined, [])) params
@ -283,8 +281,8 @@ instance ( Member (Allocator address) sig
bimap id (zeroOrMoreProduct tvars :->) <$> (catchReturn (runFunction (Evaluator . eval) (Evaluator (eval body))))
value >>= Evaluator . flip runFunctionC eval . k
Abstract.BuiltIn _ Print k -> runFunctionC (k (Rval $ String :-> Unit)) eval
Abstract.BuiltIn _ Show k -> runFunctionC (k (Rval $ Object :-> String)) eval
Abstract.BuiltIn _ Print k -> runFunctionC (k (String :-> Unit)) eval
Abstract.BuiltIn _ Show k -> runFunctionC (k (Object :-> String)) eval
Abstract.Call op paramTypes k -> runEvaluator $ do
tvar <- fresh
let needed = zeroOrMoreProduct paramTypes :-> Var tvar