Parse.y 54.2 KB
Newer Older
1 2 3 4 5 6 7
{- sv2v
 - Author: Zachary Snow <zach@zachjs.com>
 - Original Parser Author: Tom Hawkins <tomahawkins@gmail.com>
 -
 - This file has been *heavily* modified and extended from the original version
 - in tomahawkins/verilog. I have added support for numerous SystemVerilog
 - constructs, which has necessitated rewriting nearly all of this.
8 9 10 11
 -
 - This file is the only remaining one that still uses 2-space indentation. I've
 - decided to leave it this way because I think it is too important to preserve
 - the ability to easily blame/diff this file.
12
 -}
13
{
14
module Language.SystemVerilog.Parser.Parse (parse) where
15

16
import Control.Monad.Except
17
import Language.SystemVerilog.AST
18
import Language.SystemVerilog.Parser.ParseDecl
19
import Language.SystemVerilog.Parser.Tokens
20 21
}

22
%monad { ExceptT String IO }
23
%name parse
24 25 26
%tokentype { Token }
%error { parseError }

27
%expect 0
28 29 30

%token

31 32 33 34 35 36 37 38 39 40
"$bits"                { Token KW_dollar_bits                _ _ }
"$dimensions"          { Token KW_dollar_dimensions          _ _ }
"$unpacked_dimensions" { Token KW_dollar_unpacked_dimensions _ _ }
"$left"                { Token KW_dollar_left                _ _ }
"$right"               { Token KW_dollar_right               _ _ }
"$low"                 { Token KW_dollar_low                 _ _ }
"$high"                { Token KW_dollar_high                _ _ }
"$increment"           { Token KW_dollar_increment           _ _ }
"$size"                { Token KW_dollar_size                _ _ }

41 42
"accept_on"        { Token KW_accept_on    _ _ }
"alias"            { Token KW_alias        _ _ }
43 44 45 46
"always"           { Token KW_always       _ _ }
"always_comb"      { Token KW_always_comb  _ _ }
"always_ff"        { Token KW_always_ff    _ _ }
"always_latch"     { Token KW_always_latch _ _ }
47
"and"              { Token KW_and          _ _ }
48
"assert"           { Token KW_assert       _ _ }
49
"assign"           { Token KW_assign       _ _ }
50
"assume"           { Token KW_assume       _ _ }
51
"automatic"        { Token KW_automatic    _ _ }
52
"before"           { Token KW_before       _ _ }
53
"begin"            { Token KW_begin        _ _ }
54 55 56
"bind"             { Token KW_bind         _ _ }
"bins"             { Token KW_bins         _ _ }
"binsof"           { Token KW_binsof       _ _ }
57
"bit"              { Token KW_bit          _ _ }
58
"break"            { Token KW_break        _ _ }
59
"buf"              { Token KW_buf          _ _ }
60 61
"bufif0"           { Token KW_bufif0       _ _ }
"bufif1"           { Token KW_bufif1       _ _ }
62
"byte"             { Token KW_byte         _ _ }
63 64 65
"case"             { Token KW_case         _ _ }
"casex"            { Token KW_casex        _ _ }
"casez"            { Token KW_casez        _ _ }
66 67 68 69 70 71 72 73 74 75 76
"cell"             { Token KW_cell         _ _ }
"chandle"          { Token KW_chandle      _ _ }
"checker"          { Token KW_checker      _ _ }
"class"            { Token KW_class        _ _ }
"clocking"         { Token KW_clocking     _ _ }
"cmos"             { Token KW_cmos         _ _ }
"config"           { Token KW_config       _ _ }
"const"            { Token KW_const        _ _ }
"constraint"       { Token KW_constraint   _ _ }
"context"          { Token KW_context      _ _ }
"continue"         { Token KW_continue     _ _ }
77
"cover"            { Token KW_cover        _ _ }
78 79 80 81
"covergroup"       { Token KW_covergroup   _ _ }
"coverpoint"       { Token KW_coverpoint   _ _ }
"cross"            { Token KW_cross        _ _ }
"deassign"         { Token KW_deassign     _ _ }
82
"default"          { Token KW_default      _ _ }
83
"defparam"         { Token KW_defparam     _ _ }
84
"design"           { Token KW_design       _ _ }
85
"disable"          { Token KW_disable      _ _ }
86
"dist"             { Token KW_dist         _ _ }
87
"do"               { Token KW_do           _ _ }
88
"edge"             { Token KW_edge         _ _ }
89 90 91
"else"             { Token KW_else         _ _ }
"end"              { Token KW_end          _ _ }
"endcase"          { Token KW_endcase      _ _ }
92 93 94 95
"endchecker"       { Token KW_endchecker   _ _ }
"endclass"         { Token KW_endclass     _ _ }
"endclocking"      { Token KW_endclocking  _ _ }
"endconfig"        { Token KW_endconfig    _ _ }
96 97
"endfunction"      { Token KW_endfunction  _ _ }
"endgenerate"      { Token KW_endgenerate  _ _ }
98
"endgroup"         { Token KW_endgroup     _ _ }
99
"endinterface"     { Token KW_endinterface _ _ }
100
"endmodule"        { Token KW_endmodule    _ _ }
101
"endpackage"       { Token KW_endpackage   _ _ }
102 103 104 105 106 107
"endprimitive"     { Token KW_endprimitive _ _ }
"endprogram"       { Token KW_endprogram   _ _ }
"endproperty"      { Token KW_endproperty  _ _ }
"endspecify"       { Token KW_endspecify   _ _ }
"endsequence"      { Token KW_endsequence  _ _ }
"endtable"         { Token KW_endtable     _ _ }
108
"endtask"          { Token KW_endtask      _ _ }
109
"enum"             { Token KW_enum         _ _ }
110 111 112
"event"            { Token KW_event        _ _ }
"eventually"       { Token KW_eventually   _ _ }
"expect"           { Token KW_expect       _ _ }
113
"export"           { Token KW_export       _ _ }
114
"extends"          { Token KW_extends      _ _ }
115
"extern"           { Token KW_extern       _ _ }
116
"final"            { Token KW_final        _ _ }
117
"first_match"      { Token KW_first_match  _ _ }
118
"for"              { Token KW_for          _ _ }
119 120
"force"            { Token KW_force        _ _ }
"foreach"          { Token KW_foreach      _ _ }
121
"forever"          { Token KW_forever      _ _ }
122 123
"fork"             { Token KW_fork         _ _ }
"forkjoin"         { Token KW_forkjoin     _ _ }
124
"function"         { Token KW_function     _ _ }
125 126
"generate"         { Token KW_generate     _ _ }
"genvar"           { Token KW_genvar       _ _ }
127 128 129
"global"           { Token KW_global       _ _ }
"highz0"           { Token KW_highz0       _ _ }
"highz1"           { Token KW_highz1       _ _ }
130
"if"               { Token KW_if           _ _ }
131
"iff"              { Token KW_iff          _ _ }
132 133 134 135 136
"ifnone"           { Token KW_ifnone       _ _ }
"ignore_bins"      { Token KW_ignore_bins  _ _ }
"illegal_bins"     { Token KW_illegal_bins _ _ }
"implements"       { Token KW_implements   _ _ }
"implies"          { Token KW_implies      _ _ }
137
"import"           { Token KW_import       _ _ }
138 139
"incdir"           { Token KW_incdir       _ _ }
"include"          { Token KW_include      _ _ }
140 141 142
"initial"          { Token KW_initial      _ _ }
"inout"            { Token KW_inout        _ _ }
"input"            { Token KW_input        _ _ }
143 144
"inside"           { Token KW_inside       _ _ }
"instance"         { Token KW_instance     _ _ }
145
"int"              { Token KW_int          _ _ }
146
"integer"          { Token KW_integer      _ _ }
147
"interconnect"     { Token KW_interconnect _ _ }
148
"interface"        { Token KW_interface    _ _ }
149
"intersect"        { Token KW_intersect    _ _ }
150 151 152 153 154 155 156 157
"join"             { Token KW_join         _ _ }
"join_any"         { Token KW_join_any     _ _ }
"join_none"        { Token KW_join_none    _ _ }
"large"            { Token KW_large        _ _ }
"let"              { Token KW_let          _ _ }
"liblist"          { Token KW_liblist      _ _ }
"library"          { Token KW_library      _ _ }
"local"            { Token KW_local        _ _ }
158 159
"localparam"       { Token KW_localparam   _ _ }
"logic"            { Token KW_logic        _ _ }
160
"longint"          { Token KW_longint      _ _ }
161 162 163
"macromodule"      { Token KW_macromodule  _ _ }
"matches"          { Token KW_matches      _ _ }
"medium"           { Token KW_medium       _ _ }
164
"modport"          { Token KW_modport      _ _ }
165
"module"           { Token KW_module       _ _ }
166
"nand"             { Token KW_nand         _ _ }
167
"negedge"          { Token KW_negedge      _ _ }
168 169 170 171
"nettype"          { Token KW_nettype      _ _ }
"new"              { Token KW_new          _ _ }
"nexttime"         { Token KW_nexttime     _ _ }
"nmos"             { Token KW_nmos         _ _ }
172
"nor"              { Token KW_nor          _ _ }
173
"noshowcancelled"  { Token KW_noshowcancelled _ _ }
174
"not"              { Token KW_not          _ _ }
175 176 177
"notif0"           { Token KW_notif0       _ _ }
"notif1"           { Token KW_notif1       _ _ }
"null"             { Token KW_null         _ _ }
178 179
"or"               { Token KW_or           _ _ }
"output"           { Token KW_output       _ _ }
180
"package"          { Token KW_package      _ _ }
181 182
"packed"           { Token KW_packed       _ _ }
"parameter"        { Token KW_parameter    _ _ }
183
"pmos"             { Token KW_pmos         _ _ }
184
"posedge"          { Token KW_posedge      _ _ }
185
"primitive"        { Token KW_primitive    _ _ }
186
"priority"         { Token KW_priority     _ _ }
187
"program"          { Token KW_program      _ _ }
188
"property"         { Token KW_property     _ _ }
189 190 191 192 193 194 195 196 197 198 199 200 201
"protected"        { Token KW_protected    _ _ }
"pull0"            { Token KW_pull0        _ _ }
"pull1"            { Token KW_pull1        _ _ }
"pulldown"         { Token KW_pulldown     _ _ }
"pullup"           { Token KW_pullup       _ _ }
"pulsestyle_ondetect" { Token KW_pulsestyle_ondetect _ _ }
"pulsestyle_onevent"  { Token KW_pulsestyle_onevent _ _ }
"pure"             { Token KW_pure         _ _ }
"rand"             { Token KW_rand         _ _ }
"randc"            { Token KW_randc        _ _ }
"randcase"         { Token KW_randcase     _ _ }
"randsequence"     { Token KW_randsequence _ _ }
"rcmos"            { Token KW_rcmos        _ _ }
202 203
"real"             { Token KW_real         _ _ }
"realtime"         { Token KW_realtime     _ _ }
204
"ref"              { Token KW_ref          _ _ }
205
"reg"              { Token KW_reg          _ _ }
206 207
"reject_on"        { Token KW_reject_on    _ _ }
"release"          { Token KW_release      _ _ }
208
"repeat"           { Token KW_repeat       _ _ }
209
"restrict"         { Token KW_restrict     _ _ }
210
"return"           { Token KW_return       _ _ }
211 212 213 214 215 216 217 218 219 220 221 222
"rnmos"            { Token KW_rnmos        _ _ }
"rpmos"            { Token KW_rpmos        _ _ }
"rtran"            { Token KW_rtran        _ _ }
"rtranif0"         { Token KW_rtranif0     _ _ }
"rtranif1"         { Token KW_rtranif1     _ _ }
"s_always"         { Token KW_s_always     _ _ }
"s_eventually"     { Token KW_s_eventually _ _ }
"s_nexttime"       { Token KW_s_nexttime   _ _ }
"s_until"          { Token KW_s_until      _ _ }
"s_until_with"     { Token KW_s_until_with _ _ }
"scalared"         { Token KW_scalared     _ _ }
"sequence"         { Token KW_sequence     _ _ }
223 224
"shortint"         { Token KW_shortint     _ _ }
"shortreal"        { Token KW_shortreal    _ _ }
225
"showcancelled"    { Token KW_showcancelled _ _ }
226
"signed"           { Token KW_signed       _ _ }
227 228 229 230 231
"small"            { Token KW_small        _ _ }
"soft"             { Token KW_soft         _ _ }
"solve"            { Token KW_solve        _ _ }
"specify"          { Token KW_specify      _ _ }
"specparam"        { Token KW_specparam    _ _ }
232
"static"           { Token KW_static       _ _ }
233 234 235 236
"string"           { Token KW_string       _ _ }
"strong"           { Token KW_strong       _ _ }
"strong0"          { Token KW_strong0      _ _ }
"strong1"          { Token KW_strong1      _ _ }
237
"struct"           { Token KW_struct       _ _ }
238
"super"            { Token KW_super        _ _ }
239 240
"supply0"          { Token KW_supply0      _ _ }
"supply1"          { Token KW_supply1      _ _ }
241 242 243 244
"sync_accept_on"   { Token KW_sync_accept_on _ _ }
"sync_reject_on"   { Token KW_sync_reject_on _ _ }
"table"            { Token KW_table        _ _ }
"tagged"           { Token KW_tagged       _ _ }
245
"task"             { Token KW_task         _ _ }
246
"this"             { Token KW_this         _ _ }
247
"throughout"       { Token KW_throughout   _ _ }
248
"time"             { Token KW_time         _ _ }
249 250 251 252 253
"timeprecision"    { Token KW_timeprecision _ _ }
"timeunit"         { Token KW_timeunit     _ _ }
"tran"             { Token KW_tran         _ _ }
"tranif0"          { Token KW_tranif0      _ _ }
"tranif1"          { Token KW_tranif1      _ _ }
254 255 256 257 258 259
"tri"              { Token KW_tri          _ _ }
"tri0"             { Token KW_tri0         _ _ }
"tri1"             { Token KW_tri1         _ _ }
"triand"           { Token KW_triand       _ _ }
"trior"            { Token KW_trior        _ _ }
"trireg"           { Token KW_trireg       _ _ }
260
"type"             { Token KW_type         _ _ }
261
"typedef"          { Token KW_typedef      _ _ }
262
"union"            { Token KW_union        _ _ }
263
"unique"           { Token KW_unique       _ _ }
264
"unique0"          { Token KW_unique0      _ _ }
265
"unsigned"         { Token KW_unsigned     _ _ }
266 267 268 269
"until"            { Token KW_until        _ _ }
"until_with"       { Token KW_until_with   _ _ }
"untyped"          { Token KW_untyped      _ _ }
"use"              { Token KW_use          _ _ }
270
"uwire"            { Token KW_uwire        _ _ }
271 272 273 274 275 276
"var"              { Token KW_var          _ _ }
"vectored"         { Token KW_vectored     _ _ }
"virtual"          { Token KW_virtual      _ _ }
"void"             { Token KW_void         _ _ }
"wait"             { Token KW_wait         _ _ }
"wait_order"       { Token KW_wait_order   _ _ }
277
"wand"             { Token KW_wand         _ _ }
278 279 280
"weak"             { Token KW_weak         _ _ }
"weak0"            { Token KW_weak0        _ _ }
"weak1"            { Token KW_weak1        _ _ }
281
"while"            { Token KW_while        _ _ }
282
"wildcard"         { Token KW_wildcard     _ _ }
283
"wire"             { Token KW_wire         _ _ }
284
"with"             { Token KW_with         _ _ }
285
"within"           { Token KW_within       _ _ }
286
"wor"              { Token KW_wor          _ _ }
287 288
"xnor"             { Token KW_xnor         _ _ }
"xor"              { Token KW_xor          _ _ }
289 290 291 292 293 294

