invert expression scoping application order

This commit is contained in:
Zachary Snow 2024-12-11 08:51:29 -05:00
parent c56a91b290
commit 1c13bcf557
3 changed files with 20 additions and 5 deletions

View File

@ -76,6 +76,7 @@ module Convert.Scoper
import Control.Monad (join, when)
import Control.Monad.State.Strict
import Data.Functor ((<&>))
import Data.List (findIndices, intercalate, isPrefixOf, partition)
import Data.Maybe (isNothing)
import qualified Data.Map.Strict as Map
@ -204,18 +205,24 @@ replaceInExpr' replacements other =
-- refer to currently visible declarations so it can be substituted elsewhere
scopeExpr :: Monad m => Expr -> ScoperT a m Expr
scopeExpr expr = do
expr' <- traverseSinglyNestedExprsM scopeExpr expr
>>= traverseExprTypesM scopeType
details <- lookupElemM expr'
details <- lookupElemM expr
case details of
Just (accesses, _, _) -> return $ accessesToExpr accesses
_ -> return expr'
Just (accesses, replacements, _) ->
mapM (scopeResolvedAccess replacements) accesses <&> accessesToExpr
_ -> traverseSinglyNestedExprsM scopeExpr expr
>>= traverseExprTypesM scopeType
scopeType :: Monad m => Type -> ScoperT a m Type
scopeType = traverseNestedTypesM $ traverseTypeExprsM scopeExpr
{-# INLINABLE scopeExpr #-}
{-# INLINABLE scopeType #-}
scopeResolvedAccess :: Monad m => Replacements -> Access -> ScoperT a m Access
scopeResolvedAccess _ access@(Access _ Nil) = return access
scopeResolvedAccess replacements access@(Access _ (Ident index))
| Map.member index replacements = return access
scopeResolvedAccess _ (Access name expr) = scopeExpr expr <&> Access name
scopeExprWithScopes :: Scopes a -> Expr -> Expr
scopeExprWithScopes scopes = flip evalState scopes . scopeExpr

View File

@ -16,4 +16,10 @@ module top;
$display("%b %b", x[1:0], top.x[1:0]);
$display("%b %b", x[0+:1], top.x[0+:1]);
end
parameter int Q = 2;
typedef struct {
logic [Q-1:0] y;
} T;
T y;
assign y.y = 0;
endmodule

View File

@ -10,4 +10,6 @@ module top;
$display("%b %b", x[1:0], top[1:0]);
$display("%b %b", x[0+:1], top[0+:1]);
end
wire [1:0] y;
assign y = 0;
endmodule