Commit 3f20055c by Zachary Snow

proper support for static class methods

parent afc3ea43
......@@ -77,7 +77,22 @@ collectPackageM (PackageItem item) =
collectPackageM (Package _ name items) =
tell (Map.singleton name (Map.empty, items), Map.empty, [])
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 ()
-- elaborate all packages and their usages
......
......@@ -165,11 +165,13 @@ traverseModuleItemsM mapper (Class lifetime name decls items) = do
declsWrapped' <- mapM (traverseNestedModuleItemsM mapper) declsWrapped
let decls' = map (\(MIPackageItem (Decl decl)) -> decl) $
concatMap breakGenerate declsWrapped'
let itemsWrapped = map MIPackageItem items
itemsWrapped' <- mapM (traverseNestedModuleItemsM mapper) itemsWrapped
let items' = map (\(MIPackageItem item) -> item) $
concatMap breakGenerate itemsWrapped'
items' <- fmap concat $ mapM indirect 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 = unmonad traverseModuleItemsM
......
......@@ -10,6 +10,8 @@ module Language.SystemVerilog.AST.Description
, PackageItem (..)
, PartKW (..)
, Lifetime (..)
, Qualifier (..)
, ClassItem
) where
import Text.Printf (printf)
......@@ -26,7 +28,7 @@ data Description
= Part [Attr] Bool PartKW Lifetime Identifier [Identifier] [ModuleItem]
| PackageItem PackageItem
| Package Lifetime Identifier [PackageItem]
| Class Lifetime Identifier [Decl] [PackageItem]
| Class Lifetime Identifier [Decl] [ClassItem]
deriving Eq
instance Show Description where
......@@ -54,8 +56,8 @@ instance Show Description where
printf "class %s%s;\n%s\nendclass"
(showPad lifetime) name bodyStr
where
bodyStr = indent $ unlines' $ map show items'
items' = (map Decl decls) ++ items
bodyStr = indent $ unlines' $ map showClassItem items'
items' = (map (\decl -> (QNone, Decl decl)) decls) ++ items
show (PackageItem i) = show i
data PackageItem
......@@ -102,3 +104,21 @@ instance Show Lifetime where
show Static = "static"
show Automatic = "automatic"
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 @@
-}
{
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE TupleSections #-}
module Language.SystemVerilog.Parser.Parse (parse) where
import Control.Monad.Except
......@@ -557,7 +558,7 @@ InterfaceKW :: { PartKW }
PackageDeclaration :: { Description }
: "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 }
: {- empty -} { "" }
......@@ -643,7 +644,7 @@ DeclToken :: { DeclToken }
| "." Identifier {% posInject \p -> DTDot p $2 }
| PortBindings {% posInject \p -> DTInstance 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" PartialTypeAlias {% posInject \p -> DTType p $2 }
| "{" StreamOp StreamSize Concat "}" {% posInject \p -> DTStream p $2 $3 (map toLHS $4) }
......@@ -697,6 +698,7 @@ NonGenerateModuleItem :: { [ModuleItem] }
| "genvar" Identifiers ";" { map Genvar $2 }
| "modport" ModportItems ";" { map (uncurry Modport) $2 }
| NonDeclPackageItem { map MIPackageItem $1 }
| TaskOrFunction { [MIPackageItem $1] }
| 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 }
| AttributeInstance ModuleItem { map (addMIAttr $1) $2 }
......@@ -843,22 +845,45 @@ PackageItems :: { [PackageItem] }
| ";" PackageItems { $2 }
| PITrace PackageItem PackageItems { $1 : $2 ++ $3 }
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 }
| ParameterDecl(";") { map Decl $1 }
| NonDeclPackageItem { $1 }
NonDeclPackageItem :: { [PackageItem] }
: "typedef" Type Identifier ";" { [Decl $ ParamType Localparam $3 $2] }
| "typedef" Type Identifier DimensionsNonEmpty ";" { [Decl $ ParamType Localparam $3 (UnpackedType $2 $4)] }
| "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 "" ""] }
: Typedef { [Decl $1] }
| ImportOrExport { $1 }
| ForwardTypedef ";" { $1 }
| TimeunitsDeclaration { $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 }
: Identifier "." Identifier { TypedefRef $ Dot (Ident $1) $3 }
| Identifier "[" Expr "]" "." Identifier { TypedefRef $ Dot (Bit (Ident $1) $3) $6 }
......@@ -1391,6 +1416,8 @@ MITrace :: { ModuleItem }
: PITrace { MIPackageItem $1 }
PITrace :: { PackageItem }
: Trace { Decl $ CommentDecl $1 }
CITrace :: { ClassItem }
: PITrace { (QNone, $1) }
StmtTrace :: { Stmt }
: Trace { CommentStmt $1 }
Trace :: { String }
......
class C #(
parameter X = 1
);
// TODO: this should be static
task dump;
static task dump;
$display("C#(%0d)::dump()", X);
endtask
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