simpleIdentifier   { Token Id_simple       _ _ }
escapedIdentifier  { Token Id_escaped      _ _ }
systemIdentifier   { Token Id_system       _ _ }
number             { Token Lit_number      _ _ }
string             { Token Lit_string      _ _ }
295
time               { Token Lit_time        _ _ }
296
directive          { Token Spe_Directive   _ _ }
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365

"("                { Token Sym_paren_l _ _ }
")"                { Token Sym_paren_r _ _ }
"["                { Token Sym_brack_l _ _ }
"]"                { Token Sym_brack_r _ _ }
"{"                { Token Sym_brace_l _ _ }
"}"                { Token Sym_brace_r _ _ }
"~"                { Token Sym_tildy _ _ }
"!"                { Token Sym_bang _ _ }
"@"                { Token Sym_at _ _ }
"#"                { Token Sym_pound _ _ }
"%"                { Token Sym_percent _ _ }
"^"                { Token Sym_hat _ _ }
"&"                { Token Sym_amp _ _ }
"|"                { Token Sym_bar _ _ }
"*"                { Token Sym_aster _ _ }
"."                { Token Sym_dot _ _ }
","                { Token Sym_comma _ _ }
":"                { Token Sym_colon _ _ }
";"                { Token Sym_semi _ _ }
"="                { Token Sym_eq _ _ }
"<"                { Token Sym_lt _ _ }
">"                { Token Sym_gt _ _ }
"+"                { Token Sym_plus _ _ }
"-"                { Token Sym_dash _ _ }
"?"                { Token Sym_question _ _ }
"/"                { Token Sym_slash _ _ }
"$"                { Token Sym_dollar _ _ }
"'"                { Token Sym_s_quote _ _ }
"~&"               { Token Sym_tildy_amp _ _ }
"~|"               { Token Sym_tildy_bar _ _ }
"~^"               { Token Sym_tildy_hat _ _ }
"^~"               { Token Sym_hat_tildy _ _ }
"=="               { Token Sym_eq_eq _ _ }
"!="               { Token Sym_bang_eq _ _ }
"&&"               { Token Sym_amp_amp _ _ }
"||"               { Token Sym_bar_bar _ _ }
"**"               { Token Sym_aster_aster _ _ }
"<="               { Token Sym_lt_eq _ _ }
">="               { Token Sym_gt_eq _ _ }
">>"               { Token Sym_gt_gt _ _ }
"<<"               { Token Sym_lt_lt _ _ }
"++"               { Token Sym_plus_plus _ _ }
"--"               { Token Sym_dash_dash _ _ }
"+="               { Token Sym_plus_eq _ _ }
"-="               { Token Sym_dash_eq _ _ }
"*="               { Token Sym_aster_eq _ _ }
"/="               { Token Sym_slash_eq _ _ }
"%="               { Token Sym_percent_eq _ _ }
"&="               { Token Sym_amp_eq _ _ }
"|="               { Token Sym_bar_eq _ _ }
"^="               { Token Sym_hat_eq _ _ }
"+:"               { Token Sym_plus_colon _ _ }
"-:"               { Token Sym_dash_colon _ _ }
"::"               { Token Sym_colon_colon _ _ }
".*"               { Token Sym_dot_aster _ _ }
"->"               { Token Sym_dash_gt _ _ }
":="               { Token Sym_colon_eq _ _ }
":/"               { Token Sym_colon_slash _ _ }
"##"               { Token Sym_pound_pound _ _ }
"[*"               { Token Sym_brack_l_aster _ _ }
"[="               { Token Sym_brack_l_eq _ _ }
"=>"               { Token Sym_eq_gt _ _ }
"@*"               { Token Sym_at_aster _ _ }
"(*"               { Token Sym_paren_l_aster _ _ }
"*)"               { Token Sym_aster_paren_r _ _ }
"*>"               { Token Sym_aster_gt _ _ }
"==="              { Token Sym_eq_eq_eq _ _ }
"!=="              { Token Sym_bang_eq_eq _ _ }
366 367
"==?"              { Token Sym_eq_eq_question _ _ }
"!=?"              { Token Sym_bang_eq_question _ _ }
368 369 370 371
">>>"              { Token Sym_gt_gt_gt _ _ }
"<<<"              { Token Sym_lt_lt_lt _ _ }
"<<="              { Token Sym_lt_lt_eq _ _ }
">>="              { Token Sym_gt_gt_eq _ _ }
372
"<->"              { Token Sym_lt_dash_gt _ _ }
373 374 375
"|->"              { Token Sym_bar_dash_gt _ _ }
"|=>"              { Token Sym_bar_eq_gt _ _ }
"[->"              { Token Sym_brack_l_dash_gt _ _ }
376 377
"#-#"              { Token Sym_pound_dash_pound _ _ }
"#=#"              { Token Sym_pound_eq_pound _ _ }
378 379 380 381 382 383 384
"@@("              { Token Sym_at_at_paren_l _ _ }
"(*)"              { Token Sym_paren_l_aster_paren_r _ _ }
"->>"              { Token Sym_dash_gt_gt _ _ }
"&&&"              { Token Sym_amp_amp_amp _ _ }
"<<<="             { Token Sym_lt_lt_lt_eq _ _ }
">>>="             { Token Sym_gt_gt_gt_eq _ _ }

