mirror of https://github.com/zachjs/sv2v.git
faster scope resolution
This commit is contained in:
parent
5667bdb589
commit
efe8de3933
|
|
@ -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
|
||||||
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 =
|
||||||
|
|
||||||
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
|
||||||
let replacements' = Map.insert index e replacements
|
directResolve subMapping rest
|
||||||
Just (replacements', element)
|
directResolve mapping (Access x e : rest) = do
|
||||||
else if e == Nil && null index then
|
Entry _ (index @ (_ : _)) subMapping <- Map.lookup x mapping
|
||||||
Just (replacements, element)
|
(replacements, element) <- directResolve subMapping rest
|
||||||
else
|
let replacements' = Map.insert index e replacements
|
||||||
Nothing
|
Just (replacements', element)
|
||||||
|
|
||||||
|
-- lookup accesses given a current scope prefix
|
||||||
|
resolveInScope :: Mapping a -> [Tier] -> [Access] -> LookupResult a
|
||||||
|
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
|
||||||
|
|
||||||
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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue