Commit eeeade3e by Zachary Snow

allow packages to reference their own items explicitly

parent c0b8ba17
...@@ -292,13 +292,13 @@ processItems topName packageName moduleItems = do ...@@ -292,13 +292,13 @@ processItems topName packageName moduleItems = do
traverseDeclM :: Decl -> Scope Decl traverseDeclM :: Decl -> Scope Decl
traverseDeclM decl = do traverseDeclM decl = do
decl' <- case decl of decl' <- traverseDeclTypesM traverseTypeM decl
>>= traverseDeclExprsM traverseExprM
case decl' of
Variable d t x a e -> declHelp x $ \x' -> Variable d t x' a e Variable d t x a e -> declHelp x $ \x' -> Variable d t x' a e
Param p t x e -> declHelp x $ \x' -> Param p t x' e Param p t x e -> declHelp x $ \x' -> Param p t x' e
ParamType p x t -> declHelp x $ \x' -> ParamType p x' t ParamType p x t -> declHelp x $ \x' -> ParamType p x' t
CommentDecl c -> return $ CommentDecl c CommentDecl c -> return $ CommentDecl c
traverseDeclTypesM traverseTypeM decl' >>=
traverseDeclExprsM traverseExprM
where declHelp x f = prefixIdent x >>= return . f where declHelp x f = prefixIdent x >>= return . f
traverseTypeM :: Type -> Scope Type traverseTypeM :: Type -> Scope Type
...@@ -307,7 +307,7 @@ processItems topName packageName moduleItems = do ...@@ -307,7 +307,7 @@ processItems topName packageName moduleItems = do
x' <- lift $ resolveCSIdent p b scopeKeys x x' <- lift $ resolveCSIdent p b scopeKeys x
return $ Alias x' rs return $ Alias x' rs
traverseTypeM (PSAlias p x rs) = do traverseTypeM (PSAlias p x rs) = do
x' <- lift $ resolvePSIdent p x x' <- resolvePSIdent' p x
return $ Alias x' rs return $ Alias x' rs
traverseTypeM (Alias x rs) = traverseTypeM (Alias x rs) =
resolveIdent x >>= \x' -> return $ Alias x' rs resolveIdent x >>= \x' -> return $ Alias x' rs
...@@ -324,7 +324,7 @@ processItems topName packageName moduleItems = do ...@@ -324,7 +324,7 @@ processItems topName packageName moduleItems = do
x' <- lift $ resolveCSIdent p b scopeKeys x x' <- lift $ resolveCSIdent p b scopeKeys x
return $ Ident x' return $ Ident x'
traverseExprM (PSIdent p x) = do traverseExprM (PSIdent p x) = do
x' <- lift $ resolvePSIdent p x x' <- resolvePSIdent' p x
return $ Ident x' return $ Ident x'
traverseExprM (Ident x) = resolveIdent x >>= return . Ident traverseExprM (Ident x) = resolveIdent x >>= return . Ident
traverseExprM other = traverseSinglyNestedExprsM traverseExprM other traverseExprM other = traverseSinglyNestedExprsM traverseExprM other
...@@ -347,6 +347,19 @@ processItems topName packageName moduleItems = do ...@@ -347,6 +347,19 @@ processItems topName packageName moduleItems = do
traverseStmtExprsM traverseExprM >=> traverseStmtExprsM traverseExprM >=>
traverseStmtLHSsM traverseLHSM traverseStmtLHSsM traverseLHSM
-- wrapper allowing explicit reference to local package items
resolvePSIdent' :: Identifier -> Identifier -> Scope Identifier
resolvePSIdent' p x = do
if p /= packageName then
lift $ resolvePSIdent p x
else do
details <- lookupElemM $ Dot (Ident p) x
return $ case details of
Just ([_, _], _, Declared) -> p ++ '_' : x
Just ([_, _], _, Imported rootPkg) -> rootPkg ++ '_' : x
_ -> error $ "package " ++ show p ++ " references"
++ " undeclared local \"" ++ p ++ "::" ++ x ++ "\""
-- locate a package by name, processing its contents if necessary -- locate a package by name, processing its contents if necessary
findPackage :: Identifier -> PackagesState Package findPackage :: Identifier -> PackagesState Package
findPackage packageName = do findPackage packageName = do
......
package P;
localparam Bar = 1;
localparam Foo = P::Bar;
endpackage
module top;
import P::*;
initial $display(Foo);
endmodule
module top;
localparam Foo = 1;
initial $display(Foo);
endmodule
package Q;
localparam Bar = 1;
endpackage
package P;
import Q::Bar;
localparam Foo = P::Bar;
endpackage
module top;
import P::*;
initial $display(Foo);
endmodule
module top;
localparam Foo = 1;
initial $display(Foo);
endmodule
package P;
localparam Bar = 1;
function automatic integer func;
localparam Bar = 2;
func = Bar + P::Bar;
endfunction
endpackage
module top;
import P::*;
initial $display(func());
endmodule
module top;
localparam Foo = 1;
localparam Bar = 2;
initial $display(Foo + Bar);
endmodule
// pattern: package "P" references undeclared local "P::Bar"
package P;
localparam Foo = P::Bar;
localparam Bar = 1;
endpackage
module top;
import P::*;
initial $display(Foo);
endmodule
// pattern: package dependency loop: "P" depends on "P" // pattern: package "P" references undeclared local "P::Foo"
package P; package P;
localparam Foo = P::Foo; localparam Foo = P::Foo;
endpackage endpackage
......
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