385

386
-- operator precedences, from *lowest* to *highest*
387 388
%nonassoc NoElse
%nonassoc "else"
389 390 391 392 393 394 395 396 397
%right  "|->" "|=>" "#-#" "#=#"
%right "iff"
%left "or"
%left "and"
%left "intersect"
%left "within"
%right "throughout"
%left "##"
%nonassoc "[*]" "[=]" "[->]"
398
%right "->" "<->"
399 400 401 402
%right "?" ":"
%left  "||"
%left  "&&"
%left  "|" "~|"
Zachary Snow committed
403
%left  "^" "^~" "~^"
404
%left  "&" "~&"
405
%left  "==" "!=" "===" "!==" "==?" "!=?"
406
%left  "<" "<=" ">" ">=" "inside" "dist"
407
%left  "<<" ">>" "<<<" ">>>"
408 409
%left  "+" "-"
%left  "*" "/" "%"
410
%left  "**"
411
%right REDUCE_OP "!" "~" "++" "--"
412
%left  "(" ")" "[" "]" "." "::"
413 414 415

%%

416 417 418 419
opt(p) :: { Maybe a }
  : p { Just $1 }
  |   { Nothing }

420
Descriptions :: { [Description] }
421 422
  : {- empty -}              { [] }
  | Descriptions ";"         { $1 }
423
  | Descriptions Description { $1 ++ $2 }
424

425 426 427 428 429
Description :: { [Description] }
  : Part(ModuleKW   , "endmodule"   ) { [$1] }
  | Part(InterfaceKW, "endinterface") { [$1] }
  | PackageDeclaration                { [$1] }
  | PackageItem { map PackageItem $1 }
430 431

Type :: { Type }
432
  : TypeNonIdent { $1 }
433 434
  |                 Identifier Dimensions { Alias (Nothing) $1 $2 }
  | Identifier "::" Identifier Dimensions { Alias (Just $1) $3 $4 }
435 436
TypeNonIdent :: { Type }
  : PartialType OptSigning Dimensions { $1 $2 $3 }
437
PartialType :: { Signing -> [Range] -> Type }
438
  : NetType                                 {                        Net           $1    }
439 440 441
  | IntegerVectorType                       {                        IntegerVector $1    }
  | IntegerAtomType                         { \sg          -> \[] -> IntegerAtom   $1 sg }
  | NonIntegerType                          { \Unspecified -> \[] -> NonInteger    $1    }
442 443
  | "enum" EnumBaseType "{" EnumItems   "}" { \Unspecified -> Enum   $2 $4 }
  | "struct" Packing    "{" StructItems "}" { \Unspecified -> Struct $2 $4 }
444
  | "union"  Packing    "{" StructItems "}" { \Unspecified -> Union  $2 $4 }
445 446 447 448 449
CastingType :: { Type }
  : IntegerVectorType { IntegerVector $1 Unspecified [] }
  | IntegerAtomType   { IntegerAtom   $1 Unspecified    }
  | NonIntegerType    { NonInteger    $1                }
  | Signing           { Implicit      $1             [] }
450 451 452
EnumBaseType :: { Maybe Type }
  : opt(Type) { $1 }
  | DimensionsNonEmpty { Just $ Implicit Unspecified $1 }
453 454

Signing :: { Signing }
455
  : "signed"   { Signed   }
456
  | "unsigned" { Unsigned }
457 458 459
OptSigning :: { Signing }
  : Signing { $1 }
  | {- empty -} { Unspecified }
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488

NetType :: { NetType }
  : "supply0"   { TSupply0   }
  | "supply1"   { TSupply1   }
  | "tri"       { TTri       }
  | "triand"    { TTriand    }
  | "trior"     { TTrior     }
  | "trireg"    { TTrireg    }
  | "tri0"      { TTri0      }
  | "tri1"      { TTri1      }
  | "uwire"     { TUwire     }
  | "wire"      { TWire      }
  | "wand"      { TWand      }
  | "wor"       { TWor       }
IntegerVectorType :: { IntegerVectorType }
  : "bit"       { TBit       }
  | "logic"     { TLogic     }
  | "reg"       { TReg       }
IntegerAtomType :: { IntegerAtomType }
  : "byte"      { TByte      }
  | "shortint"  { TShortint  }
  | "int"       { TInt       }
  | "longint"   { TLongint   }
  | "integer"   { TInteger   }
  | "time"      { TTime      }
NonIntegerType :: { NonIntegerType }
  : "shortreal" { TShortreal }
  | "real"      { TReal      }
  | "realtime"  { TRealtime  }
489
  | "string"    { TString    }
490
  | "event"     { TEvent     }
491

492 493 494 495
EnumItems :: { [(Identifier, Maybe Expr)] }
  : VariablePortIdentifiers { $1 }

StructItems :: { [(Type, Identifier)] }
496 497 498
  : StructItem             { $1 }
  | StructItems StructItem { $1 ++ $2 }
StructItem :: { [(Type, Identifier)] }
499 500 501 502 503 504 505
  : Type FieldDecls ";" { map (fieldDecl $1) $2 }

FieldDecls :: { [(Identifier, [Range])] }
  : FieldDecl                 { [$1] }
  | FieldDecls "," FieldDecl  { $1 ++ [$3] }
FieldDecl :: { (Identifier, [Range]) }
  : Identifier Dimensions { ($1, $2) }
506

507
Packing :: { Packing }
508 509
  : "packed" OptSigning { Packed $2 }
  | {- empty -}         { Unpacked }
510

511
Part(begin, end) :: { Description }
512 513 514 515
  : AttributeInstances          begin PartHeader ModuleItems end opt(Tag) { $3 $1 False $2 $4 }
  | AttributeInstances "extern" begin PartHeader                          { $4 $1 True  $3 [] }

PartHeader :: { [Attr] -> Bool -> PartKW -> [ModuleItem] -> Description }
516
  : Lifetime Identifier PackageImportDeclarations Params PortDecls ";" { \attrs extern kw items -> Part attrs extern kw $1 $2 (fst $5) ($3 ++ $4 ++ (snd $5) ++ items) }
517 518 519 520 521

ModuleKW :: { PartKW }
  : "module" { Module }
InterfaceKW :: { PartKW }
  : "interface" { Interface }
522

523
PackageDeclaration :: { Description }
524
  : "package" Lifetime Identifier ";" PackageItems "endpackage" opt(Tag) { Package $2 $3 $5 }
525

526 527
Tag :: { Identifier }
  : ":" Identifier { $2 }
528

529 530 531 532
StrTag :: { Identifier }
  : {- empty -}    { "" }
  | ":" Identifier { $2 }

533 534 535 536 537 538 539
PackageImportDeclarations :: { [ModuleItem] }
  : PackageImportDeclaration PackageImportDeclarations { $1 ++ $2 }
  | {- empty -}                                        { [] }

PackageImportDeclaration :: { [ModuleItem] }
  : "import" PackageImportItems ";" { map (MIPackageItem . uncurry Import) $2 }

540
Params :: { [ModuleItem] }
541 542 543
  : {- empty -}          { [] }
  | "#" "(" ParamsFollow { map (MIPackageItem . Decl) $3 }
