From eeeade3e19a7ef99b19e6c451d1dc731867ed3ea Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Tue, 13 Apr 2021 14:44:42 -0400 Subject: [PATCH] allow packages to reference their own items explicitly --- src/Convert/Package.hs | 23 +++++++++++++++---- test/basic/package_self_reference.sv | 8 +++++++ test/basic/package_self_reference.v | 4 ++++ test/basic/package_self_reference_import.sv | 11 +++++++++ test/basic/package_self_reference_import.v | 4 ++++ test/basic/package_self_reference_shadow.sv | 11 +++++++++ test/basic/package_self_reference_shadow.v | 5 ++++ test/error/package_self_reference_early.sv | 9 ++++++++ ...ence.sv => package_self_reference_loop.sv} | 2 +- 9 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 test/basic/package_self_reference.sv create mode 100644 test/basic/package_self_reference.v create mode 100644 test/basic/package_self_reference_import.sv create mode 100644 test/basic/package_self_reference_import.v create mode 100644 test/basic/package_self_reference_shadow.sv create mode 100644 test/basic/package_self_reference_shadow.v create mode 100644 test/error/package_self_reference_early.sv rename test/error/{package_self_reference.sv => package_self_reference_loop.sv} (65%) diff --git a/src/Convert/Package.hs b/src/Convert/Package.hs index 1eb4f87..53ac738 100644 --- a/src/Convert/Package.hs +++ b/src/Convert/Package.hs @@ -292,13 +292,13 @@ processItems topName packageName moduleItems = do traverseDeclM :: Decl -> Scope Decl 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 Param p t x e -> declHelp x $ \x' -> Param p t x' e ParamType p x t -> declHelp x $ \x' -> ParamType p x' t CommentDecl c -> return $ CommentDecl c - traverseDeclTypesM traverseTypeM decl' >>= - traverseDeclExprsM traverseExprM where declHelp x f = prefixIdent x >>= return . f traverseTypeM :: Type -> Scope Type @@ -307,7 +307,7 @@ processItems topName packageName moduleItems = do x' <- lift $ resolveCSIdent p b scopeKeys x return $ Alias x' rs traverseTypeM (PSAlias p x rs) = do - x' <- lift $ resolvePSIdent p x + x' <- resolvePSIdent' p x return $ Alias x' rs traverseTypeM (Alias x rs) = resolveIdent x >>= \x' -> return $ Alias x' rs @@ -324,7 +324,7 @@ processItems topName packageName moduleItems = do x' <- lift $ resolveCSIdent p b scopeKeys x return $ Ident x' traverseExprM (PSIdent p x) = do - x' <- lift $ resolvePSIdent p x + x' <- resolvePSIdent' p x return $ Ident x' traverseExprM (Ident x) = resolveIdent x >>= return . Ident traverseExprM other = traverseSinglyNestedExprsM traverseExprM other @@ -347,6 +347,19 @@ processItems topName packageName moduleItems = do traverseStmtExprsM traverseExprM >=> 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 findPackage :: Identifier -> PackagesState Package findPackage packageName = do diff --git a/test/basic/package_self_reference.sv b/test/basic/package_self_reference.sv new file mode 100644 index 0000000..3e8a7f4 --- /dev/null +++ b/test/basic/package_self_reference.sv @@ -0,0 +1,8 @@ +package P; + localparam Bar = 1; + localparam Foo = P::Bar; +endpackage +module top; + import P::*; + initial $display(Foo); +endmodule diff --git a/test/basic/package_self_reference.v b/test/basic/package_self_reference.v new file mode 100644 index 0000000..3370fbb --- /dev/null +++ b/test/basic/package_self_reference.v @@ -0,0 +1,4 @@ +module top; + localparam Foo = 1; + initial $display(Foo); +endmodule diff --git a/test/basic/package_self_reference_import.sv b/test/basic/package_self_reference_import.sv new file mode 100644 index 0000000..2b74a8a --- /dev/null +++ b/test/basic/package_self_reference_import.sv @@ -0,0 +1,11 @@ +package Q; + localparam Bar = 1; +endpackage +package P; + import Q::Bar; + localparam Foo = P::Bar; +endpackage +module top; + import P::*; + initial $display(Foo); +endmodule diff --git a/test/basic/package_self_reference_import.v b/test/basic/package_self_reference_import.v new file mode 100644 index 0000000..3370fbb --- /dev/null +++ b/test/basic/package_self_reference_import.v @@ -0,0 +1,4 @@ +module top; + localparam Foo = 1; + initial $display(Foo); +endmodule diff --git a/test/basic/package_self_reference_shadow.sv b/test/basic/package_self_reference_shadow.sv new file mode 100644 index 0000000..0b562d2 --- /dev/null +++ b/test/basic/package_self_reference_shadow.sv @@ -0,0 +1,11 @@ +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 diff --git a/test/basic/package_self_reference_shadow.v b/test/basic/package_self_reference_shadow.v new file mode 100644 index 0000000..e782399 --- /dev/null +++ b/test/basic/package_self_reference_shadow.v @@ -0,0 +1,5 @@ +module top; + localparam Foo = 1; + localparam Bar = 2; + initial $display(Foo + Bar); +endmodule diff --git a/test/error/package_self_reference_early.sv b/test/error/package_self_reference_early.sv new file mode 100644 index 0000000..2dbc0a6 --- /dev/null +++ b/test/error/package_self_reference_early.sv @@ -0,0 +1,9 @@ +// 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 diff --git a/test/error/package_self_reference.sv b/test/error/package_self_reference_loop.sv similarity index 65% rename from test/error/package_self_reference.sv rename to test/error/package_self_reference_loop.sv index 154be5d..82cba94 100644 --- a/test/error/package_self_reference.sv +++ b/test/error/package_self_reference_loop.sv @@ -1,4 +1,4 @@ -// pattern: package dependency loop: "P" depends on "P" +// pattern: package "P" references undeclared local "P::Foo" package P; localparam Foo = P::Foo; endpackage