Commit 50b7bf28 by Zachary Snow

huge pass at revamping AST to be more general, easy to work with

parent e795109f
...@@ -34,8 +34,8 @@ getStmtLHSs :: Stmt -> [LHS] ...@@ -34,8 +34,8 @@ getStmtLHSs :: Stmt -> [LHS]
getStmtLHSs (Block _ stmts) = concat $ map getStmtLHSs stmts getStmtLHSs (Block _ stmts) = concat $ map getStmtLHSs stmts
getStmtLHSs (Case kw e cases (Just stmt)) = (getStmtLHSs stmt) ++ (getStmtLHSs $ Case kw e cases Nothing) getStmtLHSs (Case kw e cases (Just stmt)) = (getStmtLHSs stmt) ++ (getStmtLHSs $ Case kw e cases Nothing)
getStmtLHSs (Case _ _ cases Nothing) = concat $ map getStmtLHSs $ map snd cases getStmtLHSs (Case _ _ cases Nothing) = concat $ map getStmtLHSs $ map snd cases
getStmtLHSs (BlockingAssignment lhs _) = [lhs] getStmtLHSs (AsgnBlk lhs _) = [lhs]
getStmtLHSs (NonBlockingAssignment lhs _) = [lhs] getStmtLHSs (Asgn lhs _) = [lhs]
getStmtLHSs (For _ _ _ stmt) = getStmtLHSs stmt getStmtLHSs (For _ _ _ stmt) = getStmtLHSs stmt
getStmtLHSs (If _ s1 s2) = (getStmtLHSs s1) ++ (getStmtLHSs s2) getStmtLHSs (If _ s1 s2) = (getStmtLHSs s1) ++ (getStmtLHSs s2)
getStmtLHSs (Timing _ s) = getStmtLHSs s getStmtLHSs (Timing _ s) = getStmtLHSs s
...@@ -56,8 +56,8 @@ getRegIdents (AlwaysC _ stmt) = ...@@ -56,8 +56,8 @@ getRegIdents (AlwaysC _ stmt) =
getRegIdents _ = Set.empty getRegIdents _ = Set.empty
convertModuleItem :: RegIdents -> ModuleItem -> ModuleItem convertModuleItem :: RegIdents -> ModuleItem -> ModuleItem
convertModuleItem idents (LocalNet (Logic mr) ident val) = convertModuleItem idents (MIDecl (Variable dir (Logic mr) ident a me)) =
LocalNet (t mr) ident val MIDecl $ Variable dir (t mr) ident a me
where where
t = if Set.member ident idents then Reg else Wire t = if Set.member ident idents then Reg else Wire
convertModuleItem idents (Generate items) = Generate $ map (convertGenItem $ convertModuleItem idents) items convertModuleItem idents (Generate items) = Generate $ map (convertGenItem $ convertModuleItem idents) items
......
...@@ -40,7 +40,7 @@ convert = map convertDescription ...@@ -40,7 +40,7 @@ convert = map convertDescription
convertDescription :: Description -> Description convertDescription :: Description -> Description
convertDescription (Module name ports items) = convertDescription (Module name ports items) =
-- Insert the new items right after the LocalNet for the item to preserve -- Insert the new items right after the Variable for the item to preserve
-- declaration order, which some toolchains care about. -- declaration order, which some toolchains care about.
Module name ports $ concat $ map addUnflattener items' Module name ports $ concat $ map addUnflattener items'
where where
...@@ -49,18 +49,18 @@ convertDescription (Module name ports items) = ...@@ -49,18 +49,18 @@ convertDescription (Module name ports items) =
items' = map (convertModuleItem dimMap) items items' = map (convertModuleItem dimMap) items
outputs = Set.fromList $ mapMaybe getOutput items outputs = Set.fromList $ mapMaybe getOutput items
getOutput :: ModuleItem -> Maybe Identifier getOutput :: ModuleItem -> Maybe Identifier
getOutput (PortDecl Output _ ident) = Just ident getOutput (MIDecl (Variable Output _ ident _ _)) = Just ident
getOutput _ = Nothing getOutput _ = Nothing
getExtraDims :: ModuleItem -> Maybe (Identifier, (Type, Range)) getExtraDims :: ModuleItem -> Maybe (Identifier, (Type, Range))
getExtraDims (LocalNet t ident _) = getExtraDims (MIDecl (Variable _ t ident _ _)) =
if length rs > 1 if length rs > 1
then Just (ident, (tf $ tail rs, head rs)) then Just (ident, (tf $ tail rs, head rs))
else Nothing else Nothing
where (tf, rs) = typeDims t where (tf, rs) = typeDims t
getExtraDims _ = Nothing getExtraDims _ = Nothing
addUnflattener :: ModuleItem -> [ModuleItem] addUnflattener :: ModuleItem -> [ModuleItem]
addUnflattener (LocalNet t ident val) = addUnflattener (orig @ (MIDecl (Variable _ _ ident _ _))) =
LocalNet t ident val : orig :
case Map.lookup ident dimMap of case Map.lookup ident dimMap of
Nothing -> [] Nothing -> []
Just desc -> unflattener outputs (ident, desc) Just desc -> unflattener outputs (ident, desc)
...@@ -84,10 +84,10 @@ simplify other = other ...@@ -84,10 +84,10 @@ simplify other = other
unflattener :: Set.Set Identifier -> (Identifier, (Type, Range)) -> [ModuleItem] unflattener :: Set.Set Identifier -> (Identifier, (Type, Range)) -> [ModuleItem]
unflattener outputs (arr, (t, (majorHi, majorLo))) = unflattener outputs (arr, (t, (majorHi, majorLo))) =
[ Comment $ "sv2v packed-array-flatten unflattener for " ++ arr [ Comment $ "sv2v packed-array-flatten unflattener for " ++ arr
, LocalNet t arrUnflat (Left [(majorHi, majorLo)]) , MIDecl $ Variable Local t arrUnflat [(majorHi, majorLo)] Nothing
, Generate , Generate
[ GenModuleItem $ Genvar index [ GenModuleItem $ Genvar index
, GenModuleItem $ MIIntegerV $ IntegerV (arrUnflat ++ "_repeater_index") (Right Nothing) , GenModuleItem $ MIDecl $ Variable Local IntegerT (arrUnflat ++ "_repeater_index") [] Nothing
, GenFor , GenFor
(index, majorLo) (index, majorLo)
(BinOp Le (Ident index) majorHi) (BinOp Le (Ident index) majorHi)
...@@ -110,7 +110,7 @@ unflattener outputs (arr, (t, (majorHi, majorLo))) = ...@@ -110,7 +110,7 @@ unflattener outputs (arr, (t, (majorHi, majorLo))) =
(minorHi, minorLo) = head $ snd $ typeDims t (minorHi, minorLo) = head $ snd $ typeDims t
size = simplify $ BinOp Add (BinOp Sub minorHi minorLo) (Number "1") size = simplify $ BinOp Add (BinOp Sub minorHi minorLo) (Number "1")
localparam :: Identifier -> Expr -> GenItem localparam :: Identifier -> Expr -> GenItem
localparam x v = GenModuleItem $ MILocalparam $ Localparam Nothing x v localparam x v = GenModuleItem $ MIDecl $ Localparam (Implicit []) x v
origRange = ( (BinOp Add (Ident startBit) origRange = ( (BinOp Add (Ident startBit)
(BinOp Sub size (Number "1"))) (BinOp Sub size (Number "1")))
, Ident startBit ) , Ident startBit )
...@@ -120,16 +120,13 @@ typeDims (Reg r) = (Reg , r) ...@@ -120,16 +120,13 @@ typeDims (Reg r) = (Reg , r)
typeDims (Wire r) = (Wire , r) typeDims (Wire r) = (Wire , r)
typeDims (Logic r) = (Logic , r) typeDims (Logic r) = (Logic , r)
typeDims (Alias t r) = (Alias t, r) typeDims (Alias t r) = (Alias t, r)
typeDims (Implicit r) = (Implicit, r)
typeDims (IntegerT ) = (error "ranges cannot be applied to IntegerT", [])
typeDims (Enum t v r) = (Enum t v, r) typeDims (Enum t v r) = (Enum t v, r)
prefix :: Identifier -> Identifier prefix :: Identifier -> Identifier
prefix ident = "_sv2v_" ++ ident prefix ident = "_sv2v_" ++ ident
rewriteRangesOrAssignment :: DimMap -> RangesOrAssignment -> RangesOrAssignment
rewriteRangesOrAssignment dimMap (Right (Just e)) =
Right $ Just $ rewriteExpr dimMap e
rewriteRangesOrAssignment _ other = other
rewriteRange :: DimMap -> Range -> Range rewriteRange :: DimMap -> Range -> Range
rewriteRange dimMap (a, b) = (r a, r b) rewriteRange dimMap (a, b) = (r a, r b)
where r = rewriteExpr dimMap where r = rewriteExpr dimMap
...@@ -208,8 +205,8 @@ rewriteStmt dimMap orig = rs orig ...@@ -208,8 +205,8 @@ rewriteStmt dimMap orig = rs orig
case def of case def of
Nothing -> Nothing Nothing -> Nothing
Just stmt -> Just $ rs stmt Just stmt -> Just $ rs stmt
rs (BlockingAssignment lhs expr) = convertAssignment BlockingAssignment lhs expr rs (AsgnBlk lhs expr) = convertAssignment AsgnBlk lhs expr
rs (NonBlockingAssignment lhs expr) = convertAssignment NonBlockingAssignment lhs expr rs (Asgn lhs expr) = convertAssignment Asgn lhs expr
rs (For (x1, e1) cc (x2, e2) stmt) = For (x1, e1') cc' (x2, e2') (rs stmt) rs (For (x1, e1) cc (x2, e2) stmt) = For (x1, e1') cc' (x2, e2') (rs stmt)
where where
e1' = rewriteExpr dimMap e1 e1' = rewriteExpr dimMap e1
...@@ -236,18 +233,15 @@ rewriteStmt dimMap orig = rs orig ...@@ -236,18 +233,15 @@ rewriteStmt dimMap orig = rs orig
constructor (rewriteLHS dimMap lhs) (rewriteExpr dimMap expr) constructor (rewriteLHS dimMap lhs) (rewriteExpr dimMap expr)
convertModuleItem :: DimMap -> ModuleItem -> ModuleItem convertModuleItem :: DimMap -> ModuleItem -> ModuleItem
convertModuleItem dimMap (LocalNet t x val) = convertModuleItem dimMap (MIDecl (Variable d t x a me)) =
if Map.member x dimMap if Map.member x dimMap
then LocalNet t' x val' then MIDecl $ Variable d t' x a' me'
else LocalNet t x val' else MIDecl $ Variable d t x a' me'
where where
(tf, rs) = typeDims t (tf, rs) = typeDims t
t' = tf $ flattenRanges rs t' = tf $ flattenRanges rs
val' = rewriteRangesOrAssignment dimMap val a' = map (rewriteRange dimMap) a
convertModuleItem dimMap (PortDecl dir rs x) = me' = maybe Nothing (Just . rewriteExpr dimMap) me
if Map.member x dimMap
then PortDecl dir (flattenRanges rs) x
else PortDecl dir rs x
convertModuleItem dimMap (Generate items) = convertModuleItem dimMap (Generate items) =
Generate $ map (convertGenItem dimMap) items Generate $ map (convertGenItem dimMap) items
convertModuleItem dimMap (Assign lhs expr) = convertModuleItem dimMap (Assign lhs expr) =
...@@ -264,11 +258,9 @@ convertModuleItem dimMap (Instance m params x (Just l)) = ...@@ -264,11 +258,9 @@ convertModuleItem dimMap (Instance m params x (Just l)) =
convertPortBinding :: PortBinding -> PortBinding convertPortBinding :: PortBinding -> PortBinding
convertPortBinding (p, Nothing) = (p, Nothing) convertPortBinding (p, Nothing) = (p, Nothing)
convertPortBinding (p, Just e) = (p, Just $ rewriteExpr dimMap e) convertPortBinding (p, Just e) = (p, Just $ rewriteExpr dimMap e)
convertModuleItem _ (Comment x) = Comment x convertModuleItem _ (Comment x) = Comment x
convertModuleItem _ (Genvar x) = Genvar x convertModuleItem _ (Genvar x) = Genvar x
convertModuleItem _ (MIParameter x) = MIParameter x convertModuleItem _ (MIDecl x) = MIDecl x
convertModuleItem _ (MILocalparam x) = MILocalparam x
convertModuleItem _ (MIIntegerV x) = MIIntegerV x
convertGenItem :: DimMap -> GenItem -> GenItem convertGenItem :: DimMap -> GenItem -> GenItem
convertGenItem dimMap item = convertGenItem' item convertGenItem dimMap item = convertGenItem' item
......
...@@ -32,11 +32,9 @@ convertStmt f = f . convertStmt' ...@@ -32,11 +32,9 @@ convertStmt f = f . convertStmt'
Case kw expr cases' def' Case kw expr cases' def'
where where
cases' = map (\(exprs, stmt) -> (exprs, cs stmt)) cases cases' = map (\(exprs, stmt) -> (exprs, cs stmt)) cases
def' = case def of def' = maybe Nothing (Just . cs) def
Nothing -> Nothing convertStmt' (AsgnBlk lhs expr) = AsgnBlk lhs expr
Just stmt -> Just (cs stmt) convertStmt' (Asgn lhs expr) = Asgn lhs expr
convertStmt' (BlockingAssignment lhs expr) = BlockingAssignment lhs expr
convertStmt' (NonBlockingAssignment lhs expr) = NonBlockingAssignment lhs expr
convertStmt' (For a b c stmt) = For a b c (cs stmt) convertStmt' (For a b c stmt) = For a b c (cs stmt)
convertStmt' (If e s1 s2) = If e (cs s1) (cs s2) convertStmt' (If e s1 s2) = If e (cs s1) (cs s2)
convertStmt' (Timing sense stmt) = Timing sense (cs stmt) convertStmt' (Timing sense stmt) = Timing sense (cs stmt)
......
...@@ -2,13 +2,11 @@ ...@@ -2,13 +2,11 @@
- Author: Zachary Snow <zach@zachjs.com> - Author: Zachary Snow <zach@zachjs.com>
- -
- Conversion for `typedef` - Conversion for `typedef`
-
- Aliased types can (probably) appear in all item declarations, including
- modules, blocks, and function parameters.
-} -}
-- TODO: Right now we only support typedefs for module data items. Function
-- parameters, block items, etc., probably support typedefs, too.
-- TODO FIXME XXX: `Cast` contains a type, which we'll need to resolve/convert?
module Convert.Typedef (convert) where module Convert.Typedef (convert) where
import Data.Maybe import Data.Maybe
...@@ -37,9 +35,11 @@ convertDescription types (Module name ports items) = ...@@ -37,9 +35,11 @@ convertDescription types (Module name ports items) =
convertDescription _ other = other convertDescription _ other = other
resolveType :: Types -> Type -> Type resolveType :: Types -> Type -> Type
resolveType _ (Reg rs) = Reg rs resolveType _ (Reg rs) = Reg rs
resolveType _ (Wire rs) = Wire rs resolveType _ (Wire rs) = Wire rs
resolveType _ (Logic rs) = Logic rs resolveType _ (Logic rs) = Logic rs
resolveType _ (Implicit rs) = Implicit rs
resolveType _ (IntegerT ) = IntegerT
resolveType _ (Enum Nothing vals rs) = Enum Nothing vals rs resolveType _ (Enum Nothing vals rs) = Enum Nothing vals rs
resolveType types (Enum (Just t) vals rs) = Enum (Just $ resolveType types t) vals rs resolveType types (Enum (Just t) vals rs) = Enum (Just $ resolveType types t) vals rs
resolveType types (Alias st rs1) = resolveType types (Alias st rs1) =
...@@ -48,9 +48,72 @@ resolveType types (Alias st rs1) = ...@@ -48,9 +48,72 @@ resolveType types (Alias st rs1) =
(Wire rs2) -> Wire $ rs2 ++ rs1 (Wire rs2) -> Wire $ rs2 ++ rs1
(Logic rs2) -> Logic $ rs2 ++ rs1 (Logic rs2) -> Logic $ rs2 ++ rs1
(Enum t v rs2) -> Enum t v $ rs2 ++ rs1 (Enum t v rs2) -> Enum t v $ rs2 ++ rs1
(Implicit rs2) -> Implicit $ rs2 ++ rs1
(IntegerT ) -> error $ "resolveType encountered packed `integer` on " ++ st
(Alias _ _) -> error $ "resolveType invariant failed on " ++ st (Alias _ _) -> error $ "resolveType invariant failed on " ++ st
convertDecl :: Types -> Decl -> Decl
convertDecl types decl =
case decl of
Parameter t x e -> Parameter (rt t) x (re e)
Localparam t x e -> Localparam (rt t) x (re e)
Variable d t x a me -> Variable d (rt t) x a me'
where me' = if isJust me then Just (re $ fromJust me) else me
where
rt = resolveType types
re = convertExpr types
convertModuleItem :: Types -> ModuleItem -> ModuleItem convertModuleItem :: Types -> ModuleItem -> ModuleItem
convertModuleItem types (LocalNet t ident val) = convertModuleItem types (MIDecl decl) =
LocalNet (resolveType types t) ident val MIDecl $ convertDecl types decl
convertModuleItem types (Function t x decls stmt) =
Function (resolveType types t) x
(map (convertDecl types) decls)
(convertStmt types stmt)
convertModuleItem types (Assign lhs expr) =
Assign lhs (convertExpr types expr)
convertModuleItem types (AlwaysC kw stmt) =
AlwaysC kw (convertStmt types stmt)
convertModuleItem _ other = other convertModuleItem _ other = other
convertStmt :: Types -> Stmt -> Stmt
convertStmt types = rs
where
rd = convertDecl types
re = convertExpr types
rs :: Stmt -> Stmt
rs (Block header stmts) =
Block header' (map rs stmts)
where header' = maybe Nothing (\(x, decls) -> Just (x, map rd decls)) header
rs (Case kw e cases def) = Case kw (re e)
(map convertCase cases) def'
where
convertCase (exprs, stmt) = (map re exprs, rs stmt)
def' = maybe Nothing (Just . rs) def
rs (AsgnBlk lhs expr) = AsgnBlk lhs (re expr)
rs (Asgn lhs expr) = Asgn lhs (re expr)
rs (For (x1, e1) e (x2, e2) stmt) =
For (x1, re e1) (re e) (x2, re e2) (rs stmt)
rs (If e s1 s2) = If (re e) (rs s1) (rs s2)
rs (Timing sense stmt) = Timing sense (rs stmt)
rs (Null) = Null
convertExpr :: Types -> Expr -> Expr
convertExpr types = re
where
re :: Expr -> Expr
re (String s) = String s
re (Number s) = Number s
re (ConstBool b) = ConstBool b
re (Ident i ) = Ident i
re (IdentRange i r) = IdentRange i r
re (IdentBit i e) = IdentBit i (re e)
re (Repeat e l) = Repeat (re e) (map re l)
re (Concat l ) = Concat (map re l)
re (Call f l) = Call f (map re l)
re (UniOp o e) = UniOp o (re e)
re (BinOp o e1 e2) = BinOp o (re e1) (re e2)
re (Mux e1 e2 e3) = Mux (re e1) (re e2) (re e3)
re (Bit e n) = Bit (re e) n
-- This is the reason we have to convert expressions in this module.
re (Cast t e) = Cast (resolveType types t) (re e)
...@@ -10,19 +10,15 @@ module Language.SystemVerilog.AST ...@@ -10,19 +10,15 @@ module Language.SystemVerilog.AST
, UniOp (..) , UniOp (..)
, BinOp (..) , BinOp (..)
, Sense (..) , Sense (..)
, BlockItemDeclaration (..)
, Parameter (..)
, Localparam (..)
, IntegerV (..)
, GenItem (..) , GenItem (..)
, AlwaysKW (..) , AlwaysKW (..)
, CaseKW (..) , CaseKW (..)
, Decl (..)
, AST , AST
, PortBinding , PortBinding
, Case , Case
, Range , Range
, GenCase , GenCase
, RangesOrAssignment
) where ) where
import Data.List import Data.List
...@@ -65,49 +61,64 @@ data Direction ...@@ -65,49 +61,64 @@ data Direction
= Input = Input
| Output | Output
| Inout | Inout
| Local
deriving Eq deriving Eq
instance Show Direction where instance Show Direction where
show Input = "input" show Input = "input"
show Output = "output" show Output = "output"
show Inout = "inout" show Inout = "inout"
show Local = ""
data Type data Type
= Reg [Range] = Reg [Range]
| Wire [Range] | Wire [Range]
| Logic [Range] | Logic [Range]
| Alias String [Range] | Alias Identifier [Range]
| Implicit [Range]
| IntegerT
| Enum (Maybe Type) [(Identifier, Maybe Expr)] [Range] | Enum (Maybe Type) [(Identifier, Maybe Expr)] [Range]
deriving Eq deriving Eq
instance Show Type where instance Show Type where
show (Reg r) = "reg" ++ (showRanges r) show (Reg r) = "reg" ++ (showRanges r)
show (Wire r) = "wire" ++ (showRanges r) show (Wire r) = "wire" ++ (showRanges r)
show (Logic r) = "logic" ++ (showRanges r) show (Logic r) = "logic" ++ (showRanges r)
show (Alias t r) = t ++ (showRanges r) show (Alias t r) = t ++ (showRanges r)
show (Implicit r) = (showRanges r)
show (IntegerT ) = "integer"
show (Enum mt vals r) = printf "enum %s{%s}%s" tStr (commas $ map showVal vals) (showRanges r) show (Enum mt vals r) = printf "enum %s{%s}%s" tStr (commas $ map showVal vals) (showRanges r)
where where
tStr = case mt of tStr = maybe "" showPad mt
Nothing -> ""
Just t -> (show t) ++ " "
showVal :: (Identifier, Maybe Expr) -> String showVal :: (Identifier, Maybe Expr) -> String
showVal (x, e) = x ++ (showAssignment e) showVal (x, e) = x ++ (showAssignment e)
data Decl
= Parameter Type Identifier Expr
| Localparam Type Identifier Expr
| Variable Direction Type Identifier [Range] (Maybe Expr)
deriving Eq
instance Show Decl where
showList l _ = unlines' $ map show l
show (Parameter t x e) = printf "parameter %s%s = %s;" (showPad t) x (show e)
show (Localparam t x e) = printf "localparam %s%s = %s;" (showPad t) x (show e)
show (Variable d t x a me) = printf "%s%s %s%s%s;" (showPad d) (show t) x (showRanges a) (showAssignment me)
data ModuleItem data ModuleItem
= Comment String = Comment String
| MIParameter Parameter | MIDecl Decl
| MILocalparam Localparam
| MIIntegerV IntegerV
| PortDecl Direction [Range] Identifier
| LocalNet Type Identifier RangesOrAssignment
| 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 (Maybe FuncRet) Identifier [(Bool, BlockItemDeclaration)] Stmt | Function Type Identifier [Decl] Stmt
| Genvar Identifier | Genvar Identifier
| Generate [GenItem] | Generate [GenItem]
deriving Eq deriving Eq
-- "function inputs and outputs are inferred to be of type reg if no internal
-- data types for the ports are declared"
data AlwaysKW data AlwaysKW
= Always = Always
| AlwaysComb | AlwaysComb
...@@ -121,61 +132,29 @@ instance Show AlwaysKW where ...@@ -121,61 +132,29 @@ instance Show AlwaysKW where
show AlwaysFF = "always_ff" show AlwaysFF = "always_ff"
show AlwaysLatch = "always_latch" show AlwaysLatch = "always_latch"
-- "function inputs and outputs are inferred to be of type reg if no internal
-- data types for the ports are declared"
type PortBinding = (Identifier, Maybe Expr) type PortBinding = (Identifier, Maybe Expr)
data Parameter = Parameter (Maybe Range) Identifier Expr deriving Eq
instance Show Parameter where
show (Parameter r n e) = printf "parameter %s%s = %s;" (showRange r) n (show e)
data Localparam = Localparam (Maybe Range) Identifier Expr deriving Eq
instance Show Localparam where
show (Localparam r n e) = printf "localparam %s%s = %s;" (showRange r) n (show e)
data IntegerV = IntegerV Identifier RangesOrAssignment deriving Eq
instance Show IntegerV where
show (IntegerV x v ) = printf "integer %s%s;" x (showRangesOrAssignment v)
instance Show ModuleItem where instance Show ModuleItem where
show thing = case thing of show thing = case thing of
Comment c -> "// " ++ c Comment c -> "// " ++ c
MIParameter nest -> show nest MIDecl nest -> show nest
MILocalparam nest -> show nest
MIIntegerV nest -> show nest
PortDecl d r x -> printf "%s%s %s;" (show d) (showRanges r) x
LocalNet t x v -> printf "%s %s%s;" (show t) x (showRangesOrAssignment v)
AlwaysC k b -> printf "%s %s" (show k) (show b) AlwaysC k b -> printf "%s %s" (show k) (show b)
Assign a b -> printf "assign %s = %s;" (show a) (show b) Assign a b -> printf "assign %s = %s;" (show a) (show b)
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" (showFuncRet t) x (indent $ unlines' $ map showFunctionItem i) (indent $ show b) Function t x i b -> printf "function %s%s;\n%s\n%s\nendfunction" (showPad t) x (indent $ show i) (indent $ 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)
where where
showMaybePorts :: Maybe [(Identifier, Maybe Expr)] -> String showMaybePorts = maybe "(.*)" showPorts
showMaybePorts Nothing = "(.*)" showPorts :: [PortBinding] -> String
showMaybePorts (Just ports) = showPorts ports showPorts ports = indentedParenList $ map showPort ports
showPorts :: [(Identifier, Maybe Expr)] -> String showPort :: PortBinding -> String
showPorts ports = indentedParenList [ if i == "" then show (fromJust arg) else printf ".%s(%s)" i (if isJust arg then show $ fromJust arg else "") | (i, arg) <- ports ] showPort (i, arg) =
showFunctionItem :: (Bool, BlockItemDeclaration) -> String if i == ""
showFunctionItem (b, item) = prefix ++ (show item) then show (fromJust arg)
where prefix = if b then "input " else "" else printf ".%s(%s)" i (if isJust arg then show $ fromJust arg else "")
type FuncRet = Either Range ()
showFuncRet :: Maybe FuncRet -> String
showFuncRet Nothing = ""
showFuncRet (Just (Left r)) = showRange $ Just r
showFuncRet (Just (Right ())) = "integer "
type RangesOrAssignment = Either [Range] (Maybe Expr)
showRangesOrAssignment :: Either [Range] (Maybe Expr) -> String
showRangesOrAssignment (Left ranges) = showRanges ranges
showRangesOrAssignment (Right val) = showAssignment val
showAssignment :: Maybe Expr -> String showAssignment :: Maybe Expr -> String
showAssignment Nothing = "" showAssignment Nothing = ""
...@@ -190,6 +169,13 @@ showRange :: Maybe Range -> String ...@@ -190,6 +169,13 @@ showRange :: Maybe Range -> String
showRange Nothing = "" showRange Nothing = ""
showRange (Just (h, l)) = printf "[%s:%s] " (show h) (show l) showRange (Just (h, l)) = printf "[%s:%s] " (show h) (show l)
showPad :: Show t => t -> String
showPad x =
if str == ""
then ""
else str ++ " "
where str = show x
indent :: String -> String indent :: String -> String
indent a = '\t' : f a indent a = '\t' : f a
where where
...@@ -331,13 +317,13 @@ instance Show CaseKW where ...@@ -331,13 +317,13 @@ instance Show CaseKW where
show CaseX = "casex" show CaseX = "casex"
data Stmt data Stmt
= Block (Maybe (Identifier, [BlockItemDeclaration])) [Stmt] = Block (Maybe (Identifier, [Decl])) [Stmt]
| Case CaseKW Expr [Case] (Maybe Stmt) | Case CaseKW Expr [Case] (Maybe Stmt)
| BlockingAssignment LHS Expr | For (Identifier, Expr) Expr (Identifier, Expr) Stmt
| NonBlockingAssignment LHS Expr | AsgnBlk LHS Expr
| For (Identifier, Expr) Expr (Identifier, Expr) Stmt | Asgn LHS Expr
| If Expr Stmt Stmt | If Expr Stmt Stmt
| Timing Sense Stmt | Timing Sense Stmt
| Null | Null
deriving Eq deriving Eq
...@@ -345,32 +331,27 @@ commas :: [String] -> String ...@@ -345,32 +331,27 @@ commas :: [String] -> String
commas = intercalate ", " commas = intercalate ", "
instance Show Stmt where instance Show Stmt where
show (Block Nothing b ) = printf "begin\n%s\nend" $ indent $ unlines' $ map show b show (Block header stmts) =
show (Block (Just (a, i)) b ) = printf "begin : %s\n%s\nend" a $ indent $ unlines' $ (map show i ++ map show b) printf "begin%s\n%s\nend" extra (block stmts)
show (Case kw a b Nothing ) = printf "%s (%s)\n%s\nendcase" (show kw) (show a) (indent $ unlines' $ map showCase b) where
show (Case kw a b (Just c) ) = printf "%s (%s)\n%s\n\tdefault:\n%s\nendcase" (show kw) (show a) (indent $ unlines' $ map showCase b) (indent $ indent $ show c) block :: Show t => [t] -> String
show (BlockingAssignment a b ) = printf "%s = %s;" (show a) (show b) block = indent . unlines' . map show
show (NonBlockingAssignment a b ) = printf "%s <= %s;" (show a) (show b) extra = case header of
show (For (a, b) c (d, e) f) = printf "for (%s = %s; %s; %s = %s)\n%s" a (show b) (show c) d (show e) $ indent $ show f Nothing -> ""
show (If a b Null ) = printf "if (%s)\n%s" (show a) (indent $ show b) Just (x, i) -> printf " : %s\n%s" x (block i)
show (If a b c ) = printf "if (%s)\n%s\nelse\n%s" (show a) (indent $ show b) (indent $ show c) show (Case kw e cs def) =
show (Timing t s ) = printf "@(%s) %s" (show t) (show s) printf "%s (%s)\n%s%s\nendcase" (show kw) (show e) (indent $ unlines' $ map showCase cs) defStr
show (Null ) = ";" where
defStr = case def of
data BlockItemDeclaration Nothing -> ""
-- TODO: Maybe BIDReg should use [Range] for the first arg as well, but it's Just c -> printf "\n\tdefault:\n%s" (indent $ indent $ show c)
-- really not clear to me what *useful* purpose this would have. show (For (a,b) c (d,e) f) = printf "for (%s = %s; %s; %s = %s)\n%s" a (show b) (show c) d (show e) $ indent $ show f
= BIDReg (Maybe Range) Identifier [Range] show (AsgnBlk v e) = printf "%s = %s;" (show v) (show e)
| BIDParameter Parameter show (Asgn v e) = printf "%s <= %s;" (show v) (show e)
| BIDLocalparam Localparam show (If a b Null) = printf "if (%s)\n%s" (show a) (indent $ show b)
| BIDIntegerV IntegerV show (If a b c ) = printf "if (%s)\n%s\nelse\n%s" (show a) (indent $ show b) (indent $ show c)
deriving Eq show (Timing t s ) = printf "@(%s) %s" (show t) (show s)
show (Null ) = ";"
instance Show BlockItemDeclaration where
show (BIDReg mr x rs) = printf "reg %s%s%s;" (showRange mr) x (showRanges rs)
show (BIDParameter nest) = show nest
show (BIDLocalparam nest) = show nest
show (BIDIntegerV nest) = show nest
type Case = ([Expr], Stmt) type Case = ([Expr], Stmt)
...@@ -413,7 +394,7 @@ data GenItem ...@@ -413,7 +394,7 @@ data GenItem
instance Show GenItem where instance Show GenItem where
showList i _ = unlines' $ map show i showList i _ = unlines' $ map show i
show (GenBlock Nothing i) = printf "begin\n%s\nend" (indent $ unlines' $ map show i) show (GenBlock Nothing i) = printf "begin\n%s\nend" (indent $ unlines' $ map show i)
show (GenBlock (Just x) i) = printf "begin : %s\n%s\nend" x (indent $ unlines' $ map show i) show (GenBlock (Just x) i) = printf "begin : %s\n%s\nend" x (indent $ unlines' $ map show i)
show (GenCase e c Nothing ) = printf "case (%s)\n%s\nendcase" (show e) (indent $ unlines' $ map showCase c) show (GenCase e c Nothing ) = printf "case (%s)\n%s\nendcase" (show e) (indent $ unlines' $ map showCase c)
show (GenCase e c (Just d)) = printf "case (%s)\n%s\n\tdefault:\n%s\nendcase" (show e) (indent $ unlines' $ map showCase c) (indent $ indent $ show d) show (GenCase e c (Just d)) = printf "case (%s)\n%s\n\tdefault:\n%s\nendcase" (show e) (indent $ unlines' $ map showCase c) (indent $ indent $ show d)
......
{ {
module Language.SystemVerilog.Parser.Parse (descriptions) where module Language.SystemVerilog.Parser.Parse (descriptions) where
import Data.Bits
import Data.List import Data.List
import Data.Maybe import Data.Maybe
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
import Language.SystemVerilog.Parser.Tokens import Language.SystemVerilog.Parser.Tokens
} }
...@@ -200,7 +199,7 @@ ParamDecls :: { [ModuleItem] } ...@@ -200,7 +199,7 @@ ParamDecls :: { [ModuleItem] }
: ParamDecl(")") { $1 } : ParamDecl(")") { $1 }
| ParamDecl(",") ParamDecls { $1 ++ $2 } | ParamDecl(",") ParamDecls { $1 ++ $2 }
ParamDecl(delim) :: { [ModuleItem] } ParamDecl(delim) :: { [ModuleItem] }
: "parameter" opt(Range) DeclAsgns delim { map (MIParameter . (uncurry $ Parameter $2)) $3 } : "parameter" ParamType DeclAsgns delim { map (MIDecl . (uncurry $ Parameter $2)) $3 }
Identifier :: { Identifier } Identifier :: { Identifier }
: simpleIdentifier { tokenString $1 } : simpleIdentifier { tokenString $1 }
...@@ -223,15 +222,16 @@ PortDeclsFollow :: { [ModuleItem] } ...@@ -223,15 +222,16 @@ PortDeclsFollow :: { [ModuleItem] }
| PortDecl(",") PortDeclsFollow { $1 ++ $2 } | PortDecl(",") PortDeclsFollow { $1 ++ $2 }
PortDecl(delim) :: { [ModuleItem] } PortDecl(delim) :: { [ModuleItem] }
: "inout" opt(NetType) Dimensions Identifiers delim { portDeclToModuleItems Inout $2 $3 (zip $4 (repeat Nothing)) } : "inout" NetType Dimensions Identifiers delim { portDeclToModuleItems Inout ($2 $3) (zip $4 (repeat Nothing)) }
| "input" opt(NetType) Dimensions Identifiers delim { portDeclToModuleItems Input $2 $3 (zip $4 (repeat Nothing)) } | "input" NetType Dimensions Identifiers delim { portDeclToModuleItems Input ($2 $3) (zip $4 (repeat Nothing)) }
| "output" Dimensions Identifiers delim { portDeclToModuleItems Output Nothing $2 (zip $3 (repeat Nothing)) } | "output" Dimensions Identifiers delim { portDeclToModuleItems Output (Implicit $2) (zip $3 (repeat Nothing)) }
| "output" "wire" Dimensions Identifiers delim { portDeclToModuleItems Output (Just Wire ) $3 (zip $4 (repeat Nothing)) } | "output" "wire" Dimensions Identifiers delim { portDeclToModuleItems Output (Wire $3) (zip $4 (repeat Nothing)) }
| "output" "reg" Dimensions VariablePortIdentifiers delim { portDeclToModuleItems Output (Just Reg ) $3 $4 } | "output" "reg" Dimensions VariablePortIdentifiers delim { portDeclToModuleItems Output (Reg $3) $4 }
| "output" "logic" Dimensions VariablePortIdentifiers delim { portDeclToModuleItems Output (Just Logic) $3 $4 } | "output" "logic" Dimensions VariablePortIdentifiers delim { portDeclToModuleItems Output (Logic $3) $4 }
NetType :: { [Range] -> Type } NetType :: { [Range] -> Type }
: "wire" { Wire } : "wire" { Wire }
| "logic" { Logic } | "logic" { Logic }
| {- empty -} { Implicit }
VariablePortIdentifiers :: { [(Identifier, Maybe Expr)] } VariablePortIdentifiers :: { [(Identifier, Maybe Expr)] }
: VariablePortIdentifier { [$1] } : VariablePortIdentifier { [$1] }
| VariablePortIdentifiers "," VariablePortIdentifier { $1 ++ [$3] } | VariablePortIdentifiers "," VariablePortIdentifier { $1 ++ [$3] }
...@@ -245,18 +245,15 @@ ModuleItems :: { [ModuleItem] } ...@@ -245,18 +245,15 @@ ModuleItems :: { [ModuleItem] }
ModuleItem :: { [ModuleItem] } ModuleItem :: { [ModuleItem] }
: PortDecl(";") { $1 } : PortDecl(";") { $1 }
-- TODO: Allowing Ranges on aliases creates conflicts | Identifier VariableIdentifiers ";" { map (\(x, a, e) -> MIDecl $ Variable Local (Alias $1 []) x a e) $2 }
| Identifier VariableIdentifiers ";" { map (uncurry $ LocalNet (Alias $1 [])) $2 } | Identifier DimensionsNonEmpty VariableIdentifiers ";" { map (\(x, a, e) -> MIDecl $ Variable Local (Alias $1 $2) x a e) $3 }
| Identifier DimensionsNonEmpty VariableIdentifiers ";" { map (uncurry $ LocalNet (Alias $1 $2)) $3 } | TypeNonAlias VariableIdentifiers ";" { map (\(x, a, e) -> MIDecl $ Variable Local $1 x a e) $2 }
| TypeNonAlias VariableIdentifiers ";" { map (uncurry $ LocalNet $1) $2 } | Declaration { map MIDecl $1 }
| ParameterDeclaration { map MIParameter $1 }
| LocalparamDeclaration { map MILocalparam $1 }
| IntegerDeclaration { map MIIntegerV $1 }
| "assign" LHS "=" Expr ";" { [Assign $2 $4] } | "assign" LHS "=" Expr ";" { [Assign $2 $4] }
| AlwaysKW Stmt { [AlwaysC $1 $2] } | AlwaysKW Stmt { [AlwaysC $1 $2] }
| Identifier ModuleInstantiations ";" { map (uncurry $ Instance $1 []) $2 } | Identifier ModuleInstantiations ";" { map (uncurry $ Instance $1 []) $2 }
| Identifier ParameterBindings ModuleInstantiations ";" { map (uncurry $ Instance $1 $2) $3 } | Identifier ParameterBindings ModuleInstantiations ";" { map (uncurry $ Instance $1 $2) $3 }
| "function" opt(RangeOrType) Identifier FunctionItems Stmt "endfunction" { [Function $2 $3 $4 $5] } | "function" ParamType Identifier FunctionItems Stmt "endfunction" { [Function $2 $3 $4 $5] }
| "genvar" Identifiers ";" { map Genvar $2 } | "genvar" Identifiers ";" { map Genvar $2 }
| "generate" GenItems "endgenerate" { [Generate $2] } | "generate" GenItems "endgenerate" { [Generate $2] }
...@@ -273,35 +270,32 @@ ModuleInstantiation :: { (Identifier, Maybe [PortBinding]) } ...@@ -273,35 +270,32 @@ ModuleInstantiation :: { (Identifier, Maybe [PortBinding]) }
: Identifier "(" Bindings ")" { ($1, Just $3) } : Identifier "(" Bindings ")" { ($1, Just $3) }
| Identifier "(" ".*" ")" { ($1, Nothing) } | Identifier "(" ".*" ")" { ($1, Nothing) }
FunctionItems :: { [(Bool, BlockItemDeclaration)] } FunctionItems :: { [Decl] }
: "(" FunctionPortList ";" BlockItemDeclarations { (map ((,) True) $2) ++ (map ((,) False) $4) } : "(" FunctionPortList ";" BlockItemDeclarations { $2 ++ $4 }
| "(" FunctionPortList ";" { (map ((,) True) $2) } | "(" FunctionPortList ";" { $2 }
| ";" FunctionItemDeclarations { $2 } | ";" FunctionItemDeclarations { $2 }
FunctionPortList :: { [BlockItemDeclaration] } FunctionPortList :: { [Decl] }
: FunctionInputDeclaration(")") { $1 } : FunctionInputDeclaration(")") { $1 }
| FunctionInputDeclaration(",") FunctionPortList { $1 ++ $2 } | FunctionInputDeclaration(",") FunctionPortList { $1 ++ $2 }
FunctionItemDeclarations :: { [(Bool, BlockItemDeclaration)] } FunctionItemDeclarations :: { [Decl] }
: FunctionItemDeclaration { $1 } : FunctionItemDeclaration { $1 }
| FunctionItemDeclarations FunctionItemDeclaration { $1 ++ $2 } | FunctionItemDeclarations FunctionItemDeclaration { $1 ++ $2 }
FunctionItemDeclaration :: { [(Bool, BlockItemDeclaration)] } FunctionItemDeclaration :: { [Decl] }
: BlockItemDeclaration { map ((,) False) $1 } : BlockItemDeclaration { $1 }
| FunctionInputDeclaration(";") { map ((,) True ) $1 } | FunctionInputDeclaration(";") { $1 }
FunctionInputDeclaration(delim) :: { [BlockItemDeclaration] } FunctionInputDeclaration(delim) :: { [Decl] }
: "input" opt("reg") opt(Range) Identifiers delim { map (\x -> BIDReg $3 x []) $4 } : "input" Dimensions Identifiers delim { map (\x -> Variable Input (Implicit $2) x [] Nothing) $3 }
| "input" "integer" Identifiers delim { map (\x -> BIDIntegerV $ IntegerV x $ Left []) $3 } | "input" "reg" Dimensions Identifiers delim { map (\x -> Variable Input (Reg $3) x [] Nothing) $4 }
| "input" "integer" Identifiers delim { map (\x -> Variable Input IntegerT x [] Nothing) $3 }
ParameterDeclaration :: { [Parameter] }
: "parameter" opt(Range) DeclAsgns ";" { map (uncurry $ Parameter $2) $3 } Declaration :: { [Decl] }
: "parameter" ParamType DeclAsgns ";" { map (uncurry $ Parameter $2) $3 }
LocalparamDeclaration :: { [Localparam] } | "localparam" ParamType DeclAsgns ";" { map (uncurry $ Localparam $2) $3 }
: "localparam" opt(Range) DeclAsgns ";" { map (uncurry $ Localparam $2) $3 } | "integer" VariableIdentifiers ";" { map (\(x, a, e) -> Variable Local IntegerT x a e) $2 }
IntegerDeclaration :: { [IntegerV] } ParamType :: { Type }
: "integer" VariableIdentifiers ";" { map (uncurry IntegerV) $2 } : Dimensions { Implicit $1 }
| "integer" { IntegerT }
RangeOrType :: { Either Range () }
: Range { Left $1 }
| "integer" { Right () }
EventControl :: { Sense } EventControl :: { Sense }
: "@" "(" Sense ")" { $3 } : "@" "(" Sense ")" { $3 }
...@@ -310,13 +304,12 @@ EventControl :: { Sense } ...@@ -310,13 +304,12 @@ EventControl :: { Sense }
| "@" "*" { SenseStar } | "@" "*" { SenseStar }
| "@*" { SenseStar } | "@*" { SenseStar }
VariableIdentifiers :: { [(Identifier, Either [Range] (Maybe Expr))] } VariableIdentifiers :: { [(Identifier, [Range], Maybe Expr)] }
: VariableType { [$1] } : VariableType { [$1] }
| VariableIdentifiers "," VariableType { $1 ++ [$3] } | VariableIdentifiers "," VariableType { $1 ++ [$3] }
VariableType :: { (Identifier, Either [Range] (Maybe Expr)) } VariableType :: { (Identifier, [Range], Maybe Expr) }
: Identifier { ($1, Right $ Nothing) } : Identifier Dimensions { ($1, $2, Nothing) }
| Identifier "=" Expr { ($1, Right $ Just $3) } | Identifier Dimensions "=" Expr { ($1, $2, Just $4) }
| Identifier DimensionsNonEmpty { ($1, Left $2) }
Dimensions :: { [Range] } Dimensions :: { [Range] }
: {- empty -} { [] } : {- empty -} { [] }
...@@ -360,7 +353,7 @@ BindingsNonEmpty :: { [(Identifier, Maybe Expr)] } ...@@ -360,7 +353,7 @@ BindingsNonEmpty :: { [(Identifier, Maybe Expr)] }
: Binding { [$1] } : Binding { [$1] }
| Binding "," BindingsNonEmpty { $1 : $3} | Binding "," BindingsNonEmpty { $1 : $3}
Binding :: { (Identifier, Maybe Expr) } Binding :: { (Identifier, Maybe Expr) }
: "." Identifier "(" MaybeExpr ")" { ($2, $4) } : "." Identifier "(" opt(Expr) ")" { ($2, $4) }
| "." Identifier { ($2, Just $ Ident $2) } | "." Identifier { ($2, Just $ Ident $2) }
| Expr { ("", Just $1) } | Expr { ("", Just $1) }
...@@ -379,20 +372,18 @@ Stmt :: { Stmt } ...@@ -379,20 +372,18 @@ Stmt :: { Stmt }
| "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 ";" { BlockingAssignment $1 $3 } | LHS "=" Expr ";" { AsgnBlk $1 $3 }
| LHS "<=" Expr ";" { NonBlockingAssignment $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 }
BlockItemDeclarations :: { [BlockItemDeclaration] } BlockItemDeclarations :: { [Decl] }
: BlockItemDeclaration { $1 } : BlockItemDeclaration { $1 }
| BlockItemDeclarations BlockItemDeclaration { $1 ++ $2 } | BlockItemDeclarations BlockItemDeclaration { $1 ++ $2 }
BlockItemDeclaration :: { [BlockItemDeclaration] } BlockItemDeclaration :: { [Decl] }
: "reg" opt(Range) BlockVariableIdentifiers ";" { map (uncurry $ BIDReg $2) $3 } : "reg" Dimensions BlockVariableIdentifiers ";" { map (\(x, rs) -> Variable Local (Reg $2) x rs Nothing) $3 }
| ParameterDeclaration { map BIDParameter $1 } | Declaration { $1 }
| LocalparamDeclaration { map BIDLocalparam $1 }
| IntegerDeclaration { map BIDIntegerV $1 }
BlockVariableIdentifiers :: { [(Identifier, [Range])] } BlockVariableIdentifiers :: { [(Identifier, [Range])] }
: BlockVariableType { [$1] } : BlockVariableType { [$1] }
| BlockVariableIdentifiers "," BlockVariableType { $1 ++ [$3] } | BlockVariableIdentifiers "," BlockVariableType { $1 ++ [$3] }
...@@ -420,16 +411,12 @@ Number :: { String } ...@@ -420,16 +411,12 @@ Number :: { String }
: number { tokenString $1 } : number { tokenString $1 }
String :: { String } String :: { String }
: string { toString $1 } : string { tail $ init $ tokenString $1 }
CallArgs :: { [Expr] } CallArgs :: { [Expr] }
: Expr { [$1] } : Expr { [$1] }
| CallArgs "," Expr { $1 ++ [$3] } | CallArgs "," Expr { $1 ++ [$3] }
MaybeExpr :: { Maybe Expr }
: { Nothing }
| Expr { Just $1 }
Exprs :: { [Expr] } Exprs :: { [Expr] }
: Expr { [$1] } : Expr { [$1] }
| Exprs "," Expr { $1 ++ [$3] } | Exprs "," Expr { $1 ++ [$3] }
...@@ -513,44 +500,19 @@ parseError a = case a of ...@@ -513,44 +500,19 @@ parseError a = case a of
[] -> error "Parse error: no tokens left to parse." [] -> error "Parse error: no tokens left to parse."
Token t s p : _ -> error $ "Parse error: unexpected token '" ++ s ++ "' (" ++ show t ++ ") at " ++ show p ++ "." Token t s p : _ -> error $ "Parse error: unexpected token '" ++ s ++ "' (" ++ show t ++ ") at " ++ show p ++ "."
toString :: Token -> String portDeclToModuleItems :: Direction -> Type -> [PortBinding] -> [ModuleItem]
toString = tail . init . tokenString portDeclToModuleItems dir t l =
map (\(x, me) -> MIDecl $ Variable dir t x [] me) l
portDeclToModuleItems
:: Direction
-> (Maybe ([Range] -> Type))
-> [Range]
-> [(Identifier, Maybe Expr)]
-> [ModuleItem]
portDeclToModuleItems dir Nothing rs l =
map (PortDecl dir rs) $ map toIdentifier $ l
where
toIdentifier (x, Just _) = error "ParseError: Incomplete port decl cannot have initialization"
toIdentifier (x, Nothing) = x
portDeclToModuleItems dir (Just tf) rs l =
concat $ map toItems l
where
toItems (x, e) =
[ PortDecl dir rs x
, LocalNet (tf rs) x (Right e) ]
getPortNames :: [ModuleItem] -> [Identifier] getPortNames :: [ModuleItem] -> [Identifier]
getPortNames items = getPortNames items =
mapMaybe getPortName items mapMaybe getPortName items
where where
getPortName :: ModuleItem -> Maybe Identifier getPortName :: ModuleItem -> Maybe Identifier
getPortName (PortDecl _ _ ident) = Just ident getPortName (MIDecl (Variable Local _ _ _ _)) = Nothing
getPortName (MIDecl (Variable _ _ ident _ _)) = Just ident
getPortName _ = Nothing getPortName _ = Nothing
stmtsToStmt :: [Stmt] -> Stmt
stmtsToStmt [] = error "stmtsToStmt given empty list!"
stmtsToStmt [s] = s
stmtsToStmt ss = Block Nothing ss
moduleItemsToSingleGenItem :: [ModuleItem] -> GenItem
moduleItemsToSingleGenItem [x] = GenModuleItem x
moduleItemsToSingleGenItem other = error $ "multiple module items in a generate block where only one was allowed" ++ show other
genItemsToGenItem :: [GenItem] -> GenItem genItemsToGenItem :: [GenItem] -> GenItem
genItemsToGenItem [] = error "genItemsToGenItem given empty list!" genItemsToGenItem [] = error "genItemsToGenItem given empty list!"
genItemsToGenItem [x] = x genItemsToGenItem [x] = x
......
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