ParamsFollow :: { [Decl] }
544 545 546 547
  : ParamAsgn ")"              { [$1] }
  | ParamAsgn "," ParamsFollow { $1 : $3 }
  |               ParamsDecl   { $1 }
ParamsDecl :: { [Decl] }
548 549
  : ModuleParameterDecl(")")            { $1 }
  | ModuleParameterDecl(",") ParamsDecl { $1 ++ $2 }
550 551
ParamAsgn :: { Decl }
  : Identifier "=" Expr { Param Parameter (Implicit Unspecified []) $1 $3 }
552

553 554
PortDecls :: { ([Identifier], [ModuleItem]) }
  : "(" DeclTokens(")") { parseDTsAsPortDecls $2 }
555
  | "("            ")"  { ([], []) }
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
  | {- empty -}         { ([], []) }

ModportItems :: { [(Identifier, [ModportDecl])] }
  : ModportItem                  { [$1] }
  | ModportItems "," ModportItem { $1 ++ [$3] }
ModportItem :: { (Identifier, [ModportDecl]) }
  : Identifier "(" ModportPortsDeclarations { ($1, $3) }
ModportPortsDeclarations :: { [ModportDecl] }
  : ModportPortsDeclaration(")")                          { $1 }
  | ModportPortsDeclaration(",") ModportPortsDeclarations { $1 ++ $2 }
ModportPortsDeclaration(delim) :: { [ModportDecl] }
  : ModportSimplePortsDeclaration(delim) { $1 }
ModportSimplePortsDeclaration(delim) :: { [ModportDecl] }
  : Direction ModportSimplePorts delim { map (\(a, b) -> ($1, a, b)) $2 }
ModportSimplePorts :: { [(Identifier, Maybe Expr)] }
  : ModportSimplePort                        { [$1] }
  | ModportSimplePorts "," ModportSimplePort { $1 ++ [$3] }
ModportSimplePort :: { (Identifier, Maybe Expr) }
  : "." Identifier "(" opt(Expr) ")" { ($2, $4) }
  | Identifier                       { ($1, Just $ Ident $1) }

577
Identifier :: { Identifier }
578 579 580
  : simpleIdentifier  { tokenString $1 }
  | escapedIdentifier { tokenString $1 }
  | systemIdentifier  { tokenString $1 }
581

582 583 584 585
Identifiers :: { [Identifier] }
  :                 Identifier { [$1] }
  | Identifiers "," Identifier { $1 ++ [$3] }

586 587
-- uses delimiter propagation hack to avoid conflicts
DeclTokens(delim) :: { [DeclToken] }
588 589 590 591
  : DeclToken                  delim  { [$1] }
  | DeclToken       DeclTokens(delim) { [$1] ++ $2 }
  | AsgnOp Expr "," DeclTokens(delim) { [DTAsgn $1 $2, DTComma] ++ $4 }
  | AsgnOp Expr                delim  { [DTAsgn $1 $2] }
592
DeclToken :: { DeclToken }
593 594
  : DeclOrStmtToken   { $1 }
  | ParameterBindings { DTParams   $1 }
595 596 597 598

DeclOrStmtTokens(delim) :: { [DeclToken] }
  : DeclOrStmtToken                  delim  { [$1] }
  | DeclOrStmtToken DeclOrStmtTokens(delim) { [$1] ++ $2 }
599 600
  | AsgnOp Expr "," DeclOrStmtTokens(delim) { [DTAsgn $1 $2, DTComma] ++ $4 }
  | AsgnOp Expr                      delim  { [DTAsgn $1 $2] }
601
  | IncOrDecOperator                 delim  { [DTAsgn (AsgnOp $1) (Number "1")] }
602 603
  | "<=" opt(DelayOrEventControl) Expr "," DeclOrStmtTokens(delim) { [DTAsgnNBlk $2 $3, DTComma] ++ $5 }
  | "<=" opt(DelayOrEventControl) Expr                      delim  { [DTAsgnNBlk $2 $3] }
604
DeclOrStmtToken :: { DeclToken }
605
  : ","            { DTComma }
606
  | "[" "]"        { DTAutoDim }
607 608 609 610
  | PartSelect     { DTRange    $1 }
  | Identifier     { DTIdent    $1 }
  | Direction      { DTDir      $1 }
  | "[" Expr "]"   { DTBit      $2 }
611
  | LHSConcat      { DTConcat   $1 }
612 613
  | PartialType    { DTType     $1 }
  | "." Identifier { DTDot      $2 }
614
  | PortBindings   { DTInstance $1 }
615
  | Signing        { DTSigning  $1 }
616
  | ExplicitLifetime { DTLifetime $1 }
617
  | Identifier "::" Identifier { DTPSIdent $1 $3 }
Zachary Snow committed
618
  | "const" PartialType { DTType $2 }
619 620
  | "{" StreamOp StreamSize Concat "}" { DTStream $2 $3           (map toLHS $4) }
  | "{" StreamOp            Concat "}" { DTStream $2 (Number "1") (map toLHS $3) }
621

622 623 624 625 626 627
VariablePortIdentifiers :: { [(Identifier, Maybe Expr)] }
  : VariablePortIdentifier                             { [$1] }
  | VariablePortIdentifiers "," VariablePortIdentifier { $1 ++ [$3] }
VariablePortIdentifier :: { (Identifier, Maybe Expr) }
  : Identifier          { ($1, Nothing) }
  | Identifier "=" Expr { ($1, Just $3) }
628

629 630 631 632 633
Direction :: { Direction }
  : "inout"  { Inout  }
  | "input"  { Input  }
  | "output" { Output }

634
ModuleItems :: { [ModuleItem] }
635 636
  : {- empty -}            { [] }
  | ModuleItems ModuleItem { $1 ++ $2 }
637
  | ModuleItems ";"        { $1 }
638 639

ModuleItem :: { [ModuleItem] }
640 641 642 643 644
  : NonGenerateModuleItem { $1 }
  | ConditionalGenerateConstruct      { [Generate [$1]] }
  | LoopGenerateConstruct             { [Generate [$1]] }
  | "generate" GenItems "endgenerate" { [Generate $2] }
NonGenerateModuleItem :: { [ModuleItem] }
645
  -- This item covers module instantiations and all declarations
646 647
  : DeclTokens(";")                      { parseDTsAsModuleItems $1 }
  | ParameterDecl(";")                   { map (MIPackageItem . Decl) $1 }
648 649
  | "defparam" LHSAsgns ";"              { map (uncurry Defparam) $2 }
  | "assign" opt(DelayControl) LHSAsgns ";" { map (uncurry $ Assign $2) $3 }
650
  | AlwaysKW Stmt                        { [AlwaysC $1 $2] }
651
  | "initial" Stmt                       { [Initial $2] }
652
  | "final"   Stmt                       { [Final   $2] }
653 654
  | "genvar" Identifiers ";"             { map Genvar $2 }
  | "modport" ModportItems ";"           { map (uncurry Modport) $2 }
655
  | NonDeclPackageItem                   { map MIPackageItem $1 }
656 657
  | NInputGateKW  NInputGates  ";"       { map (\(a, b, c) -> NInputGate  $1 a b c) $2 }
  | NOutputGateKW NOutputGates ";"       { map (\(a, b, c) -> NOutputGate $1 a b c) $2 }
658
  | AttributeInstance ModuleItem         { map (MIAttr $1) $2 }
659
  | AssertionItem                        { [AssertionItem $1] }
660 661 662 663 664 665 666 667 668 669 670 671 672 673

-- for ModuleItem, for now
AssertionItem :: { AssertionItem }
  : ConcurrentAssertionItem { $1 }

-- for Stmt, for now
ProceduralAssertionStatement :: { Assertion }
  : ConcurrentAssertionStatement { $1 }
  | ImmediateAssertionStatement  { $1 }

ConcurrentAssertionItem :: { AssertionItem }
  : Identifier ":" ConcurrentAssertionStatement { (Just $1, $3) }
  |                ConcurrentAssertionStatement { (Nothing, $1) }
ConcurrentAssertionStatement :: { Assertion }
674 675 676
  : "assert" "property" "(" PropertySpec ")" ActionBlock { Assert (Left $4) $6 }
  | "assume" "property" "(" PropertySpec ")" ActionBlock { Assume (Left $4) $6 }
  | "cover"  "property" "(" PropertySpec ")" Stmt        { Cover  (Left $4) $6 }
677 678 679 680

ImmediateAssertionStatement :: { Assertion }
  : SimpleImmediateAssertionStatement { $1 }
SimpleImmediateAssertionStatement :: { Assertion }
681 682 683
  : "assert" "(" Expr ")" ActionBlock { Assert (Right $3) $5 }
  | "assume" "(" Expr ")" ActionBlock { Assume (Right $3) $5 }
  | "cover"  "(" Expr ")" Stmt        { Cover  (Right $3) $5 }
684 685

PropertySpec :: { PropertySpec }
686 687 688 689 690
  : opt(ClockingEvent) "disable" "iff" "(" Expr ")" PropExpr { PropertySpec $1 (Just $5) $7 }
  | opt(ClockingEvent)                              PropExpr { PropertySpec $1 (Nothing) $2 }

PropExpr :: { PropExpr }
  : SeqExpr { PropExpr $1 }
691 692 693
  | PropExprParens { $1 }
PropExprParens :: { PropExpr }
  : "(" PropExprParens ")" { $2 }
