diff --git a/src/Convert/Package.hs b/src/Convert/Package.hs index dde27e2..5b29005 100644 --- a/src/Convert/Package.hs +++ b/src/Convert/Package.hs @@ -304,7 +304,8 @@ processItems topName packageName moduleItems = do traverseTypeM :: Type -> Scope Type traverseTypeM (CSAlias p b x rs) = do scopeKeys <- bindingsScopeKeys b - x' <- lift $ resolveCSIdent p b scopeKeys x + b' <- mapM traverseParamBindingM b + x' <- lift $ resolveCSIdent p b' scopeKeys x return $ Alias x' rs traverseTypeM (PSAlias p x rs) = do x' <- resolvePSIdent' p x @@ -321,7 +322,8 @@ processItems topName packageName moduleItems = do traverseExprM :: Expr -> Scope Expr traverseExprM (CSIdent p b x) = do scopeKeys <- bindingsScopeKeys b - x' <- lift $ resolveCSIdent p b scopeKeys x + b' <- mapM traverseParamBindingM b + x' <- lift $ resolveCSIdent p b' scopeKeys x return $ Ident x' traverseExprM (PSIdent p x) = do x' <- resolvePSIdent' p x @@ -347,6 +349,12 @@ processItems topName packageName moduleItems = do traverseStmtExprsM traverseExprM >=> traverseStmtLHSsM traverseLHSM + traverseParamBindingM :: ParamBinding -> Scope ParamBinding + traverseParamBindingM (x, Left t) = + traverseTypeM t >>= return . (x, ) . Left + traverseParamBindingM (x, Right e) = + traverseExprM e >>= return . (x, ) . Right + -- wrapper allowing explicit reference to local package items resolvePSIdent' :: Identifier -> Identifier -> Scope Identifier resolvePSIdent' p x = do @@ -481,7 +489,6 @@ resolveCSIdent className paramBindings scopeKeys itemName = do Decl $ Param Parameter t x $ case lookup x' bindings of Just (Right e') -> e' - Just (Left (Alias y [])) -> Ident y Just (Left t') -> error $ "cannot override parameter " ++ show x' ++ " in class " ++ show className @@ -497,7 +504,7 @@ resolveCSIdent className paramBindings scopeKeys itemName = do Decl $ ParamType Parameter x $ case lookup x' bindings of Just (Left t') -> t' - Just (Right (Ident t')) -> Alias t' [] + Just (Right (Ident y)) -> Alias y [] Just (Right e') -> error $ "cannot override type parameter " ++ show x' ++ " in class " ++ show className diff --git a/test/basic/class_param_nest.sv b/test/basic/class_param_nest.sv new file mode 100644 index 0000000..6c10aae --- /dev/null +++ b/test/basic/class_param_nest.sv @@ -0,0 +1,24 @@ +class C #( + parameter X = 1 +); + localparam Y = X * 2; +endclass + +package P; + localparam W = 5; +endpackage + +`define DUMP(expr) $display(`"expr = %0d`", expr); +`define DUMP_BOTH(prefix) `DUMP(prefix::X) `DUMP(prefix::Y) + +module top; + localparam Z = 3; + initial begin + `DUMP(Z) + `DUMP(P::W) + `DUMP_BOTH(C#()) + `DUMP_BOTH(C#(Z)) + `DUMP_BOTH(C#(P::W)) + `DUMP_BOTH(C#(C#(Z)::Y)) + end +endmodule diff --git a/test/basic/class_param_nest.v b/test/basic/class_param_nest.v new file mode 100644 index 0000000..1b28125 --- /dev/null +++ b/test/basic/class_param_nest.v @@ -0,0 +1,14 @@ +`define DUMP(expr, value) $display(`"expr = %0d`", value); +`define DUMP_BOTH(prefix, value) `DUMP(prefix::X, value) `DUMP(prefix::Y, (value) * 2) + +module top; + localparam Z = 3; + initial begin + `DUMP(Z, Z) + `DUMP(P::W, 5) + `DUMP_BOTH(C#(), 1) + `DUMP_BOTH(C#(Z), Z) + `DUMP_BOTH(C#(P::W), 5) + `DUMP_BOTH(C#(C#(Z)::Y), Z * 2) + end +endmodule