1#![allow(unused_variables)]
6#![allow(unused_mut)]
7#![allow(dead_code)]
8
9use crate::ast;
10use crate::ast::*;
11use crate::lexer::{Lexer, TokenAndSpan};
12use crate::token::*;
13use moore_common::{arenas::Alloc, errors::*, name::*, source::*, util::HasSpan};
14use std;
15use std::collections::VecDeque;
16
17type ParseResult<T> = Result<T, DiagBuilder2>;
27
28type ReportedResult<T> = Result<T, ()>;
31
32trait AbstractParser<'n> {
36 fn arena(&self) -> &'n ast::Arena<'n>;
37 fn peek(&mut self, offset: usize) -> TokenAndSpan;
38 fn bump(&mut self);
39 fn skip(&mut self);
40 fn consumed(&self) -> usize;
41 fn last_span(&self) -> Span;
42 fn add_diag(&mut self, diag: DiagBuilder2);
43 fn severity(&self) -> Severity;
44
45 fn try_eat_ident(&mut self) -> Option<(Name, Span)> {
46 match self.peek(0) {
47 (Ident(name), span) => {
48 self.bump();
49 Some((name, span))
50 }
51 (EscIdent(name), span) => {
52 self.bump();
53 Some((name, span))
54 }
55 _ => None,
56 }
57 }
58
59 fn eat_ident_or(&mut self, msg: &str) -> ParseResult<(Name, Span)> {
60 match self.peek(0) {
61 (Ident(name), span) => {
62 self.bump();
63 Ok((name, span))
64 }
65 (EscIdent(name), span) => {
66 self.bump();
67 Ok((name, span))
68 }
69 (tkn, span) => {
70 Err(DiagBuilder2::error(format!("expected {} before `{}`", msg, tkn)).span(span))
71 }
72 }
73 }
74
75 fn eat_ident(&mut self, msg: &str) -> ReportedResult<(Name, Span)> {
76 match self.peek(0) {
77 (Ident(name), span) => {
78 self.bump();
79 Ok((name, span))
80 }
81 (EscIdent(name), span) => {
82 self.bump();
83 Ok((name, span))
84 }
85 (tkn, span) => {
86 self.add_diag(
87 DiagBuilder2::error(format!("expected {} before `{}`", msg, tkn)).span(span),
88 );
89 Err(())
90 }
91 }
92 }
93
94 fn is_ident(&mut self) -> bool {
95 match self.peek(0).0 {
96 Ident(_) | EscIdent(_) => true,
97 _ => false,
98 }
99 }
100
101 fn require(&mut self, expect: Token) -> Result<(), DiagBuilder2> {
102 match self.peek(0) {
103 (actual, _) if actual == expect => {
104 self.bump();
105 Ok(())
106 }
107 (wrong, span) => Err(DiagBuilder2::error(format!(
108 "expected `{}`, but found `{}` instead",
109 expect, wrong
110 ))
111 .span(span)),
112 }
113 }
114
115 fn require_reported(&mut self, expect: Token) -> ReportedResult<()> {
116 match self.require(expect) {
117 Ok(x) => Ok(x),
118 Err(e) => {
119 self.add_diag(e);
120 Err(())
121 }
122 }
123 }
124
125 fn try_eat(&mut self, expect: Token) -> bool {
126 match self.peek(0) {
127 (actual, _) if actual == expect => {
128 self.bump();
129 true
130 }
131 _ => false,
132 }
133 }
134
135 fn recover_balanced(&mut self, terminators: &[Token], eat_terminator: bool) {
156 let mut stack = Vec::new();
158 loop {
159 let (tkn, sp) = self.peek(0);
160 if stack.is_empty() {
161 for t in terminators {
162 if *t == tkn {
163 if eat_terminator {
164 self.skip();
165 }
166 return;
167 }
168 }
169 }
170
171 match tkn {
172 OpenDelim(x) => stack.push(x),
173 CloseDelim(x) => {
174 if let Some(open) = stack.pop() {
175 if open != x {
176 self.add_diag(
177 DiagBuilder2::fatal(format!(
178 "found closing `{}` which is not the complement to the \
179 previous opening `{}`",
180 CloseDelim(x),
181 OpenDelim(open)
182 ))
183 .span(sp),
184 );
185 break;
186 }
187 } else {
188 self.add_diag(
189 DiagBuilder2::fatal(format!(
190 "found closing `{}` without an earlier opening `{}`",
191 CloseDelim(x),
192 OpenDelim(x)
193 ))
194 .span(sp),
195 );
196 break;
197 }
198 }
199 Eof => break,
200 _ => (),
201 }
202 self.skip();
203 }
204 }
205
206 fn is_fatal(&self) -> bool {
207 self.severity() >= Severity::Fatal
208 }
209
210 fn is_error(&self) -> bool {
211 self.severity() >= Severity::Error
212 }
213
214 fn anticipate(&mut self, tokens: &[Token]) -> ReportedResult<()> {
215 let (tkn, sp) = self.peek(0);
216 for t in tokens {
217 if *t == tkn {
218 return Ok(());
219 }
220 }
221 self.add_diag(
222 DiagBuilder2::error(format!(
223 "expected {:?}, but found {:?} instead",
224 tokens, tkn
225 ))
226 .span(sp),
227 );
228 Err(())
229 }
230}
231
232struct Parser<'a, 'n> {
233 input: Lexer<'a>,
234 queue: VecDeque<TokenAndSpan>,
235 diagnostics: Vec<DiagBuilder2>,
236 last_span: Span,
237 severity: Severity,
238 consumed: usize,
239 arena: &'n ast::Arena<'n>,
240}
241
242impl<'a, 'n> AbstractParser<'n> for Parser<'a, 'n> {
243 fn arena(&self) -> &'n ast::Arena<'n> {
244 self.arena
245 }
246
247 fn peek(&mut self, offset: usize) -> TokenAndSpan {
248 self.ensure_queue_filled(offset);
249 if offset < self.queue.len() {
250 self.queue[offset]
251 } else {
252 *self
253 .queue
254 .back()
255 .expect("At least an Eof token should be in the queue")
256 }
257 }
258
259 fn bump(&mut self) {
260 if self.queue.is_empty() {
261 self.ensure_queue_filled(1);
262 }
263 if let Some((_, sp)) = self.queue.pop_front() {
264 self.last_span = sp;
265 self.consumed += 1;
266 }
267 }
268
269 fn skip(&mut self) {
270 self.bump()
271 }
272
273 fn consumed(&self) -> usize {
274 self.consumed
275 }
276
277 fn last_span(&self) -> Span {
278 self.last_span
279 }
280
281 fn add_diag(&mut self, diag: DiagBuilder2) {
282 eprintln!("");
283 eprintln!("{}", diag);
284
285 if diag.get_severity() >= Severity::Warning {
287 trace!(
288 "Diagnostic triggered here:\n{:?}",
289 backtrace::Backtrace::new()
290 );
291 }
292
293 if diag.get_severity() > self.severity {
296 self.severity = diag.get_severity();
297 }
298 self.diagnostics.push(diag);
299 }
300
301 fn severity(&self) -> Severity {
302 self.severity
303 }
304}
305
306impl<'a, 'n> Parser<'a, 'n> {
307 fn new(input: Lexer<'a>, arena: &'n ast::Arena<'n>) -> Self {
308 Parser {
309 input: input,
310 queue: VecDeque::new(),
311 diagnostics: Vec::new(),
312 last_span: INVALID_SPAN,
313 severity: Severity::Note,
314 consumed: 0,
315 arena,
316 }
317 }
318
319 fn ensure_queue_filled(&mut self, min_tokens: usize) {
320 if let Some(&(Eof, _)) = self.queue.back() {
321 return;
322 }
323 while self.queue.len() <= min_tokens {
324 match self.input.next_token() {
325 Ok((Eof, sp)) => self.queue.push_back((Eof, sp)),
326 Ok(tkn) => self.queue.push_back(tkn),
327 Err(x) => self.add_diag(x),
328 }
329 }
330 }
331}
332
333fn flanked<'n, R, F>(
337 p: &mut dyn AbstractParser<'n>,
338 delim: DelimToken,
339 mut inner: F,
340) -> ReportedResult<R>
341where
342 F: FnMut(&mut dyn AbstractParser<'n>) -> ReportedResult<R>,
343{
344 p.require_reported(OpenDelim(delim))?;
345 match inner(p) {
346 Ok(r) => match p.require_reported(CloseDelim(delim)) {
347 Ok(_) => Ok(r),
348 Err(e) => {
349 p.recover_balanced(&[CloseDelim(delim)], true);
350 Err(e)
351 }
352 },
353 Err(e) => {
354 p.recover_balanced(&[CloseDelim(delim)], true);
355 Err(e)
356 }
357 }
358}
359
360fn try_flanked<'n, R, F>(
365 p: &mut dyn AbstractParser<'n>,
366 delim: DelimToken,
367 inner: F,
368) -> ReportedResult<Option<R>>
369where
370 F: FnMut(&mut dyn AbstractParser<'n>) -> ReportedResult<R>,
371{
372 if p.peek(0).0 == OpenDelim(delim) {
373 flanked(p, delim, inner).map(|r| Some(r))
374 } else {
375 Ok(None)
376 }
377}
378
379fn comma_list<'n, R, F, T>(
382 p: &mut dyn AbstractParser<'n>,
383 mut term: T,
384 msg: &str,
385 mut item: F,
386) -> ReportedResult<Vec<R>>
387where
388 F: FnMut(&mut dyn AbstractParser<'n>) -> ReportedResult<R>,
389 T: Predicate,
390{
391 let mut v = Vec::new();
392 while !p.is_fatal() && p.peek(0).0 != Eof && !term.matches(p) {
393 match item(p) {
395 Ok(x) => v.push(x),
396 Err(e) => {
397 term.recover(p, false);
398 return Err(e);
399 }
400 }
401
402 if term.matches(p) {
406 break;
407 } else if p.try_eat(Comma) {
408 if term.matches(p) {
409 let q = p.last_span();
410 p.add_diag(DiagBuilder2::warning("superfluous trailing comma").span(q));
411 break;
412 }
413 } else {
414 let sp = p.peek(0).1;
415 p.add_diag(
416 DiagBuilder2::error(format!("expected , or {} after {}", term.describe(), msg))
417 .span(sp),
418 );
419 term.recover(p, false);
420 return Err(());
421 }
422 }
423 Ok(v)
424}
425
426fn comma_list_nonempty<'n, R, F, T>(
428 p: &mut dyn AbstractParser<'n>,
429 term: T,
430 msg: &str,
431 item: F,
432) -> ReportedResult<Vec<R>>
433where
434 F: FnMut(&mut dyn AbstractParser<'n>) -> ReportedResult<R>,
435 T: Predicate,
436{
437 let q = p.peek(0).1;
438 let v = comma_list(p, term, msg, item)?;
439 if v.is_empty() {
440 p.add_diag(DiagBuilder2::error(format!("expected at least one {}", msg)).span(q));
441 Err(())
442 } else {
443 Ok(v)
444 }
445}
446
447fn repeat_until<'n, R, F>(
448 p: &mut dyn AbstractParser<'n>,
449 term: Token,
450 mut item: F,
451) -> ReportedResult<Vec<R>>
452where
453 F: FnMut(&mut dyn AbstractParser<'n>) -> ReportedResult<R>,
454{
455 let mut v = Vec::new();
456 while p.peek(0).0 != term && p.peek(0).0 != Eof {
457 match item(p) {
458 Ok(x) => v.push(x),
459 Err(_) => {
460 p.recover_balanced(&[term], false);
461 break;
462 }
463 }
464 }
465 Ok(v)
466}
467
468fn recovered<'n, R, F>(
469 p: &mut dyn AbstractParser<'n>,
470 term: Token,
471 mut item: F,
472) -> ReportedResult<R>
473where
474 F: FnMut(&mut dyn AbstractParser<'n>) -> ReportedResult<R>,
475{
476 match item(p) {
477 Ok(x) => Ok(x),
478 Err(e) => {
479 p.recover_balanced(&[term], false);
480 Err(e)
481 }
482 }
483}
484
485#[allow(dead_code)]
489fn r#try<'n, R, F>(p: &mut dyn AbstractParser<'n>, mut parse: F) -> Option<R>
490where
491 F: FnMut(&mut dyn AbstractParser<'n>) -> ReportedResult<R>,
492{
493 let mut bp = BranchParser::new(p);
494 match parse(&mut bp) {
495 Ok(r) => {
496 bp.commit();
497 Some(r)
498 }
499 Err(_) => None,
500 }
501}
502
503fn parse_identifier<'n, M: std::fmt::Display>(
505 p: &mut dyn AbstractParser<'n>,
506 msg: M,
507) -> ReportedResult<ast::Identifier> {
508 parse_identifier_name(p, msg).map(|n| ast::Identifier {
509 span: n.span,
510 name: n.value,
511 })
512}
513
514fn parse_identifier_name<'n, M: std::fmt::Display>(
516 p: &mut dyn AbstractParser<'n>,
517 msg: M,
518) -> ReportedResult<Spanned<Name>> {
519 let (tkn, span) = p.peek(0);
520 match tkn {
521 Ident(n) | EscIdent(n) => {
522 p.bump();
523 Ok(Spanned::new(n, span))
524 }
525 x => {
526 p.add_diag(
527 DiagBuilder2::error(format!("expected {}, but found `{}` instead", msg, x))
528 .span(span),
529 );
530 Err(())
531 }
532 }
533}
534
535fn parse_string_literal<'n, M: std::fmt::Display>(
537 p: &mut dyn AbstractParser<'n>,
538 msg: M,
539) -> ReportedResult<Spanned<Name>> {
540 let (tkn, span) = p.peek(0);
541 match tkn {
542 Literal(Lit::Str(n)) => {
543 p.bump();
544 Ok(Spanned::new(n, span))
545 }
546 x => {
547 p.add_diag(
548 DiagBuilder2::error(format!("expected {}, but found `{}` instead", msg, x))
549 .span(span),
550 );
551 Err(())
552 }
553 }
554}
555
556fn try_identifier<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Option<ast::Identifier>> {
557 try_identifier_name(p).map(|n| {
558 n.map(|n| ast::Identifier {
559 span: n.span,
560 name: n.value,
561 })
562 })
563}
564
565fn try_identifier_name<'n>(
566 p: &mut dyn AbstractParser<'n>,
567) -> ReportedResult<Option<Spanned<Name>>> {
568 let (tkn, span) = p.peek(0);
569 match tkn {
570 Ident(n) | EscIdent(n) => {
571 p.bump();
572 Ok(Some(Spanned::new(n, span)))
573 }
574 _ => Ok(None),
575 }
576}
577
578trait Predicate {
579 fn matches(&mut self, _: &mut dyn AbstractParser<'_>) -> bool;
580 fn recover(&mut self, _: &mut dyn AbstractParser<'_>, consume: bool);
581 fn describe(&self) -> String;
582}
583
584impl Predicate for Token {
585 fn matches(&mut self, p: &mut dyn AbstractParser<'_>) -> bool {
586 p.peek(0).0 == *self
587 }
588
589 fn recover(&mut self, p: &mut dyn AbstractParser<'_>, consume: bool) {
590 p.recover_balanced(&[*self], consume)
591 }
592
593 fn describe(&self) -> String {
594 self.as_str().into()
595 }
596}
597
598struct FuncPredicate<
599 M: FnMut(&mut dyn AbstractParser<'_>) -> bool,
600 R: FnMut(&mut dyn AbstractParser<'_>, bool),
601> {
602 match_func: M,
603 recover_func: R,
604 desc: &'static str,
605}
606
607impl<
608 M: FnMut(&mut dyn AbstractParser<'_>) -> bool,
609 R: FnMut(&mut dyn AbstractParser<'_>, bool),
610 > Predicate for FuncPredicate<M, R>
611{
612 fn matches(&mut self, p: &mut dyn AbstractParser<'_>) -> bool {
613 (self.match_func)(p)
614 }
615
616 fn recover(&mut self, p: &mut dyn AbstractParser<'_>, consume: bool) {
617 (self.recover_func)(p, consume)
618 }
619
620 fn describe(&self) -> String {
621 self.desc.into()
622 }
623}
624
625pub fn parse<'n>(input: Lexer, arena: &'n ast::Arena<'n>) -> Result<ast::SourceFile<'n>, ()> {
626 let mut p = Parser::new(input, arena);
627 let root = parse_source_text(&mut p);
628 if p.is_error() {
629 Err(())
630 } else {
631 Ok(root)
632 }
633}
634
635fn parse_source_text<'n>(p: &mut dyn AbstractParser<'n>) -> ast::SourceFile<'n> {
636 let mut span = p.peek(0).1;
637 let mut root = ast::SourceFileData {
638 timeunits: Timeunit {
639 unit: None,
640 prec: None,
641 },
642 items: Vec::new(),
643 };
644
645 match parse_time_units(p) {
647 Ok(x) => root.timeunits = x,
648 Err(()) => (),
649 }
650
651 while !p.is_fatal() && p.peek(0).0 != Eof {
653 match parse_item(p) {
654 Ok(item) => root.items.push(item),
655 Err(()) => (), }
657 }
658
659 span.expand(p.last_span());
660 ast::SourceFile::new(span, root)
661}
662
663fn parse_time_units<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Timeunit> {
664 let mut unit = None;
665 let mut prec = None;
666 while p.peek(0).0 == Keyword(Kw::Timeunit) || p.peek(0).0 == Keyword(Kw::Timeprecision) {
667 recovered(p, Semicolon, |p| {
668 if p.try_eat(Keyword(Kw::Timeunit)) {
669 unit = Some(parse_time_literal(p)?);
670 if p.try_eat(Operator(Op::Div)) {
671 prec = Some(parse_time_literal(p)?);
672 }
673 } else if p.try_eat(Keyword(Kw::Timeprecision)) {
674 prec = Some(parse_time_literal(p)?);
675 } else {
676 unreachable!();
677 }
678 Ok(())
679 })?;
680 p.require_reported(Semicolon)?;
681 }
682
683 Ok(Timeunit { unit, prec })
684}
685
686fn parse_time_literal<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Spanned<Lit>> {
687 let (tkn, sp) = p.peek(0);
688 match tkn {
689 Literal(lit @ Time(..)) => {
690 p.bump();
691 Ok(Spanned::new(lit, sp))
692 }
693 _ => {
694 p.add_diag(
695 DiagBuilder2::error(format!("expected time literal, instead got `{}`", tkn))
696 .span(sp),
697 );
698 Err(())
699 }
700 }
701}
702
703fn as_lifetime(tkn: Token) -> Option<Lifetime> {
706 match tkn {
707 Keyword(Kw::Static) => Some(Lifetime::Static),
708 Keyword(Kw::Automatic) => Some(Lifetime::Automatic),
709 _ => None,
710 }
711}
712
713fn parse_interface_decl<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Interface<'n>> {
714 let mut span = p.peek(0).1;
715 p.require_reported(Keyword(Kw::Interface))?;
716 let result = recovered(p, Keyword(Kw::Endinterface), |p| {
717 let lifetime = match as_lifetime(p.peek(0).0) {
719 Some(l) => {
720 p.bump();
721 l
722 }
723 None => Lifetime::Static,
724 };
725
726 let (name, name_sp) = p.eat_ident("interface name")?;
728
729 let param_ports = if p.try_eat(Hashtag) {
733 parse_parameter_port_list(p)?
734 } else {
735 Vec::new()
736 };
737
738 let ports = if p.try_eat(OpenDelim(Paren)) {
740 parse_port_list(p)?
741 } else {
742 Vec::new()
743 };
744
745 if !p.try_eat(Semicolon) {
747 let q = p.peek(0).1.end();
748 p.add_diag(
749 DiagBuilder2::error(format!(
750 "Missing semicolon \";\" after header of interface \"{}\"",
751 name
752 ))
753 .span(q),
754 );
755 }
756
757 let mut items = Vec::new();
759 while !p.is_fatal() && p.peek(0).0 != Keyword(Kw::Endinterface) && p.peek(0).0 != Eof {
760 if p.try_eat(Semicolon) {
761 continue;
762 }
763 items.push(parse_item(p)?);
764 }
765
766 span.expand(p.last_span());
767 Ok(Interface::new(
768 span,
769 InterfaceData {
770 lifetime: lifetime,
771 name: Spanned::new(name, name_sp),
772 params: param_ports,
773 ports: ports,
774 items: items,
775 },
776 ))
777 });
778 p.require_reported(Keyword(Kw::Endinterface))?;
779 if p.try_eat(Colon) {
780 p.eat_ident("interface name")?;
781 }
782 result
783}
784
785fn parse_parameter_port_list<'n>(
786 p: &mut dyn AbstractParser<'n>,
787) -> ReportedResult<Vec<ParamDecl<'n>>> {
788 let mut local = false;
789
790 flanked(p, Paren, |p| {
791 comma_list(p, CloseDelim(Paren), "parameter port", |p| {
792 let mut outer_span = p.peek(0).1;
795 match p.peek(0).0 {
796 Keyword(Kw::Parameter) => {
797 p.bump();
798 local = false;
799 }
800 Keyword(Kw::Localparam) => {
801 p.bump();
802 local = true;
803 }
804 _ => (),
805 };
806
807 let kind = if p.try_eat(Keyword(Kw::Type)) {
810 let mut span = p.peek(0).1;
811 let name = parse_identifier_name(p, "parameter name")?;
812 let ty = if p.try_eat(Operator(Op::Assign)) {
813 Some(parse_explicit_type(p)?)
814 } else {
815 None
816 };
817 p.anticipate(&[Comma, CloseDelim(Paren)])?;
818 span.expand(p.last_span());
819 ast::ParamKind::Type(vec![ast::ParamTypeDecl::new(
820 span,
821 ParamTypeDeclData { name, ty },
822 )])
823 } else {
824 let mut pp = ParallelParser::new();
827 pp.add("explicit type", |p| {
828 let ty = parse_explicit_type(p)?;
829 tail(p, ty)
830 });
831 pp.add("implicit type", |p| {
832 let ty = parse_implicit_type(p)?;
833 tail(p, ty)
834 });
835
836 fn tail<'n>(
837 p: &mut dyn AbstractParser<'n>,
838 ty: Type<'n>,
839 ) -> ReportedResult<ast::ParamValueDecl<'n>> {
840 let mut span = p.peek(0).1;
841 let name = parse_identifier_name(p, "parameter name")?;
842 let (dims, _) = parse_optional_dimensions(p)?;
843 let expr = if p.try_eat(Operator(Op::Assign)) {
844 Some(parse_expr(p)?)
845 } else {
846 None
847 };
848 p.anticipate(&[Comma, CloseDelim(Paren)])?;
849 span.expand(p.last_span());
850 Ok(ParamValueDecl::new(
851 span,
852 ParamValueDeclData {
853 ty,
854 name,
855 dims,
856 expr,
857 },
858 ))
859 }
860
861 ast::ParamKind::Value(vec![pp.finish(p, "explicit or implicit type")?])
862 };
863
864 outer_span.expand(p.last_span());
865 Ok(ast::ParamDecl::new(
866 outer_span,
867 ast::ParamDeclData { local, kind },
868 ))
869 })
870 })
871}
872
873fn parse_module_decl<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Module<'n>> {
876 let mut span = p.peek(0).1;
877 p.require_reported(Keyword(Kw::Module))?;
878 let result = recovered(p, Keyword(Kw::Endmodule), |p| {
879 let lifetime = match as_lifetime(p.peek(0).0) {
881 Some(l) => {
882 p.bump();
883 l
884 }
885 None => Lifetime::Static,
886 };
887
888 let (name, name_sp) = p.eat_ident("module name")?;
890
891 let mut imports = vec![];
893 while p.peek(0).0 == Keyword(Kw::Import) {
894 imports.push(parse_import_decl(p)?);
895 }
896
897 let params = if p.try_eat(Hashtag) {
899 parse_parameter_port_list(p)?
900 } else {
901 Vec::new()
902 };
903
904 let ports = if p.try_eat(OpenDelim(Paren)) {
907 parse_port_list(p)?
908 } else {
909 Vec::new()
910 };
911
912 if !p.try_eat(Semicolon) {
914 let q = p.peek(0).1.end();
915 p.add_diag(
916 DiagBuilder2::error(format!("Missing ; after header of module \"{}\"", name))
917 .span(q),
918 );
919 }
920
921 let mut items = Vec::new();
923 while !p.is_fatal() && p.peek(0).0 != Keyword(Kw::Endmodule) && p.peek(0).0 != Eof {
924 if p.try_eat(Semicolon) {
925 continue;
926 }
927 items.push(parse_item(p)?);
928 }
929
930 span.expand(p.last_span());
931 Ok(Module::new(
932 span,
933 ModuleData {
934 lifetime,
935 name: Spanned::new(name, name_sp),
936 imports,
937 params,
938 ports,
939 items,
940 },
941 ))
942 });
943 let sp = p.peek(0).1;
944 p.require_reported(Keyword(Kw::Endmodule))?;
945 if p.try_eat(Colon) {
946 p.eat_ident("module name")?;
947 }
948 result
949}
950
951fn parse_package_decl<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Package<'n>> {
952 let mut span = p.peek(0).1;
953 p.require_reported(Keyword(Kw::Package))?;
954 let result = recovered(p, Keyword(Kw::Endpackage), |p| {
955 let lifetime = match as_lifetime(p.peek(0).0) {
957 Some(x) => {
958 p.bump();
959 x
960 }
961 None => Lifetime::Static,
962 };
963
964 let (name, name_span) = p.eat_ident("package name")?;
966 p.require_reported(Semicolon)?;
967
968 let mut items = Vec::new();
970 while !p.is_fatal() && p.peek(0).0 != Keyword(Kw::Endpackage) && p.peek(0).0 != Eof {
971 if p.try_eat(Semicolon) {
972 continue;
973 }
974 items.push(parse_item(p)?);
975 }
976
977 span.expand(p.last_span());
978 Ok(Package::new(
979 span,
980 PackageData {
981 lifetime: lifetime,
982 name: Spanned::new(name, name_span),
983 items: items,
984 },
985 ))
986 });
987 p.require_reported(Keyword(Kw::Endpackage))?;
988 if p.try_eat(Colon) {
989 p.eat_ident("package name")?;
990 }
991 result
992}
993
994fn parse_program_decl<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<()> {
995 p.require_reported(Keyword(Kw::Program))?;
996 let result = recovered(p, Keyword(Kw::Endprogram), |p| {
997 let q = p.peek(0).1;
998 p.add_diag(DiagBuilder2::error("Don't know how to parse program declarations").span(q));
999 Err(())
1000 });
1001 p.require_reported(Keyword(Kw::Endprogram))?;
1002 result
1003}
1004
1005fn parse_item<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Item<'n>> {
1006 let mut span = p.peek(0).1;
1007 let item = parse_item_data(p)?;
1008 span.expand(p.last_span());
1009 Ok(Item::new(span, item))
1010}
1011
1012fn parse_item_data<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ItemData<'n>> {
1013 if p.is_ident() && p.peek(1).0 == Colon {
1015 p.bump();
1016 p.bump();
1017 }
1018
1019 let class_follows = p.peek(1).0 == Keyword(Kw::Class);
1022 let strlit_follows = match p.peek(1).0 {
1023 Literal(Lit::Str(..)) => true,
1024 _ => false,
1025 };
1026 match p.peek(0).0 {
1027 Keyword(Kw::Module) => return parse_module_decl(p).map(ItemData::ModuleDecl),
1028 Keyword(Kw::Interface) | Keyword(Kw::Virtual) if class_follows => {
1029 return parse_class_decl(p).map(ItemData::ClassDecl)
1030 }
1031 Keyword(Kw::Class) => return parse_class_decl(p).map(ItemData::ClassDecl),
1032 Keyword(Kw::Interface) => return parse_interface_decl(p).map(ItemData::InterfaceDecl),
1033 Keyword(Kw::Package) => return parse_package_decl(p).map(ItemData::PackageDecl),
1034 Keyword(Kw::Program) => return parse_program_decl(p).map(ItemData::ProgramDecl),
1035
1036 Keyword(Kw::Localparam) | Keyword(Kw::Parameter) => {
1037 let decl = parse_param_decl(p, false)?;
1038 p.require_reported(Semicolon)?;
1039 return Ok(ItemData::ParamDecl(decl));
1040 }
1041 Keyword(Kw::Modport) => return parse_modport_decl(p).map(|x| ItemData::ModportDecl(x)),
1042 Keyword(Kw::Typedef) => return parse_typedef(p).map(|x| ItemData::Typedef(x)),
1043 Keyword(Kw::Import) if strlit_follows => return parse_dpi_decl(p).map(ItemData::DpiDecl),
1044 Keyword(Kw::Export) => return parse_dpi_decl(p).map(ItemData::DpiDecl),
1045 Keyword(Kw::Import) => return parse_import_decl(p).map(|x| ItemData::ImportDecl(x)),
1046 Keyword(Kw::Timeunit) | Keyword(Kw::Timeprecision) => {
1047 return parse_time_units(p).map(ItemData::Timeunit)
1048 }
1049
1050 Keyword(Kw::Initial) => {
1052 return parse_procedure(p, ProcedureKind::Initial).map(|x| ItemData::Procedure(x));
1053 }
1054 Keyword(Kw::Always) => {
1055 return parse_procedure(p, ProcedureKind::Always).map(|x| ItemData::Procedure(x));
1056 }
1057 Keyword(Kw::AlwaysComb) => {
1058 return parse_procedure(p, ProcedureKind::AlwaysComb).map(|x| ItemData::Procedure(x));
1059 }
1060 Keyword(Kw::AlwaysLatch) => {
1061 return parse_procedure(p, ProcedureKind::AlwaysLatch).map(|x| ItemData::Procedure(x));
1062 }
1063 Keyword(Kw::AlwaysFf) => {
1064 return parse_procedure(p, ProcedureKind::AlwaysFf).map(|x| ItemData::Procedure(x));
1065 }
1066 Keyword(Kw::Final) => {
1067 return parse_procedure(p, ProcedureKind::Final).map(|x| ItemData::Procedure(x));
1068 }
1069 Keyword(Kw::Function) | Keyword(Kw::Task) => {
1070 return parse_subroutine_decl(p).map(|x| ItemData::SubroutineDecl(x));
1071 }
1072
1073 Keyword(Kw::Inout) | Keyword(Kw::Input) | Keyword(Kw::Output) | Keyword(Kw::Ref) => {
1075 return parse_port_decl(p).map(|x| ItemData::PortDecl(x));
1076 }
1077
1078 Keyword(Kw::Assign) => {
1080 return parse_continuous_assign(p).map(|x| ItemData::ContAssign(x));
1081 }
1082
1083 Keyword(Kw::Genvar) => {
1085 p.bump();
1086 let decl = comma_list_nonempty(p, Semicolon, "genvar declaration", parse_genvar_decl)?;
1087 p.require_reported(Semicolon)?;
1088 return Ok(ItemData::GenvarDecl(decl));
1089 }
1090
1091 Keyword(Kw::Generate) => {
1093 let mut span = p.peek(0).1;
1094 p.bump();
1095 let items = repeat_until(p, Keyword(Kw::Endgenerate), parse_generate_item)?;
1096 p.require_reported(Keyword(Kw::Endgenerate))?;
1097 span.expand(p.last_span());
1098 return Ok(ItemData::GenerateRegion(span, items));
1099 }
1100 Keyword(Kw::For) => return parse_generate_for(p).map(|x| ItemData::GenerateFor(x)),
1101 Keyword(Kw::If) => return parse_generate_if(p).map(|x| ItemData::GenerateIf(x)),
1102 Keyword(Kw::Case) => return parse_generate_case(p).map(|x| ItemData::GenerateCase(x)),
1103
1104 Keyword(Kw::Assert)
1106 | Keyword(Kw::Assume)
1107 | Keyword(Kw::Cover)
1108 | Keyword(Kw::Expect)
1109 | Keyword(Kw::Restrict) => return parse_assertion(p).map(|x| ItemData::Assertion(x)),
1110 Semicolon => {
1111 p.bump();
1112 return Ok(ItemData::Dummy);
1113 }
1114
1115 Keyword(Kw::Default) => {
1117 p.bump();
1118 let mut span = p.last_span();
1119 if p.try_eat(Keyword(Kw::Clocking)) {
1120 let name = p.eat_ident("clocking identifier")?;
1121 p.require_reported(Semicolon)?;
1122 span.expand(p.last_span());
1123 return Ok(ItemData::Dummy);
1124 }
1125 if p.try_eat(Keyword(Kw::Disable)) {
1126 p.require_reported(Keyword(Kw::Iff))?;
1127 let expr = parse_expr(p)?;
1128 p.require_reported(Semicolon)?;
1129 span.expand(p.last_span());
1130 return Ok(ItemData::Dummy);
1131 }
1132 p.add_diag(
1133 DiagBuilder2::error("expected `clocking` or `disable` after `default`").span(span),
1134 );
1135 p.recover_balanced(&[Semicolon], true);
1136 return Err(());
1137 }
1138
1139 SysIdent(..) => return parse_elab_system_task(p).map(|_| ItemData::Dummy),
1141
1142 _ => (),
1143 }
1144
1145 let mut pp = ParallelParser::new();
1147 pp.add_greedy("net declaration", |p| {
1148 parse_net_decl(p).map(|d| ItemData::NetDecl(d))
1149 });
1150 pp.add("instantiation", |p| {
1151 parse_inst(p).map(|i| ItemData::Inst(i))
1152 });
1153 pp.add("variable declaration", |p| {
1154 parse_var_decl(p).map(|d| ItemData::VarDecl(d))
1155 });
1156 let res = pp.finish(p, "hierarchy item");
1157 if res.is_err() {
1158 p.recover_balanced(&[Semicolon], true);
1159 }
1160 res
1161}
1162
1163fn parse_elab_system_task<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<()> {
1164 let mut span = p.peek(0).1;
1165 let name = match p.peek(0).0 {
1166 SysIdent(name) => name,
1167 _ => unreachable!(),
1168 };
1169 p.recover_balanced(&[Semicolon], true);
1170 span.expand(p.last_span());
1171 p.add_diag(DiagBuilder2::warning("unsupported elaboration system task").span(span));
1172 Ok(())
1173}
1174
1175fn parse_localparam_decl<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<()> {
1176 p.require_reported(Keyword(Kw::Localparam))?;
1177 loop {
1181 let (name, name_sp) = match p.eat_ident_or("parameter name") {
1183 Ok(x) => x,
1184 Err(e) => {
1185 p.add_diag(e);
1186 return Err(());
1187 }
1188 };
1189
1190 if p.try_eat(Operator(Op::Assign)) {
1194 match parse_expr(p) {
1195 Ok(_) => (),
1196 Err(_) => p.recover_balanced(&[Comma, Semicolon], false),
1197 }
1198 }
1199
1200 match p.peek(0) {
1202 (Comma, sp) => {
1203 p.bump();
1204
1205 if p.peek(0).0 == Semicolon {
1209 p.add_diag(DiagBuilder2::warning("superfluous trailing comma").span(sp));
1211 break;
1212 }
1213 }
1214 (Semicolon, _) => break,
1215 (x, sp) => {
1216 p.add_diag(
1217 DiagBuilder2::error(format!("expected , or ; after localparam, found {}", x))
1218 .span(sp),
1219 );
1220 return Err(());
1221 }
1222 }
1223 }
1224 p.require_reported(Semicolon)?;
1225 Ok(())
1226}
1227
1228fn parse_parameter_decl<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<()> {
1229 p.require_reported(Keyword(Kw::Parameter))?;
1230
1231 let mut pp = ParallelParser::new();
1233 pp.add("explicit type", |p| {
1234 let ty = parse_explicit_type(p)?;
1235 Ok((ty, tail(p)?))
1236 });
1237 pp.add("implicit type", |p| {
1238 let ty = parse_implicit_type(p)?;
1239 Ok((ty, tail(p)?))
1240 });
1241 let (ty, ()) = pp.finish(p, "explicit or implicit type")?;
1242
1243 fn tail<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<()> {
1244 let names = parse_parameter_names(p)?;
1245 p.require_reported(Semicolon)?;
1246 Ok(())
1247 }
1248
1249 return Ok(());
1250}
1251
1252fn parse_parameter_names<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Vec<()>> {
1253 let v = comma_list_nonempty(p, Semicolon, "parameter name", |p| {
1254 let (name, name_sp) = p.eat_ident("parameter name")?;
1256 let (dims, _) = parse_optional_dimensions(p)?;
1257
1258 let expr = if p.try_eat(Operator(Op::Assign)) {
1260 Some(parse_expr(p)?)
1261 } else {
1262 None
1263 };
1264
1265 Ok(())
1266 })?;
1267 Ok(v)
1268}
1269
1270fn parse_modport_decl<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ast::Modport<'n>> {
1282 let mut span = p.peek(0).1;
1283 p.require_reported(Keyword(Kw::Modport))?;
1284 let names = comma_list_nonempty(p, Semicolon, "modport item", parse_modport_item)?;
1285 p.require_reported(Semicolon)?;
1286 span.expand(p.last_span());
1287
1288 Ok(ast::Modport::new(span, ast::ModportData { names }))
1289
1290 }
1312
1313fn parse_modport_item<'n>(
1324 p: &mut dyn AbstractParser<'n>,
1325) -> ReportedResult<&'n ast::ModportName<'n>> {
1326 let mut span = p.peek(0).1;
1327
1328 let name = parse_identifier_name(p, "modport name")?;
1330
1331 let ports = flanked(p, Paren, |p| {
1333 comma_list(
1334 p,
1335 CloseDelim(Paren),
1336 "modport ports declaration",
1337 parse_modport_ports_decl,
1338 )
1339 })?;
1340
1341 span.expand(p.last_span());
1342 Ok(p.arena().alloc(ast::ModportName::new(
1343 span,
1344 ast::ModportNameData { name, ports },
1345 )))
1346}
1347
1348fn parse_modport_ports_decl<'n>(
1356 p: &mut dyn AbstractParser<'n>,
1357) -> ReportedResult<&'n ast::ModportPort<'n>> {
1358 let mut span = p.peek(0).1;
1359
1360 if let Some(dir) = as_port_direction(p.peek(0).0) {
1363 let dir = Spanned::new(dir, p.peek(0).1);
1364 let mut port: Vec<&_> = vec![];
1365 p.bump();
1366 loop {
1367 let mut span = p.peek(0).1;
1368 let (name, expr) = if p.try_eat(Period) {
1369 let name = parse_identifier_name(p, "port name")?;
1370 p.require_reported(OpenDelim(Paren))?;
1371 let expr: &_ = p.arena().alloc(parse_expr(p)?);
1372 p.require_reported(CloseDelim(Paren))?;
1373 (name, Some(expr))
1374 } else {
1375 let name = parse_identifier_name(p, "port name")?;
1376 (name, None)
1377 };
1378 span.expand(p.last_span());
1379 port.push(p.arena().alloc(ast::ModportSimplePort::new(
1380 span,
1381 ast::ModportSimplePortData { name, expr },
1382 )));
1383
1384 match (p.peek(0).0, p.peek(1).0) {
1391 (Comma, Keyword(_)) => break,
1392 (Comma, _) => {
1393 p.bump();
1394 continue;
1395 }
1396 _ => break,
1397 }
1398 }
1399 span.expand(p.last_span());
1400 return Ok(p.arena().alloc(ast::ModportPort::new(
1401 span,
1402 ast::ModportPortData::Simple { dir, port },
1403 )));
1404 }
1405
1406 if p.try_eat(Keyword(Kw::Import)) || p.try_eat(Keyword(Kw::Export)) {
1408 p.add_diag(
1410 DiagBuilder2::error("modport task/function ports not implemented").span(p.last_span()),
1411 );
1412 return Err(());
1413 }
1414
1415 if p.try_eat(Keyword(Kw::Clocking)) {
1417 p.add_diag(DiagBuilder2::error("modport clocking declaration not implemented").span(span));
1419 return Err(());
1420 }
1421
1422 p.add_diag(DiagBuilder2::error("expected modport port declaration").span(span));
1424 Err(())
1425}
1426
1427fn as_port_direction(tkn: Token) -> Option<PortDir> {
1430 match tkn {
1431 Keyword(Kw::Input) => Some(PortDir::Input),
1432 Keyword(Kw::Output) => Some(PortDir::Output),
1433 Keyword(Kw::Inout) => Some(PortDir::Inout),
1434 Keyword(Kw::Ref) => Some(PortDir::Ref),
1435 _ => None,
1436 }
1437}
1438
1439fn parse_data_type<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Type<'n>> {
1450 {
1452 let mut bp = BranchParser::new(p);
1453 match parse_explicit_type(&mut bp) {
1454 Ok(x) => {
1455 bp.commit();
1456 return Ok(x);
1457 }
1458 Err(_) => (),
1459 }
1460 }
1461
1462 parse_implicit_type(p)
1465}
1466
1467fn parse_explicit_type<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Type<'n>> {
1468 let mut span = p.peek(0).1;
1469 let data = parse_type_data(p)?;
1470 span.expand(p.last_span());
1471 let ty = parse_type_signing_and_dimensions(p, span, data)?;
1472 parse_type_suffix(p, ty)
1473}
1474
1475fn parse_type_suffix<'n>(p: &mut dyn AbstractParser<'n>, ty: Type<'n>) -> ReportedResult<Type<'n>> {
1476 let tkn = p.peek(0).0;
1477 let sp = ty.span;
1478 match tkn {
1479 Period => {
1482 p.bump();
1483 let name = parse_identifier_name(p, "member type name")?;
1484 let subty = parse_type_signing_and_dimensions(
1485 p,
1486 sp,
1487 ScopedType {
1488 ty: Box::new(ty),
1489 member: true,
1490 name: name,
1491 },
1492 )?;
1493 parse_type_suffix(p, subty)
1494 }
1495
1496 Namespace => {
1498 p.bump();
1499 let name = parse_identifier_name(p, "type name")?;
1500 let subty = parse_type_signing_and_dimensions(
1501 p,
1502 sp,
1503 ScopedType {
1504 ty: Box::new(ty),
1505 member: false,
1506 name: name,
1507 },
1508 )?;
1509 parse_type_suffix(p, subty)
1510 }
1511
1512 Hashtag => {
1514 p.bump();
1515 let params = parse_parameter_assignments(p)?;
1516 let span = Span::union(sp, p.last_span());
1517 parse_type_suffix(
1518 p,
1519 ast::Type::new(
1520 span,
1521 ast::TypeData {
1522 kind: ast::TypeKind::new(span, ast::SpecializedType(Box::new(ty), params)),
1523 sign: ast::TypeSign::None,
1524 dims: Vec::new(),
1525 },
1526 ),
1527 )
1528 }
1529
1530 _ => Ok(ty),
1531 }
1532}
1533
1534fn parse_implicit_type<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Type<'n>> {
1536 let span = p.peek(0).1.begin().into();
1537 parse_type_signing_and_dimensions(p, span, ImplicitType)
1538}
1539
1540fn parse_type_signing_and_dimensions<'n>(
1543 p: &mut dyn AbstractParser<'n>,
1544 mut span: Span,
1545 kind: TypeKindData<'n>,
1546) -> ReportedResult<Type<'n>> {
1547 let kind = TypeKind::new(span, kind);
1549
1550 let sign = match p.peek(0).0 {
1552 Keyword(Kw::Signed) => {
1553 p.bump();
1554 TypeSign::Signed
1555 }
1556 Keyword(Kw::Unsigned) => {
1557 p.bump();
1558 TypeSign::Unsigned
1559 }
1560 _ => TypeSign::None,
1561 };
1562
1563 let (dims, _) = parse_optional_dimensions(p)?;
1565 span.expand(p.last_span());
1566
1567 Ok(Type::new(span, TypeData { kind, sign, dims }))
1568}
1569
1570fn parse_type_data<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<TypeKindData<'n>> {
1572 let (tkn, sp) = p.peek(0);
1573 match tkn {
1574 Keyword(Kw::Void) => {
1575 p.bump();
1576 Ok(ast::VoidType)
1577 }
1578 Keyword(Kw::String) => {
1579 p.bump();
1580 Ok(ast::StringType)
1581 }
1582 Keyword(Kw::Chandle) => {
1583 p.bump();
1584 Ok(ast::ChandleType)
1585 }
1586 Keyword(Kw::Event) => {
1587 p.bump();
1588 Ok(ast::EventType)
1589 }
1590 Keyword(Kw::Bit) => {
1601 p.bump();
1602 Ok(ast::BitType)
1603 }
1604 Keyword(Kw::Logic) => {
1605 p.bump();
1606 Ok(ast::LogicType)
1607 }
1608 Keyword(Kw::Reg) => {
1609 p.bump();
1610 Ok(ast::RegType)
1611 }
1612
1613 Keyword(Kw::Byte) => {
1615 p.bump();
1616 Ok(ast::ByteType)
1617 }
1618 Keyword(Kw::Shortint) => {
1619 p.bump();
1620 Ok(ast::ShortIntType)
1621 }
1622 Keyword(Kw::Int) => {
1623 p.bump();
1624 Ok(ast::IntType)
1625 }
1626 Keyword(Kw::Longint) => {
1627 p.bump();
1628 Ok(ast::LongIntType)
1629 }
1630 Keyword(Kw::Integer) => {
1631 p.bump();
1632 Ok(ast::IntegerType)
1633 }
1634 Keyword(Kw::Time) => {
1635 p.bump();
1636 Ok(ast::TimeType)
1637 }
1638
1639 Keyword(Kw::Shortreal) => {
1641 p.bump();
1642 Ok(ast::ShortRealType)
1643 }
1644 Keyword(Kw::Real) => {
1645 p.bump();
1646 Ok(ast::RealType)
1647 }
1648 Keyword(Kw::Realtime) => {
1649 p.bump();
1650 Ok(ast::RealtimeType)
1651 }
1652
1653 Keyword(Kw::Enum) => parse_enum_type(p),
1655 Keyword(Kw::Struct) | Keyword(Kw::Union) => parse_struct_type(p),
1656
1657 Ident(n) if &*n.as_str() == "mailbox" => {
1659 p.bump();
1660 Ok(ast::MailboxType)
1661 }
1662
1663 Ident(n) | EscIdent(n) => {
1665 p.bump();
1666 Ok(ast::NamedType(Spanned::new(n, sp)))
1667 }
1668
1669 Keyword(Kw::Virtual) => {
1671 p.bump();
1672 p.try_eat(Keyword(Kw::Interface));
1673 let (name, _) = p.eat_ident("virtual interface name")?;
1674 Ok(ast::VirtIntfType(name))
1675 }
1676
1677 Keyword(Kw::Type) => {
1680 p.bump();
1681 let arg = flanked(p, Paren, |p| parse_type_or_expr(p, &[CloseDelim(Paren)]))?;
1682 Ok(ast::TypeRef(Box::new(arg)))
1683 }
1684
1685 _ => {
1686 let q = p.peek(0).1;
1687 p.add_diag(DiagBuilder2::error("expected type").span(q));
1688 return Err(());
1689 }
1690 }
1691}
1692
1693fn parse_enum_type<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<TypeKindData<'n>> {
1694 let mut span = p.peek(0).1;
1695
1696 p.bump();
1698
1699 let base = if p.peek(0).0 != OpenDelim(Brace) {
1701 Some(Box::new(parse_data_type(p)?))
1702 } else {
1703 None
1704 };
1705
1706 let names = flanked(p, Brace, |p| {
1708 comma_list(p, CloseDelim(Brace), "enum name", parse_enum_name)
1709 })?;
1710 span.expand(p.last_span());
1711
1712 Ok(ast::EnumType(ast::Enum::new(
1713 span,
1714 ast::EnumData {
1715 base_type: base,
1716 variants: names,
1717 },
1718 )))
1719}
1720
1721fn parse_enum_name<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<EnumName<'n>> {
1722 let mut span = p.peek(0).1;
1723
1724 let name = parse_identifier_name(p, "enum name")?;
1726
1727 let range = try_flanked(p, Brack, parse_expr)?;
1729
1730 let value = if p.try_eat(Operator(Op::Assign)) {
1732 Some(parse_expr(p)?)
1733 } else {
1734 None
1735 };
1736 span.expand(p.last_span());
1737
1738 Ok(EnumName::new(span, EnumNameData { name, range, value }))
1739}
1740
1741fn parse_struct_type<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<TypeKindData<'n>> {
1742 let mut span = p.peek(0).1;
1743
1744 let kind = match (p.peek(0).0, p.peek(1).0) {
1746 (Keyword(Kw::Struct), _) => {
1747 p.bump();
1748 StructKind::Struct
1749 }
1750 (Keyword(Kw::Union), Keyword(Kw::Tagged)) => {
1751 p.bump();
1752 p.bump();
1753 StructKind::TaggedUnion
1754 }
1755 (Keyword(Kw::Union), _) => {
1756 p.bump();
1757 StructKind::Union
1758 }
1759 _ => {
1760 p.add_diag(
1761 DiagBuilder2::error("expected `struct`, `union`, or `union tagged`").span(span),
1762 );
1763 return Err(());
1764 }
1765 };
1766
1767 let (packed, signing) = if p.try_eat(Keyword(Kw::Packed)) {
1770 (true, parse_signing(p))
1771 } else {
1772 (false, TypeSign::None)
1773 };
1774
1775 if p.peek(0).0 == OpenDelim(Brace) {
1776 let members = flanked(p, Brace, |p| {
1778 repeat_until(p, CloseDelim(Brace), parse_struct_member)
1779 })?;
1780
1781 span.expand(p.last_span());
1782 Ok(ast::StructType(ast::Struct::new(
1783 span,
1784 ast::StructData {
1785 kind: kind,
1786 packed: packed,
1787 signing: signing,
1788 members: members,
1789 },
1790 )))
1791 } else {
1792 span.expand(p.last_span());
1794 let struct_type = ast::StructType(ast::Struct::new(
1795 span,
1796 ast::StructData {
1797 kind: kind,
1798 packed: packed,
1799 signing: signing,
1800 members: Vec::default(),
1801 },
1802 ));
1803
1804 let forward_type = ast::ForwardType {
1805 kind: Box::new(TypeKind::new(span, struct_type)),
1806 };
1807
1808 Ok(forward_type)
1809 }
1810}
1811
1812fn parse_struct_member<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<StructMember<'n>> {
1813 let mut span = p.peek(0).1;
1814
1815 let rand_qualifier = match p.peek(0).0 {
1817 Keyword(Kw::Rand) => {
1818 p.bump();
1819 Some(RandomQualifier::Rand)
1820 }
1821 Keyword(Kw::Randc) => {
1822 p.bump();
1823 Some(RandomQualifier::Randc)
1824 }
1825 _ => None,
1826 };
1827
1828 let ty = parse_data_type(p)?;
1830
1831 let names = comma_list_nonempty(p, Semicolon, "member name", parse_variable_decl_assignment)?;
1833
1834 p.require_reported(Semicolon)?;
1835 span.expand(p.last_span());
1836
1837 Ok(ast::StructMember::new(
1838 span,
1839 ast::StructMemberData {
1840 rand_qualifier,
1841 ty: Box::new(ty),
1842 names,
1843 },
1844 ))
1845}
1846
1847fn try_signing<'n>(p: &mut dyn AbstractParser<'n>) -> Option<TypeSign> {
1848 match p.peek(0).0 {
1849 Keyword(Kw::Signed) => {
1850 p.bump();
1851 Some(TypeSign::Signed)
1852 }
1853 Keyword(Kw::Unsigned) => {
1854 p.bump();
1855 Some(TypeSign::Unsigned)
1856 }
1857 _ => None,
1858 }
1859}
1860
1861fn parse_signing<'n>(p: &mut dyn AbstractParser<'n>) -> TypeSign {
1862 try_signing(p).unwrap_or(TypeSign::None)
1863}
1864
1865fn parse_optional_dimensions<'n>(
1866 p: &mut dyn AbstractParser<'n>,
1867) -> ReportedResult<(Vec<TypeDim<'n>>, Span)> {
1868 let mut v = Vec::new();
1869 let mut span;
1870 if let Some((d, sp)) = try_dimension(p)? {
1871 span = sp;
1872 v.push(d);
1873 } else {
1874 return Ok((v, INVALID_SPAN));
1875 }
1876 while let Some((d, sp)) = try_dimension(p)? {
1877 v.push(d);
1878 span.expand(sp);
1879 }
1880 Ok((v, span))
1881}
1882
1883fn try_dimension<'n>(
1884 p: &mut dyn AbstractParser<'n>,
1885) -> ReportedResult<Option<(TypeDim<'n>, Span)>> {
1886 let mut span = Span::from(p.peek(0).1.begin());
1887 let dim = try_flanked(p, Brack, |p| {
1888 Ok(match p.peek(0).0 {
1889 CloseDelim(Brack) => TypeDim::Unsized,
1891 Operator(Op::Mul) => {
1893 p.bump();
1894 TypeDim::Associative(None)
1895 }
1896 Dollar => {
1899 p.bump();
1900 let expr = if p.try_eat(Colon) {
1901 Some(parse_expr(p)?)
1902 } else {
1903 None
1904 };
1905 TypeDim::Queue(expr)
1906 }
1907 _ => match parse_type_or_expr(p, &[Colon, CloseDelim(Brack)])? {
1908 TypeOrExpr::Type(ty) => TypeDim::Associative(Some(ty.clone())),
1910 TypeOrExpr::Expr(expr) => {
1913 if p.try_eat(Colon) {
1914 let other = parse_expr(p)?;
1915 TypeDim::Range(expr.clone(), other.clone())
1916 } else {
1917 TypeDim::Expr(expr.clone())
1918 }
1919 }
1920 },
1921 })
1922 })?;
1923 span.expand(p.last_span());
1924 Ok(dim.map(|dim| (dim, span)))
1925}
1926
1927fn parse_list_of_port_connections<'n>(
1928 p: &mut dyn AbstractParser<'n>,
1929) -> ReportedResult<Vec<PortConn<'n>>> {
1930 comma_list(p, CloseDelim(Paren), "list of port connections", |p| {
1931 let mut span = p.peek(0).1;
1932
1933 let kind = if p.try_eat(Period) {
1936 if p.try_eat(Operator(Op::Mul)) {
1937 ast::PortConnData::Auto
1939 } else {
1940 let name = parse_identifier_name(p, "port name")?;
1941 let mode = try_flanked(p, Paren, |p| {
1943 Ok(if p.peek(0).0 != CloseDelim(Paren) {
1944 ast::PortConnMode::Connected(parse_expr(p)?)
1945 } else {
1946 ast::PortConnMode::Unconnected
1947 })
1948 })?
1949 .unwrap_or(ast::PortConnMode::Auto);
1950 ast::PortConnData::Named(name, mode)
1951 }
1952 } else {
1953 ast::PortConnData::Positional(parse_expr(p)?)
1954 };
1955
1956 span.expand(p.last_span());
1957 Ok(ast::PortConn::new(span, kind))
1958 })
1959}
1960
1961fn parse_type_or_expr<'n>(
1963 p: &mut dyn AbstractParser<'n>,
1964 terminators: &[Token],
1965) -> ReportedResult<ast::TypeOrExpr<'n>> {
1966 let terminators = Vec::from(terminators);
1967 let mut pp = ParallelParser::new();
1968 pp.add_greedy("expression", |p| {
1969 let expr = parse_expr(p)?;
1970 p.anticipate(&terminators)?;
1971 Ok(ast::TypeOrExpr::Expr(p.arena().alloc(expr)))
1972 });
1973 pp.add("type", |p| {
1974 let ty = parse_explicit_type(p)?;
1975 p.anticipate(&terminators)?;
1976 Ok(ast::TypeOrExpr::Type(p.arena().alloc(ty)))
1977 });
1978 pp.finish(p, "type or expression")
1979}
1980
1981fn parse_expr<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Expr<'n>> {
1982 parse_expr_prec(p, Precedence::Min)
1983}
1984
1985fn parse_expr_prec<'n>(
1986 p: &mut dyn AbstractParser<'n>,
1987 precedence: Precedence,
1988) -> ReportedResult<Expr<'n>> {
1989 if p.try_eat(Keyword(Kw::New)) {
2003 let mut span = p.last_span();
2004 if let Some(dim_expr) = try_flanked(p, Brack, parse_expr)? {
2005 let expr = try_flanked(p, Paren, parse_expr)?;
2006 span.expand(p.last_span());
2007 return Ok(Expr::new(
2008 span,
2009 ArrayNewExpr(Box::new(dim_expr), expr.map(|x| Box::new(x))),
2010 ));
2011 } else {
2012 if let Some(args) = try_flanked(p, Paren, parse_call_args)? {
2013 span.expand(p.last_span());
2014 return Ok(Expr::new(span, ConstructorCallExpr(args)));
2015 } else {
2016 let mut bp = BranchParser::new(p);
2018 let expr = match parse_expr(&mut bp) {
2019 Ok(x) => {
2020 bp.commit();
2021 Some(Box::new(x))
2022 }
2023 Err(_) => None,
2024 };
2025 span.expand(p.last_span());
2026 return Ok(Expr::new(span, ClassNewExpr(expr)));
2027 }
2028 }
2029 }
2030
2031 {
2036 let mut bp = BranchParser::new(p);
2037 let mut span = bp.peek(0).1;
2038 let ty = parse_explicit_type(&mut bp);
2039 match (ty, bp.peek(0).0, bp.peek(1).0) {
2040 (Ok(ty), Apostrophe, OpenDelim(Paren)) => {
2042 bp.commit();
2043 p.require_reported(Apostrophe)?;
2044 let expr = flanked(p, Paren, parse_expr)?;
2045 span.expand(p.last_span());
2046 let cast = Expr::new(span, CastExpr(ty, Box::new(expr)));
2047 return parse_expr_suffix(p, cast, precedence);
2048 }
2049 (Ok(ty), Apostrophe, OpenDelim(Brace)) => {
2051 bp.commit();
2052 let expr = parse_expr(p)?;
2054 span.expand(p.last_span());
2055 let cast = Expr::new(span, CastExpr(ty, Box::new(expr)));
2056 return parse_expr_suffix(p, cast, precedence);
2057 }
2058 _ => (),
2059 }
2060 }
2061
2062 if let Some(sign) = try_signing(p) {
2065 let mut span = p.last_span();
2066 let sign = Spanned::new(sign, span);
2067 p.require_reported(Apostrophe)?;
2068 let expr = flanked(p, Paren, parse_expr)?;
2069 span.expand(p.last_span());
2070 let cast = Expr::new(span, CastSignExpr(sign, Box::new(expr)));
2071 return parse_expr_suffix(p, cast, precedence);
2072 }
2073
2074 let q = p.peek(0).1;
2076 let prefix = parse_expr_first(p, precedence)?;
2078 parse_expr_suffix(p, prefix, precedence)
2079}
2080
2081fn parse_expr_suffix<'n>(
2082 p: &mut dyn AbstractParser<'n>,
2083 prefix: Expr<'n>,
2084 precedence: Precedence,
2085) -> ReportedResult<Expr<'n>> {
2086 let (tkn, sp) = p.peek(0);
2090 match tkn {
2091 OpenDelim(Brack) if precedence <= Precedence::Postfix => {
2093 p.bump();
2094 let expr = match parse_range_expr(p) {
2095 Ok(x) => x,
2096 Err(e) => {
2097 p.recover_balanced(&[CloseDelim(Brack)], true);
2098 return Err(e);
2099 }
2100 };
2101 p.require_reported(CloseDelim(Brack))?;
2102 let expr = Expr::new(
2103 Span::union(prefix.span, p.last_span()),
2104 IndexExpr {
2105 indexee: Box::new(prefix),
2106 index: Box::new(expr),
2107 },
2108 );
2109 return parse_expr_suffix(p, expr, precedence);
2110 }
2111
2112 OpenDelim(Paren) if precedence <= Precedence::Postfix => {
2114 if let ast::SysIdentExpr(name) = prefix.data {
2117 match try_builtin_system_task(p, name, prefix.span)? {
2118 Some(expr) => return parse_expr_suffix(p, expr, precedence),
2119 None => (),
2120 }
2121 }
2122 let args = flanked(p, Paren, parse_call_args)?;
2123 let expr = Expr::new(
2124 Span::union(prefix.span, p.last_span()),
2125 CallExpr(Box::new(prefix), args),
2126 );
2127 return parse_expr_suffix(p, expr, precedence);
2128 }
2129
2130 Period if precedence <= Precedence::Scope => {
2132 p.bump();
2133 let name = parse_identifier_name(p, "member name")?;
2134 let expr = Expr::new(
2135 Span::union(prefix.span, p.last_span()),
2136 MemberExpr {
2137 expr: Box::new(prefix),
2138 name,
2139 },
2140 );
2141 return parse_expr_suffix(p, expr, precedence);
2142 }
2143
2144 Namespace if precedence <= Precedence::Scope => {
2146 p.bump();
2147 let ident = parse_identifier_name(p, "scope name")?;
2148 let expr = Expr::new(
2149 Span::union(prefix.span, p.last_span()),
2150 ScopeExpr(Box::new(prefix), ident),
2151 );
2152 return parse_expr_suffix(p, expr, precedence);
2153 }
2154
2155 Operator(Op::Inc) if precedence <= Precedence::Unary => {
2157 p.bump();
2158 let expr = Expr::new(
2159 Span::union(prefix.span, p.last_span()),
2160 UnaryExpr {
2161 op: Op::Inc,
2162 expr: Box::new(prefix),
2163 postfix: true,
2164 },
2165 );
2166 return parse_expr_suffix(p, expr, precedence);
2167 }
2168
2169 Operator(Op::Dec) if precedence <= Precedence::Unary => {
2171 p.bump();
2172 let expr = Expr::new(
2173 Span::union(prefix.span, p.last_span()),
2174 UnaryExpr {
2175 op: Op::Dec,
2176 expr: Box::new(prefix),
2177 postfix: true,
2178 },
2179 );
2180 return parse_expr_suffix(p, expr, precedence);
2181 }
2182
2183 Ternary if precedence < Precedence::Ternary => {
2185 p.bump();
2186 let true_expr = parse_expr_prec(p, Precedence::Ternary)?;
2187 p.require_reported(Colon)?;
2188 let false_expr = parse_expr_prec(p, Precedence::Ternary)?;
2189 let expr = Expr::new(
2190 Span::union(prefix.span, p.last_span()),
2191 TernaryExpr {
2192 cond: Box::new(prefix),
2193 true_expr: Box::new(true_expr),
2194 false_expr: Box::new(false_expr),
2195 },
2196 );
2197 return parse_expr_suffix(p, expr, precedence);
2198 }
2199
2200 Keyword(Kw::Inside) if precedence <= Precedence::Relational => {
2202 p.bump();
2203 let set = flanked(p, Brace, |p| {
2204 comma_list_nonempty(p, CloseDelim(Brace), "range", |p| {
2205 if p.peek(0).0 == OpenDelim(Brack) {
2206 p.require_reported(OpenDelim(Brack))?;
2207 let mut sp = p.last_span();
2208 let lo = parse_expr(p)?;
2209 p.require_reported(Colon)?;
2210 let hi = parse_expr(p)?;
2211 p.require_reported(CloseDelim(Brack))?;
2212 sp.expand(p.last_span());
2213 Ok(ValueRange::Range { lo, hi, span: sp })
2214 } else {
2215 Ok(ValueRange::Single(parse_expr(p)?))
2216 }
2217 })
2218 })?;
2219 let expr = Expr::new(
2220 Span::union(prefix.span, p.last_span()),
2221 InsideExpr(Box::new(prefix), set),
2222 );
2223 return parse_expr_suffix(p, expr, precedence);
2224 }
2225
2226 Apostrophe if precedence <= Precedence::Postfix => {
2228 p.bump();
2229 let inner = flanked(p, Paren, |p| parse_expr(p))?;
2230 let expr = Expr::new(
2231 Span::union(prefix.span, p.last_span()),
2232 CastSizeExpr(Box::new(prefix), Box::new(inner)),
2233 );
2234 return parse_expr_suffix(p, expr, precedence);
2235 }
2236 _ => (),
2237 }
2238
2239 if let Some(op) = as_assign_operator(tkn) {
2241 if precedence <= Precedence::Assignment {
2242 p.bump();
2243 let rhs = parse_expr_prec(p, Precedence::Assignment)?;
2244 let expr = Expr::new(
2245 Span::union(prefix.span, p.last_span()),
2246 AssignExpr {
2247 op: op,
2248 lhs: Box::new(prefix),
2249 rhs: Box::new(rhs),
2250 },
2251 );
2252 return parse_expr_suffix(p, expr, precedence);
2253 }
2254 }
2255
2256 if let Some(op) = as_binary_operator(tkn) {
2258 let prec = op.get_precedence();
2259 if precedence < prec {
2260 p.bump();
2261 let rhs = parse_expr_prec(p, prec)?;
2262 let expr = Expr::new(
2263 Span::union(prefix.span, p.last_span()),
2264 BinaryExpr {
2265 op: op,
2266 lhs: Box::new(prefix),
2267 rhs: Box::new(rhs),
2268 },
2269 );
2270 return parse_expr_suffix(p, expr, precedence);
2271 }
2272 }
2273
2274 Ok(prefix)
2275}
2276
2277fn parse_expr_first<'n>(
2278 p: &mut dyn AbstractParser<'n>,
2279 precedence: Precedence,
2280) -> ReportedResult<Expr<'n>> {
2281 let first = p.peek(0).1;
2282
2283 match p.peek(0) {
2286 (Operator(Op::Inc), _) if precedence <= Precedence::Unary => {
2287 p.bump();
2288 let expr = parse_expr_prec(p, Precedence::Unary)?;
2289 return Ok(Expr::new(
2290 Span::union(first, p.last_span()),
2291 UnaryExpr {
2292 op: Op::Inc,
2293 expr: Box::new(expr),
2294 postfix: false,
2295 },
2296 ));
2297 }
2298
2299 (Operator(Op::Dec), _) if precedence <= Precedence::Unary => {
2300 p.bump();
2301 let expr = parse_expr_prec(p, Precedence::Unary)?;
2302 return Ok(Expr::new(
2303 Span::union(first, p.last_span()),
2304 UnaryExpr {
2305 op: Op::Dec,
2306 expr: Box::new(expr),
2307 postfix: false,
2308 },
2309 ));
2310 }
2311
2312 (Keyword(Kw::Tagged), sp) => {
2313 p.add_diag(DiagBuilder2::error("Tagged union expressions not implemented").span(sp));
2314 return Err(());
2315 }
2316
2317 _ => (),
2318 }
2319
2320 if let Some(op) = as_unary_operator(p.peek(0).0) {
2322 p.bump();
2323 let expr = parse_expr_prec(p, Precedence::Unary)?;
2324 return Ok(Expr::new(
2325 Span::union(first, p.last_span()),
2326 UnaryExpr {
2327 op: op,
2328 expr: Box::new(expr),
2329 postfix: false,
2330 },
2331 ));
2332 }
2333
2334 parse_primary_expr(p)
2336}
2337
2338fn parse_primary_expr<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Expr<'n>> {
2339 let (tkn, sp) = p.peek(0);
2340 match tkn {
2341 Literal(lit) => {
2343 p.bump();
2344 return Ok(Expr::new(sp, LiteralExpr(lit)));
2345 }
2346
2347 Ident(n) | EscIdent(n) => {
2349 p.bump();
2350 return Ok(Expr::new(sp, IdentExpr(Spanned::new(n, sp))));
2351 }
2352 SysIdent(n) => {
2353 p.bump();
2354 return Ok(Expr::new(sp, SysIdentExpr(Spanned::new(n, sp))));
2355 }
2356
2357 Keyword(Kw::This) => {
2359 p.bump();
2360 return Ok(Expr::new(sp, ThisExpr));
2361 }
2362
2363 Dollar => {
2365 p.bump();
2366 return Ok(Expr::new(sp, DollarExpr));
2367 }
2368
2369 Keyword(Kw::Null) => {
2371 p.bump();
2372 return Ok(Expr::new(sp, NullExpr));
2373 }
2374
2375 OpenDelim(Brace) => {
2377 p.bump();
2378 if p.try_eat(CloseDelim(Brace)) {
2379 return Ok(Expr::new(Span::union(sp, p.last_span()), EmptyQueueExpr));
2380 }
2381 let data = match parse_concat_expr(p) {
2382 Ok(x) => x,
2383 Err(e) => {
2384 p.recover_balanced(&[CloseDelim(Brace)], true);
2385 return Err(e);
2386 }
2387 };
2388 p.require_reported(CloseDelim(Brace))?;
2389 return Ok(Expr::new(Span::union(sp, p.last_span()), data));
2390 }
2391
2392 OpenDelim(Paren) => {
2394 p.bump();
2395 let expr = match parse_primary_parenthesis(p) {
2396 Ok(x) => x,
2397 Err(e) => {
2398 p.recover_balanced(&[CloseDelim(Paren)], true);
2399 return Err(e);
2400 }
2401 };
2402 p.require_reported(CloseDelim(Paren))?;
2403 return Ok(expr);
2404 }
2405
2406 Apostrophe => {
2408 p.bump();
2409 let fields = flanked(p, Brace, |p| {
2410 comma_list_nonempty(p, CloseDelim(Brace), "pattern field", parse_pattern_field)
2411 })?;
2412 return Ok(Expr::new(
2413 Span::union(sp, p.last_span()),
2414 PatternExpr(fields),
2415 ));
2416 }
2417
2418 tkn => {
2419 p.add_diag(
2420 DiagBuilder2::error(format!("expected expression, found `{}` instead", tkn))
2421 .span(sp),
2422 );
2423 return Err(());
2424 }
2425 }
2426}
2427
2428fn parse_pattern_field<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<PatternField<'n>> {
2429 let mut span = p.peek(0).1;
2430
2431 if p.try_eat(Keyword(Kw::Default)) {
2433 p.require_reported(Colon)?;
2434 let value = Box::new(parse_expr(p)?);
2435 span.expand(p.last_span());
2436 return Ok(PatternField::new(span, PatternFieldData::Default(value)));
2437 }
2438
2439 let mut pp = ParallelParser::new();
2441
2442 pp.add_greedy("expression pattern", |p| {
2444 let expr = Box::new(parse_expr(p)?);
2445 p.require_reported(Colon)?;
2446 let value = Box::new(parse_expr(p)?);
2447 Ok(PatternFieldData::Member(expr, value))
2448 });
2449
2450 pp.add_greedy("type pattern", |p| {
2452 let ty = parse_explicit_type(p)?;
2453 p.require_reported(Colon)?;
2454 let value = Box::new(parse_expr(p)?);
2455 Ok(PatternFieldData::Type(ty, value))
2456 });
2457
2458 pp.add("expression or repeat pattern", |p| {
2469 let expr = Box::new(parse_expr(p)?);
2470
2471 let data = if let Some(inner_exprs) = try_flanked(p, Brace, |p| {
2474 comma_list(p, CloseDelim(Brace), "expression", parse_expr)
2475 })? {
2476 PatternFieldData::Repeat(expr, inner_exprs)
2477 } else {
2478 PatternFieldData::Expr(expr)
2479 };
2480
2481 p.anticipate(&[Comma, CloseDelim(Brace)])?;
2483 Ok(data)
2484 });
2485
2486 let data = pp.finish(p, "expression pattern")?;
2487 span.expand(p.last_span());
2488 Ok(PatternField::new(span, data))
2489}
2490
2491pub enum StreamDir {
2492 In,
2493 Out,
2494}
2495
2496fn parse_concat_expr<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ExprData<'n>> {
2497 let stream = match p.peek(0).0 {
2499 Operator(Op::LogicShL) => Some(StreamDir::Out),
2500 Operator(Op::LogicShR) => Some(StreamDir::In),
2501 _ => None,
2502 };
2503
2504 if let Some(dir) = stream {
2505 p.bump();
2506
2507 let slice_size = if p.peek(0).0 != OpenDelim(Brace) {
2511 let mut pp = ParallelParser::new();
2512 pp.add_greedy("slice size expression", |p| {
2513 let s = parse_expr(p).map(|e| StreamConcatSlice::Expr(Box::new(e)))?;
2514 p.anticipate(&[OpenDelim(Brace)])?;
2515 Ok(s)
2516 });
2517 pp.add_greedy("slice size type", |p| {
2518 let s = parse_explicit_type(p).map(|t| StreamConcatSlice::Type(t))?;
2519 p.anticipate(&[OpenDelim(Brace)])?;
2520 Ok(s)
2521 });
2522 Some(pp.finish(p, "slice size expression or type")?)
2523 } else {
2524 None
2525 };
2526
2527 let exprs = flanked(p, Brace, |p| {
2529 comma_list_nonempty(p, CloseDelim(Brace), "stream expression", |p| {
2530 let expr = Box::new(parse_expr(p)?);
2532
2533 let range = if p.try_eat(Keyword(Kw::With)) {
2535 Some(Box::new(flanked(p, Brack, parse_range_expr)?))
2536 } else {
2537 None
2538 };
2539
2540 Ok(StreamExpr {
2541 expr: expr,
2542 range: range,
2543 })
2544 })
2545 })?;
2546
2547 return Ok(StreamConcatExpr {
2548 slice: slice_size,
2549 exprs: exprs,
2550 });
2551 }
2552
2553 let first_expr = parse_expr_prec(p, Precedence::Concatenation)?;
2557
2558 if p.try_eat(OpenDelim(Brace)) {
2560 let exprs = match parse_expr_list(p) {
2561 Ok(x) => x,
2562 Err(e) => {
2563 p.recover_balanced(&[CloseDelim(Brace)], true);
2564 return Err(e);
2565 }
2566 };
2567 p.require_reported(CloseDelim(Brace))?;
2568 return Ok(ConcatExpr {
2569 repeat: Some(Box::new(first_expr)),
2570 exprs: exprs,
2571 });
2572 }
2573
2574 let mut exprs = Vec::new();
2577 exprs.push(first_expr);
2578 while p.try_eat(Comma) {
2579 if p.peek(0).0 == CloseDelim(Brace) {
2580 let q = p.peek(0).1;
2581 p.add_diag(DiagBuilder2::warning("superfluous trailing comma").span(q));
2582 break;
2583 }
2584 exprs.push(parse_expr_prec(p, Precedence::Min)?);
2585 }
2586
2587 Ok(ConcatExpr {
2588 repeat: None,
2589 exprs: exprs,
2590 })
2591}
2592
2593fn parse_expr_list<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Vec<Expr<'n>>> {
2594 let mut v = Vec::new();
2595 loop {
2596 v.push(parse_expr_prec(p, Precedence::Min)?);
2597
2598 match p.peek(0) {
2599 (Comma, sp) => {
2600 p.bump();
2601 if p.peek(0).0 == CloseDelim(Brace) {
2602 p.add_diag(DiagBuilder2::warning("superfluous trailing comma").span(sp));
2603 break;
2604 }
2605 }
2606 (CloseDelim(Brace), _) => break,
2607 (_, sp) => {
2608 p.add_diag(DiagBuilder2::error("expected , or } after expression").span(sp));
2609 return Err(());
2610 }
2611 }
2612 }
2613 Ok(v)
2614}
2615
2616fn parse_primary_parenthesis<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Expr<'n>> {
2624 let first = parse_expr_prec(p, Precedence::Min)?;
2625 if p.try_eat(Colon) {
2626 let typ = parse_expr_prec(p, Precedence::Min)?;
2627 p.require_reported(Colon)?;
2628 let max = parse_expr_prec(p, Precedence::Min)?;
2629 Ok(Expr::new(
2630 Span::union(first.span, max.span),
2631 MinTypMaxExpr {
2632 min: Box::new(first),
2633 typ: Box::new(typ),
2634 max: Box::new(max),
2635 },
2636 ))
2637 } else {
2638 Ok(first)
2639 }
2640}
2641
2642fn parse_range_expr<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Expr<'n>> {
2652 let mut span = p.peek(0).1;
2653 let first_expr = parse_expr(p)?;
2654 let mode = match p.peek(0).0 {
2655 Colon => RangeMode::Absolute,
2656 AddColon => RangeMode::RelativeUp,
2657 SubColon => RangeMode::RelativeDown,
2658
2659 _ => return Ok(first_expr),
2661 };
2662 p.bump(); let second_expr = parse_expr(p)?;
2664 span.expand(p.last_span());
2665 Ok(Expr::new(
2666 span,
2667 RangeExpr {
2668 mode: mode,
2669 lhs: Box::new(first_expr),
2670 rhs: Box::new(second_expr),
2671 },
2672 ))
2673}
2674
2675fn as_unary_operator(tkn: Token) -> Option<Op> {
2678 if let Operator(op) = tkn {
2679 match op {
2680 Op::Add
2681 | Op::Sub
2682 | Op::LogicNot
2683 | Op::BitNot
2684 | Op::BitAnd
2685 | Op::BitNand
2686 | Op::BitOr
2687 | Op::BitNor
2688 | Op::BitXor
2689 | Op::BitNxor
2690 | Op::BitXnor => Some(op),
2691 _ => None,
2692 }
2693 } else {
2694 None
2695 }
2696}
2697
2698fn as_binary_operator(tkn: Token) -> Option<Op> {
2701 if let Operator(op) = tkn {
2702 match op {
2703 Op::Add
2704 | Op::Sub
2705 | Op::Mul
2706 | Op::Div
2707 | Op::Mod
2708 | Op::LogicEq
2709 | Op::LogicNeq
2710 | Op::CaseEq
2711 | Op::CaseNeq
2712 | Op::WildcardEq
2713 | Op::WildcardNeq
2714 | Op::LogicAnd
2715 | Op::LogicOr
2716 | Op::Pow
2717 | Op::Lt
2718 | Op::Leq
2719 | Op::Gt
2720 | Op::Geq
2721 | Op::BitAnd
2722 | Op::BitNand
2723 | Op::BitOr
2724 | Op::BitNor
2725 | Op::BitXor
2726 | Op::BitXnor
2727 | Op::BitNxor
2728 | Op::LogicShL
2729 | Op::LogicShR
2730 | Op::ArithShL
2731 | Op::ArithShR
2732 | Op::LogicImpl
2733 | Op::LogicEquiv => Some(op),
2734 _ => None,
2735 }
2736 } else {
2737 None
2738 }
2739}
2740
2741fn as_assign_operator(tkn: Token) -> Option<AssignOp> {
2744 match tkn {
2745 Operator(Op::Assign) => Some(AssignOp::Identity),
2746 Operator(Op::AssignAdd) => Some(AssignOp::Add),
2747 Operator(Op::AssignSub) => Some(AssignOp::Sub),
2748 Operator(Op::AssignMul) => Some(AssignOp::Mul),
2749 Operator(Op::AssignDiv) => Some(AssignOp::Div),
2750 Operator(Op::AssignMod) => Some(AssignOp::Mod),
2751 Operator(Op::AssignBitAnd) => Some(AssignOp::BitAnd),
2752 Operator(Op::AssignBitOr) => Some(AssignOp::BitOr),
2753 Operator(Op::AssignBitXor) => Some(AssignOp::BitXor),
2754 Operator(Op::AssignLogicShL) => Some(AssignOp::LogicShL),
2755 Operator(Op::AssignLogicShR) => Some(AssignOp::LogicShR),
2756 Operator(Op::AssignArithShL) => Some(AssignOp::ArithShL),
2757 Operator(Op::AssignArithShR) => Some(AssignOp::ArithShR),
2758 _ => None,
2759 }
2760}
2761
2762fn parse_port_list<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Vec<Port<'n>>> {
2765 let mut v = Vec::new();
2766
2767 if p.try_eat(CloseDelim(Paren)) {
2769 return Ok(v);
2770 }
2771
2772 loop {
2773 match parse_port(p) {
2775 Ok(x) => v.push(x),
2776 Err(()) => p.recover_balanced(&[Comma, CloseDelim(Paren)], false),
2777 }
2778
2779 match p.peek(0) {
2781 (Comma, sp) => {
2782 p.bump();
2783 if p.peek(0).0 == CloseDelim(Paren) {
2784 p.add_diag(DiagBuilder2::warning("superfluous trailing comma").span(sp));
2785 break;
2786 }
2787 }
2788 (CloseDelim(Paren), _) => break,
2789 (_, sp) => {
2790 p.add_diag(DiagBuilder2::error("expected , or ) after port").span(sp));
2791 p.recover_balanced(&[CloseDelim(Paren)], false);
2792 break;
2793 }
2794 }
2795 }
2796
2797 p.require_reported(CloseDelim(Paren))?;
2798 Ok(v)
2799}
2800
2801fn parse_port<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ast::Port<'n>> {
2938 let mut pp = ParallelParser::new();
2939 pp.add_greedy("interface port", parse_interface_port);
2940 pp.add_greedy("explicit port", parse_explicit_port);
2941 pp.add_greedy("named port", parse_named_port);
2942 pp.add_greedy("implicit port", parse_implicit_port);
2943 pp.finish(p, "port")
2944}
2945
2946fn parse_interface_port<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ast::Port<'n>> {
2951 let mut span = p.peek(0).1;
2952
2953 p.require_reported(Keyword(Kw::Interface))?;
2955
2956 let modport = if p.try_eat(Period) {
2958 Some(parse_identifier_name(p, "modport name")?)
2959 } else {
2960 None
2961 };
2962
2963 let name = parse_identifier_name(p, "port name")?;
2965
2966 let (dims, _) = parse_optional_dimensions(p)?;
2968
2969 let expr = if p.try_eat(Operator(Op::Assign)) {
2971 Some(parse_expr(p)?)
2972 } else {
2973 None
2974 };
2975
2976 p.anticipate(&[CloseDelim(Paren), Comma])?;
2977 span.expand(p.last_span());
2978 Ok(ast::Port::new(
2979 span,
2980 ast::PortData::Intf {
2981 modport,
2982 name,
2983 dims,
2984 expr,
2985 },
2986 ))
2987}
2988
2989fn parse_explicit_port<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ast::Port<'n>> {
2994 let mut span = p.peek(0).1;
2995
2996 let dir = as_port_direction(p.peek(0).0);
2998 if dir.is_some() {
2999 p.bump();
3000 }
3001
3002 p.require_reported(Period)?;
3004 let name = parse_identifier_name(p, "port name")?;
3005
3006 let expr = flanked(p, Paren, |p| {
3008 if p.peek(0).0 == CloseDelim(Paren) {
3009 Ok(None)
3010 } else {
3011 Ok(Some(parse_expr(p)?))
3012 }
3013 })?;
3014
3015 p.anticipate(&[CloseDelim(Paren), Comma])?;
3016 span.expand(p.last_span());
3017 Ok(ast::Port::new(
3018 span,
3019 ast::PortData::Explicit { dir, name, expr },
3020 ))
3021}
3022
3023fn parse_named_port<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ast::Port<'n>> {
3028 let mut span = p.peek(0).1;
3029
3030 let dir = as_port_direction(p.peek(0).0);
3032 if dir.is_some() {
3033 p.bump();
3034 }
3035
3036 let kind = {
3039 let tkn = p.peek(0).0;
3040 if let Some(ty) = as_net_type(tkn) {
3041 p.bump();
3042 Some(ast::VarKind::Net {
3043 ty,
3044 kind: ast::NetKind::None,
3045 })
3046 } else if tkn == Keyword(Kw::Var) {
3047 p.bump();
3048 Some(ast::VarKind::Var)
3049 } else {
3050 None
3051 }
3052 };
3053
3054 let mut pp = ParallelParser::new();
3056 pp.add("explicit type", |p| {
3057 let ty = parse_explicit_type(p)?;
3058 Ok((ty, tail(p)?))
3059 });
3060 pp.add("implicit type", |p| {
3061 let ty = parse_implicit_type(p)?;
3062 Ok((ty, tail(p)?))
3063 });
3064 let (ty, (name, dims, expr)) = pp.finish(p, "explicit or implicit type")?;
3065
3066 fn tail<'n>(
3067 p: &mut dyn AbstractParser<'n>,
3068 ) -> ReportedResult<(Spanned<Name>, Vec<ast::TypeDim<'n>>, Option<ast::Expr<'n>>)> {
3069 let name = parse_identifier_name(p, "port name")?;
3071
3072 let (dims, _) = parse_optional_dimensions(p)?;
3074
3075 let expr = if p.try_eat(Operator(Op::Assign)) {
3077 Some(parse_expr(p)?)
3078 } else {
3079 None
3080 };
3081
3082 p.anticipate(&[CloseDelim(Paren), Comma])?;
3083 Ok((name, dims, expr))
3084 }
3085
3086 span.expand(p.last_span());
3087 Ok(ast::Port::new(
3088 span,
3089 ast::PortData::Named {
3090 dir,
3091 kind,
3092 ty,
3093 name,
3094 dims,
3095 expr,
3096 },
3097 ))
3098}
3099
3100fn parse_implicit_port<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ast::Port<'n>> {
3105 let mut span = p.peek(0).1;
3106 let expr = parse_expr(p)?;
3107 span.expand(p.last_span());
3108 Ok(ast::Port::new(span, ast::PortData::Implicit(expr)))
3109}
3110
3111fn parse_parameter_assignments<'n>(
3112 p: &mut dyn AbstractParser<'n>,
3113) -> ReportedResult<Vec<ast::ParamAssignment<'n>>> {
3114 flanked(p, Paren, |p| {
3115 comma_list(
3116 p,
3117 CloseDelim(Paren),
3118 "parameter assignment",
3119 parse_parameter_assignment,
3120 )
3121 })
3122}
3123
3124fn parse_parameter_assignment<'n>(
3125 p: &mut dyn AbstractParser<'n>,
3126) -> ReportedResult<ast::ParamAssignment<'n>> {
3127 let mut span = p.peek(0).1;
3128 let terms = [Comma, CloseDelim(Paren)];
3129 let (name, expr) = if p.try_eat(Period) {
3132 let name = parse_identifier(p, "parameter name")?;
3133 let expr = flanked(p, Paren, |p| parse_type_or_expr(p, &terms))?;
3134 (Some(name), expr)
3135 } else {
3136 (None, parse_type_or_expr(p, &terms)?)
3137 };
3138 span.expand(p.last_span());
3139 Ok(ast::ParamAssignment {
3140 span: span,
3141 name: name,
3142 expr: expr,
3143 })
3144}
3145
3146fn parse_procedure<'n>(
3147 p: &mut dyn AbstractParser<'n>,
3148 kind: ProcedureKind,
3149) -> ReportedResult<Procedure<'n>> {
3150 p.bump();
3151 let mut span = p.last_span();
3152 let stmt = parse_stmt(p)?;
3153 span.expand(p.last_span());
3154 Ok(Procedure::new(
3155 span,
3156 ProcedureData {
3157 kind: kind,
3158 stmt: stmt,
3159 },
3160 ))
3161}
3162
3163fn parse_subroutine_decl<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<SubroutineDecl<'n>> {
3164 let mut span = p.peek(0).1;
3165
3166 let prototype = parse_subroutine_prototype(p)?;
3169
3170 let term = match prototype.kind {
3172 SubroutineKind::Func => Keyword(Kw::Endfunction),
3173 SubroutineKind::Task => Keyword(Kw::Endtask),
3174 };
3175 let items = repeat_until(p, term, parse_subroutine_item)?;
3176
3177 p.require_reported(term)?;
3179 if p.try_eat(Colon) {
3180 p.eat_ident("function/task name")?;
3181 }
3182 span.expand(p.last_span());
3183 Ok(SubroutineDecl::new(
3184 span,
3185 SubroutineDeclData { prototype, items },
3186 ))
3187}
3188
3189fn parse_subroutine_kind<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<SubroutineKind> {
3190 let span = p.peek(0).1;
3191 match p.peek(0).0 {
3192 Keyword(Kw::Function) => {
3193 p.bump();
3194 Ok(SubroutineKind::Func)
3195 }
3196 Keyword(Kw::Task) => {
3197 p.bump();
3198 Ok(SubroutineKind::Task)
3199 }
3200 _ => {
3201 p.add_diag(DiagBuilder2::error("expected `function` or `task`").span(span));
3202 Err(())
3203 }
3204 }
3205}
3206
3207fn parse_subroutine_prototype<'n>(
3208 p: &mut dyn AbstractParser<'n>,
3209) -> ReportedResult<SubroutinePrototype<'n>> {
3210 let mut span = p.peek(0).1;
3211
3212 let kind = parse_subroutine_kind(p)?;
3215
3216 let lifetime = as_lifetime(p.peek(0).0);
3218 if lifetime.is_some() {
3219 p.bump();
3220 }
3221
3222 let (retty, (name, args)) = if kind == SubroutineKind::Func {
3225 if p.peek(0).0 == Keyword(Kw::New) {
3226 (None, parse_subroutine_prototype_tail(p)?)
3227 } else {
3228 let mut pp = ParallelParser::new();
3229 pp.add("implicit function return type", |p| {
3230 let ty = parse_implicit_type(p)?;
3231 Ok((Some(ty), parse_subroutine_prototype_tail(p)?))
3232 });
3233 pp.add("explicit function return type", |p| {
3234 let ty = parse_explicit_type(p)?;
3235 Ok((Some(ty), parse_subroutine_prototype_tail(p)?))
3236 });
3237 pp.finish(p, "implicit or explicit function return type")?
3238 }
3239 } else {
3240 (None, parse_subroutine_prototype_tail(p)?)
3241 };
3242
3243 span.expand(p.last_span());
3244 Ok(SubroutinePrototype::new(
3245 span,
3246 SubroutinePrototypeData {
3247 kind,
3248 lifetime,
3249 name,
3250 args,
3251 retty,
3252 },
3253 ))
3254}
3255
3256fn parse_subroutine_prototype_tail<'n>(
3257 p: &mut dyn AbstractParser<'n>,
3258) -> ReportedResult<(Spanned<Name>, Option<Vec<SubroutinePort<'n>>>)> {
3259 let name = if p.try_eat(Keyword(Kw::New)) {
3262 Spanned::new(get_name_table().intern("new", true), p.last_span())
3263 } else {
3264 parse_identifier_name(p, "function or task name")?
3265 };
3266
3267 let args = try_flanked(p, Paren, |p| {
3269 comma_list(p, CloseDelim(Paren), "subroutine port", |p| {
3270 let mut span = p.peek(0).1;
3271
3272 let dir = try_subroutine_port_dir(p);
3274
3275 let var = p.try_eat(Keyword(Kw::Var));
3277
3278 let mut pp = ParallelParser::new();
3280 pp.add("explicit type", |p| {
3281 let ty = parse_explicit_type(p)?;
3282 Ok((ty, tail(p)?))
3283 });
3284 pp.add("implicit type", |p| {
3285 let ty = parse_implicit_type(p)?;
3286 Ok((ty, tail(p)?))
3287 });
3288 let ty_name = pp.finish_ambiguous(p, "explicit or implicit type")?;
3289
3290 fn tail<'n>(
3295 p: &mut dyn AbstractParser<'n>,
3296 ) -> ReportedResult<Option<SubroutinePortName<'n>>> {
3297 let data = if let Some(name) = try_identifier_name(p)? {
3299 let (dims, _) = parse_optional_dimensions(p)?;
3301
3302 let expr = if p.try_eat(Operator(Op::Assign)) {
3304 Some(parse_expr(p)?)
3305 } else {
3306 None
3307 };
3308
3309 Some(SubroutinePortName { name, dims, expr })
3310 } else {
3311 None
3312 };
3313
3314 match p.peek(0) {
3316 (Comma, _) | (CloseDelim(Paren), _) => Ok(data),
3317 (_, sp) => {
3318 p.add_diag(
3319 DiagBuilder2::error("expected , or ) after subroutine port").span(sp),
3320 );
3321 Err(())
3322 }
3323 }
3324 }
3325
3326 span.expand(p.last_span());
3327 Ok(SubroutinePort::new(
3328 span,
3329 SubroutinePortData { dir, var, ty_name },
3330 ))
3331 })
3332 })?;
3333
3334 p.require_reported(Semicolon)?;
3336 Ok((name, args))
3337}
3338
3339fn try_subroutine_port_dir<'n>(p: &mut dyn AbstractParser<'n>) -> Option<SubroutinePortDir> {
3340 match (p.peek(0).0, p.peek(1).0) {
3341 (Keyword(Kw::Input), _) => {
3342 p.bump();
3343 Some(SubroutinePortDir::Input)
3344 }
3345 (Keyword(Kw::Output), _) => {
3346 p.bump();
3347 Some(SubroutinePortDir::Output)
3348 }
3349 (Keyword(Kw::Inout), _) => {
3350 p.bump();
3351 Some(SubroutinePortDir::Inout)
3352 }
3353 (Keyword(Kw::Ref), _) => {
3354 p.bump();
3355 Some(SubroutinePortDir::Ref)
3356 }
3357 (Keyword(Kw::Const), Keyword(Kw::Ref)) => {
3358 p.bump();
3359 p.bump();
3360 Some(SubroutinePortDir::ConstRef)
3361 }
3362 _ => None,
3363 }
3364}
3365
3366fn parse_subroutine_item<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<SubroutineItem<'n>> {
3367 let mut span = p.peek(0).1;
3368
3369 if let Some(dir) = try_subroutine_port_dir(p) {
3372 let var = p.try_eat(Keyword(Kw::Var));
3374
3375 let mut pp = ParallelParser::new();
3377 pp.add("explicit type", |p| {
3378 let ty = parse_explicit_type(p)?;
3379 let names = comma_list_nonempty(
3380 p,
3381 Semicolon,
3382 "port declaration",
3383 parse_variable_decl_assignment,
3384 )?;
3385 p.require_reported(Semicolon)?;
3386 Ok((ty, names))
3387 });
3388 pp.add("implicit type", |p| {
3389 let ty = parse_implicit_type(p)?;
3390 let names = comma_list_nonempty(
3391 p,
3392 Semicolon,
3393 "port declaration",
3394 parse_variable_decl_assignment,
3395 )?;
3396 p.require_reported(Semicolon)?;
3397 Ok((ty, names))
3398 });
3399 let (ty, names) = pp.finish(p, "explicit or implicit type")?;
3400
3401 span.expand(p.last_span());
3403 return Ok(SubroutineItem::PortDecl(SubroutinePortDecl::new(
3404 span,
3405 SubroutinePortDeclData {
3406 dir,
3407 var,
3408 ty,
3409 names,
3410 },
3411 )));
3412 }
3413
3414 Ok(SubroutineItem::Stmt(parse_stmt(p)?))
3416}
3417
3418fn parse_stmt<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Stmt<'n>> {
3419 let mut span = p.peek(0).1;
3420
3421 if p.try_eat(Semicolon) {
3423 return Ok(Stmt::new_null(span));
3424 }
3425
3426 let mut label = if p.is_ident() && p.peek(1).0 == Colon {
3428 let (n, _) = p.eat_ident("statement label")?;
3429 p.bump(); Some(n)
3431 } else {
3432 None
3433 };
3434
3435 let kind = parse_stmt_kind(p, &mut label)?;
3437 span.expand(p.last_span());
3438
3439 Ok(Stmt::new(span, StmtData { label, kind }))
3440}
3441
3442fn parse_stmt_kind<'n>(
3443 p: &mut dyn AbstractParser<'n>,
3444 label: &mut Option<Name>,
3445) -> ReportedResult<StmtKind<'n>> {
3446 let (tkn, sp) = p.peek(0);
3447
3448 if let Some(dc) = try_delay_control(p)? {
3451 let stmt = Box::new(parse_stmt(p)?);
3452 return Ok(TimedStmt(TimingControl::Delay(dc), stmt));
3453 }
3454 if let Some(ec) = try_event_control(p)? {
3455 let stmt = Box::new(parse_stmt(p)?);
3456 return Ok(TimedStmt(TimingControl::Event(ec), stmt));
3457 }
3458 if let Some(cd) = try_cycle_delay(p)? {
3459 let stmt = Box::new(parse_stmt(p)?);
3460 return Ok(TimedStmt(TimingControl::Cycle(cd), stmt));
3461 }
3462
3463 Ok(match tkn {
3464 OpenDelim(Bgend) => {
3466 p.bump();
3467 let (stmts, _) = parse_block(p, label, &[CloseDelim(Bgend)])?;
3468 SequentialBlock(stmts)
3469 }
3470
3471 Keyword(Kw::Fork) => {
3473 p.bump();
3474 let (stmts, terminator) = parse_block(
3475 p,
3476 label,
3477 &[
3478 Keyword(Kw::Join),
3479 Keyword(Kw::JoinAny),
3480 Keyword(Kw::JoinNone),
3481 ],
3482 )?;
3483 let join = match terminator {
3484 Keyword(Kw::Join) => JoinKind::All,
3485 Keyword(Kw::JoinAny) => JoinKind::Any,
3486 Keyword(Kw::JoinNone) => JoinKind::None,
3487 x => panic!("Invalid parallel block terminator {:?}", x),
3488 };
3489 ParallelBlock(stmts, join)
3490 }
3491
3492 Keyword(Kw::Unique) => {
3494 p.bump();
3495 parse_if_or_case(p, Some(UniquePriority::Unique))?
3496 }
3497 Keyword(Kw::Unique0) => {
3498 p.bump();
3499 parse_if_or_case(p, Some(UniquePriority::Unique0))?
3500 }
3501 Keyword(Kw::Priority) => {
3502 p.bump();
3503 parse_if_or_case(p, Some(UniquePriority::Priority))?
3504 }
3505 Keyword(Kw::If) | Keyword(Kw::Case) | Keyword(Kw::Casex) | Keyword(Kw::Casez) => {
3506 parse_if_or_case(p, None)?
3507 }
3508
3509 Keyword(Kw::Forever) => {
3511 p.bump();
3512 let stmt = Box::new(parse_stmt(p)?);
3513 ForeverStmt(stmt)
3514 }
3515 Keyword(Kw::Repeat) => {
3516 p.bump();
3517 let expr = flanked(p, Paren, parse_expr)?;
3518 let stmt = Box::new(parse_stmt(p)?);
3519 RepeatStmt(expr, stmt)
3520 }
3521 Keyword(Kw::While) => {
3522 p.bump();
3523 let expr = flanked(p, Paren, parse_expr)?;
3524 let stmt = Box::new(parse_stmt(p)?);
3525 WhileStmt(expr, stmt)
3526 }
3527 Keyword(Kw::Do) => {
3528 p.bump();
3529 let stmt = Box::new(parse_stmt(p)?);
3530 let q = p.last_span();
3531 if !p.try_eat(Keyword(Kw::While)) {
3532 p.add_diag(DiagBuilder2::error("Do loop requires a while clause").span(q));
3533 return Err(());
3534 }
3535 let expr = flanked(p, Paren, parse_expr)?;
3536 DoStmt(stmt, expr)
3537 }
3538 Keyword(Kw::For) => {
3539 p.bump();
3540 let (init, cond, step) = flanked(p, Paren, |p| {
3541 let init = Box::new(parse_stmt(p)?);
3542 let cond = parse_expr(p)?;
3543 p.require_reported(Semicolon)?;
3544 let step = parse_expr(p)?;
3545 Ok((init, cond, step))
3546 })?;
3547 let stmt = Box::new(parse_stmt(p)?);
3548 ForStmt(init, cond, step, stmt)
3549 }
3550 Keyword(Kw::Foreach) => {
3551 p.bump();
3552 let (expr, vars) = flanked(p, Paren, |p| {
3553 let expr = parse_expr_prec(p, Precedence::Scope)?;
3554 let vars = flanked(p, Brack, |p| {
3555 Ok(comma_list(p, CloseDelim(Brack), "loop variables", |p| {
3556 Ok(if p.peek(0).0 != Comma {
3557 Some(parse_identifier_name(p, "loop variable name")?)
3558 } else {
3559 None
3560 })
3561 })?
3562 .into_iter()
3563 .enumerate()
3564 .flat_map(|(i, name)| {
3565 name.map(|name| {
3566 ast::ForeachIndex::new(
3567 name.span,
3568 ast::ForeachIndexData { index: i, name },
3569 )
3570 })
3571 })
3572 .collect())
3573 })?;
3574 Ok((expr, vars))
3575 })?;
3576 let stmt = Box::new(parse_stmt(p)?);
3577 ForeachStmt(expr, vars, stmt)
3578 }
3579
3580 Keyword(Kw::Genvar) => {
3582 p.bump();
3583 let names = comma_list_nonempty(p, Semicolon, "genvar declaration", parse_genvar_decl)?;
3584 p.require_reported(Semicolon)?;
3585 GenvarDeclStmt(names)
3586 }
3587
3588 Keyword(Kw::Return) => {
3590 p.bump();
3591 ReturnStmt(if p.try_eat(Semicolon) {
3592 None
3593 } else {
3594 let expr = parse_expr(p)?;
3595 p.require_reported(Semicolon)?;
3596 Some(expr)
3597 })
3598 }
3599 Keyword(Kw::Break) => {
3600 p.bump();
3601 p.require_reported(Semicolon)?;
3602 BreakStmt
3603 }
3604 Keyword(Kw::Continue) => {
3605 p.bump();
3606 p.require_reported(Semicolon)?;
3607 ContinueStmt
3608 }
3609
3610 Keyword(Kw::Import) => ImportStmt(parse_import_decl(p)?),
3612
3613 Keyword(Kw::Assert)
3615 | Keyword(Kw::Assume)
3616 | Keyword(Kw::Cover)
3617 | Keyword(Kw::Expect)
3618 | Keyword(Kw::Restrict) => AssertionStmt(Box::new(parse_assertion(p)?)),
3619
3620 Keyword(Kw::Wait) => {
3622 p.bump();
3623 match p.peek(0) {
3624 (OpenDelim(Paren), _) => {
3625 let expr = flanked(p, Paren, parse_expr)?;
3626 let stmt = Box::new(parse_stmt(p)?);
3627 WaitExprStmt(expr, stmt)
3628 }
3629 (Keyword(Kw::Fork), _) => {
3630 p.bump();
3631 p.require_reported(Semicolon)?;
3632 WaitForkStmt
3633 }
3634 (tkn, sp) => {
3635 p.add_diag(
3636 DiagBuilder2::error(format!(
3637 "expected (<expr>) or fork after wait, found {} instead",
3638 tkn
3639 ))
3640 .span(sp),
3641 );
3642 return Err(());
3643 }
3644 }
3645 }
3646 Keyword(Kw::WaitOrder) => {
3647 p.add_diag(
3648 DiagBuilder2::error("Don't know how to parse wait_order statements").span(sp),
3649 );
3650 return Err(());
3651 }
3652
3653 Keyword(Kw::Disable) => {
3655 p.bump();
3656 if p.try_eat(Keyword(Kw::Fork)) {
3657 p.require_reported(Semicolon)?;
3658 DisableForkStmt
3659 } else {
3660 let (name, _) = p.eat_ident("task or block name")?;
3661 p.require_reported(Semicolon)?;
3662 DisableStmt(name)
3663 }
3664 }
3665
3666 _ => {
3669 let result = {
3670 let mut pp = ParallelParser::new();
3671 pp.add("variable declaration", |p| {
3672 parse_var_decl(p).map(|d| ast::VarDeclStmt(d))
3673 });
3674 pp.add("assign statement", |p| parse_assign_stmt(p));
3675 pp.add("expression statement", |p| parse_expr_stmt(p));
3676 pp.finish(p, "statement")
3677 };
3678 match result {
3679 Ok(x) => x,
3680 Err(_) => {
3681 p.recover_balanced(&[Semicolon], true);
3682 return Err(());
3683 }
3684 }
3685 }
3686 })
3687}
3688
3689fn parse_block<'n>(
3690 p: &mut dyn AbstractParser<'n>,
3691 label: &mut Option<Name>,
3692 terminators: &[Token],
3693) -> ReportedResult<(Vec<Stmt<'n>>, Token)> {
3694 let span = p.last_span();
3695
3696 if p.try_eat(Colon) {
3699 let (name, name_span) = p.eat_ident("block label")?;
3700 if let Some(existing) = *label {
3701 if name == existing {
3702 p.add_diag(
3703 DiagBuilder2::warning(format!("Block {} labelled twice", name)).span(name_span),
3704 );
3705 } else {
3706 p.add_diag(
3707 DiagBuilder2::error(format!(
3708 "Block has been given two conflicting labels, {} and {}",
3709 existing, name
3710 ))
3711 .span(name_span),
3712 );
3713 }
3714 } else {
3715 *label = Some(name);
3716 }
3717 }
3718
3719 let mut v = Vec::new();
3721 let terminator;
3722 'outer: loop {
3723 let tkn = p.peek(0).0;
3725 for term in terminators {
3726 if tkn == *term {
3727 terminator = *term;
3728 p.bump();
3729 break 'outer;
3730 }
3731 }
3732
3733 match parse_stmt(p) {
3735 Ok(x) => v.push(x),
3736 Err(()) => {
3737 p.recover_balanced(terminators, false);
3738 terminator = p.peek(0).0;
3739 p.bump();
3740 break;
3741 }
3742 }
3743 }
3744
3745 if p.try_eat(Colon) {
3748 let (name, name_span) = p.eat_ident("block label")?;
3749 if let Some(before) = *label {
3750 if before != name {
3751 p.add_diag(
3752 DiagBuilder2::error(format!(
3753 "Block label {} at end of block does not match label {} at beginning of \
3754 block",
3755 name, before
3756 ))
3757 .span(name_span),
3758 );
3759 }
3760 } else {
3761 p.add_diag(
3762 DiagBuilder2::error(format!(
3763 "Block label {} provided at the end of the block, but not at the beginning",
3764 name
3765 ))
3766 .span(name_span),
3767 );
3768 }
3769 }
3770
3771 Ok((v, terminator))
3772}
3773
3774fn parse_continuous_assign<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ContAssign<'n>> {
3780 let mut span = p.peek(0).1;
3781 p.require_reported(Keyword(Kw::Assign))?;
3782
3783 let strength = try_flanked(p, Paren, |p| {
3785 let span = p.peek(0).1;
3786 match try_drive_strength(p)? {
3787 Some(x) => Ok(x),
3788 None => {
3789 p.add_diag(DiagBuilder2::error("expected drive strength").span(span));
3790 Err(())
3791 }
3792 }
3793 })?;
3794
3795 let delay_control = try_delay_control(p)?;
3797
3798 let assignments = comma_list_nonempty(p, Semicolon, "continuous assignment", parse_assignment)?;
3800 p.require_reported(Semicolon)?;
3801
3802 span.expand(p.last_span());
3803 Ok(ast::ContAssign::new(
3804 span,
3805 ast::ContAssignData {
3806 strength,
3807 delay: None,
3808 delay_control,
3809 assignments,
3810 },
3811 ))
3812}
3813
3814fn parse_if_or_case<'n>(
3815 p: &mut dyn AbstractParser<'n>,
3816 up: Option<UniquePriority>,
3817) -> ReportedResult<StmtKind<'n>> {
3818 let (tkn, span) = p.peek(0);
3819 match tkn {
3820 Keyword(Kw::Case) => {
3822 p.bump();
3823 parse_case(p, up, CaseKind::Normal)
3824 }
3825 Keyword(Kw::Casez) => {
3826 p.bump();
3827 parse_case(p, up, CaseKind::DontCareZ)
3828 }
3829 Keyword(Kw::Casex) => {
3830 p.bump();
3831 parse_case(p, up, CaseKind::DontCareXZ)
3832 }
3833
3834 Keyword(Kw::If) => {
3836 p.bump();
3837 parse_if(p, up)
3838 }
3839
3840 x => {
3841 p.add_diag(
3842 DiagBuilder2::error(format!("expected case or if statement, got {:?}", x))
3843 .span(span),
3844 );
3845 Err(())
3846 }
3847 }
3848}
3849
3850fn parse_case<'n>(
3852 p: &mut dyn AbstractParser<'n>,
3853 up: Option<UniquePriority>,
3854 kind: CaseKind,
3855) -> ReportedResult<StmtKind<'n>> {
3856 let q = p.last_span();
3857
3858 p.require_reported(OpenDelim(Paren))?;
3860 let expr = match parse_expr(p) {
3861 Ok(x) => x,
3862 Err(()) => {
3863 p.recover_balanced(&[CloseDelim(Paren)], true);
3864 return Err(());
3865 }
3866 };
3867 p.require_reported(CloseDelim(Paren))?;
3868
3869 let mode = match p.peek(0).0 {
3872 Keyword(Kw::Inside) => {
3873 p.bump();
3874 CaseMode::Inside
3875 }
3876 Keyword(Kw::Matches) => {
3877 p.bump();
3878 CaseMode::Pattern
3879 }
3880 _ => CaseMode::Normal,
3881 };
3882
3883 let mut items = Vec::new();
3885 while p.peek(0).0 != Keyword(Kw::Endcase) && p.peek(0).0 != Eof {
3886 let mut span = p.peek(0).1;
3887
3888 if p.peek(0).0 == Keyword(Kw::Default) {
3890 p.bump();
3891 p.try_eat(Colon);
3892 let stmt = Box::new(parse_stmt(p)?);
3893 items.push(CaseItem::Default(stmt));
3894 }
3895 else {
3897 let mut exprs = Vec::new();
3898 loop {
3899 if p.peek(0).0 == OpenDelim(Brack) {
3900 p.require_reported(OpenDelim(Brack))?;
3903 parse_expr(p)?;
3904 p.require_reported(Colon)?;
3905 parse_expr(p)?;
3906 p.require_reported(CloseDelim(Brack))?;
3907 } else {
3908 match parse_expr(p) {
3909 Ok(x) => exprs.push(x),
3910 Err(()) => {
3911 p.recover_balanced(&[Colon], false);
3912 break;
3913 }
3914 }
3915 }
3916
3917 match p.peek(0) {
3918 (Comma, sp) => {
3919 p.bump();
3920 if p.try_eat(Colon) {
3921 p.add_diag(
3922 DiagBuilder2::warning("superfluous trailing comma").span(sp),
3923 );
3924 break;
3925 }
3926 }
3927 (Colon, _) => break,
3928 (_, sp) => {
3929 p.add_diag(
3930 DiagBuilder2::error("expected , or : after case expression").span(sp),
3931 );
3932 break;
3933 }
3934 }
3935 }
3936
3937 p.require_reported(Colon)?;
3939 let stmt = Box::new(parse_stmt(p)?);
3940 items.push(CaseItem::Expr(exprs, stmt));
3941 }
3942 }
3943
3944 p.require_reported(Keyword(Kw::Endcase))?;
3945
3946 Ok(CaseStmt {
3947 up: up,
3948 kind: kind,
3949 expr: expr,
3950 mode: mode,
3951 items: items,
3952 })
3953}
3954
3955fn parse_if<'n>(
3956 p: &mut dyn AbstractParser<'n>,
3957 up: Option<UniquePriority>,
3958) -> ReportedResult<StmtKind<'n>> {
3959 p.require_reported(OpenDelim(Paren))?;
3961 let cond = match parse_expr(p) {
3962 Ok(x) => x,
3963 Err(()) => {
3964 p.recover_balanced(&[CloseDelim(Paren)], true);
3965 return Err(());
3966 }
3967 };
3968 p.require_reported(CloseDelim(Paren))?;
3969
3970 let main_stmt = Box::new(parse_stmt(p)?);
3972
3973 let else_stmt = if p.peek(0).0 == Keyword(Kw::Else) {
3975 p.bump();
3976 Some(Box::new(parse_stmt(p)?))
3977 } else {
3978 None
3979 };
3980
3981 Ok(IfStmt {
3982 up: up,
3983 cond: cond,
3984 main_stmt: main_stmt,
3985 else_stmt: else_stmt,
3986 })
3987}
3988
3989fn try_delay_control<'n>(
3990 p: &mut dyn AbstractParser<'n>,
3991) -> ReportedResult<Option<DelayControl<'n>>> {
3992 if !p.try_eat(Hashtag) {
3994 return Ok(None);
3995 }
3996 let mut span = p.last_span();
3997
3998 let (tkn, sp) = p.peek(0);
4001 let expr = match tkn {
4002 OpenDelim(Paren) => {
4004 p.bump();
4005 let e = parse_expr_prec(p, Precedence::MinTypMax)?;
4006 p.require_reported(CloseDelim(Paren))?;
4007 e
4008 }
4009
4010 Literal(Number(..)) | Literal(Time(..)) | Ident(..) => {
4012 parse_expr_first(p, Precedence::Max)?
4013 }
4014
4015 _ => {
4017 p.add_diag(DiagBuilder2::error("expected delay value or expression after #").span(sp));
4018 return Err(());
4019 }
4020 };
4021 span.expand(p.last_span());
4022
4023 Ok(Some(DelayControl {
4024 span: span,
4025 expr: expr,
4026 }))
4027}
4028
4029fn try_event_control<'n>(
4031 p: &mut dyn AbstractParser<'n>,
4032) -> ReportedResult<Option<EventControl<'n>>> {
4033 if !p.try_eat(At) {
4034 return Ok(None);
4035 }
4036 let mut span = p.last_span();
4037
4038 if p.peek(0).0 == Operator(Op::Mul) {
4040 p.bump();
4041 span.expand(p.last_span());
4042 return Ok(Some(EventControl {
4043 span: span,
4044 data: EventControlData::Implicit,
4045 }));
4046 }
4047
4048 if p.peek(0).0 == OpenDelim(Paren)
4050 && p.peek(1).0 == Operator(Op::Mul)
4051 && p.peek(2).0 == CloseDelim(Paren)
4052 {
4053 p.bump();
4054 p.bump();
4055 p.bump();
4056 span.expand(p.last_span());
4057 return Ok(Some(EventControl {
4058 span: span,
4059 data: EventControlData::Implicit,
4060 }));
4061 }
4062
4063 let expr = parse_event_expr(p, EventPrecedence::Max)?;
4064 span.expand(p.last_span());
4065
4066 Ok(Some(EventControl {
4067 span: span,
4068 data: EventControlData::Expr(expr),
4069 }))
4070}
4071
4072fn try_cycle_delay<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Option<CycleDelay>> {
4073 if !p.try_eat(DoubleHashtag) {
4074 return Ok(None);
4075 }
4076
4077 let q = p.last_span();
4078 p.add_diag(DiagBuilder2::error("Don't know how to parse cycle delay").span(q));
4079 Err(())
4080}
4081
4082fn parse_assignment<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<(Expr<'n>, Expr<'n>)> {
4083 let lhs = parse_expr_prec(p, Precedence::Postfix)?;
4084 p.require_reported(Operator(Op::Assign))?;
4085 let rhs = parse_expr_prec(p, Precedence::Assignment)?;
4086 Ok((lhs, rhs))
4087}
4088
4089fn parse_assign_stmt<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<StmtKind<'n>> {
4090 let expr = parse_expr_prec(p, Precedence::Postfix)?;
4092 let (tkn, sp) = p.peek(0);
4093
4094 if let Some(op) = as_assign_operator(tkn) {
4097 p.bump();
4098 let rhs = parse_expr(p)?;
4099 p.require_reported(Semicolon)?;
4100 return Ok(BlockingAssignStmt {
4101 lhs: expr,
4102 rhs: rhs,
4103 op: op,
4104 });
4105 }
4106
4107 if tkn == Operator(Op::Leq) {
4109 p.bump();
4110
4111 let delay_control = try_delay_control(p)?;
4113 let event_control = None;
4114
4115 let rhs = parse_expr(p)?;
4117 p.require_reported(Semicolon)?;
4118
4119 return Ok(NonblockingAssignStmt {
4120 lhs: expr,
4121 rhs: rhs,
4122 delay: delay_control,
4123 event: event_control,
4124 });
4125 }
4126
4127 p.add_diag(DiagBuilder2::error("expected blocking or non-blocking assign statement").span(sp));
4128 Err(())
4129}
4130
4131fn parse_expr_stmt<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<StmtKind<'n>> {
4132 let expr = parse_expr_prec(p, Precedence::Unary)?;
4133 p.require_reported(Semicolon)?;
4134 Ok(ExprStmt(expr))
4135}
4136
4137fn parse_event_expr<'n>(
4138 p: &mut dyn AbstractParser<'n>,
4139 precedence: EventPrecedence,
4140) -> ReportedResult<EventExpr<'n>> {
4141 let mut span = p.peek(0).1;
4142
4143 if p.try_eat(OpenDelim(Paren)) {
4145 return match parse_event_expr(p, EventPrecedence::Min) {
4146 Ok(x) => {
4147 p.require_reported(CloseDelim(Paren))?;
4148 parse_event_expr_suffix(p, x, precedence)
4149 }
4150 Err(()) => {
4151 p.recover_balanced(&[CloseDelim(Paren)], true);
4152 Err(())
4153 }
4154 };
4155 }
4156
4157 let edge = as_edge_ident(p.peek(0).0);
4159 if edge != EdgeIdent::Implicit {
4160 p.bump();
4161 }
4162
4163 let value = parse_expr(p)?;
4165 span.expand(p.last_span());
4166
4167 let expr = EventExpr::Edge {
4168 span: span,
4169 edge: edge,
4170 value: value,
4171 };
4172 parse_event_expr_suffix(p, expr, precedence)
4173
4174 }
4177
4178fn parse_event_expr_suffix<'n>(
4179 p: &mut dyn AbstractParser<'n>,
4180 expr: EventExpr<'n>,
4181 precedence: EventPrecedence,
4182) -> ReportedResult<EventExpr<'n>> {
4183 match p.peek(0).0 {
4184 Keyword(Kw::Iff) if precedence < EventPrecedence::Iff => {
4186 p.bump();
4187 let cond = parse_expr(p)?;
4188 Ok(EventExpr::Iff {
4189 span: Span::union(expr.span(), cond.span),
4190 expr: Box::new(expr),
4191 cond: cond,
4192 })
4193 }
4194 Keyword(Kw::Or) | Comma if precedence <= EventPrecedence::Or => {
4197 p.bump();
4198 let rhs = parse_event_expr(p, EventPrecedence::Or)?;
4199 Ok(EventExpr::Or {
4200 span: Span::union(expr.span(), rhs.span()),
4201 lhs: Box::new(expr),
4202 rhs: Box::new(rhs),
4203 })
4204 }
4205 _ => Ok(expr),
4206 }
4207}
4208
4209#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
4210enum EventPrecedence {
4211 Min,
4212 Or,
4213 Iff,
4214 Max,
4215}
4216
4217fn as_edge_ident(tkn: Token) -> EdgeIdent {
4218 match tkn {
4219 Keyword(Kw::Edge) => EdgeIdent::Edge,
4220 Keyword(Kw::Posedge) => EdgeIdent::Posedge,
4221 Keyword(Kw::Negedge) => EdgeIdent::Negedge,
4222 _ => EdgeIdent::Implicit,
4223 }
4224}
4225
4226fn parse_call_args<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Vec<CallArg<'n>>> {
4227 let mut v = Vec::new();
4228 while p.peek(0).0 != CloseDelim(Paren) {
4229 match p.peek(0) {
4230 (Comma, sp) | (CloseDelim(Paren), sp) => v.push(CallArg::new(
4231 sp,
4232 CallArgData {
4233 name: None,
4234 expr: None,
4235 },
4236 )),
4237 (Period, mut sp) => {
4238 p.bump();
4239 let (name, mut name_sp) = p.eat_ident("argument name")?;
4240 name_sp.expand(sp);
4241 let expr = flanked(p, Paren, |p| {
4242 Ok(if p.peek(0).0 == CloseDelim(Paren) {
4243 None
4244 } else {
4245 Some(parse_expr(p)?)
4246 })
4247 })?;
4248 sp.expand(p.last_span());
4249
4250 v.push(CallArg::new(
4251 sp,
4252 CallArgData {
4253 name: Some(Spanned::new(name, name_sp)),
4254 expr,
4255 },
4256 ));
4257 }
4258 (_, mut sp) => {
4259 let expr = parse_expr(p)?;
4260 sp.expand(p.last_span());
4261 v.push(CallArg::new(
4262 sp,
4263 CallArgData {
4264 name: None,
4265 expr: Some(expr),
4266 },
4267 ));
4268 }
4269 }
4270
4271 match p.peek(0) {
4272 (Comma, sp) => p.bump(),
4273 (CloseDelim(Paren), _) => (),
4274 (_, sp) => {
4275 p.add_diag(DiagBuilder2::error("expected , or ) after call argument").span(sp));
4276 return Err(());
4277 }
4278 }
4279 }
4280 Ok(v)
4281}
4282
4283fn parse_variable_decl_assignment<'n>(
4284 p: &mut dyn AbstractParser<'n>,
4285) -> ReportedResult<VarDeclName<'n>> {
4286 let mut span = p.peek(0).1;
4287
4288 let (name, name_span) = p.eat_ident("variable name")?;
4290
4291 let (dims, _) = parse_optional_dimensions(p)?;
4293
4294 let init = if p.try_eat(Operator(Op::Assign)) {
4296 Some(parse_expr(p)?)
4297 } else {
4298 None
4299 };
4300 span.expand(p.last_span());
4301
4302 Ok(VarDeclName::new(
4303 span,
4304 VarDeclNameData {
4305 name: name,
4306 name_span: name_span,
4307 dims: dims,
4308 init: init,
4309 },
4310 ))
4311}
4312
4313fn parse_genvar_decl<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<GenvarDecl<'n>> {
4314 let mut span = p.peek(0).1;
4315
4316 let name = parse_identifier_name(p, "genvar name")?;
4318
4319 let init = if p.try_eat(Operator(Op::Assign)) {
4321 Some(parse_expr(p)?)
4322 } else {
4323 None
4324 };
4325 span.expand(p.last_span());
4326
4327 Ok(GenvarDecl::new(span, GenvarDeclData { name, init }))
4328}
4329
4330fn parse_generate_item<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Item<'n>> {
4331 let mut span = p.peek(0).1;
4332 let data = match p.peek(0).0 {
4333 Keyword(Kw::For) => ItemData::GenerateFor(parse_generate_for(p)?),
4334 Keyword(Kw::If) => ItemData::GenerateIf(parse_generate_if(p)?),
4335 Keyword(Kw::Case) => ItemData::GenerateCase(parse_generate_case(p)?),
4336 _ => return parse_item(p),
4337 };
4338 span.expand(p.last_span());
4339 Ok(Item::new(span, data))
4340}
4341
4342fn parse_generate_for<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<GenerateFor<'n>> {
4347 let mut span = p.peek(0).1;
4348 p.require_reported(Keyword(Kw::For))?;
4349 let (init, cond, step) = flanked(p, Paren, |p| {
4350 let init = parse_stmt(p)?;
4351 let cond = parse_expr(p)?;
4352 p.require_reported(Semicolon)?;
4353 let step = parse_expr(p)?;
4354 Ok((init, cond, step))
4355 })?;
4356 let block = parse_generate_block(p)?;
4357 span.expand(p.last_span());
4358 Ok(GenerateFor::new(
4359 span,
4360 GenerateForData {
4361 init,
4362 cond,
4363 step,
4364 block,
4365 },
4366 ))
4367}
4368
4369fn parse_generate_if<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<GenerateIf<'n>> {
4370 let mut span = p.peek(0).1;
4371 p.require_reported(Keyword(Kw::If))?;
4372 let cond = flanked(p, Paren, parse_expr)?;
4373 let main_block = parse_generate_block(p)?;
4374 let else_block = if p.try_eat(Keyword(Kw::Else)) {
4375 Some(parse_generate_block(p)?)
4376 } else {
4377 None
4378 };
4379 span.expand(p.last_span());
4380 Ok(GenerateIf::new(
4381 span,
4382 GenerateIfData {
4383 cond,
4384 main_block,
4385 else_block,
4386 },
4387 ))
4388}
4389
4390fn parse_generate_case<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<GenerateCase<'n>> {
4391 let mut span = p.peek(0).1;
4392 p.require_reported(Keyword(Kw::Case))?;
4393 p.recover_balanced(&[Keyword(Kw::Endcase)], true);
4394 if p.try_eat(Colon) {
4395 parse_identifier_name(p, "generate block label")?;
4396 }
4397 span.expand(p.last_span());
4398 p.add_diag(DiagBuilder2::error("case-generate statements not supported").span(span));
4399 Ok(GenerateCase::new(span, GenerateCaseData {}))
4400}
4401
4402fn parse_generate_block<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<GenerateBlock<'n>> {
4403 let mut span = p.peek(0).1;
4404
4405 let mut label = if p.is_ident() && p.peek(1).0 == Colon {
4407 let n = parse_identifier_name(p, "generate block label")?;
4408 p.require_reported(Colon)?;
4409 Some(n)
4410 } else {
4411 None
4412 };
4413
4414 if !p.try_eat(OpenDelim(Bgend)) {
4417 if label.is_some() {
4418 let (t, q) = p.peek(0);
4419 p.add_diag(
4420 DiagBuilder2::error(format!(
4421 "expected `begin` keyword after generate block label, found {} instead",
4422 t
4423 ))
4424 .span(q),
4425 );
4426 return Err(());
4427 }
4428 let item = parse_generate_item(p)?;
4429 span.expand(p.last_span());
4430 return Ok(GenerateBlock::new(
4431 span,
4432 GenerateBlockData {
4433 label: label,
4434 items: vec![item],
4435 },
4436 ));
4437 }
4438
4439 if p.try_eat(Colon) {
4441 let n = parse_identifier_name(p, "generate block label")?;
4442 if let Some(existing) = label {
4443 if existing.value == n.value {
4444 p.add_diag(
4445 DiagBuilder2::warning(format!("Generate block {} labelled twice", n))
4446 .span(n.span),
4447 );
4448 } else {
4449 p.add_diag(
4450 DiagBuilder2::error(format!(
4451 "Generate block given conflicting labels {} and {}",
4452 existing, n
4453 ))
4454 .span(n.span),
4455 );
4456 return Err(());
4457 }
4458 } else {
4459 label = Some(n);
4460 }
4461 }
4462
4463 let items = repeat_until(p, CloseDelim(Bgend), parse_generate_item)?;
4464 p.require_reported(CloseDelim(Bgend))?;
4465
4466 if p.try_eat(Colon) {
4468 let n = parse_identifier_name(p, "generate block label")?;
4469 if let Some(existing) = label {
4470 if existing.value != n.value {
4471 p.add_diag(
4472 DiagBuilder2::error(format!(
4473 "Label {} given after generate block does not match label {} given before \
4474 the block",
4475 n, existing
4476 ))
4477 .span(n.span),
4478 );
4479 return Err(());
4480 }
4481 } else {
4482 p.add_diag(
4483 DiagBuilder2::warning(format!(
4484 "Generate block has trailing label {}, but is missing leading label",
4485 n
4486 ))
4487 .span(n.span),
4488 );
4489 }
4490 }
4491
4492 span.expand(p.last_span());
4493 Ok(GenerateBlock::new(
4494 span,
4495 GenerateBlockData {
4496 label: label,
4497 items: items,
4498 },
4499 ))
4500}
4501
4502fn parse_class_decl<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ClassDecl<'n>> {
4503 let mut span = p.peek(0).1;
4504 let result = recovered(p, Keyword(Kw::Endclass), |p| {
4505 let virt = p.try_eat(Keyword(Kw::Virtual));
4507 let intf = p.try_eat(Keyword(Kw::Interface));
4508
4509 p.require_reported(Keyword(Kw::Class))?;
4511
4512 let lifetime = match as_lifetime(p.peek(0).0) {
4514 Some(l) => {
4515 p.bump();
4516 l
4517 }
4518 None => Lifetime::Static,
4519 };
4520
4521 let name = parse_identifier_name(p, "class name")?;
4523
4524 let params = if p.try_eat(Hashtag) {
4526 parse_parameter_port_list(p)?
4527 } else {
4528 Vec::new()
4529 };
4530
4531 let extends = if p.try_eat(Keyword(Kw::Extends)) {
4533 let superclass = parse_data_type(p)?;
4534 let args = try_flanked(p, Paren, parse_call_args)?.unwrap_or(Vec::new());
4535 Some((superclass, args))
4536 } else {
4537 None
4538 };
4539
4540 let impls = if p.try_eat(Keyword(Kw::Implements)) {
4542 comma_list_nonempty(p, Semicolon, "interface class", |p| {
4543 parse_identifier_name(p, "class name")
4544 })?
4545 } else {
4546 vec![]
4547 };
4548
4549 p.require_reported(Semicolon)?;
4550
4551 let items = repeat_until(p, Keyword(Kw::Endclass), |p| parse_class_item(p, intf))?;
4553 Ok((virt, lifetime, name, params, extends, impls, items))
4554 });
4555 p.require_reported(Keyword(Kw::Endclass))?;
4556
4557 let (virt, lifetime, name, params, extends, impls, items) = result?;
4558
4559 if p.try_eat(Colon) {
4561 let n = parse_identifier_name(p, "class name")?;
4562 if n.value != name.value {
4563 p.add_diag(
4564 DiagBuilder2::error(format!(
4565 "Class name {} disagrees with name {} given before",
4566 n, name
4567 ))
4568 .span(n.span),
4569 );
4570 return Err(());
4571 }
4572 }
4573
4574 span.expand(p.last_span());
4575 Ok(ClassDecl::new(
4576 span,
4577 ClassDeclData {
4578 virt,
4579 lifetime,
4580 name,
4581 params,
4582 extends,
4583 impls,
4584 items,
4585 },
4586 ))
4587}
4588
4589fn parse_class_item<'n>(
4590 p: &mut dyn AbstractParser<'n>,
4591 intf: bool,
4592) -> ReportedResult<ClassItem<'n>> {
4593 let mut span = p.peek(0).1;
4594
4595 if p.try_eat(Semicolon) {
4597 return Ok(ClassItem {
4598 span,
4599 qualifiers: vec![],
4600 data: ClassItemData::Null,
4601 });
4602 }
4603
4604 match p.peek(0).0 {
4607 Keyword(Kw::Localparam) | Keyword(Kw::Parameter) => {
4608 let decl = parse_param_decl(p, false)?;
4609 span.expand(p.last_span());
4610 p.require_reported(Semicolon)?;
4611 return Ok(ClassItem {
4612 span,
4613 qualifiers: vec![],
4614 data: ClassItemData::ParamDecl(decl),
4615 });
4616 }
4617 Keyword(Kw::Extern) => {
4619 p.bump();
4620 let proto = parse_subroutine_prototype(p)?;
4621 span.expand(p.last_span());
4622 return Ok(ClassItem {
4623 span,
4624 qualifiers: vec![],
4625 data: ClassItemData::ExternSubroutine(proto),
4626 });
4627 }
4628 Keyword(Kw::Typedef) => {
4630 let def = parse_typedef(p)?;
4631 span.expand(p.last_span());
4632 return Ok(ClassItem {
4633 span,
4634 qualifiers: vec![],
4635 data: ClassItemData::Typedef(def),
4636 });
4637 }
4638 _ => (),
4639 }
4640
4641 let qualifiers = parse_class_item_qualifiers(p)?;
4643
4644 let data = {
4645 let mut pp = ParallelParser::new();
4646 pp.add("class property", |p| {
4647 let ty = parse_data_type(p)?;
4648 let names = comma_list_nonempty(
4649 p,
4650 Semicolon,
4651 "data declaration",
4652 parse_variable_decl_assignment,
4653 )?;
4654 p.require_reported(Semicolon)?;
4655 Ok(ClassItemData::Property)
4656 });
4657 if intf {
4658 pp.add("class function or task prototype", |p| {
4659 parse_subroutine_prototype(p).map(ClassItemData::ExternSubroutine)
4660 });
4661 } else {
4662 pp.add("class function or task", |p| {
4663 parse_subroutine_decl(p).map(ClassItemData::SubroutineDecl)
4664 });
4665 }
4666 pp.add("class constraint", |p| {
4667 parse_constraint(p).map(ClassItemData::Constraint)
4668 });
4669 pp.finish(p, "class item")?
4670 };
4671 span.expand(p.last_span());
4672
4673 Ok(ClassItem {
4674 span: span,
4675 qualifiers: qualifiers,
4676 data: data,
4677 })
4678}
4679
4680fn parse_class_item_qualifiers<'n>(
4681 p: &mut dyn AbstractParser<'n>,
4682) -> ReportedResult<Vec<(ClassItemQualifier, Span)>> {
4683 let mut v = Vec::new();
4684 loop {
4685 let (tkn, sp) = p.peek(0);
4686 match tkn {
4687 Keyword(Kw::Static) => v.push((ClassItemQualifier::Static, sp)),
4688 Keyword(Kw::Protected) => v.push((ClassItemQualifier::Protected, sp)),
4689 Keyword(Kw::Local) => v.push((ClassItemQualifier::Local, sp)),
4690 Keyword(Kw::Rand) => v.push((ClassItemQualifier::Rand, sp)),
4691 Keyword(Kw::Randc) => v.push((ClassItemQualifier::Randc, sp)),
4692 Keyword(Kw::Pure) => v.push((ClassItemQualifier::Pure, sp)),
4693 Keyword(Kw::Virtual) => v.push((ClassItemQualifier::Virtual, sp)),
4694 Keyword(Kw::Const) => v.push((ClassItemQualifier::Const, sp)),
4695 _ => break,
4696 }
4697 p.bump();
4698 }
4699 Ok(v)
4700}
4701
4702fn parse_class_method<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ClassItem<'n>> {
4703 println!("Parsing class method");
4704 Err(())
4705}
4706
4707fn parse_class_property<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ClassItem<'n>> {
4708 println!("Parsing class property");
4709 p.try_eat(Keyword(Kw::Rand));
4710 Err(())
4711}
4712
4713fn parse_constraint<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Constraint<'n>> {
4714 let mut span = p.peek(0).1;
4715
4716 let kind = match p.peek(0).0 {
4718 Keyword(Kw::Extern) => {
4719 p.bump();
4720 ConstraintKind::ExternProto
4721 }
4722 Keyword(Kw::Pure) => {
4723 p.bump();
4724 ConstraintKind::PureProto
4725 }
4726 _ => ConstraintKind::Decl,
4727 };
4728 let kind_span = span;
4729
4730 let statik = p.try_eat(Keyword(Kw::Static));
4732
4733 p.require_reported(Keyword(Kw::Constraint))?;
4735
4736 let (name, name_span) = p.eat_ident("constraint name")?;
4738
4739 let items = if p.try_eat(Semicolon) {
4740 let kind = match kind {
4741 ConstraintKind::Decl => ConstraintKind::Proto,
4742 x => x,
4743 };
4744 Vec::new()
4745 } else {
4746 if kind == ConstraintKind::ExternProto || kind == ConstraintKind::PureProto {
4749 p.add_diag(
4750 DiagBuilder2::error("Only constraint prototypes can be extern or pure")
4751 .span(kind_span),
4752 );
4753 return Err(());
4754 }
4755 flanked(p, Brace, |p| {
4756 repeat_until(p, CloseDelim(Brace), parse_constraint_item)
4757 })?
4758 };
4759 span.expand(p.last_span());
4760
4761 Ok(Constraint {
4762 span: span,
4763 kind: kind,
4764 statik: statik,
4765 name: name,
4766 name_span: name_span,
4767 items: items,
4768 })
4769}
4770
4771fn parse_constraint_item<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ConstraintItem<'n>> {
4772 let mut span = p.peek(0).1;
4773 let data = parse_constraint_item_data(p)?;
4774 span.expand(p.last_span());
4775 Ok(ConstraintItem {
4776 span: span,
4777 data: data,
4778 })
4779}
4780
4781fn parse_constraint_item_data<'n>(
4782 p: &mut dyn AbstractParser<'n>,
4783) -> ReportedResult<ConstraintItemData<'n>> {
4784 if p.try_eat(Keyword(Kw::If)) {
4786 let q = p.last_span();
4787 p.add_diag(DiagBuilder2::error("Don't know how to parse `if` constraint items").span(q));
4788 return Err(());
4789 }
4790
4791 if p.try_eat(Keyword(Kw::Foreach)) {
4792 let q = p.last_span();
4793 p.add_diag(
4794 DiagBuilder2::error("Don't know how to parse `foreach` constraint items").span(q),
4795 );
4796 return Err(());
4797 }
4798
4799 let expr = parse_expr(p)?;
4801 p.require_reported(Semicolon)?;
4802 Ok(ConstraintItemData::Expr(expr))
4803}
4804
4805struct ParallelParser<'a, 'n, R: Clone> {
4806 branches: Vec<(
4807 String,
4808 Box<dyn FnMut(&mut dyn AbstractParser<'n>) -> ReportedResult<R> + 'a>,
4809 bool,
4810 )>,
4811}
4812
4813impl<'a, 'n, R: Clone> ParallelParser<'a, 'n, R> {
4814 pub fn new() -> Self {
4815 ParallelParser {
4816 branches: Vec::new(),
4817 }
4818 }
4819
4820 pub fn add<F>(&mut self, name: &str, func: F)
4821 where
4822 F: FnMut(&mut dyn AbstractParser<'n>) -> ReportedResult<R> + 'a,
4823 {
4824 self.branches.push((name.to_owned(), Box::new(func), false));
4825 }
4826
4827 pub fn add_greedy<F>(&mut self, name: &str, func: F)
4828 where
4829 F: FnMut(&mut dyn AbstractParser<'n>) -> ReportedResult<R> + 'a,
4830 {
4831 self.branches.push((name.to_owned(), Box::new(func), true));
4832 }
4833
4834 fn finish_prolog(
4835 self,
4836 p: &mut dyn AbstractParser<'n>,
4837 msg: &str,
4838 ) -> (
4839 Vec<(String, usize, Vec<DiagBuilder2>, R, Span)>,
4840 Vec<(String, usize, usize, Vec<DiagBuilder2>)>,
4841 ) {
4842 let q = p.peek(0).1;
4843 let mut results = Vec::new();
4844 let mut matched = Vec::new();
4845 for (name, mut func, greedy) in self.branches {
4846 let mut bp = BranchParser::new(p);
4847 match func(&mut bp) {
4848 Ok(x) => {
4849 if greedy {
4850 results.clear();
4851 matched.clear();
4852 }
4853 let sp = bp.last_span();
4854 results.push((name, bp.consumed, bp.diagnostics, x, Span::union(q, sp)));
4855 if greedy {
4856 break;
4857 }
4858 }
4859 Err(_) => matched.push((
4860 name,
4861 bp.consumed() - bp.skipped(),
4862 bp.consumed(),
4863 bp.diagnostics,
4864 )),
4865 }
4866 }
4867 (results, matched)
4868 }
4869
4870 fn finish_epilog(
4871 p: &mut dyn AbstractParser<'n>,
4872 msg: &str,
4873 tkn: Token,
4874 q: Span,
4875 mut results: Vec<(String, usize, Vec<DiagBuilder2>, R, Span)>,
4876 mut matched: Vec<(String, usize, usize, Vec<DiagBuilder2>)>,
4877 ) -> ReportedResult<R> {
4878 if results.len() > 1 {
4879 let mut names = String::new();
4880 names.push_str(&results[0].0);
4881 if results.len() == 2 {
4882 names.push_str(" or ");
4883 names.push_str(&results[1].0);
4884 } else {
4885 for &(ref name, _, _, _, _) in &results[..results.len() - 1] {
4886 names.push_str(", ");
4887 names.push_str(&name);
4888 }
4889 names.push_str(", or ");
4890 names.push_str(&results[results.len() - 1].0);
4891 }
4892 p.add_diag(DiagBuilder2::fatal(format!("ambiguous code, could be {}", names)).span(q));
4893 for &(ref name, _, _, _, span) in &results {
4894 p.add_diag(DiagBuilder2::note(format!("{} would be this part", name)).span(span));
4895 }
4896 Err(())
4897 } else if let Some(&(_, consumed, ref diagnostics, ref res, _)) = results.last() {
4898 for d in diagnostics {
4899 p.add_diag(d.clone());
4900 }
4901 for _ in 0..consumed {
4902 p.bump();
4903 }
4904 Ok((*res).clone())
4905 } else {
4906 matched.sort_by(|a, b| (b.1).cmp(&a.1));
4909 let highest_score = matched[0].1;
4910 let highest_consumed = matched[0].2;
4911 let errors = matched
4912 .into_iter()
4913 .take_while(|e| e.1 == highest_score)
4914 .collect::<Vec<_>>();
4915 let num_errors = errors.len();
4916
4917 if num_errors != 1 {
4919 p.add_diag(
4920 DiagBuilder2::error(format!("expected {}, found `{}` instead", msg, tkn))
4921 .span(q),
4922 );
4923 for (name, _, _, ds) in errors {
4924 p.add_diag(DiagBuilder2::note(format!("parsing as {}:", name)));
4925 for d in ds {
4926 p.add_diag(d);
4927 }
4928 }
4929 } else {
4930 for d in errors.into_iter().next().unwrap().3 {
4931 p.add_diag(d);
4932 }
4933 }
4934 for _ in 0..highest_consumed {
4935 p.bump();
4936 }
4937 Err(())
4938 }
4939 }
4940
4941 pub fn finish_ambiguous(
4942 self,
4943 p: &mut dyn AbstractParser<'n>,
4944 msg: &str,
4945 ) -> ReportedResult<ast::Ambiguous<R>> {
4946 let (tkn, span) = p.peek(0);
4947 let (mut results, mut matched) = self.finish_prolog(p, msg);
4948
4949 if results.len() > 1 && results.iter().all(|x| x.1 == results[0].1) {
4952 for _ in 0..results[0].1 {
4953 p.bump();
4954 }
4955 Ok(ast::Ambiguous::Ambiguous(
4956 results.into_iter().map(|x| x.3).collect(),
4957 ))
4958 }
4959 else {
4961 Self::finish_epilog(p, msg, tkn, span, results, matched).map(ast::Ambiguous::Unique)
4962 }
4963 }
4964
4965 pub fn finish(self, p: &mut dyn AbstractParser<'n>, msg: &str) -> ReportedResult<R> {
4966 let (tkn, span) = p.peek(0);
4967 let (mut results, mut matched) = self.finish_prolog(p, msg);
4968 Self::finish_epilog(p, msg, tkn, span, results, matched)
4969 }
4970}
4971
4972struct BranchParser<'tp, 'n> {
4973 parser: &'tp mut dyn AbstractParser<'n>,
4974 consumed: usize,
4975 skipped: usize,
4976 diagnostics: Vec<DiagBuilder2>,
4977 last_span: Span,
4978 severity: Severity,
4979}
4980
4981impl<'tp, 'n> BranchParser<'tp, 'n> {
4982 pub fn new(parser: &'tp mut dyn AbstractParser<'n>) -> Self {
4983 let last = parser.last_span();
4984 BranchParser {
4985 parser: parser,
4986 consumed: 0,
4987 skipped: 0,
4988 diagnostics: Vec::new(),
4989 last_span: last,
4990 severity: Severity::Note,
4991 }
4992 }
4993
4994 pub fn skipped(&self) -> usize {
4995 self.skipped
4996 }
4997
4998 pub fn commit(self) {
4999 for _ in 0..self.consumed {
5000 self.parser.bump();
5001 }
5002 for d in self.diagnostics {
5003 self.parser.add_diag(d);
5004 }
5005 }
5006}
5007
5008impl<'tp, 'n> AbstractParser<'n> for BranchParser<'tp, 'n> {
5009 fn arena(&self) -> &'n ast::Arena<'n> {
5010 self.parser.arena()
5011 }
5012
5013 fn peek(&mut self, offset: usize) -> TokenAndSpan {
5014 self.parser.peek(self.consumed + offset)
5015 }
5016
5017 fn bump(&mut self) {
5018 self.last_span = self.parser.peek(self.consumed).1;
5019 self.consumed += 1;
5020 }
5021
5022 fn skip(&mut self) {
5023 self.bump();
5024 self.skipped += 1;
5025 }
5026
5027 fn consumed(&self) -> usize {
5028 self.consumed
5029 }
5030
5031 fn last_span(&self) -> Span {
5032 self.last_span
5033 }
5034
5035 fn add_diag(&mut self, diag: DiagBuilder2) {
5036 if diag.severity > self.severity {
5037 self.severity = diag.severity;
5038 }
5039 self.diagnostics.push(diag);
5040 }
5041
5042 fn severity(&self) -> Severity {
5043 self.severity
5044 }
5045}
5046
5047fn parse_typedef<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Typedef<'n>> {
5048 let mut span = p.peek(0).1;
5049 p.require_reported(Keyword(Kw::Typedef))?;
5050
5051 {
5055 let mut bp = BranchParser::new(p);
5056 if bp.peek(0).0 == Keyword(Kw::Enum) {
5057 bp.bump();
5058 }
5059 let name = parse_identifier_name(&mut bp, "type name");
5060 let semi = bp.require_reported(Semicolon);
5061 if let (Ok(name), Ok(semi)) = (name, semi) {
5062 bp.commit();
5063 span.expand(p.last_span());
5064
5065 let dims = Vec::default();
5066 let ty = Type::new(
5067 span,
5068 TypeData {
5069 kind: TypeKind::new(
5070 span,
5071 ast::ForwardType {
5072 kind: Box::new(TypeKind::new(span, ImplicitType)),
5073 },
5074 ),
5075 sign: TypeSign::None,
5076 dims: Vec::default(),
5077 },
5078 );
5079 return Ok(Typedef::new(span, TypedefData { name, ty, dims }));
5080 }
5081 }
5082
5083 let mut ty = parse_explicit_type(p)?;
5084 let ident_name = parse_identifier_name(p, "type name")?;
5085 let (dims, _) = parse_optional_dimensions(p)?;
5086 p.require_reported(Semicolon)?;
5087 span.expand(p.last_span());
5088 Ok(Typedef::new(
5089 span,
5090 TypedefData {
5091 name: ident_name,
5092 ty: ty,
5093 dims: dims,
5094 },
5095 ))
5096}
5097
5098fn parse_port_decl<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<PortDecl<'n>> {
5099 let mut span = p.peek(0).1;
5100
5101 let dir = match as_port_direction(p.peek(0).0) {
5103 Some(x) => {
5104 p.bump();
5105 x
5106 }
5107 None => {
5108 p.add_diag(
5109 DiagBuilder2::error("expected port direction (inout, input, output, or ref)")
5110 .span(span),
5111 );
5112 return Err(());
5113 }
5114 };
5115
5116 let kind = if let Some(ty) = as_net_type(p.peek(0).0) {
5118 p.bump();
5119 Some(VarKind::Net {
5120 ty,
5121 kind: NetKind::None,
5122 })
5123 } else if p.try_eat(Keyword(Kw::Var)) {
5124 Some(VarKind::Var)
5125 } else {
5126 None
5127 };
5128
5129 let mut pp = ParallelParser::new();
5131 pp.add("explicit type", |p| {
5132 let ty = parse_explicit_type(p)?;
5133 Ok((ty, tail(p)?))
5134 });
5135 pp.add("implicit type", |p| {
5136 let ty = parse_implicit_type(p)?;
5137 Ok((ty, tail(p)?))
5138 });
5139 let (ty, names) = pp.finish(p, "explicit or implicit type")?;
5140
5141 fn tail<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Vec<VarDeclName<'n>>> {
5142 let names = comma_list_nonempty(
5143 p,
5144 Semicolon,
5145 "port declaration",
5146 parse_variable_decl_assignment,
5147 )?;
5148 p.require_reported(Semicolon)?;
5149 Ok(names)
5150 }
5151
5152 span.expand(p.last_span());
5154 Ok(ast::PortDecl::new(
5155 span,
5156 ast::PortDeclData {
5157 dir,
5158 kind,
5159 ty,
5160 names,
5161 },
5162 ))
5163}
5164
5165fn as_net_type(tkn: Token) -> Option<NetType> {
5166 match tkn {
5167 Keyword(Kw::Supply0) => Some(NetType::Supply0),
5168 Keyword(Kw::Supply1) => Some(NetType::Supply1),
5169 Keyword(Kw::Tri) => Some(NetType::Tri),
5170 Keyword(Kw::Triand) => Some(NetType::TriAnd),
5171 Keyword(Kw::Trior) => Some(NetType::TriOr),
5172 Keyword(Kw::Trireg) => Some(NetType::TriReg),
5173 Keyword(Kw::Tri0) => Some(NetType::Tri0),
5174 Keyword(Kw::Tri1) => Some(NetType::Tri1),
5175 Keyword(Kw::Uwire) => Some(NetType::Uwire),
5176 Keyword(Kw::Wire) => Some(NetType::Wire),
5177 Keyword(Kw::Wand) => Some(NetType::WireAnd),
5178 Keyword(Kw::Wor) => Some(NetType::WireOr),
5179 _ => None,
5180 }
5181}
5182
5183fn parse_net_decl<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<NetDecl<'n>> {
5184 let mut span = p.peek(0).1;
5185
5186 let net_type = match as_net_type(p.peek(0).0) {
5188 Some(x) => {
5189 p.bump();
5190 x
5191 }
5192 None => {
5193 let q = p.peek(0).1;
5194 p.add_diag(DiagBuilder2::error("expected net type").span(q));
5195 return Err(());
5196 }
5197 };
5198
5199 let strength = try_flanked(p, Paren, parse_net_strength)?;
5201
5202 let kind = match p.peek(0).0 {
5204 Keyword(Kw::Vectored) => {
5205 p.bump();
5206 NetKind::Vectored
5207 }
5208 Keyword(Kw::Scalared) => {
5209 p.bump();
5210 NetKind::Scalared
5211 }
5212 _ => NetKind::None,
5213 };
5214
5215 let mut pp = ParallelParser::new();
5217 pp.add("explicit type", |p| {
5218 let ty = parse_explicit_type(p)?;
5219 Ok((ty, tail(p)?))
5220 });
5221 pp.add("implicit type", |p| {
5222 let ty = parse_implicit_type(p)?;
5223 Ok((ty, tail(p)?))
5224 });
5225 let (ty, (delay, names)) = pp.finish(p, "explicit or implicit type")?;
5226
5227 fn tail<'n>(
5229 p: &mut dyn AbstractParser<'n>,
5230 ) -> ReportedResult<(Option<DelayControl<'n>>, Vec<VarDeclName<'n>>)> {
5231 let delay = try_delay_control(p)?;
5233
5234 let names = comma_list_nonempty(
5236 p,
5237 Semicolon,
5238 "net declaration",
5239 parse_variable_decl_assignment,
5240 )?;
5241 p.require_reported(Semicolon)?;
5242 Ok((delay, names))
5243 }
5244
5245 span.expand(p.last_span());
5246 Ok(ast::NetDecl::new(
5247 span,
5248 ast::NetDeclData {
5249 net_type,
5250 strength,
5251 kind,
5252 ty,
5253 delay,
5254 names,
5255 },
5256 ))
5257}
5258
5259fn try_drive_strength<'n>(
5260 p: &mut dyn AbstractParser<'n>,
5261) -> ReportedResult<Option<(DriveStrength, DriveStrength)>> {
5262 if let Some(a) = as_drive_strength(p.peek(0).0) {
5263 p.bump();
5264 p.require_reported(Comma)?;
5265 if let Some(b) = as_drive_strength(p.peek(0).0) {
5266 p.bump();
5267 Ok(Some((a, b)))
5268 } else {
5269 let q = p.peek(0).1;
5270 p.add_diag(DiagBuilder2::error("expected second drive strength").span(q));
5271 Err(())
5272 }
5273 } else {
5274 Ok(None)
5275 }
5276}
5277
5278fn parse_net_strength<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<NetStrength> {
5279 if let Some((a, b)) = try_drive_strength(p)? {
5280 Ok(NetStrength::Drive(a, b))
5281 } else if let Some(s) = as_charge_strength(p.peek(0).0) {
5282 p.bump();
5283 Ok(NetStrength::Charge(s))
5284 } else {
5285 let q = p.peek(0).1;
5286 p.add_diag(DiagBuilder2::error("expected drive or charge strength").span(q));
5287 Err(())
5288 }
5289}
5290
5291fn as_drive_strength(tkn: Token) -> Option<DriveStrength> {
5292 match tkn {
5293 Keyword(Kw::Supply0) => Some(DriveStrength::Supply0),
5294 Keyword(Kw::Strong0) => Some(DriveStrength::Strong0),
5295 Keyword(Kw::Pull0) => Some(DriveStrength::Pull0),
5296 Keyword(Kw::Weak0) => Some(DriveStrength::Weak0),
5297 Keyword(Kw::Highz0) => Some(DriveStrength::HighZ0),
5298 Keyword(Kw::Supply1) => Some(DriveStrength::Supply1),
5299 Keyword(Kw::Strong1) => Some(DriveStrength::Strong1),
5300 Keyword(Kw::Pull1) => Some(DriveStrength::Pull1),
5301 Keyword(Kw::Weak1) => Some(DriveStrength::Weak1),
5302 Keyword(Kw::Highz1) => Some(DriveStrength::HighZ1),
5303 _ => None,
5304 }
5305}
5306
5307fn as_charge_strength(tkn: Token) -> Option<ChargeStrength> {
5308 match tkn {
5309 Keyword(Kw::Small) => Some(ChargeStrength::Small),
5310 Keyword(Kw::Medium) => Some(ChargeStrength::Medium),
5311 Keyword(Kw::Large) => Some(ChargeStrength::Large),
5312 _ => None,
5313 }
5314}
5315
5316fn parse_dpi_decl<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ast::DpiDecl<'n>> {
5323 let mut span = p.peek(0).1;
5324
5325 let data = if p.try_eat(Keyword(Kw::Import)) {
5326 let spec = parse_string_literal(p, "DPI specifier string")?;
5327 let property = if p.try_eat(Keyword(Kw::Context)) {
5328 Some(Spanned::new(ast::DpiProperty::Context, p.last_span()))
5329 } else if p.try_eat(Keyword(Kw::Pure)) {
5330 Some(Spanned::new(ast::DpiProperty::Pure, p.last_span()))
5331 } else {
5332 None
5333 };
5334 let cident = if let Some(ident) = try_identifier_name(p)? {
5335 p.require_reported(Operator(Op::Assign))?;
5336 Some(ident)
5337 } else {
5338 None
5339 };
5340 let prototype = parse_subroutine_prototype(p)?;
5341 ast::DpiDeclData::Import {
5343 spec,
5344 property,
5345 cident,
5346 prototype,
5347 }
5348 } else if p.try_eat(Keyword(Kw::Export)) {
5349 let spec = parse_string_literal(p, "DPI specifier string")?;
5350 let cident = if let Some(ident) = try_identifier_name(p)? {
5351 p.require_reported(Operator(Op::Assign))?;
5352 Some(ident)
5353 } else {
5354 None
5355 };
5356 let kind = parse_subroutine_kind(p)?;
5357 let name = parse_identifier_name(p, "DPI task/function name")?;
5358 p.require_reported(Semicolon)?;
5359 ast::DpiDeclData::Export {
5360 spec,
5361 cident,
5362 kind,
5363 name,
5364 }
5365 } else {
5366 let span = p.peek(0).1;
5367 p.add_diag(
5368 DiagBuilder2::error("expected `import` or `export` at the start of a DPI declaration")
5369 .span(span),
5370 );
5371 return Err(());
5372 };
5373
5374 span.expand(p.last_span());
5375 Ok(ast::DpiDecl::new(span, data))
5376}
5377
5378fn parse_import_decl<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ImportDecl<'n>> {
5384 let mut span = p.peek(0).1;
5385 p.require_reported(Keyword(Kw::Import))?;
5386 let items = comma_list_nonempty(p, Semicolon, "import item", |p| {
5387 let mut span = p.peek(0).1;
5390 let pkg = parse_identifier_name(p, "package name")?;
5391 p.require_reported(Namespace)?;
5392 let (tkn, sp) = p.peek(0);
5393 match tkn {
5394 Operator(Op::Mul) => {
5396 p.bump();
5397 span.expand(p.last_span());
5398 Ok(ImportItem::new(span, ImportItemData { pkg, name: None }))
5399 }
5400
5401 Ident(n) | EscIdent(n) => {
5403 p.bump();
5404 span.expand(p.last_span());
5405 Ok(ImportItem::new(
5406 span,
5407 ImportItemData {
5408 pkg,
5409 name: Some(Spanned::new(n, sp)),
5410 },
5411 ))
5412 }
5413
5414 _ => {
5415 p.add_diag(
5416 DiagBuilder2::error(
5417 "expected identifier or `*` after `::` in import declaration",
5418 )
5419 .span(sp),
5420 );
5421 Err(())
5422 }
5423 }
5424 })?;
5425 p.require_reported(Semicolon)?;
5426 span.expand(p.last_span());
5427 Ok(ImportDecl::new(span, ImportDeclData { items }))
5428}
5429
5430fn parse_assertion<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Assertion<'n>> {
5431 let mut span = p.peek(0).1;
5432
5433 let null = get_name_table().intern("0", false);
5437 let is_property = p.peek(1).0 == Keyword(Kw::Property);
5438 let is_sequence = p.peek(1).0 == Keyword(Kw::Sequence);
5439 let is_deferred_observed = p.peek(1).0 == Hashtag && p.peek(2).0 == Literal(Number(null, None));
5440 let is_deferred_final = p.peek(1).0 == Keyword(Kw::Final);
5441 let is_deferred = is_deferred_observed || is_deferred_final;
5442 let deferred_mode = match is_deferred_final {
5443 true => AssertionDeferred::Final,
5444 false => AssertionDeferred::Observed,
5445 };
5446
5447 let data = match p.peek(0).0 {
5450 Keyword(Kw::Assert) if is_property => {
5455 p.bump();
5456 p.bump();
5457 let prop = flanked(p, Paren, parse_property_spec)?;
5458 let action = parse_assertion_action_block(p)?;
5459 AssertionData::Concurrent(ConcurrentAssertion::AssertProperty(prop, action))
5460 }
5461
5462 Keyword(Kw::Assume) if is_property => {
5464 p.bump();
5465 p.bump();
5466 let prop = flanked(p, Paren, parse_property_spec)?;
5467 let action = parse_assertion_action_block(p)?;
5468 AssertionData::Concurrent(ConcurrentAssertion::AssumeProperty(prop, action))
5469 }
5470
5471 Keyword(Kw::Cover) if is_property => {
5473 p.bump();
5474 p.bump();
5475 let prop = flanked(p, Paren, parse_property_spec)?;
5476 let stmt = parse_stmt(p)?;
5477 AssertionData::Concurrent(ConcurrentAssertion::CoverProperty(prop, stmt))
5478 }
5479
5480 Keyword(Kw::Cover) if is_sequence => {
5482 p.bump();
5483 p.bump();
5484 p.add_diag(DiagBuilder2::error("Don't know how to parse cover sequences").span(span));
5485 return Err(());
5486 }
5488
5489 Keyword(Kw::Expect) => {
5491 p.bump();
5492 let prop = flanked(p, Paren, parse_property_spec)?;
5493 let action = parse_assertion_action_block(p)?;
5494 AssertionData::Concurrent(ConcurrentAssertion::ExpectProperty(prop, action))
5495 }
5496
5497 Keyword(Kw::Restrict) if is_property => {
5499 p.bump();
5500 p.bump();
5501 let prop = flanked(p, Paren, parse_property_spec)?;
5502 AssertionData::Concurrent(ConcurrentAssertion::RestrictProperty(prop))
5503 }
5504
5505 Keyword(Kw::Assert) => {
5510 p.bump();
5511 if is_deferred {
5512 p.bump();
5513 if is_deferred_observed {
5514 p.bump();
5515 }
5516 }
5517 let expr = flanked(p, Paren, parse_expr)?;
5518 let action = parse_assertion_action_block(p)?;
5519 let a = BlockingAssertion::Assert(expr, action);
5520 if is_deferred {
5521 AssertionData::Deferred(deferred_mode, a)
5522 } else {
5523 AssertionData::Immediate(a)
5524 }
5525 }
5526
5527 Keyword(Kw::Assume) => {
5529 p.bump();
5530 if is_deferred {
5531 p.bump();
5532 if is_deferred_observed {
5533 p.bump();
5534 }
5535 }
5536 let expr = flanked(p, Paren, parse_expr)?;
5537 let action = parse_assertion_action_block(p)?;
5538 let a = BlockingAssertion::Assume(expr, action);
5539 if is_deferred {
5540 AssertionData::Deferred(deferred_mode, a)
5541 } else {
5542 AssertionData::Immediate(a)
5543 }
5544 }
5545
5546 Keyword(Kw::Cover) => {
5548 p.bump();
5549 if is_deferred {
5550 p.bump();
5551 if is_deferred_observed {
5552 p.bump();
5553 }
5554 }
5555 let expr = flanked(p, Paren, parse_expr)?;
5556 let stmt = parse_stmt(p)?;
5557 let a = BlockingAssertion::Cover(expr, stmt);
5558 if is_deferred {
5559 AssertionData::Deferred(deferred_mode, a)
5560 } else {
5561 AssertionData::Immediate(a)
5562 }
5563 }
5564
5565 _ => {
5566 p.add_diag(
5567 DiagBuilder2::error("expected assert, assume, cover, expect, or restrict")
5568 .span(span),
5569 );
5570 return Err(());
5571 }
5572 };
5573
5574 span.expand(p.last_span());
5575 Ok(Assertion {
5576 span: span,
5577 label: None,
5578 data: data,
5579 })
5580}
5581
5582fn parse_assertion_action_block<'n>(
5583 p: &mut dyn AbstractParser<'n>,
5584) -> ReportedResult<AssertionActionBlock<'n>> {
5585 if p.try_eat(Keyword(Kw::Else)) {
5586 Ok(AssertionActionBlock::Negative(parse_stmt(p)?))
5587 } else {
5588 let stmt = parse_stmt(p)?;
5589 if p.try_eat(Keyword(Kw::Else)) {
5590 Ok(AssertionActionBlock::Both(stmt, parse_stmt(p)?))
5592 } else {
5593 Ok(AssertionActionBlock::Positive(stmt))
5594 }
5595 }
5596}
5597
5598fn parse_property_spec<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<PropSpec> {
5599 let mut span = p.peek(0).1;
5600
5601 p.recover_balanced(&[CloseDelim(Paren)], false);
5603 return Ok(PropSpec);
5604
5605 }
5624
5625#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
5626#[allow(dead_code)]
5627enum PropSeqPrecedence {
5628 Min,
5629 AlEvIfAccRejSyn,
5630 ImplFollow, Until, Iff, Or, And, NotNexttime,
5636 Intersect, Within, Throughout, CycleDelay, Brack,
5641 Max,
5642}
5643
5644fn parse_propexpr<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<PropExpr<'n>> {
5645 parse_propexpr_prec(p, PropSeqPrecedence::Min)
5646}
5647
5648fn parse_propexpr_prec<'n>(
5649 p: &mut dyn AbstractParser<'n>,
5650 precedence: PropSeqPrecedence,
5651) -> ReportedResult<PropExpr<'n>> {
5652 let mut span = p.peek(0).1;
5653
5654 let mut pp = ParallelParser::new();
5668 pp.add_greedy("sequence expression", move |p| {
5669 parse_propexpr_seq(p, precedence)
5670 });
5671 pp.add_greedy("property expression", move |p| {
5672 parse_propexpr_nonseq(p, precedence)
5673 });
5674 let data = pp.finish(p, "sequence or primary property expression")?;
5675
5676 span.expand(p.last_span());
5677 let expr = PropExpr {
5678 span: span,
5679 data: data,
5680 };
5681 parse_propexpr_suffix(p, expr, precedence)
5682}
5683
5684fn parse_propexpr_nonseq<'n>(
5685 p: &mut dyn AbstractParser<'n>,
5686 precedence: PropSeqPrecedence,
5687) -> ReportedResult<PropExprData<'n>> {
5688 match p.peek(0).0 {
5690 OpenDelim(Paren) => return flanked(p, Paren, parse_propexpr).map(|pe| pe.data),
5692
5693 Keyword(Kw::Not) => {
5695 p.bump();
5696 let expr = parse_propexpr_prec(p, PropSeqPrecedence::NotNexttime)?;
5697 return Ok(PropExprData::Not(Box::new(expr)));
5698 }
5699
5700 At => {
5702 p.bump();
5703 let ev = parse_event_expr(p, EventPrecedence::Min)?;
5704 let expr = parse_propexpr(p)?;
5705 return Ok(PropExprData::Clocked(ev, Box::new(expr)));
5706 }
5707
5708 _ => {
5709 let q = p.peek(0).1;
5710 p.add_diag(DiagBuilder2::error("expected primary property expression").span(q));
5711 return Err(());
5712 }
5713 }
5714}
5715
5716fn parse_propexpr_seq<'n>(
5717 p: &mut dyn AbstractParser<'n>,
5718 precedence: PropSeqPrecedence,
5719) -> ReportedResult<PropExprData<'n>> {
5720 let (seqop, seqexpr) = match p.peek(0).0 {
5722 Keyword(Kw::Strong) => {
5723 p.bump();
5724 (PropSeqOp::Strong, flanked(p, Paren, parse_seqexpr)?)
5725 }
5726 Keyword(Kw::Weak) => {
5727 p.bump();
5728 (PropSeqOp::Weak, flanked(p, Paren, parse_seqexpr)?)
5729 }
5730 _ => (PropSeqOp::None, parse_seqexpr_prec(p, precedence)?),
5731 };
5732
5733 if precedence <= PropSeqPrecedence::ImplFollow {
5736 if let Some(op) = match p.peek(0).0 {
5737 Operator(Op::SeqImplOl) => Some(PropSeqBinOp::ImplOverlap),
5738 Operator(Op::SeqImplNol) => Some(PropSeqBinOp::ImplNonoverlap),
5739 Operator(Op::SeqFollowOl) => Some(PropSeqBinOp::FollowOverlap),
5740 Operator(Op::SeqFollowNol) => Some(PropSeqBinOp::FollowNonoverlap),
5741 _ => None,
5742 } {
5743 p.bump();
5744 let expr = parse_propexpr_prec(p, PropSeqPrecedence::ImplFollow)?;
5745 return Ok(PropExprData::SeqBinOp(op, seqop, seqexpr, Box::new(expr)));
5746 }
5747 }
5748
5749 Ok(PropExprData::SeqOp(seqop, seqexpr))
5751}
5752
5753fn parse_propexpr_suffix<'n>(
5754 p: &mut dyn AbstractParser<'n>,
5755 prefix: PropExpr<'n>,
5756 precedence: PropSeqPrecedence,
5757) -> ReportedResult<PropExpr<'n>> {
5758 if let Some((op, prec, rassoc)) = match p.peek(0).0 {
5761 Keyword(Kw::Or) => Some((PropBinOp::Or, PropSeqPrecedence::Or, false)),
5762 Keyword(Kw::And) => Some((PropBinOp::And, PropSeqPrecedence::And, false)),
5763 Keyword(Kw::Until) => Some((PropBinOp::Until, PropSeqPrecedence::Until, true)),
5764 Keyword(Kw::SUntil) => Some((PropBinOp::SUntil, PropSeqPrecedence::Until, true)),
5765 Keyword(Kw::UntilWith) => Some((PropBinOp::UntilWith, PropSeqPrecedence::Until, true)),
5766 Keyword(Kw::SUntilWith) => Some((PropBinOp::SUntilWith, PropSeqPrecedence::Until, true)),
5767 Keyword(Kw::Implies) => Some((PropBinOp::Impl, PropSeqPrecedence::Until, true)),
5768 Keyword(Kw::Iff) => Some((PropBinOp::Iff, PropSeqPrecedence::Iff, true)),
5769 _ => None,
5770 } {
5771 if precedence < prec || (rassoc && precedence == prec) {
5772 p.bump();
5773 let rhs = parse_propexpr_prec(p, prec)?;
5774 return Ok(PropExpr {
5775 span: Span::union(prefix.span, rhs.span),
5776 data: PropExprData::BinOp(op, Box::new(prefix), Box::new(rhs)),
5777 });
5778 }
5779 }
5780
5781 Ok(prefix)
5782}
5783
5784fn parse_seqexpr<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<SeqExpr<'n>> {
5785 parse_seqexpr_prec(p, PropSeqPrecedence::Min)
5786}
5787
5788fn parse_seqexpr_prec<'n>(
5789 p: &mut dyn AbstractParser<'n>,
5790 precedence: PropSeqPrecedence,
5791) -> ReportedResult<SeqExpr<'n>> {
5792 let mut span = p.peek(0).1;
5793
5794 let mut pp = ParallelParser::new();
5797 pp.add_greedy("expression", move |p| parse_seqexpr_expr(p, precedence));
5798 pp.add_greedy("sequence", move |p| parse_seqexpr_nonexpr(p, precedence));
5799 let data = pp.finish(p, "sequence or primary property expression")?;
5800
5801 span.expand(p.last_span());
5802 let expr = SeqExpr {
5803 span: span,
5804 data: data,
5805 };
5806 parse_seqexpr_suffix(p, expr, precedence)
5807}
5808
5809fn parse_seqexpr_expr<'n>(
5810 p: &mut dyn AbstractParser<'n>,
5811 precedence: PropSeqPrecedence,
5812) -> ReportedResult<SeqExprData<'n>> {
5813 let q = p.peek(0).1;
5815 p.add_diag(
5816 DiagBuilder2::error(
5817 "Don't know how to parse sequence expression that don't start with an expression",
5818 )
5819 .span(q),
5820 );
5821 Err(())
5822}
5823
5824fn parse_seqexpr_nonexpr<'n>(
5825 p: &mut dyn AbstractParser<'n>,
5826 precedence: PropSeqPrecedence,
5827) -> ReportedResult<SeqExprData<'n>> {
5828 let expr = parse_expr(p)?;
5831
5832 if precedence <= PropSeqPrecedence::Throughout && p.try_eat(Keyword(Kw::Throughout)) {
5835 let rhs = parse_seqexpr_prec(p, PropSeqPrecedence::Throughout)?;
5836 return Ok(SeqExprData::Throughout(expr, Box::new(rhs)));
5837 }
5838
5839 let rep = try_flanked(p, Brack, parse_seqrep)?;
5841
5842 Ok(SeqExprData::Expr(expr, rep))
5843}
5844
5845fn parse_seqexpr_suffix<'n>(
5846 p: &mut dyn AbstractParser<'n>,
5847 prefix: SeqExpr<'n>,
5848 precedence: PropSeqPrecedence,
5849) -> ReportedResult<SeqExpr<'n>> {
5850 Ok(prefix)
5852}
5853
5854fn parse_seqrep<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<SeqRep<'n>> {
5855 match p.peek(0).0 {
5856 Operator(Op::Mul) => {
5859 p.bump();
5860 if p.peek(0).0 == CloseDelim(Brack) {
5861 Ok(SeqRep::ConsecStar)
5862 } else {
5863 Ok(SeqRep::Consec(parse_expr(p)?))
5864 }
5865 }
5866
5867 Operator(Op::Add) => {
5869 p.bump();
5870 Ok(SeqRep::ConsecPlus)
5871 }
5872
5873 Operator(Op::Assign) => {
5875 p.bump();
5876 Ok(SeqRep::Nonconsec(parse_expr(p)?))
5877 }
5878
5879 Operator(Op::LogicImpl) => {
5881 p.bump();
5882 Ok(SeqRep::Goto(parse_expr(p)?))
5883 }
5884
5885 _ => {
5886 let q = p.peek(0).1;
5887 p.add_diag(
5888 DiagBuilder2::error(
5889 "expected sequence repetition [+], [*], [* <expr>], [= <expr>], or [-> <expr>]",
5890 )
5891 .span(q),
5892 );
5893 Err(())
5894 }
5895 }
5896}
5897
5898fn parse_inst<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ast::Inst<'n>> {
5899 let mut span = p.peek(0).1;
5900
5901 let target = parse_identifier_name(p, "module name")?;
5903 let params = if p.try_eat(Hashtag) {
5907 parse_parameter_assignments(p)?
5908 } else {
5909 Vec::new()
5910 };
5911
5912 let names = comma_list_nonempty(p, Semicolon, "hierarchical instance", |p| {
5914 let mut span = p.peek(0).1;
5915 let name = parse_identifier_name(p, "instance name")?;
5916 let (dims, _) = parse_optional_dimensions(p)?;
5917 let conns = flanked(p, Paren, parse_list_of_port_connections)?;
5918 span.expand(p.last_span());
5919 Ok(ast::InstName::new(
5920 span,
5921 ast::InstNameData { name, dims, conns },
5922 ))
5923 })?;
5924
5925 p.require_reported(Semicolon)?;
5926 span.expand(p.last_span());
5927 Ok(ast::Inst::new(
5928 span,
5929 ast::InstData {
5930 target,
5931 params,
5932 names,
5933 },
5934 ))
5935}
5936
5937fn parse_var_decl<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ast::VarDecl<'n>> {
5938 let mut span = p.peek(0).1;
5939
5940 let konst = p.try_eat(Keyword(Kw::Const));
5942
5943 let var = p.try_eat(Keyword(Kw::Var));
5945
5946 let lifetime = as_lifetime(p.peek(0).0);
5948 if lifetime.is_some() {
5949 p.bump();
5950 }
5951
5952 let mut pp = ParallelParser::new();
5956 pp.add("explicit type", |p| {
5957 let ty = parse_explicit_type(p)?;
5958 Ok((ty, tail(p)?))
5959 });
5960 if var {
5961 pp.add("implicit type", |p| {
5962 let ty = parse_implicit_type(p)?;
5963 Ok((ty, tail(p)?))
5964 });
5965 }
5966 let (ty, names) = pp.finish(p, "explicit or implicit type")?;
5967
5968 fn tail<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Vec<VarDeclName<'n>>> {
5969 let names = comma_list_nonempty(
5970 p,
5971 Semicolon,
5972 "variable name",
5973 parse_variable_decl_assignment,
5974 )?;
5975 p.require_reported(Semicolon)?;
5976 Ok(names)
5977 }
5978
5979 span.expand(p.last_span());
5980 Ok(ast::VarDecl::new(
5981 span,
5982 ast::VarDeclData {
5983 konst: konst,
5984 var: var,
5985 lifetime: lifetime,
5986 ty: ty,
5987 names: names,
5988 },
5989 ))
5990}
5991
5992fn parse_param_decl<'n>(
5993 p: &mut dyn AbstractParser<'n>,
5994 keyword_optional: bool,
5995) -> ReportedResult<ast::ParamDecl<'n>> {
5996 let mut span = p.peek(0).1;
5997
5998 let local = match p.peek(0) {
6002 (Keyword(Kw::Localparam), _) => {
6003 p.bump();
6004 true
6005 }
6006 (Keyword(Kw::Parameter), _) => {
6007 p.bump();
6008 false
6009 }
6010 (_, _) if keyword_optional => false,
6011 (tkn, sp) => {
6012 p.add_diag(
6013 DiagBuilder2::error(format!(
6014 "expected `parameter` or `localparam`, but found {} instead",
6015 tkn
6016 ))
6017 .span(sp),
6018 );
6019 return Err(());
6020 }
6021 };
6022
6023 let predicate = FuncPredicate {
6033 match_func: |p| match p.peek(0).0 {
6034 Semicolon | CloseDelim(Paren) => true,
6035 Comma => match p.peek(1).0 {
6036 Keyword(Kw::Parameter) | Keyword(Kw::Localparam) => true,
6037 _ => false,
6038 },
6039 _ => false,
6040 },
6041 recover_func: |p, consume| p.recover_balanced(&[CloseDelim(Paren), Semicolon], consume),
6042 desc: ") or ;",
6043 };
6044
6045 let kind = if p.try_eat(Keyword(Kw::Type)) {
6048 let decls = comma_list_nonempty(p, predicate, "parameter name", |p| {
6049 let mut span = p.peek(0).1;
6050 let name = parse_identifier_name(p, "parameter name")?;
6051 let ty = if p.try_eat(Operator(Op::Assign)) {
6052 Some(parse_explicit_type(p)?)
6053 } else {
6054 None
6055 };
6056 p.anticipate(&[Semicolon, Comma, CloseDelim(Paren)])?;
6057 span.expand(p.last_span());
6058 Ok(ast::ParamTypeDecl::new(
6059 span,
6060 ast::ParamTypeDeclData { name, ty },
6061 ))
6062 })?;
6063 p.anticipate(&[Semicolon, Comma, CloseDelim(Paren)])?;
6064 ast::ParamKind::Type(decls)
6065 } else {
6066 let decls = comma_list_nonempty(p, predicate, "parameter name", |p| {
6067 let mut pp = ParallelParser::new();
6070 pp.add("explicit type", |p| {
6071 let ty = parse_explicit_type(p)?;
6072 tail(p, ty)
6073 });
6074 pp.add("implicit type", |p| {
6075 let ty = parse_implicit_type(p)?;
6076 tail(p, ty)
6077 });
6078
6079 fn tail<'n>(
6080 p: &mut dyn AbstractParser<'n>,
6081 ty: Type<'n>,
6082 ) -> ReportedResult<ast::ParamValueDecl<'n>> {
6083 let mut span = p.peek(0).1;
6084 let name = parse_identifier_name(p, "parameter name")?;
6085 let (dims, _) = parse_optional_dimensions(p)?;
6086 let expr = if p.try_eat(Operator(Op::Assign)) {
6087 Some(parse_expr(p)?)
6088 } else {
6089 None
6090 };
6091 p.anticipate(&[Semicolon, Comma, CloseDelim(Paren)])?;
6092 span.expand(p.last_span());
6093 Ok(ast::ParamValueDecl::new(
6094 span,
6095 ast::ParamValueDeclData {
6096 ty,
6097 name,
6098 dims,
6099 expr,
6100 },
6101 ))
6102 }
6103
6104 pp.finish(p, "explicit or implicit type")
6105 })?;
6106 p.anticipate(&[Semicolon, Comma, CloseDelim(Paren)])?;
6107 ast::ParamKind::Value(decls)
6108 };
6109
6110 span.expand(p.last_span());
6111 Ok(ast::ParamDecl::new(
6112 span,
6113 ast::ParamDeclData { local, kind },
6114 ))
6115}
6116
6117fn parse_hname<'n>(p: &mut dyn AbstractParser<'n>, msg: &str) -> ReportedResult<ast::Identifier> {
6118 parse_identifier(p, msg)
6119}
6120
6121fn try_builtin_system_task<'n>(
6122 p: &mut dyn AbstractParser<'n>,
6123 name: Spanned<Name>,
6124 mut span: Span,
6125) -> ReportedResult<Option<Expr<'n>>> {
6126 Ok(match name.value.as_str().as_ref() {
6127 "bits" => {
6129 let arg = flanked(p, Paren, |p| parse_type_or_expr(p, &[CloseDelim(Paren)]))?;
6130 span.expand(p.last_span());
6131 Some(ast::Expr::new(span, ast::BitsExpr { name, arg }))
6132 }
6133 _ => None,
6134 })
6135}