694 695 696 697 698
  | SeqExpr "|->" PropExpr { PropExprImpliesO  $1 $3 }
  | SeqExpr "|=>" PropExpr { PropExprImpliesNO $1 $3 }
  | SeqExpr "#-#" PropExpr { PropExprFollowsO  $1 $3 }
  | SeqExpr "#=#" PropExpr { PropExprFollowsNO $1 $3 }
  | PropExpr "iff" PropExpr { PropExprIff $1 $3 }
699 700
SeqExpr :: { SeqExpr }
  : Expr { SeqExpr $1 }
701 702 703
  | SeqExprParens { $1 }
SeqExprParens :: { SeqExpr }
  : "(" SeqExprParens ")" { $2 }
704 705 706 707 708 709 710 711 712 713 714 715
  | SeqExpr "and"        SeqExpr { SeqExprAnd        $1 $3 }
  | SeqExpr "or"         SeqExpr { SeqExprOr         $1 $3 }
  | SeqExpr "intersect"  SeqExpr { SeqExprIntersect  $1 $3 }
  | Expr    "throughout" SeqExpr { SeqExprThroughout $1 $3 }
  | SeqExpr "within"     SeqExpr { SeqExprWithin     $1 $3 }
  | SeqExpr "##" Number  SeqExpr { SeqExprDelay (Just $1) (Number $3) $4 }
  |         "##" Number  SeqExpr { SeqExprDelay (Nothing) (Number $2) $3 }
  | "first_match" "(" SeqExpr SeqMatchItems ")" { SeqExprFirstMatch $3 $4 }
SeqMatchItems :: { [SeqMatchItem] }
  : "," SeqMatchItem               { [$2] }
  | SeqMatchItems "," SeqMatchItem { $1 ++ [$3] }
SeqMatchItem :: { SeqMatchItem }
716 717
  : ForStepAssignment   { Left $1 }
  | Identifier CallArgs { Right ($1, $2) }
718 719 720 721 722

ActionBlock :: { ActionBlock }
  : Stmt %prec NoElse { ActionBlockIf   $1 }
  |      "else" Stmt  { ActionBlockElse (Nothing) $2 }
  | Stmt "else" Stmt  { ActionBlockElse (Just $1) $3 }
723

724 725 726
AttributeInstances :: { [Attr] }
  : {- empty -}                          { [] }
  | AttributeInstance AttributeInstances { $1 : $2 }
727 728 729 730 731 732 733 734
AttributeInstance :: { Attr }
  : "(*" AttrSpecs "*)" { Attr $2 }
AttrSpecs :: { [AttrSpec] }
  : AttrSpec               { [$1] }
  | AttrSpecs "," AttrSpec { $1 ++ [$3] }
AttrSpec :: { AttrSpec }
  : Identifier "=" Expr { ($1, Just $3) }
  | Identifier          { ($1, Nothing) }
735 736 737 738 739 740 741 742 743 744 745 746 747 748

NInputGates :: { [(Maybe Identifier, LHS, [Expr])] }
  : NInputGate                 { [$1] }
  | NInputGates "," NInputGate { $1 ++ [$3]}
NOutputGates :: { [(Maybe Identifier, [LHS], Expr)] }
  : NOutputGate                  { [$1] }
  | NOutputGates "," NOutputGate { $1 ++ [$3]}

NInputGate :: { (Maybe Identifier, LHS, [Expr]) }
  : opt(Identifier) "(" LHS "," Exprs ")" { ($1, $3, $5) }
NOutputGate :: { (Maybe Identifier, [LHS], Expr) }
  : opt(Identifier) "(" NOutputGateItems { ($1, fst $3, snd $3) }
NOutputGateItems :: { ([LHS], Expr) }
  : Expr ")" { ([], $1) }
749
  | Expr "," NOutputGateItems { (fst $3 ++ [toLHS $1], snd $3) }
750 751 752 753 754 755 756 757 758 759 760

NInputGateKW :: { NInputGateKW }
  : "and"  { GateAnd  }
  | "nand" { GateNand }
  | "or"   { GateOr   }
  | "nor"  { GateNor  }
  | "xor"  { GateXor  }
  | "xnor" { GateXnor }
NOutputGateKW :: { NOutputGateKW }
  : "buf"  { GateBuf  }
  | "not"  { GateNot  }
761

762 763 764 765
LHSAsgns :: { [(LHS, Expr)] }
  : LHSAsgn                   { [$1] }
  | LHSAsgns "," LHSAsgn { $1 ++ [$3] }
LHSAsgn :: { (LHS, Expr) }
766 767
  : LHS "=" Expr { ($1, $3) }

768
PackageItems :: { [PackageItem] }
769
  : {- empty -}              { [] }
770
  | PackageItems ";"         { $1 }
771 772
  | PackageItems PackageItem { $1 ++ $2 }
PackageItem :: { [PackageItem] }
773 774 775
  : DeclTokens(";")    { map Decl $ parseDTsAsDecls $1 }
  | ParameterDecl(";") { map Decl $1 }
  | NonDeclPackageItem { $1 }
776 777
NonDeclPackageItem :: { [PackageItem] }
  : "typedef" Type Identifier ";" { [Typedef $2 $3] }
778 779 780
  | "function" Lifetime FuncRetAndName    TFItems DeclsAndStmts "endfunction" opt(Tag) { [Function $2 (fst $3) (snd $3) (map defaultFuncInput $ (map makeInput $4) ++ fst $5) (snd $5)] }
  | "function" Lifetime "void" Identifier TFItems DeclsAndStmts "endfunction" opt(Tag) { [Task     $2 $4                (map defaultFuncInput $ $5 ++ fst $6) (snd $6)] }
  | "task"     Lifetime Identifier        TFItems DeclsAndStmts "endtask"     opt(Tag) { [Task     $2 $3                (map defaultFuncInput $ $4 ++ fst $5) (snd $5)] }
781
  | "import" PackageImportItems ";" { map (uncurry Import) $2 }
782 783
  | "export" PackageImportItems ";" { map (Export .  Just) $2 }
  | "export" "*" "::" "*" ";"       { [Export Nothing] } -- "Nothing" being no restrictions
784
  | ForwardTypedef ";"              { $1 }
785
  | TimeunitsDeclaration            { $1 }
786
  | Directive                       { [Directive $1] }
787
ForwardTypedef :: { [PackageItem] }
788 789
  : "typedef"          Identifier { [] }
  | "typedef" "enum"   Identifier { [] }
790 791
  | "typedef" "struct" Identifier { [] }
  | "typedef" "union"  Identifier { [] }
792 793 794 795
TimeunitsDeclaration :: { [PackageItem] }
  : "timeunit" Time          ";" { [] }
  | "timeunit" Time "/" Time ";" { [] }
  | "timeprecision" Time     ";" { [] }
796

797 798 799
Directive :: { String }
  : directive { tokenString $1 }

800 801 802 803 804 805
PackageImportItems :: { [(Identifier, Maybe Identifier)] }
  : PackageImportItem                        { [$1] }
  | PackageImportItems "," PackageImportItem { $1 ++ [$3] }
PackageImportItem :: { (Identifier, Maybe Identifier) }
  : Identifier "::" Identifier { ($1, Just $3) }
  | Identifier "::" "*"        { ($1, Nothing) }
806 807

FuncRetAndName :: { (Type, Identifier) }
808 809 810 811 812
  : Type                       Identifier { ($1                     , $2) }
  |                            Identifier { (Implicit Unspecified [], $1) }
  | Signing                    Identifier { (Implicit $1          [], $2) }
  |         DimensionsNonEmpty Identifier { (Implicit Unspecified $1, $2) }
  | Signing DimensionsNonEmpty Identifier { (Implicit $1          $2, $3) }
813

814 815 816 817 818 819
AlwaysKW :: { AlwaysKW }
  : "always"       { Always      }
  | "always_comb"  { AlwaysComb  }
  | "always_ff"    { AlwaysFF    }
  | "always_latch" { AlwaysLatch }

820
Lifetime :: { Lifetime }
821 822 823
  : {- empty -} { Inherit }
  | ExplicitLifetime { $1 }
ExplicitLifetime :: { Lifetime }
824 825 826
  : "static"    { Static    }
  | "automatic" { Automatic }

827 828
TFItems :: { [Decl] }
  : "(" DeclTokens(")") ";" { parseDTsAsDecls $2 }
829
  | "("            ")"  ";" { [] }
830
  |                     ";" { [] }
831 832

ParamType :: { Type }
833
  : PartialType OptSigning Dimensions { $1 $2 $3 }
834
  | DimensionsNonEmpty { Implicit Unspecified $1 }
835
  | Signing Dimensions { Implicit $1          $2 }
836

837
Dimensions :: { [Range] }
838 839 840
  : {- empty -}        { [] }
  | DimensionsNonEmpty { $1 }
DimensionsNonEmpty :: { [Range] }
841 842 843 844
  : Dimension                    { [$1] }
  | DimensionsNonEmpty Dimension { $1 ++ [$2] }
Dimension :: { Range }
  : Range        { $1 }
845
  | "[" Expr "]" { (Number "0", BinOp Sub $2 (Number "1")) }
846

847
DeclAsgns :: { [(Identifier, Expr, [Range])] }
848
  : DeclAsgn               { [$1] }
849
  | DeclAsgns "," DeclAsgn { $1 ++ [$3] }
850 851 852
DeclAsgn :: { (Identifier, Expr, [Range]) }
  : Identifier                    "=" Expr { ($1, $3, []) }
  | Identifier DimensionsNonEmpty "=" Expr { ($1, $4, $2) }
