Commit b95af2b6 by Zachary Snow

support for automatic functions

parent 729a75cd
...@@ -104,8 +104,9 @@ traverseStmtsM mapper = moduleItemMapper ...@@ -104,8 +104,9 @@ traverseStmtsM mapper = moduleItemMapper
where where
moduleItemMapper (AlwaysC kw stmt) = moduleItemMapper (AlwaysC kw stmt) =
fullMapper stmt >>= return . AlwaysC kw fullMapper stmt >>= return . AlwaysC kw
moduleItemMapper (Function ret name decls stmt) = moduleItemMapper (Function lifetime ret name decls stmts) = do
fullMapper stmt >>= return . Function ret name decls stmts' <- mapM fullMapper stmts
return $ Function lifetime ret name decls stmts'
moduleItemMapper other = return $ other moduleItemMapper other = return $ other
fullMapper = traverseNestedStmtsM mapper fullMapper = traverseNestedStmtsM mapper
...@@ -135,6 +136,7 @@ traverseNestedStmtsM mapper = fullMapper ...@@ -135,6 +136,7 @@ traverseNestedStmtsM mapper = fullMapper
s2' <- fullMapper s2 s2' <- fullMapper s2
return $ If e s1' s2' return $ If e s1' s2'
cs (Timing sense stmt) = fullMapper stmt >>= return . Timing sense cs (Timing sense stmt) = fullMapper stmt >>= return . Timing sense
cs (Return expr) = return $ Return expr
cs (Null) = return Null cs (Null) = return Null
traverseStmtLHSsM :: Monad m => MapperM m LHS -> MapperM m Stmt traverseStmtLHSsM :: Monad m => MapperM m LHS -> MapperM m Stmt
...@@ -245,6 +247,8 @@ traverseExprsM mapper = moduleItemMapper ...@@ -245,6 +247,8 @@ traverseExprsM mapper = moduleItemMapper
flatStmtMapper (If cc s1 s2) = flatStmtMapper (If cc s1 s2) =
exprMapper cc >>= \cc' -> return $ If cc' s1 s2 exprMapper cc >>= \cc' -> return $ If cc' s1 s2
flatStmtMapper (Timing sense stmt) = return $ Timing sense stmt flatStmtMapper (Timing sense stmt) = return $ Timing sense stmt
flatStmtMapper (Return expr) =
exprMapper expr >>= return . Return
flatStmtMapper (Null) = return Null flatStmtMapper (Null) = return Null
portBindingMapper (p, me) = portBindingMapper (p, me) =
...@@ -256,10 +260,10 @@ traverseExprsM mapper = moduleItemMapper ...@@ -256,10 +260,10 @@ traverseExprsM mapper = moduleItemMapper
exprMapper expr >>= return . Assign lhs exprMapper expr >>= return . Assign lhs
moduleItemMapper (AlwaysC kw stmt) = moduleItemMapper (AlwaysC kw stmt) =
stmtMapper stmt >>= return . AlwaysC kw stmtMapper stmt >>= return . AlwaysC kw
moduleItemMapper (Function ret f decls stmt) = do moduleItemMapper (Function lifetime ret f decls stmts) = do
decls' <- mapM declMapper decls decls' <- mapM declMapper decls
stmt' <- stmtMapper stmt stmts' <- mapM stmtMapper stmts
return $ Function ret f decls' stmt' return $ Function lifetime ret f decls' stmts'
moduleItemMapper (Instance m params x ml) = do moduleItemMapper (Instance m params x ml) = do
if ml == Nothing if ml == Nothing
then return $ Instance m params x Nothing then return $ Instance m params x Nothing
...@@ -297,9 +301,9 @@ traverseDeclsM mapper item = do ...@@ -297,9 +301,9 @@ traverseDeclsM mapper item = do
where where
miMapperA (MIDecl decl) = miMapperA (MIDecl decl) =
mapper decl >>= return . MIDecl mapper decl >>= return . MIDecl
miMapperA (Function t x decls s) = do miMapperA (Function l t x decls s) = do
decls' <- mapM mapper decls decls' <- mapM mapper decls
return $ Function t x decls' s return $ Function l t x decls' s
miMapperA other = return other miMapperA other = return other
miMapperB (Block (Just (name, decls)) stmts) = do miMapperB (Block (Just (name, decls)) stmts) = do
decls' <- mapM mapper decls decls' <- mapM mapper decls
...@@ -313,7 +317,7 @@ collectDeclsM = collectify traverseDeclsM ...@@ -313,7 +317,7 @@ collectDeclsM = collectify traverseDeclsM
traverseTypesM :: Monad m => MapperM m Type -> MapperM m ModuleItem traverseTypesM :: Monad m => MapperM m Type -> MapperM m ModuleItem
traverseTypesM mapper item = traverseTypesM mapper item =
traverseDeclsM declMapper item >>= traverseExprsM exprMapper miMapper item >>= traverseDeclsM declMapper >>= traverseExprsM exprMapper
where where
exprMapper (Cast t e) = do exprMapper (Cast t e) = do
t' <- mapper t t' <- mapper t
...@@ -330,6 +334,9 @@ traverseTypesM mapper item = ...@@ -330,6 +334,9 @@ traverseTypesM mapper item =
mapper t >>= \t' -> return $ Localparam t' x e mapper t >>= \t' -> return $ Localparam t' x e
declMapper (Variable d t x a me) = declMapper (Variable d t x a me) =
mapper t >>= \t' -> return $ Variable d t' x a me mapper t >>= \t' -> return $ Variable d t' x a me
miMapper (Function l t x d s) =
mapper t >>= \t' -> return $ Function l t' x d s
miMapper other = return other
traverseTypes :: Mapper Type -> Mapper ModuleItem traverseTypes :: Mapper Type -> Mapper ModuleItem
traverseTypes = unmonad traverseTypesM traverseTypes = unmonad traverseTypesM
......
...@@ -16,6 +16,7 @@ module Language.SystemVerilog.AST ...@@ -16,6 +16,7 @@ module Language.SystemVerilog.AST
, CaseKW (..) , CaseKW (..)
, PartKW (..) , PartKW (..)
, Decl (..) , Decl (..)
, Lifetime (..)
, AST , AST
, PortBinding , PortBinding
, ModportDecl , ModportDecl
...@@ -150,7 +151,7 @@ data ModuleItem ...@@ -150,7 +151,7 @@ data ModuleItem
| AlwaysC AlwaysKW Stmt | AlwaysC AlwaysKW Stmt
| Assign LHS Expr | Assign LHS Expr
| Instance Identifier [PortBinding] Identifier (Maybe [PortBinding]) -- `Nothing` represents `.*` | Instance Identifier [PortBinding] Identifier (Maybe [PortBinding]) -- `Nothing` represents `.*`
| Function Type Identifier [Decl] Stmt | Function (Maybe Lifetime) Type Identifier [Decl] [Stmt]
| Genvar Identifier | Genvar Identifier
| Generate [GenItem] | Generate [GenItem]
| Modport Identifier [ModportDecl] | Modport Identifier [ModportDecl]
...@@ -184,7 +185,7 @@ instance Show ModuleItem where ...@@ -184,7 +185,7 @@ instance Show ModuleItem where
Instance m params i ports Instance m params i ports
| null params -> printf "%s %s%s;" m i (showMaybePorts ports) | null params -> printf "%s %s%s;" m i (showMaybePorts ports)
| otherwise -> printf "%s #%s %s%s;" m (showPorts params) i (showMaybePorts ports) | otherwise -> printf "%s #%s %s%s;" m (showPorts params) i (showMaybePorts ports)
Function t x i b -> printf "function %s%s;\n%s\n%s\nendfunction" (showPad t) x (indent $ show i) (indent $ show b) Function ml t x i b -> printf "function %s%s%s;\n%s\n%s\nendfunction" (showLifetime ml) (showPad t) x (indent $ show i) (indent $ unlines' $ map show b)
Genvar x -> printf "genvar %s;" x Genvar x -> printf "genvar %s;" x
Generate b -> printf "generate\n%s\nendgenerate" (indent $ unlines' $ map show b) Generate b -> printf "generate\n%s\nendgenerate" (indent $ unlines' $ map show b)
Modport x l -> printf "modport %s(\n%s\n);" x (indent $ intercalate ",\n" $ map showModportDecl l) Modport x l -> printf "modport %s(\n%s\n);" x (indent $ intercalate ",\n" $ map showModportDecl l)
...@@ -383,6 +384,7 @@ data Stmt ...@@ -383,6 +384,7 @@ data Stmt
| Asgn LHS Expr | Asgn LHS Expr
| If Expr Stmt Stmt | If Expr Stmt Stmt
| Timing Sense Stmt | Timing Sense Stmt
| Return Expr
| Null | Null
deriving Eq deriving Eq
...@@ -409,6 +411,7 @@ instance Show Stmt where ...@@ -409,6 +411,7 @@ instance Show Stmt where
show (Asgn v e) = printf "%s <= %s;" (show v) (show e) show (Asgn v e) = printf "%s <= %s;" (show v) (show e)
show (If a b Null) = printf "if (%s) %s" (show a) (show b) show (If a b Null) = printf "if (%s) %s" (show a) (show b)
show (If a b c ) = printf "if (%s) %s\nelse %s" (show a) (show b) (show c) show (If a b c ) = printf "if (%s) %s\nelse %s" (show a) (show b) (show c)
show (Return e ) = printf "return %s;" (show e)
show (Timing t s ) = printf "@(%s)%s" (show t) rest show (Timing t s ) = printf "@(%s)%s" (show t) rest
where where
rest = case s of rest = case s of
...@@ -466,3 +469,16 @@ instance Show GenItem where ...@@ -466,3 +469,16 @@ instance Show GenItem where
show (GenFor (x1, e1) c (x2, e2) x is) = printf "for (%s = %s; %s; %s = %s) %s" x1 (show e1) (show c) x2 (show e2) (show $ GenBlock (Just x) is) show (GenFor (x1, e1) c (x2, e2) x is) = printf "for (%s = %s; %s; %s = %s) %s" x1 (show e1) (show c) x2 (show e2) (show $ GenBlock (Just x) is)
show GenNull = ";" show GenNull = ";"
show (GenModuleItem item) = show item show (GenModuleItem item) = show item
data Lifetime
= Static
| Automatic
deriving (Eq, Ord)
instance Show Lifetime where
show Static = "static"
show Automatic = "automatic"
showLifetime :: Maybe Lifetime -> String
showLifetime Nothing = ""
showLifetime (Just l) = show l ++ " "
...@@ -57,6 +57,7 @@ tokens :- ...@@ -57,6 +57,7 @@ tokens :-
"always_ff" { tok KW_always_ff } "always_ff" { tok KW_always_ff }
"always_latch" { tok KW_always_latch } "always_latch" { tok KW_always_latch }
"assign" { tok KW_assign } "assign" { tok KW_assign }
"automatic" { tok KW_automatic }
"begin" { tok KW_begin } "begin" { tok KW_begin }
"case" { tok KW_case } "case" { tok KW_case }
"casex" { tok KW_casex } "casex" { tok KW_casex }
...@@ -91,6 +92,8 @@ tokens :- ...@@ -91,6 +92,8 @@ tokens :-
"parameter" { tok KW_parameter } "parameter" { tok KW_parameter }
"posedge" { tok KW_posedge } "posedge" { tok KW_posedge }
"reg" { tok KW_reg } "reg" { tok KW_reg }
"return" { tok KW_return }
"static" { tok KW_static }
"struct" { tok KW_struct } "struct" { tok KW_struct }
"typedef" { tok KW_typedef } "typedef" { tok KW_typedef }
"unique" { tok KW_unique } "unique" { tok KW_unique }
......
...@@ -22,6 +22,7 @@ import Language.SystemVerilog.Parser.Tokens ...@@ -22,6 +22,7 @@ import Language.SystemVerilog.Parser.Tokens
"always_ff" { Token KW_always_ff _ _ } "always_ff" { Token KW_always_ff _ _ }
"always_latch" { Token KW_always_latch _ _ } "always_latch" { Token KW_always_latch _ _ }
"assign" { Token KW_assign _ _ } "assign" { Token KW_assign _ _ }
"automatic" { Token KW_automatic _ _ }
"begin" { Token KW_begin _ _ } "begin" { Token KW_begin _ _ }
"case" { Token KW_case _ _ } "case" { Token KW_case _ _ }
"casex" { Token KW_casex _ _ } "casex" { Token KW_casex _ _ }
...@@ -56,6 +57,8 @@ import Language.SystemVerilog.Parser.Tokens ...@@ -56,6 +57,8 @@ import Language.SystemVerilog.Parser.Tokens
"parameter" { Token KW_parameter _ _ } "parameter" { Token KW_parameter _ _ }
"posedge" { Token KW_posedge _ _ } "posedge" { Token KW_posedge _ _ }
"reg" { Token KW_reg _ _ } "reg" { Token KW_reg _ _ }
"return" { Token KW_return _ _ }
"static" { Token KW_static _ _ }
"struct" { Token KW_struct _ _ } "struct" { Token KW_struct _ _ }
"typedef" { Token KW_typedef _ _ } "typedef" { Token KW_typedef _ _ }
"unique" { Token KW_unique _ _ } "unique" { Token KW_unique _ _ }
...@@ -259,10 +262,12 @@ Identifiers :: { [Identifier] } ...@@ -259,10 +262,12 @@ Identifiers :: { [Identifier] }
-- uses delimiter propagation hack to avoid conflicts -- uses delimiter propagation hack to avoid conflicts
DeclTokens(delim) :: { [DeclToken] } DeclTokens(delim) :: { [DeclToken] }
: DeclToken delim { [$1] } : DeclToken delim { [$1] }
| DeclToken DeclTokens(delim) { [$1] ++ $2 } | DeclToken DeclTokens(delim) { [$1] ++ $2 }
| "=" Expr "," DeclTokens(delim) { [DTAsgn $2, DTComma] ++ $4 } | "=" Expr "," DeclTokens(delim) { [DTAsgn $2, DTComma] ++ $4 }
| "=" Expr delim { [DTAsgn $2] } | "<=" Expr "," DeclTokens(delim) { [DTAsgnNBlk $2, DTComma] ++ $4 }
| "=" Expr delim { [DTAsgn $2] }
| "<=" Expr delim { [DTAsgnNBlk $2] }
DeclToken :: { DeclToken } DeclToken :: { DeclToken }
: "," { DTComma } : "," { DTComma }
| Range { DTRange $1 } | Range { DTRange $1 }
...@@ -272,6 +277,9 @@ DeclToken :: { DeclToken } ...@@ -272,6 +277,9 @@ DeclToken :: { DeclToken }
| ModuleInstantiation { DTInstance $1 } | ModuleInstantiation { DTInstance $1 }
| PartialType { DTType $1 } | PartialType { DTType $1 }
| Identifier "." Identifier { DTType $ InterfaceT $1 (Just $3) } | Identifier "." Identifier { DTType $ InterfaceT $1 (Just $3) }
| "[" Expr "]" { DTBit $2 }
| "{" LHSs "}" { DTConcat $2 }
-- | LHS "." Identifier { LHSDot $1 $3 }
VariablePortIdentifiers :: { [(Identifier, Maybe Expr)] } VariablePortIdentifiers :: { [(Identifier, Maybe Expr)] }
: VariablePortIdentifier { [$1] } : VariablePortIdentifier { [$1] }
...@@ -294,14 +302,17 @@ ModuleItem :: { [ModuleItem] } ...@@ -294,14 +302,17 @@ ModuleItem :: { [ModuleItem] }
: DeclTokens(";") { parseDTsAsModuleItems $1 } : DeclTokens(";") { parseDTsAsModuleItems $1 }
| "parameter" ParamType DeclAsgns ";" { map MIDecl $ map (uncurry $ Parameter $2) $3 } | "parameter" ParamType DeclAsgns ";" { map MIDecl $ map (uncurry $ Parameter $2) $3 }
| "localparam" ParamType DeclAsgns ";" { map MIDecl $ map (uncurry $ Localparam $2) $3 } | "localparam" ParamType DeclAsgns ";" { map MIDecl $ map (uncurry $ Localparam $2) $3 }
| "assign" LHS "=" Expr ";" { [Assign $2 $4] } | "assign" LHS "=" Expr ";" { [Assign $2 $4] }
| AlwaysKW Stmt { [AlwaysC $1 $2] } | AlwaysKW Stmt { [AlwaysC $1 $2] }
| "function" Identifier FunctionItems Stmt "endfunction" opt(Tag) { [Function (Implicit []) $2 $3 $4] } | "genvar" Identifiers ";" { map Genvar $2 }
| "function" DimensionsNonEmpty Identifier FunctionItems Stmt "endfunction" opt(Tag) { [Function (Implicit $2) $3 $4 $5] } | "generate" GenItems "endgenerate" { [Generate $2] }
| "function" Type Identifier FunctionItems Stmt "endfunction" opt(Tag) { [Function $2 $3 $4 $5] } | "modport" ModportItems ";" { map (uncurry Modport) $2 }
| "genvar" Identifiers ";" { map Genvar $2 } | "function" opt(Lifetime) FuncRetAndName FunctionItems DeclsAndStmts "endfunction" opt(Tag) { [Function $2 (fst $3) (snd $3) ($4 ++ fst $5) (snd $5)] }
| "generate" GenItems "endgenerate" { [Generate $2] }
| "modport" ModportItems ";" { map (uncurry Modport) $2 } FuncRetAndName :: { (Type, Identifier) }
: {- empty -} Identifier { (Implicit [], $1) }
| DimensionsNonEmpty Identifier { (Implicit $1, $2) }
| Type Identifier { ($1 , $2) }
AlwaysKW :: { AlwaysKW } AlwaysKW :: { AlwaysKW }
: "always" { Always } : "always" { Always }
...@@ -309,13 +320,17 @@ AlwaysKW :: { AlwaysKW } ...@@ -309,13 +320,17 @@ AlwaysKW :: { AlwaysKW }
| "always_ff" { AlwaysFF } | "always_ff" { AlwaysFF }
| "always_latch" { AlwaysLatch } | "always_latch" { AlwaysLatch }
Lifetime :: { Lifetime }
: "static" { Static }
| "automatic" { Automatic }
ModuleInstantiation :: { (Identifier, Maybe [PortBinding]) } ModuleInstantiation :: { (Identifier, Maybe [PortBinding]) }
: Identifier "(" Bindings ")" { ($1, Just $3) } : Identifier "(" Bindings ")" { ($1, Just $3) }
| Identifier "(" ".*" ")" { ($1, Nothing) } | Identifier "(" ".*" ")" { ($1, Nothing) }
FunctionItems :: { [Decl] } FunctionItems :: { [Decl] }
: "(" DeclTokens(")") ";" BlockItemDeclarations { (parseDTsAsDecls $2) ++ $4 } : "(" DeclTokens(")") ";" { map makeInput $ parseDTsAsDecls $2 }
| ";" BlockItemDeclarations { $2 } | ";" { [] }
ParamType :: { Type } ParamType :: { Type }
: Dimensions { Implicit $1 } : Dimensions { Implicit $1 }
...@@ -328,13 +343,6 @@ EventControl :: { Sense } ...@@ -328,13 +343,6 @@ EventControl :: { Sense }
| "@" "*" { SenseStar } | "@" "*" { SenseStar }
| "@*" { SenseStar } | "@*" { SenseStar }
VariableIdentifiers :: { [(Identifier, [Range], Maybe Expr)] }
: VariableType { [$1] }
| VariableIdentifiers "," VariableType { $1 ++ [$3] }
VariableType :: { (Identifier, [Range], Maybe Expr) }
: Identifier Dimensions { ($1, $2, Nothing) }
| Identifier Dimensions "=" Expr { ($1, $2, Just $4) }
Dimensions :: { [Range] } Dimensions :: { [Range] }
: {- empty -} { [] } : {- empty -} { [] }
| DimensionsNonEmpty { $1 } | DimensionsNonEmpty { $1 }
...@@ -390,34 +398,28 @@ Stmts :: { [Stmt] } ...@@ -390,34 +398,28 @@ Stmts :: { [Stmt] }
| Stmts Stmt { $1 ++ [$2] } | Stmts Stmt { $1 ++ [$2] }
Stmt :: { Stmt } Stmt :: { Stmt }
: StmtNonAsgn { $1 }
| LHS "=" Expr ";" { AsgnBlk $1 $3 }
| LHS "<=" Expr ";" { Asgn $1 $3 }
StmtNonAsgn :: { Stmt }
: ";" { Null } : ";" { Null }
| "begin" Stmts "end" { Block Nothing $2 } | "begin" Stmts "end" { Block Nothing $2 }
| "begin" ":" Identifier BlockItemDeclarations Stmts "end" { Block (Just ($3, $4)) $5 } | "begin" ":" Identifier DeclsAndStmts "end" { Block (Just ($3, fst $4)) (snd $4) }
| "if" "(" Expr ")" Stmt "else" Stmt { If $3 $5 $7 } | "if" "(" Expr ")" Stmt "else" Stmt { If $3 $5 $7 }
| "if" "(" Expr ")" Stmt %prec NoElse { If $3 $5 Null } | "if" "(" Expr ")" Stmt %prec NoElse { If $3 $5 Null }
| "for" "(" Identifier "=" Expr ";" Expr ";" Identifier "=" Expr ")" Stmt { For ($3, $5) $7 ($9, $11) $13 } | "for" "(" Identifier "=" Expr ";" Expr ";" Identifier "=" Expr ")" Stmt { For ($3, $5) $7 ($9, $11) $13 }
| LHS "=" Expr ";" { AsgnBlk $1 $3 }
| LHS "<=" Expr ";" { Asgn $1 $3 }
| CaseKW "(" Expr ")" Cases opt(CaseDefault) "endcase" { Case $1 $3 $5 $6 } | CaseKW "(" Expr ")" Cases opt(CaseDefault) "endcase" { Case $1 $3 $5 $6 }
| EventControl Stmt { Timing $1 $2 } | EventControl Stmt { Timing $1 $2 }
| "return" Expr ";" { Return $2 }
BlockItemDeclarations :: { [Decl] }
: {- empty -} { [] } DeclsAndStmts :: { ([Decl], [Stmt]) }
| BlockItemDeclarations BlockItemDeclaration { $1 ++ $2 } : DeclOrStmt DeclsAndStmts { combineDeclsAndStmts $1 $2 }
BlockItemDeclaration :: { [Decl] } | StmtNonAsgn Stmts { ([], $1 : $2) }
: "reg" Dimensions BlockVariableIdentifiers ";" { map (\(x, rs) -> Variable Local (Reg $2) x rs Nothing) $3 } | {- empty -} { ([], []) }
| "parameter" ParamType DeclAsgns ";" { map (uncurry $ Parameter $2) $3 } DeclOrStmt :: { ([Decl], [Stmt]) }
| "localparam" ParamType DeclAsgns ";" { map (uncurry $ Localparam $2) $3 } : DeclTokens(";") { parseDTsAsDeclOrAsgn $1 }
| "integer" VariableIdentifiers ";" { map (\(x, a, e) -> Variable Local IntegerT x a e) $2 } | "parameter" ParamType DeclAsgns ";" { (map (uncurry $ Parameter $2) $3, []) }
| "input" Dimensions Identifiers ";" { map (\x -> Variable Input (Implicit $2) x [] Nothing) $3 } | "localparam" ParamType DeclAsgns ";" { (map (uncurry $ Localparam $2) $3, []) }
| "input" "reg" Dimensions Identifiers ";" { map (\x -> Variable Input (Reg $3) x [] Nothing) $4 }
| "input" "integer" Identifiers ";" { map (\x -> Variable Input IntegerT x [] Nothing) $3 }
BlockVariableIdentifiers :: { [(Identifier, [Range])] }
: BlockVariableType { [$1] }
| BlockVariableIdentifiers "," BlockVariableType { $1 ++ [$3] }
BlockVariableType :: { (Identifier, [Range]) }
: Identifier Dimensions { ($1, $2) }
CaseKW :: { CaseKW } CaseKW :: { CaseKW }
-- We just drop the unique keyword, for now. In the future, we should add it -- We just drop the unique keyword, for now. In the future, we should add it
...@@ -548,4 +550,11 @@ genItemsToGenItem [] = error "genItemsToGenItem given empty list!" ...@@ -548,4 +550,11 @@ genItemsToGenItem [] = error "genItemsToGenItem given empty list!"
genItemsToGenItem [x] = x genItemsToGenItem [x] = x
genItemsToGenItem xs = GenBlock Nothing xs genItemsToGenItem xs = GenBlock Nothing xs
combineDeclsAndStmts :: ([Decl], [Stmt]) -> ([Decl], [Stmt]) -> ([Decl], [Stmt])
combineDeclsAndStmts (a1, b1) (a2, b2) = (a1 ++ a2, b1 ++ b2)
makeInput :: Decl -> Decl
makeInput (Variable _ t x a me) = Variable Input t x a me
makeInput other = error $ "unexpected non-var decl: " ++ (show other)
} }
...@@ -35,6 +35,7 @@ module Language.SystemVerilog.Parser.ParseDecl ...@@ -35,6 +35,7 @@ module Language.SystemVerilog.Parser.ParseDecl
, parseDTsAsModuleItems , parseDTsAsModuleItems
, parseDTsAsDecls , parseDTsAsDecls
, parseDTsAsDecl , parseDTsAsDecl
, parseDTsAsDeclOrAsgn
) where ) where
import Data.List (findIndices) import Data.List (findIndices)
...@@ -46,12 +47,15 @@ import Language.SystemVerilog.AST ...@@ -46,12 +47,15 @@ import Language.SystemVerilog.AST
data DeclToken data DeclToken
= DTComma = DTComma
| DTAsgn Expr | DTAsgn Expr
| DTAsgnNBlk Expr
| DTRange Range | DTRange Range
| DTIdent Identifier | DTIdent Identifier
| DTDir Direction | DTDir Direction
| DTType ([Range] -> Type) | DTType ([Range] -> Type)
| DTParams [PortBinding] | DTParams [PortBinding]
| DTInstance (Identifier, Maybe [PortBinding]) | DTInstance (Identifier, Maybe [PortBinding])
| DTBit Expr
| DTConcat [LHS]
deriving (Show, Eq) deriving (Show, Eq)
...@@ -136,6 +140,39 @@ parseDTsAsDecl tokens = ...@@ -136,6 +140,39 @@ parseDTsAsDecl tokens =
where components = parseDTsAsComponents tokens where components = parseDTsAsComponents tokens
-- [PUBLIC]: parser for single block item declarations of assign statetments
parseDTsAsDeclOrAsgn :: [DeclToken] -> ([Decl], [Stmt])
parseDTsAsDeclOrAsgn tokens =
if any isAsgnToken tokens || tripLookahead tokens
then ([], [constructor lhs expr])
else (parseDTsAsDecl tokens, [])
where
(constructor, expr) = case last tokens of
DTAsgn e -> (AsgnBlk, e)
DTAsgnNBlk e -> (Asgn , e)
_ -> error $ "invalid block item decl or stmt: " ++ (show tokens)
(lhs, []) = takeLHS $ init tokens
isAsgnToken :: DeclToken -> Bool
isAsgnToken (DTBit _) = True
isAsgnToken (DTConcat _) = True
isAsgnToken _ = False
-- TODO: It looks like our LHS type doesn't represent the full set of possible
-- LHSs, i.e., `foo[0][0]` isn't representable. When this is addressed, we'll
-- have to take another pass at this function. It will probably need to be
-- recursive.
takeLHS :: [DeclToken] -> (LHS, [DeclToken])
takeLHS (DTConcat lhss : rest) = (LHSConcat lhss, rest)
takeLHS (DTIdent x : DTBit e : rest) = (LHSBit x e , rest)
takeLHS (DTIdent x : DTRange r : rest) = (LHSRange x r , rest)
takeLHS (DTIdent x : rest) = (LHS x , rest)
takeLHS (DTType tf : rest) =
case tf [] of
InterfaceT x (Just y) [] -> (LHSDot (LHS x) y, rest)
_ -> error $ "unexpected type in assignment: " ++ (show tf)
takeLHS tokens = error $ "missing LHS in assignment: " ++ (show tokens)
-- batches together seperate declaration lists -- batches together seperate declaration lists
type Triplet = (Identifier, [Range], Maybe Expr) type Triplet = (Identifier, [Range], Maybe Expr)
type Component = (Direction, Type, [Triplet]) type Component = (Direction, Type, [Triplet])
...@@ -207,9 +244,14 @@ takeRanges (DTRange r : rest) = (r : rs, rest') ...@@ -207,9 +244,14 @@ takeRanges (DTRange r : rest) = (r : rs, rest')
where (rs, rest') = takeRanges rest where (rs, rest') = takeRanges rest
takeRanges rest = ([], rest) takeRanges rest = ([], rest)
-- TODO: entrypoints besides `parseDTsAsDeclOrAsgn` should disallow `DTAsgnNBlk`
-- Note: matching DTAsgnNBlk too is a bit of a hack to allow for tripLookahead
-- to work both for standard declarations and in `parseDTsAsDeclOrAsgn`, where
-- we're checking for an assignment
takeAsgn :: [DeclToken] -> (Maybe Expr, [DeclToken]) takeAsgn :: [DeclToken] -> (Maybe Expr, [DeclToken])
takeAsgn (DTAsgn e : rest) = (Just e , rest) takeAsgn (DTAsgn e : rest) = (Just e , rest)
takeAsgn rest = (Nothing, rest) takeAsgn (DTAsgnNBlk e : rest) = (Just e , rest)
takeAsgn rest = (Nothing, rest)
takeComma :: [DeclToken] -> (Bool, [DeclToken]) takeComma :: [DeclToken] -> (Bool, [DeclToken])
takeComma [] = (False, []) takeComma [] = (False, [])
......
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