Commit efe8de39 by Zachary Snow

faster scope resolution

parent 5667bdb5
...@@ -43,8 +43,7 @@ module Convert.Scoper ...@@ -43,8 +43,7 @@ module Convert.Scoper
import Control.Monad.State import Control.Monad.State
import Data.Functor.Identity (runIdentity) import Data.Functor.Identity (runIdentity)
import Data.List (inits) import Data.Maybe (isNothing)
import Data.Maybe (catMaybes)
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import Convert.Traverse import Convert.Traverse
...@@ -130,10 +129,6 @@ exitProcedure = do ...@@ -130,10 +129,6 @@ exitProcedure = do
then error "exitProcedure invariant failed" then error "exitProcedure invariant failed"
else put $ s { sProcedure = False } else put $ s { sProcedure = False }
tierToAccess :: Tier -> Access
tierToAccess (Tier x "") = Access x Nil
tierToAccess (Tier x y) = Access x (Ident y)
exprToAccesses :: Expr -> Maybe [Access] exprToAccesses :: Expr -> Maybe [Access]
exprToAccesses (Ident x) = Just [Access x Nil] exprToAccesses (Ident x) = Just [Access x Nil]
exprToAccesses (Bit (Ident x) y) = Just [Access x y] exprToAccesses (Bit (Ident x) y) = Just [Access x y]
...@@ -166,21 +161,38 @@ injectItem item = ...@@ -166,21 +161,38 @@ injectItem item =
type Replacements = Map.Map Identifier Expr type Replacements = Map.Map Identifier Expr
attemptResolve :: Mapping a -> [Access] -> Maybe (Replacements, a) -- lookup accesses by direct match (no search)
attemptResolve _ [] = Nothing directResolve :: Mapping a -> [Access] -> Maybe (Replacements, a)
attemptResolve mapping (Access x e : rest) = do directResolve _ [] = Nothing
Entry maybeElement index subMapping <- Map.lookup x mapping directResolve mapping [Access x Nil] = do
if null rest && e == Nil then Entry maybeElement _ _ <- Map.lookup x mapping
fmap (Map.empty, ) maybeElement fmap (Map.empty, ) maybeElement
else do directResolve _ [_] = Nothing
(replacements, element) <- attemptResolve subMapping rest directResolve mapping (Access x Nil : rest) = do
if e /= Nil && not (null index) then do Entry _ "" subMapping <- Map.lookup x mapping
directResolve subMapping rest
directResolve mapping (Access x e : rest) = do
Entry _ (index @ (_ : _)) subMapping <- Map.lookup x mapping
(replacements, element) <- directResolve subMapping rest
let replacements' = Map.insert index e replacements let replacements' = Map.insert index e replacements
Just (replacements', element) Just (replacements', element)
else if e == Nil && null index then
Just (replacements, element) -- lookup accesses given a current scope prefix
else resolveInScope :: Mapping a -> [Tier] -> [Access] -> LookupResult a
Nothing resolveInScope mapping [] accesses = do
(replacements, element) <- directResolve mapping accesses
Just (accesses, replacements, element)
resolveInScope mapping (Tier x y : rest) accesses = do
Entry _ _ subMapping <- Map.lookup x mapping
let deep = resolveInScope subMapping rest accesses
let side = resolveInScope subMapping [] accesses
let chosen = if isNothing deep then side else deep
(accesses', replacements, element) <- chosen
if null y
then Just (Access x Nil : accesses', replacements, element)
else do
let replacements' = Map.insert y (Ident y) replacements
Just (Access x (Ident y) : accesses', replacements', element)
type LookupResult a = Maybe ([Access], Replacements, a) type LookupResult a = Maybe ([Access], Replacements, a)
...@@ -200,17 +212,9 @@ instance ScopeKey Identifier where ...@@ -200,17 +212,9 @@ instance ScopeKey Identifier where
lookupAccesses :: Scopes a -> [Access] -> LookupResult a lookupAccesses :: Scopes a -> [Access] -> LookupResult a
lookupAccesses scopes accesses = do lookupAccesses scopes accesses = do
if null results let deep = resolveInScope (sMapping scopes) (sCurrent scopes) accesses
then Nothing let side = resolveInScope (sMapping scopes) [] accesses
else Just $ last results if isNothing deep then side else deep
where
options = inits $ map tierToAccess (sCurrent scopes)
try option =
fmap toResult $ attemptResolve (sMapping scopes) full
where
full = option ++ accesses
toResult (a, b) = (full, a, b)
results = catMaybes $ map try options
withinProcedureM :: Monad m => ScoperT a m Bool withinProcedureM :: Monad m => ScoperT a m Bool
withinProcedureM = gets sProcedure withinProcedureM = gets sProcedure
......
Markdown is supported
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