853

854
Range :: { Range }
855
  : "[" Expr ":"  Expr "]" { ($2, $4) }
856 857 858 859 860

PartSelect :: { (PartSelectMode, Range) }
  : "[" Expr ":"  Expr "]" { (NonIndexed  , ($2, $4)) }
  | "[" Expr "+:" Expr "]" { (IndexedPlus , ($2, $4)) }
  | "[" Expr "-:" Expr "]" { (IndexedMinus, ($2, $4)) }
861 862

LHS :: { LHS }
863
  : Identifier         { LHSIdent  $1    }
864
  | LHS PartSelect     { LHSRange  $1 (fst $2) (snd $2) }
865 866
  | LHS "[" Expr "]"   { LHSBit    $1 $3 }
  | LHS "." Identifier { LHSDot    $1 $3 }
867 868 869
  | LHSConcat          { LHSConcat $1    }
  | "{" StreamOp StreamSize Concat "}" { LHSStream $2 $3           (map toLHS $4) }
  | "{" StreamOp            Concat "}" { LHSStream $2 (Number "1") (map toLHS $3) }
870

871 872
LHSConcat :: { [LHS] }
  : "{" LHSs "}" { $2 }
873
LHSs :: { [LHS] }
874 875
  : LHS           { [$1] }
  | LHSs "," LHS  { $1 ++ [$3] }
876

877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898
PortBindings :: { [PortBinding] }
  : "("                    ")" { [] }
  | "(" PortBindingsInside ")" { $2 }
PortBindingsInside :: { [PortBinding] }
  : PortBinding                        { [$1] }
  | PortBinding "," PortBindingsInside { $1 : $3}
PortBinding :: { PortBinding }
  : "." Identifier "(" opt(Expr) ")" { ($2, $4) }
  | "." Identifier                   { ($2, Just $ Ident $2) }
  | Expr                             { ("", Just $1) }
  | ".*"                             { ("*", Nothing) }

ParameterBindings :: { [ParamBinding] }
  : "#" "(" ParamBindingsInside ")" { $3 }
ParamBindingsInside :: { [ParamBinding] }
  : ParamBinding                         { [$1] }
  | ParamBinding "," ParamBindingsInside { $1 : $3}
ParamBinding :: { ParamBinding }
  : "." Identifier "(" TypeOrExpr ")" { ($2, $4) }
  | "." Identifier "("            ")" { ($2, Right Nil) }
  | TypeOrExpr                        { ("", $1) }

899
Stmts :: { [Stmt] }
900 901
  : {- empty -} { [] }
  | Stmts Stmt  { $1 ++ [$2] }
902 903

Stmt :: { Stmt }
904 905 906 907 908 909 910
  : StmtAsgn    { $1 }
  | StmtNonAsgn { $1 }

StmtAsgn :: { Stmt }
  : LHS AsgnOp Expr ";"                        { AsgnBlk $2 $1 $3 }
  | LHS IncOrDecOperator ";"                   { AsgnBlk (AsgnOp $2) $1 (Number "1") }
  | LHS "<=" opt(DelayOrEventControl) Expr ";" { Asgn $3 $1 $4 }
911 912
  | LHS          ";" { Subroutine (lhsToExpr $1) (Args [] []) }
  | LHS CallArgs ";" { Subroutine (lhsToExpr $1) $2 }
913
StmtNonAsgn :: { Stmt }
914 915 916 917 918 919 920 921
  : StmtBlock(BlockKWSeq, "end" ) { $1 }
  | StmtBlock(BlockKWPar, "join") { $1 }
  |                StmtNonBlock   { $1 }
  | Identifier ":" StmtNonBlock   { Block Seq $1 [] [$3] }
StmtBlock(begin, end) :: { Stmt }
  :                begin StrTag DeclsAndStmts end StrTag { uncurry (Block $1 $ combineTags $2 $5) $3 }
  | Identifier ":" begin        DeclsAndStmts end StrTag { uncurry (Block $3 $ combineTags $1 $6) $4 }
StmtNonBlock :: { Stmt }
922
  : ";" { Null }
923 924 925
  | Unique "if" "(" Expr ")" Stmt "else" Stmt  { If $1 $4 $6 $8   }
  | Unique "if" "(" Expr ")" Stmt %prec NoElse { If $1 $4 $6 Null }
  | "for" "(" ForInit ForCond ForStep ")" Stmt { For $3 $4 $5 $7 }
926
  | Unique CaseKW "(" Expr ")" Cases "endcase" { Case $1 $2 $4 $6 }
927
  | TimingControl Stmt                         { Timing $1 $2 }
928
  | "return" Expr ";"                          { Return $2 }
929 930 931
  | "return"      ";"                          { Return Nil }
  | "break"       ";"                          { Break }
  | "continue"    ";"                          { Continue }
932 933 934 935
  | "while"  "(" Expr ")" Stmt                 { While   $3 $5 }
  | "repeat" "(" Expr ")" Stmt                 { RepeatL $3 $5 }
  | "do"      Stmt "while" "(" Expr ")" ";"    { DoWhile $5 $2 }
  | "forever" Stmt                             { Forever $2 }
936
  | "foreach" "(" Identifier IdxVars ")" Stmt  { Foreach $3 $4 $6 }
937 938
  | "->"  Identifier ";"                       { Trigger True  $2 }
  | "->>" Identifier ";"                       { Trigger False $2 }
939
  | AttributeInstance Stmt                     { StmtAttr $1 $2 }
940
  | ProceduralAssertionStatement               { Assertion $1 }
941
  | IncOrDecOperator LHS ";"                   { AsgnBlk (AsgnOp $1) $2 (Number "1") }
942

943 944 945 946 947
BlockKWPar :: { BlockKW }
  : "fork" { Par }
BlockKWSeq :: { BlockKW }
  : "begin" { Seq }

948 949 950 951 952
Unique :: { ViolationCheck }
  : {- empty -} { NoCheck  }
  | "unique"    { Unique   }
  | "unique0"   { Unique0  }
  | "priority"  { Priority }
953

954 955 956 957 958 959 960 961
ForInit :: { Either [Decl] [(LHS, Expr)] }
  :            ";"  { Right [] }
  | DeclTokens(";") { parseDTsAsDeclsOrAsgns $1 }

ForCond :: { Expr }
  :      ";" { Number "1" }
  | Expr ";" { $1 }

962 963 964 965 966 967 968 969 970 971 972
ForStep :: { [(LHS, AsgnOp, Expr)] }
  : {- empty -}     { [] }
  | ForStepNonEmpty { $1 }
ForStepNonEmpty :: { [(LHS, AsgnOp, Expr)] }
  : ForStepAssignment                     { [$1] }
  | ForStepNonEmpty "," ForStepAssignment { $1 ++ [$3] }
ForStepAssignment :: { (LHS, AsgnOp, Expr) }
  : LHS AsgnOp Expr { ($1, $2, $3) }
  | IncOrDecOperator LHS { ($2, AsgnOp $1, Number "1") }
  | LHS IncOrDecOperator { ($1, AsgnOp $2, Number "1") }

973 974 975 976 977 978
IdxVars :: { [Maybe Identifier] }
  : "[" IdxVarsInside "]" { $2 }
IdxVarsInside :: { [Maybe Identifier] }
  : opt(Identifier)                   { [$1] }
  | opt(Identifier) "," IdxVarsInside { $1 : $3 }

979 980 981 982 983
DeclsAndStmts :: { ([Decl], [Stmt]) }
  : DeclOrStmt DeclsAndStmts { combineDeclsAndStmts $1 $2 }
  | StmtNonAsgn Stmts        { ([], $1 : $2) }
  | {- empty -}              { ([], []) }
DeclOrStmt :: { ([Decl], [Stmt]) }
984
  : DeclOrStmtTokens(";") { parseDTsAsDeclOrAsgn $1 }
985
  | ParameterDecl(";")    { ($1, []) }
986

987 988 989
ModuleParameterDecl(delim) :: { [Decl] }
  :    ParameterDecl(delim) { $1 }
  | "type" TypeAsgns delim  { map (uncurry $ ParamType Parameter) $2 }
990
ParameterDecl(delim) :: { [Decl] }
991 992 993 994
  : ParameterDeclKW                                       DeclAsgns delim { makeParamDecls $1 (Implicit Unspecified []) $2 }
  | ParameterDeclKW                             ParamType DeclAsgns delim { makeParamDecls $1 ($2                     ) $3 }
  | ParameterDeclKW                 Identifier Dimensions DeclAsgns delim { makeParamDecls $1 (Alias (Nothing)   $2 $3) $4 }
  | ParameterDeclKW Identifier "::" Identifier Dimensions DeclAsgns delim { makeParamDecls $1 (Alias (Just $2)   $4 $5) $6 }
995 996
  | ParameterDeclKW "type"                                TypeAsgns delim { map (uncurry $ ParamType $1) $3 }
ParameterDeclKW :: { ParamScope }
997 998 999
  : "parameter"  { Parameter  }
  | "localparam" { Localparam }

1000 1001 1002 1003 1004 1005 1006
TypeAsgns :: { [(Identifier, Maybe Type)] }
  : TypeAsgn               { [$1] }
  | TypeAsgns "," TypeAsgn { $1 ++ [$3] }
TypeAsgn :: { (Identifier, Maybe Type) }
  : Identifier "=" Type { ($1, Just $3) }
  | Identifier          { ($1, Nothing) }

