Commit 3f20055c by Zachary Snow

proper support for static class methods

parent afc3ea43
...@@ -77,7 +77,22 @@ collectPackageM (PackageItem item) = ...@@ -77,7 +77,22 @@ collectPackageM (PackageItem item) =
collectPackageM (Package _ name items) = collectPackageM (Package _ name items) =
tell (Map.singleton name (Map.empty, items), Map.empty, []) tell (Map.singleton name (Map.empty, items), Map.empty, [])
collectPackageM (Class _ name decls items) = collectPackageM (Class _ name decls items) =
tell (Map.empty, Map.singleton name (decls, items), []) tell (Map.empty, Map.singleton name (decls, map unpackClassItem items), [])
where
unpackClassItem :: ClassItem -> PackageItem
unpackClassItem (item @ (_, Task{})) = checkTF item
unpackClassItem (item @ (_, Function{})) = checkTF item
unpackClassItem item = checkNonTF item
checkTF :: ClassItem -> PackageItem
checkTF (QStatic, item) = item
checkTF (_, item) =
error $ "unsupported declaration of non-static method " ++ itemName
where [itemName] = piNames item
checkNonTF :: ClassItem -> PackageItem
checkNonTF (QNone, item) = item
checkNonTF (qualifier, _) =
error $ "unexpected qualifier " ++ show qualifier
++ " on a class item which is not a task or a function"
collectPackageM _ = return () collectPackageM _ = return ()
-- elaborate all packages and their usages -- elaborate all packages and their usages
......
...@@ -165,11 +165,13 @@ traverseModuleItemsM mapper (Class lifetime name decls items) = do ...@@ -165,11 +165,13 @@ traverseModuleItemsM mapper (Class lifetime name decls items) = do
declsWrapped' <- mapM (traverseNestedModuleItemsM mapper) declsWrapped declsWrapped' <- mapM (traverseNestedModuleItemsM mapper) declsWrapped
let decls' = map (\(MIPackageItem (Decl decl)) -> decl) $ let decls' = map (\(MIPackageItem (Decl decl)) -> decl) $
concatMap breakGenerate declsWrapped' concatMap breakGenerate declsWrapped'
let itemsWrapped = map MIPackageItem items items' <- fmap concat $ mapM indirect items
itemsWrapped' <- mapM (traverseNestedModuleItemsM mapper) itemsWrapped
let items' = map (\(MIPackageItem item) -> item) $
concatMap breakGenerate itemsWrapped'
return $ Class lifetime name decls' items' return $ Class lifetime name decls' items'
where
indirect (qualifier, item) =
fmap (map (unwrap qualifier) . breakGenerate) $
traverseNestedModuleItemsM mapper (MIPackageItem item)
unwrap qualifier = \(MIPackageItem item) -> (qualifier, item)
traverseModuleItems :: Mapper ModuleItem -> Mapper Description traverseModuleItems :: Mapper ModuleItem -> Mapper Description
traverseModuleItems = unmonad traverseModuleItemsM traverseModuleItems = unmonad traverseModuleItemsM
......
...@@ -10,6 +10,8 @@ module Language.SystemVerilog.AST.Description ...@@ -10,6 +10,8 @@ module Language.SystemVerilog.AST.Description
, PackageItem (..) , PackageItem (..)
, PartKW (..) , PartKW (..)
, Lifetime (..) , Lifetime (..)
, Qualifier (..)
, ClassItem
) where ) where
import Text.Printf (printf) import Text.Printf (printf)
...@@ -26,7 +28,7 @@ data Description ...@@ -26,7 +28,7 @@ data Description
= Part [Attr] Bool PartKW Lifetime Identifier [Identifier] [ModuleItem] = Part [Attr] Bool PartKW Lifetime Identifier [Identifier] [ModuleItem]
| PackageItem PackageItem | PackageItem PackageItem
| Package Lifetime Identifier [PackageItem] | Package Lifetime Identifier [PackageItem]
| Class Lifetime Identifier [Decl] [PackageItem] | Class Lifetime Identifier [Decl] [ClassItem]
deriving Eq deriving Eq
instance Show Description where instance Show Description where
...@@ -54,8 +56,8 @@ instance Show Description where ...@@ -54,8 +56,8 @@ instance Show Description where
printf "class %s%s;\n%s\nendclass" printf "class %s%s;\n%s\nendclass"
(showPad lifetime) name bodyStr (showPad lifetime) name bodyStr
where where
bodyStr = indent $ unlines' $ map show items' bodyStr = indent $ unlines' $ map showClassItem items'
items' = (map Decl decls) ++ items items' = (map (\decl -> (QNone, Decl decl)) decls) ++ items
show (PackageItem i) = show i show (PackageItem i) = show i
data PackageItem data PackageItem
...@@ -102,3 +104,21 @@ instance Show Lifetime where ...@@ -102,3 +104,21 @@ instance Show Lifetime where
show Static = "static" show Static = "static"
show Automatic = "automatic" show Automatic = "automatic"
show Inherit = "" show Inherit = ""
type ClassItem = (Qualifier, PackageItem)
showClassItem :: ClassItem -> String
showClassItem (qualifier, item) = showPad qualifier ++ show item
data Qualifier
= QNone
| QStatic
| QLocal
| QProtected
deriving Eq
instance Show Qualifier where
show QNone = ""
show QStatic = "static"
show QLocal = "local"
show QProtected = "protected"
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
-} -}
{ {
{-# LANGUAGE BlockArguments #-} {-# LANGUAGE BlockArguments #-}
{-# LANGUAGE TupleSections #-}
module Language.SystemVerilog.Parser.Parse (parse) where module Language.SystemVerilog.Parser.Parse (parse) where
import Control.Monad.Except import Control.Monad.Except
...@@ -557,7 +558,7 @@ InterfaceKW :: { PartKW } ...@@ -557,7 +558,7 @@ InterfaceKW :: { PartKW }
PackageDeclaration :: { Description } PackageDeclaration :: { Description }
: "package" Lifetime Identifier ";" PackageItems endpackage StrTag {% checkTag $3 $7 $ Package $2 $3 $5 } : "package" Lifetime Identifier ";" PackageItems endpackage StrTag {% checkTag $3 $7 $ Package $2 $3 $5 }
| "class" Lifetime Identifier PIParams ";" PackageItems endclass StrTag {% checkTag $3 $8 $ Class $2 $3 $4 $6 } | "class" Lifetime Identifier PIParams ";" ClassItems endclass StrTag {% checkTag $3 $8 $ Class $2 $3 $4 $6 }
StrTag :: { Identifier } StrTag :: { Identifier }
: {- empty -} { "" } : {- empty -} { "" }
...@@ -643,7 +644,7 @@ DeclToken :: { DeclToken } ...@@ -643,7 +644,7 @@ DeclToken :: { DeclToken }
| "." Identifier {% posInject \p -> DTDot p $2 } | "." Identifier {% posInject \p -> DTDot p $2 }
| PortBindings {% posInject \p -> DTInstance p $1 } | PortBindings {% posInject \p -> DTInstance p $1 }
| Signing {% posInject \p -> DTSigning p $1 } | Signing {% posInject \p -> DTSigning p $1 }
| ExplicitLifetime {% posInject \p -> DTLifetime p $1 } | "automatic" {% posInject \p -> DTLifetime p Automatic }
| "const" PartialType {% posInject \p -> DTType p $2 } | "const" PartialType {% posInject \p -> DTType p $2 }
| "const" PartialTypeAlias {% posInject \p -> DTType p $2 } | "const" PartialTypeAlias {% posInject \p -> DTType p $2 }
| "{" StreamOp StreamSize Concat "}" {% posInject \p -> DTStream p $2 $3 (map toLHS $4) } | "{" StreamOp StreamSize Concat "}" {% posInject \p -> DTStream p $2 $3 (map toLHS $4) }
...@@ -697,6 +698,7 @@ NonGenerateModuleItem :: { [ModuleItem] } ...@@ -697,6 +698,7 @@ NonGenerateModuleItem :: { [ModuleItem] }
| "genvar" Identifiers ";" { map Genvar $2 } | "genvar" Identifiers ";" { map Genvar $2 }
| "modport" ModportItems ";" { map (uncurry Modport) $2 } | "modport" ModportItems ";" { map (uncurry Modport) $2 }
| NonDeclPackageItem { map MIPackageItem $1 } | NonDeclPackageItem { map MIPackageItem $1 }
| TaskOrFunction { [MIPackageItem $1] }
| NInputGateKW NInputGates ";" { map (\(a, b, c, d) -> NInputGate $1 a b c d) $2 } | NInputGateKW NInputGates ";" { map (\(a, b, c, d) -> NInputGate $1 a b c d) $2 }
| NOutputGateKW NOutputGates ";" { map (\(a, b, c, d) -> NOutputGate $1 a b c d) $2 } | NOutputGateKW NOutputGates ";" { map (\(a, b, c, d) -> NOutputGate $1 a b c d) $2 }
| AttributeInstance ModuleItem { map (addMIAttr $1) $2 } | AttributeInstance ModuleItem { map (addMIAttr $1) $2 }
...@@ -843,22 +845,45 @@ PackageItems :: { [PackageItem] } ...@@ -843,22 +845,45 @@ PackageItems :: { [PackageItem] }
| ";" PackageItems { $2 } | ";" PackageItems { $2 }
| PITrace PackageItem PackageItems { $1 : $2 ++ $3 } | PITrace PackageItem PackageItems { $1 : $2 ++ $3 }
PackageItem :: { [PackageItem] } PackageItem :: { [PackageItem] }
: PackageOrClassItem { $1}
| TaskOrFunction { [$1] }
ClassItems :: { [ClassItem] }
: {- empty -} { [] }
| ";" ClassItems { $2 }
| CITrace ClassItem ClassItems { $1 : $2 ++ $3 }
ClassItem :: { [ClassItem] }
: ClassItemQualifier PackageOrClassItem { map ($1, ) $2 }
| ClassItemQualifier TaskOrFunction { [($1, $2)] }
ClassItemQualifier :: { Qualifier }
: {- empty -} { QNone }
| "static" { QStatic }
| "local" { QLocal }
| "protected" { QProtected }
PackageOrClassItem :: { [PackageItem] }
: DeclTokens(";") { map Decl $ parseDTsAsDecls $1 } : DeclTokens(";") { map Decl $ parseDTsAsDecls $1 }
| ParameterDecl(";") { map Decl $1 } | ParameterDecl(";") { map Decl $1 }
| NonDeclPackageItem { $1 } | NonDeclPackageItem { $1 }
NonDeclPackageItem :: { [PackageItem] } NonDeclPackageItem :: { [PackageItem] }
: "typedef" Type Identifier ";" { [Decl $ ParamType Localparam $3 $2] } : Typedef { [Decl $1] }
| "typedef" Type Identifier DimensionsNonEmpty ";" { [Decl $ ParamType Localparam $3 (UnpackedType $2 $4)] } | ImportOrExport { $1 }
| "typedef" TypedefRef Identifier ";" { [Decl $ ParamType Localparam $3 $2] }
| "function" Lifetime FuncRetAndName TFItems DeclsAndStmts endfunction StrTag {% checkTag (snd $3) $7 [Function $2 (fst $3) (snd $3) (map makeInput $4 ++ fst $5) (snd $5)] }
| "function" Lifetime "void" Identifier TFItems DeclsAndStmts endfunction StrTag {% checkTag $4 $8 [Task $2 $4 ($5 ++ fst $6) (snd $6)] }
| "task" Lifetime Identifier TFItems DeclsAndStmts endtask StrTag {% checkTag $3 $7 [Task $2 $3 ($4 ++ fst $5) (snd $5)] }
| "import" PackageImportItems ";" { map (uncurry Import) $2 }
| "export" PackageImportItems ";" { map (uncurry Export) $2 }
| "export" "*" "::" "*" ";" { [Export "" ""] }
| ForwardTypedef ";" { $1 } | ForwardTypedef ";" { $1 }
| TimeunitsDeclaration { $1 } | TimeunitsDeclaration { $1 }
| Directive { [Directive $1] } | Directive { [Directive $1] }
ImportOrExport :: { [PackageItem] }
: "import" PackageImportItems ";" { map (uncurry Import) $2 }
| "export" PackageImportItems ";" { map (uncurry Export) $2 }
| "export" "*" "::" "*" ";" { [Export "" ""] }
TaskOrFunction :: { PackageItem }
: "function" Lifetime FuncRetAndName TFItems DeclsAndStmts endfunction StrTag {% checkTag (snd $3) $7 $ Function $2 (fst $3) (snd $3) (map makeInput $4 ++ fst $5) (snd $5) }
| "function" Lifetime "void" Identifier TFItems DeclsAndStmts endfunction StrTag {% checkTag $4 $8 $ Task $2 $4 ($5 ++ fst $6) (snd $6) }
| "task" Lifetime Identifier TFItems DeclsAndStmts endtask StrTag {% checkTag $3 $7 $ Task $2 $3 ($4 ++ fst $5) (snd $5) }
Typedef :: { Decl }
: "typedef" Type Identifier ";" { ParamType Localparam $3 $2 }
| "typedef" Type Identifier DimensionsNonEmpty ";" { ParamType Localparam $3 (UnpackedType $2 $4) }
| "typedef" TypedefRef Identifier ";" { ParamType Localparam $3 $2 }
TypedefRef :: { Type } TypedefRef :: { Type }
: Identifier "." Identifier { TypedefRef $ Dot (Ident $1) $3 } : Identifier "." Identifier { TypedefRef $ Dot (Ident $1) $3 }
| Identifier "[" Expr "]" "." Identifier { TypedefRef $ Dot (Bit (Ident $1) $3) $6 } | Identifier "[" Expr "]" "." Identifier { TypedefRef $ Dot (Bit (Ident $1) $3) $6 }
...@@ -1391,6 +1416,8 @@ MITrace :: { ModuleItem } ...@@ -1391,6 +1416,8 @@ MITrace :: { ModuleItem }
: PITrace { MIPackageItem $1 } : PITrace { MIPackageItem $1 }
PITrace :: { PackageItem } PITrace :: { PackageItem }
: Trace { Decl $ CommentDecl $1 } : Trace { Decl $ CommentDecl $1 }
CITrace :: { ClassItem }
: PITrace { (QNone, $1) }
StmtTrace :: { Stmt } StmtTrace :: { Stmt }
: Trace { CommentStmt $1 } : Trace { CommentStmt $1 }
Trace :: { String } Trace :: { String }
......
class C #( class C #(
parameter X = 1 parameter X = 1
); );
// TODO: this should be static static task dump;
task dump;
$display("C#(%0d)::dump()", X); $display("C#(%0d)::dump()", X);
endtask endtask
endclass endclass
......
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