1007 1008 1009
-- TODO: This does not allow for @identifier
ClockingEvent :: { Sense }
  : "@" "(" Senses ")" { $3 }
1010

1011
TimingControl :: { Timing }
1012
  : DelayOrEventControl { $1 }
1013
  | CycleDelay          { Cycle $1 }
1014
DelayOrEventControl :: { Timing }
1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025
  : DelayControl { Delay $1 }
  | EventControl { Event $1 }
DelayControl :: { Expr }
  : "#" DelayValue   { $2 }
  | "#" "(" Expr ")" { $3 }
CycleDelay :: { Expr }
  : "##" Expr { $2 }
EventControl :: { Sense }
  : "@" "(" Senses ")" { $3 }
  | "@" "(*)"          { SenseStar }
  | "@*"               { SenseStar }
1026
  | "@" Identifier     { Sense $ LHSIdent $2 }
1027 1028 1029
Senses :: { Sense }
  : Sense             { $1 }
  | Senses "or" Sense { SenseOr $1 $3 }
1030
  | Senses ","  Sense { SenseOr $1 $3 }
1031
Sense :: { Sense }
1032 1033 1034 1035 1036 1037
  : "(" Sense ")"         {              $2 }
  |               LHS     { Sense        $1 }
  | "posedge"     LHS     { SensePosedge $2 }
  | "negedge"     LHS     { SenseNegedge $2 }
  | "posedge" "(" LHS ")" { SensePosedge $3 }
  | "negedge" "(" LHS ")" { SenseNegedge $3 }
1038

1039 1040
DelayValue :: { Expr }
  : Number { Number $1 }
Zachary Snow committed
1041
  | Time   { Time   $1 }
1042 1043
  | Identifier { Ident $1 }
  | Identifier "::" Identifier { PSIdent $1 $3 }
1044
  | "(" Expr ":" Expr ":" Expr ")" { MinTypMax $2 $4 $6 }
1045

1046
CaseKW :: { CaseKW }
1047 1048 1049
  : "case"  { CaseN }
  | "casex" { CaseX }
  | "casez" { CaseZ }
1050

1051
Cases :: { [Case] }
1052 1053 1054 1055 1056 1057 1058
  : opt("inside") InsideCases { validateCases $1 $2 }
InsideCases :: { [([ExprOrRange], Stmt)] }
  : InsideCase             { [$1] }
  | InsideCases InsideCase { $1 ++ [$2] }
InsideCase :: { ([ExprOrRange], Stmt) }
  : OpenRangeList ":"  Stmt { ($1, $3) }
  | "default" opt(":") Stmt { ([], $3) }
1059

1060 1061
Number :: { String }
  : number    { tokenString $1 }
1062 1063

String :: { String }
1064
  : string { tail $ init $ tokenString $1 }
1065

1066 1067 1068
Time :: { String }
  : time { tokenString $1 }

1069
CallArgs :: { Args }
1070 1071
  : "(" CallArgsInside ")" { $2 }
CallArgsInside :: { Args }
1072 1073 1074 1075 1076 1077
  : {- empty -}                        { Args [            ] [] }
  |                NamedCallArgsFollow { Args [            ] $1 }
  | Expr                 NamedCallArgs { Args [Just $1     ] $2 }
  |      UnnamedCallArgs NamedCallArgs { Args (Nothing : $1) $2 }
  | Expr UnnamedCallArgs NamedCallArgs { Args (Just $1 : $2) $3 }
UnnamedCallArgs :: { [Maybe Expr] }
1078
  : "," opt(Expr)                { [$2] }
1079 1080 1081 1082 1083 1084 1085 1086 1087
  | UnnamedCallArgs "," opt(Expr) { $1 ++ [$3] }
NamedCallArgs :: { [(Identifier, Maybe Expr)] }
  : {- empty -}        { [] }
  | "," NamedCallArgsFollow  { $2 }
NamedCallArgsFollow :: { [(Identifier, Maybe Expr)] }
  : NamedCallArg                         { [$1] }
  | NamedCallArgsFollow "," NamedCallArg { $1 ++ [$3] }
NamedCallArg :: { (Identifier, Maybe Expr) }
  : "." Identifier "(" opt(Expr) ")" { ($2, $4) }
1088 1089

Exprs :: { [Expr] }
1090 1091
  :           Expr  { [$1] }
  | Exprs "," Expr  { $1 ++ [$3] }
1092

1093
TypeOrExpr :: { TypeOrExpr }
1094 1095
  : TypeNonIdent { Left $1 }
  | Expr         { Right $1 }
1096

1097 1098 1099 1100 1101 1102 1103
OpenRangeList :: { [ExprOrRange] }
  : ValueRange                   { [$1] }
  | OpenRangeList "," ValueRange { $1 ++ [$3] }
ValueRange :: { ExprOrRange }
  : Expr  { Left  $1 }
  | Range { Right $1 }

1104
Expr :: { Expr }
1105 1106 1107
  : "(" Expr ")"                { $2 }
  | String                      { String $1 }
  | Number                      { Number $1 }
1108
  | Time                        { Time   $1 }
1109
  | Expr CallArgs               { Call $1 $2 }
1110 1111 1112
  | DimsFn "(" TypeOrExpr ")"   { DimsFn $1 $3 }
  | DimFn  "(" TypeOrExpr ")"   { DimFn  $1 $3 (Number "1") }
  | DimFn  "(" TypeOrExpr "," Expr ")" { DimFn $1 $3 $5 }
1113
  | Identifier                  { Ident $1 }
1114
  | Identifier "::" Identifier  { PSIdent $1 $3 }
1115
  | Expr PartSelect             { Range $1 (fst $2) (snd $2) }
1116
  | Expr "[" Expr "]"           { Bit   $1 $3 }
1117 1118
  | "{" Expr Concat "}"         { Repeat $2 $3 }
  | Concat                      { Concat $1 }
1119
  | Expr "?" Expr ":" Expr      { Mux $1 $3 $5 }
1120 1121
  | CastingType "'" "(" Expr ")" { Cast (Left            $1) $4 }
  | Number      "'" "(" Expr ")" { Cast (Right $ Number  $1) $4 }
1122
  | "(" Expr ")" "'""(" Expr ")" { Cast (Right           $2) $6 }
1123 1124
  |                 Identifier  "'" "(" Expr ")" { Cast (Right $ Ident   $1   ) $4 }
  | Identifier "::" Identifier  "'" "(" Expr ")" { Cast (Right $ PSIdent $1 $3) $6 }
1125 1126
  | Expr "." Identifier         { Dot $1 $3 }
  | "'" "{" PatternItems "}"    { Pattern $3 }
1127 1128
  | "{" StreamOp StreamSize Concat "}" { Stream $2 $3           $4 }
  | "{" StreamOp            Concat "}" { Stream $2 (Number "1") $3 }
1129
  | Expr "inside" "{" OpenRangeList "}" { Inside $1 $4 }
1130
  | "(" Expr ":" Expr ":" Expr ")" { MinTypMax $2 $4 $6 }
1131 1132 1133
  -- binary expressions
  | Expr "||"  Expr { BinOp LogOr  $1 $3 }
  | Expr "&&"  Expr { BinOp LogAnd $1 $3 }
1134 1135
  | Expr "->"  Expr { BinOp LogImp $1 $3 }
  | Expr "<->" Expr { BinOp LogEq  $1 $3 }
1136 1137 1138
  | Expr "|"   Expr { BinOp BitOr  $1 $3 }
  | Expr "^"   Expr { BinOp BitXor $1 $3 }
  | Expr "&"   Expr { BinOp BitAnd $1 $3 }
Zachary Snow committed
1139 1140
  | Expr "~^"  Expr { BinOp BitXnor $1 $3 }
  | Expr "^~"  Expr { BinOp BitXnor $1 $3 }
1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172
  | Expr "+"   Expr { BinOp Add $1 $3 }
  | Expr "-"   Expr { BinOp Sub $1 $3 }
  | Expr "*"   Expr { BinOp Mul $1 $3 }
  | Expr "/"   Expr { BinOp Div $1 $3 }
  | Expr "%"   Expr { BinOp Mod $1 $3 }
  | Expr "**"  Expr { BinOp Pow $1 $3 }
  | Expr "=="  Expr { BinOp Eq $1 $3 }
  | Expr "!="  Expr { BinOp Ne $1 $3 }
  | Expr "<"   Expr { BinOp Lt $1 $3 }
  | Expr "<="  Expr { BinOp Le $1 $3 }
  | Expr ">"   Expr { BinOp Gt $1 $3 }
  | Expr ">="  Expr { BinOp Ge $1 $3 }
  | Expr "===" Expr { BinOp TEq $1 $3 }
  | Expr "!==" Expr { BinOp TNe $1 $3 }
  | Expr "==?" Expr { BinOp WEq $1 $3 }
  | Expr "!=?" Expr { BinOp WNe $1 $3 }
  | Expr "<<"  Expr { BinOp ShiftL $1 $3 }
  | Expr ">>"  Expr { BinOp ShiftR $1 $3 }
  | Expr "<<<" Expr { BinOp ShiftAL $1 $3 }
  | Expr ">>>" Expr { BinOp ShiftAR $1 $3 }
  -- unary expressions
  | "!"  Expr                 { UniOp LogNot $2 }
  | "~"  Expr                 { UniOp BitNot $2 }
  | "+"  Expr %prec REDUCE_OP { UniOp UniAdd $2 }
  | "-"  Expr %prec REDUCE_OP { UniOp UniSub $2 }
  | "&"  Expr %prec REDUCE_OP { UniOp RedAnd  $2 }
  | "~&" Expr %prec REDUCE_OP { UniOp RedNand $2 }
  | "|"  Expr %prec REDUCE_OP { UniOp RedOr   $2 }
  | "~|" Expr %prec REDUCE_OP { UniOp RedNor  $2 }
  | "^"  Expr %prec REDUCE_OP { UniOp RedXor  $2 }
  | "~^" Expr %prec REDUCE_OP { UniOp RedXnor $2 }
  | "^~" Expr %prec REDUCE_OP { UniOp RedXnor $2 }
1173

1174 1175 1176
PatternItems :: { [(Identifier, Expr)] }
  : PatternNamedItems   { $1 }
  | PatternUnnamedItems { zip (repeat "") $1 }
1177 1178 1179 1180
PatternNamedItems :: { [(Identifier, Expr)] }
  : PatternNamedItem                       { [$1] }
  | PatternNamedItems "," PatternNamedItem { $1 ++ [$3] }
PatternNamedItem :: { (Identifier, Expr) }
1181 1182 1183
  : Identifier  ":" Expr { ($1       , $3) }
  | PartialType ":" Expr { (':' : show $1  , $3) }
  | "default"   ":" Expr { (':' : "default", $3) }
1184
PatternUnnamedItems :: { [Expr] }
1185 1186 1187 1188 1189
  :                         PatternUnnamedItem { [$1] }
  | PatternUnnamedItems "," PatternUnnamedItem { $1 ++ [$3] }
PatternUnnamedItem :: { Expr }
  : Expr        { $1 }
  | Expr Concat { Repeat $1 $2 }
1190

1191 1192 1193 1194 1195 1196 1197
Concat :: { [Expr] }
  : "{" Exprs "}" { $2 }

StreamOp :: { StreamOp }
  : "<<" { StreamL }
  | ">>" { StreamR }
StreamSize :: { Expr }
1198
  : TypeNonIdent { DimsFn FnBits (Left $1) }
1199 1200
  | Expr         { $1 }

1201 1202 1203 1204 1205 1206 1207 1208 1209
GenItemOrNull :: { GenItem }
  : GenItem { $1 }
  | ";"     { GenNull }

GenItems :: { [GenItem] }
  : {- empty -}      { [] }
  | GenItems GenItem { $1 ++ [$2] }

GenItem :: { GenItem }
1210 1211 1212 1213 1214
  : GenBlock              { uncurry GenBlock $1 }
  | NonGenerateModuleItem { genItemsToGenItem $ map GenModuleItem $1 }
  | ConditionalGenerateConstruct { $1 }
  | LoopGenerateConstruct        { $1 }
ConditionalGenerateConstruct :: { GenItem }
1215 1216
  : "if" "(" Expr ")" GenItemOrNull "else" GenItemOrNull { GenIf $3 $5 $7      }
  | "if" "(" Expr ")" GenItemOrNull %prec NoElse         { GenIf $3 $5 GenNull }
1217
  | "case" "(" Expr ")" GenCases "endcase" { GenCase $3 $5 }
1218
LoopGenerateConstruct :: { GenItem }
1219
  : "for" "(" GenvarInitialization ";" Expr ";" GenvarIteration ")" GenItem { GenFor $3 $5 $7 $9 }
1220

1221 1222
GenBlock :: { (Identifier, [GenItem]) }
  : "begin" StrTag GenItems "end" StrTag { (combineTags $2 $5, $3) }
1223

1224
GenCases :: { [GenCase] }
1225 1226
  : GenCase          { [$1] }
  | GenCases GenCase { validateGenCases $ $1 ++ [$2] }
1227
GenCase :: { GenCase }
1228 1229
  : Exprs         ":"  GenItemOrNull { ($1, $3) }
  | "default" opt(":") GenItemOrNull { ([], $3) }
1230

1231 1232 1233 1234
GenvarInitialization :: { (Bool, Identifier, Expr) }
  : "genvar" Identifier "=" Expr { (True , $2, $4) }
  |          Identifier "=" Expr { (False, $1, $3) }

1235
GenvarIteration :: { (Identifier, AsgnOp, Expr) }
1236
  : Identifier AsgnOp Expr { ($1, $2, $3) }
1237 1238 1239
  | IncOrDecOperator Identifier { ($2, AsgnOp $1, Number "1") }
  | Identifier IncOrDecOperator { ($1, AsgnOp $2, Number "1") }

1240
AsgnOp :: { AsgnOp }
1241 1242 1243 1244 1245 1246
  : "="    { AsgnOpEq }
  | "+="   { AsgnOp Add }
  | "-="   { AsgnOp Sub }
  | "*="   { AsgnOp Mul }
  | "/="   { AsgnOp Div }
  | "%="   { AsgnOp Mod }
1247 1248 1249
  | "&="   { AsgnOp BitAnd }
  | "|="   { AsgnOp BitOr  }
  | "^="   { AsgnOp BitXor }
1250 1251 1252 1253 1254 1255 1256 1257
  | "<<="  { AsgnOp ShiftL }
  | ">>="  { AsgnOp ShiftR }
  | "<<<=" { AsgnOp ShiftAL }
  | ">>>=" { AsgnOp ShiftAR }

IncOrDecOperator :: { BinOp }
  : "++" { Add }
  | "--" { Sub }
1258

1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270
DimsFn :: { DimsFn }
  : "$bits"                { FnBits               }
  | "$dimensions"          { FnDimensions         }
  | "$unpacked_dimensions" { FnUnpackedDimensions }
DimFn :: { DimFn }
  : "$left"                { FnLeft               }
  | "$right"               { FnRight              }
  | "$low"                 { FnLow                }
  | "$high"                { FnHigh               }
  | "$increment"           { FnIncrement          }
  | "$size"                { FnSize               }

1271
{
1272

1273
parseError :: [Token] -> ExceptT String IO a
1274
parseError a = case a of
1275
  []              -> throwError $ "Parse error: no tokens left to parse."
1276
  Token t s p : _ -> throwError $ show p ++ ": Parse error: unexpected token '" ++ s ++ "' (" ++ show t ++ ")."
1277

1278 1279
genItemsToGenItem :: [GenItem] -> GenItem
genItemsToGenItem [x] = x
1280
genItemsToGenItem xs = GenBlock "" xs
1281

1282 1283 1284 1285
combineDeclsAndStmts :: ([Decl], [Stmt]) -> ([Decl], [Stmt]) -> ([Decl], [Stmt])
combineDeclsAndStmts (a1, b1) (a2, b2) = (a1 ++ a2, b1 ++ b2)

makeInput :: Decl -> Decl
1286 1287 1288 1289
makeInput (Variable Local t x a me) = Variable Input t x a me
makeInput (Variable Input t x a me) = Variable Input t x a me
makeInput other =
  error $ "unexpected non-var or non-input decl: " ++ (show other)
1290

1291
defaultFuncInput :: Decl -> Decl
1292 1293 1294 1295 1296 1297
defaultFuncInput (Variable dir (Implicit sg rs) x a me) =
  Variable dir t x a me
  where
    t = if dir == Input || dir == Inout
      then IntegerVector TLogic sg rs
      else Implicit sg rs
1298 1299
defaultFuncInput other = other

1300 1301 1302 1303
combineTags :: Identifier -> Identifier -> Identifier
combineTags a "" = a
combineTags "" b = b
combineTags a b =
1304
  if a == b
1305
    then a
1306 1307
    else error $ "tag mismatch: " ++ show (a, b)

1308 1309 1310 1311 1312 1313
toLHS :: Expr -> LHS
toLHS expr =
  case exprToLHS expr of
    Just lhs -> lhs
    Nothing -> error $ "Parse error: cannot convert expression to LHS: "
                ++ show expr
1314 1315

makeParamDecls
1316
  :: ParamScope
1317 1318 1319
  -> Type
  -> [(Identifier, Expr, [Range])]
  -> [Decl]
1320
makeParamDecls s t items =
1321 1322 1323
  map mapper items
  where
    (tf, rs) = typeRanges t
1324
    mapper (x, e, a) = Param s (tf $ a ++ rs) x e
1325

1326 1327 1328 1329 1330
fieldDecl :: Type -> (Identifier, [Range]) -> (Type, Identifier)
fieldDecl t (x, rs2) =
  (tf $ rs2 ++ rs1, x)
  where (tf, rs1) = typeRanges t

1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360
validateCases :: Maybe Token -> [([ExprOrRange], Stmt)] -> [Case]
validateCases Nothing items =
  if length (filter null exprs) <= 1
    then zip exprs' stmts
    else error $ "multiple default cases: " ++ show items
  where
    (exprs, stmts) = unzip items
    exprs' = map (map unwrap) exprs
    unwrap (Left expr) = expr
    unwrap (Right range) =
      error $ "illegal use of a range (" ++ show range
        ++ ") in a non-inside case"
validateCases (Just _) items =
  if length (filter null sets) <= 1
    then zip sets' stmts
    else error $ "multiple default cases: " ++ show items
  where
    (sets, stmts) = unzip items
    sets' = map unwrap sets
    unwrap [] = []
    unwrap ls = [Inside Nil ls]

validateGenCases :: [GenCase] -> [GenCase]
validateGenCases items =
  if length (filter null exprs) <= 1
    then items
    else error $ "multiple default generate cases: " ++ show items
  where
    (exprs, _) = unzip items

1361
}