moore_svlog_syntax/
parser.rs

1// Copyright (c) 2016-2021 Fabian Schuiki
2
3//! A parser for the SystemVerilog language. Based on IEEE 1800-2009.
4
5#![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
17// The problem with data_declaration and data_type_or_implicit:
18//
19//     [7:0] foo;            # implicit "[7:0]", var "foo"
20//     foo bar;              # explicit "foo", var "bar"
21//     foo [7:0];            # implicit, var "foo[7:0]"
22//     foo [7:0] bar [7:0];  # explicit "foo[7:0]", var "bar[7:0]"
23
24/// Return type of the lower parse primitives, allowing for further adjustment
25/// of the diagnostic message that would be generated.
26type ParseResult<T> = Result<T, DiagBuilder2>;
27
28/// Return type of functions that emit diagnostic messages and only need to
29/// communicate success to the parent.
30type ReportedResult<T> = Result<T, ()>;
31
32/// An abstraction around concrete parsers.
33///
34/// The lifetime `'n` represents nodes allocated into the the AST node arena.
35trait 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(&mut self, terminators: &[Token], eat_terminator: bool) {
136    //  // println!("recovering to {:?}", terminators);
137    //  loop {
138    //      match self.peek(0) {
139    //          (Eof, _) => return,
140    //          (tkn, _) => {
141    //              for t in terminators {
142    //                  if *t == tkn {
143    //                      if eat_terminator {
144    //                          self.skip();
145    //                      }
146    //                      return;
147    //                  }
148    //              }
149    //              self.skip();
150    //          }
151    //      }
152    //  }
153    // }
154
155    fn recover_balanced(&mut self, terminators: &[Token], eat_terminator: bool) {
156        // println!("recovering (balanced) to {:?}", terminators);
157        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        // Emit a backtrace for this diagnostic.
286        if diag.get_severity() >= Severity::Warning {
287            trace!(
288                "Diagnostic triggered here:\n{:?}",
289                backtrace::Backtrace::new()
290            );
291        }
292
293        // Keep track of the worst diagnostic severity we've encountered, such
294        // that parsing can be aborted accordingly.
295        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
333/// Parses the opening delimiter, calls the `inner` function, and parses the
334/// closing delimiter. Properly recovers to and including the closing
335/// delimiter if the `inner` function throws an error.
336fn 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
360/// If the opening delimiter is present, consumes it, calls the `inner`
361/// function, and parses the closing delimiter. Properly recovers to and
362/// including the closing delimiter if the `inner` function throws an error.
363/// If the opening delimiter is not present, returns `None`.
364fn 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
379/// Parse a comma-separated list of items, until a terminator token has been
380/// reached. The terminator is not consumed.
381fn 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        // Parse the item.
394        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        // Try to match the terminator. If it does not, consume a comma and
403        // catch the case where the comma is immediately followed by the
404        // terminator (superfluous terminator).
405        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
426/// Same as `comma_list`, but at least one item is required.
427fn 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/// Speculatively apply a parse function. If it fails, the parser `p` is left
486/// untouched. If it succeeds, `p` is in the same state as if `parse` was called
487/// on it directly. Use a ParallelParser for better error reporting.
488#[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
503/// Consumes a `Ident` or `EscIdent` token, wrapping it in a `ast::Identifier`.
504fn 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
514/// Consumes a `Ident` or `EscIdent` token, wrapping it in a `Spanned<Name>`.
515fn 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
535/// Consumes a string literal token, wrapping it in a `Spanned<Name>`.
536fn 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    // Parse the optional timeunits declaration.
646    match parse_time_units(p) {
647        Ok(x) => root.timeunits = x,
648        Err(()) => (),
649    }
650
651    // Parse the descriptions in the source text.
652    while !p.is_fatal() && p.peek(0).0 != Eof {
653        match parse_item(p) {
654            Ok(item) => root.items.push(item),
655            Err(()) => (), // parse_item handles recovery, so no need to do anything here
656        }
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
703/// Convert a token to the corresponding lifetime. Yields `None` if the token
704/// does not correspond to a lifetime.
705fn 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        // Eat the optional lifetime.
718        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        // Eat the interface name.
727        let (name, name_sp) = p.eat_ident("interface name")?;
728
729        // TODO: Parse package import declarations.
730
731        // Eat the parameter port list.
732        let param_ports = if p.try_eat(Hashtag) {
733            parse_parameter_port_list(p)?
734        } else {
735            Vec::new()
736        };
737
738        // Eat the optional list of ports.
739        let ports = if p.try_eat(OpenDelim(Paren)) {
740            parse_port_list(p)?
741        } else {
742            Vec::new()
743        };
744
745        // Eat the semicolon at the end of the header.
746        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        // Eat the items in the interface.
758        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            // Parse the optional `parameter` or `localparam` keyword. If none is
793            // provided, the previous scope is assumed.
794            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            // If the next token is the `type` keyword, this is a type parameter.
808            // Otherwise this is a value parameter.
809            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                // Use a parallel parser to distinguish between the explicit and
825                // implicit type versions of the declaration.
826                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
873/// Parse a module declaration, assuming that the leading `module` keyword has
874/// already been consumed.
875fn 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        // Eat the optional lifetime.
880        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        // Eat the module name.
889        let (name, name_sp) = p.eat_ident("module name")?;
890
891        // Eat the optional package import declarations.
892        let mut imports = vec![];
893        while p.peek(0).0 == Keyword(Kw::Import) {
894            imports.push(parse_import_decl(p)?);
895        }
896
897        // Eat the optional parameter port list.
898        let params = if p.try_eat(Hashtag) {
899            parse_parameter_port_list(p)?
900        } else {
901            Vec::new()
902        };
903
904        // Eat the optional list of ports. Not having such a list requires the ports
905        // to be defined further down in the body of the module.
906        let ports = if p.try_eat(OpenDelim(Paren)) {
907            parse_port_list(p)?
908        } else {
909            Vec::new()
910        };
911
912        // Eat the semicolon after the header.
913        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        // Parse the module items.
922        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        // Parse the optional lifetime.
956        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        // Parse the package name.
965        let (name, name_span) = p.eat_ident("package name")?;
966        p.require_reported(Semicolon)?;
967
968        // Parse the package items.
969        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    // Consume optional leading label.
1014    if p.is_ident() && p.peek(1).0 == Colon {
1015        p.bump();
1016        p.bump();
1017    }
1018
1019    // First attempt the simple cases where a keyword reliably identifies the
1020    // following item.
1021    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        // Structured procedures as per IEEE 1800-2009 section 9.2
1051        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        // Port declarations
1074        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        // Continuous assign
1079        Keyword(Kw::Assign) => {
1080            return parse_continuous_assign(p).map(|x| ItemData::ContAssign(x));
1081        }
1082
1083        // Genvar declaration
1084        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        // Generate region and constructs
1092        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        // Assertions
1105        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        // Default clocking and disable declarations.
1116        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        // Unsupported constructs as of now.
1140        SysIdent(..) => return parse_elab_system_task(p).map(|_| ItemData::Dummy),
1141
1142        _ => (),
1143    }
1144
1145    // Handle the possibly ambiguous cases.
1146    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    // TODO: Parse data type or implicit type.
1178
1179    // Eat the list of parameter assignments.
1180    loop {
1181        // parameter_identifier { unpacked_dimension } [ = constant_param_expression ]
1182        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        // TODO: Eat the unpacked dimensions.
1191
1192        // Eat the optional assignment.
1193        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        // Eat the trailing comma or semicolon.
1201        match p.peek(0) {
1202            (Comma, sp) => {
1203                p.bump();
1204
1205                // A closing parenthesis indicates that the previous
1206                // comma was superfluous. Report the issue but continue
1207                // gracefully.
1208                if p.peek(0).0 == Semicolon {
1209                    // TODO: This should be an error in pedantic mode.
1210                    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    // Branch to try the explicit and implicit type version.
1232    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        // Consume the parameter name and optional dimensions.
1255        let (name, name_sp) = p.eat_ident("parameter name")?;
1256        let (dims, _) = parse_optional_dimensions(p)?;
1257
1258        // Parse the optional assignment.
1259        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
1270/// Parse a modport declaration.
1271///
1272/// ```text
1273/// modport_decl: "modport" modport_item {"," modport_item} ";"
1274/// modport_item: ident "(" modport_ports_decl {"," modport_ports_decl} ")"
1275/// modport_ports_decl:
1276///   port_direction modport_simple_port {"," modport_simple_port} |
1277///   ("import"|"export") modport_tf_port {"," modport_tf_port} |
1278///   "clocking" ident
1279/// modport_simple_port: ident | "." ident "(" [expr] ")"
1280/// ```
1281fn 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    // loop {
1291    //  parse_modport_item(p)?;
1292    //  match p.peek(0) {
1293    //      (Comma, sp) => {
1294    //          p.bump();
1295    //          if let (Semicolon, _) = p.peek(0) {
1296    //              p.add_diag(DiagBuilder2::warning("superfluous trailing comma").span(sp));
1297    //              break;
1298    //          } else {
1299    //              continue;
1300    //          }
1301    //      },
1302    //      (Semicolon, _) => break,
1303    //      (x, sp) => {
1304    //          p.add_diag(DiagBuilder2::error(format!("expected , or ; after modport declaration, got `{:?}`", x)).span(sp));
1305    //          return Err(());
1306    //      }
1307    //  }
1308    // }
1309
1310    // Ok(())
1311}
1312
1313/// Parse a modport item.
1314///
1315/// ```text
1316/// modport_item: ident "(" modport_ports_decl {"," modport_ports_decl} ")"
1317/// modport_ports_decl:
1318///   port_direction modport_simple_port {"," modport_simple_port} |
1319///   ("import"|"export") modport_tf_port {"," modport_tf_port} |
1320///   "clocking" ident
1321/// modport_simple_port: ident | "." ident "(" [expr] ")"
1322/// ```
1323fn 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    // Eat the modport item name.
1329    let name = parse_identifier_name(p, "modport name")?;
1330
1331    // Eat the port declarations.
1332    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
1348/// ```text
1349/// modport_ports_decl:
1350///   port_direction modport_simple_port {"," modport_simple_port} |
1351///   ("import"|"export") modport_tf_port {"," modport_tf_port} |
1352///   "clocking" ident
1353/// modport_simple_port: ident | "." ident "(" [expr] ")"
1354/// ```
1355fn 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    // Attempt to parse a simple port introduced by one of the port direction
1361    // keywords.
1362    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            // Decide whether we should continue iterating and thus consuming
1385            // more simple ports. According to the grammar, a comma followed by
1386            // a keyword indicates a different port declaration, so we abort.
1387            // Otherwise, if the next item is a comma still, we continue
1388            // iteration. In all other cases, we assume the port declaration to
1389            // be done.
1390            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    // Attempt to parse a TF port.
1407    if p.try_eat(Keyword(Kw::Import)) || p.try_eat(Keyword(Kw::Export)) {
1408        // TODO: Parse modport_tf_ports_declaration.
1409        p.add_diag(
1410            DiagBuilder2::error("modport task/function ports not implemented").span(p.last_span()),
1411        );
1412        return Err(());
1413    }
1414
1415    // Attempt to parse a clocking declaration.
1416    if p.try_eat(Keyword(Kw::Clocking)) {
1417        // TODO: Parse modport_clocking_declaration.
1418        p.add_diag(DiagBuilder2::error("modport clocking declaration not implemented").span(span));
1419        return Err(());
1420    }
1421
1422    // If we've come this far, none of the above matched.
1423    p.add_diag(DiagBuilder2::error("expected modport port declaration").span(span));
1424    Err(())
1425}
1426
1427/// Convert a token to the corresponding PortDir. The token may be one of the
1428/// keywords `input`, `output`, `inout`, or `ref`. Otherwise `None` is returned.
1429fn 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
1439/// Parse an implicit or explicit type. This is a catch-all function that will
1440/// always succeed unless one of the explicit types contains a syntax error. For
1441/// all other tokens the function will at least return an ImplicitType if none
1442/// could be consumed. You might have to use `parse_explicit_type` and
1443/// `parse_implicit_type` separately if the type is to be embedded in a larger
1444/// function. For example, a variable declaration with implicit type looks like
1445/// an explicit type at first glance. Only after reaching the trailing `[=,;]`
1446/// it becomes apparent that the explicit type was rather the name of the
1447/// variable. In this case, having to parallel parsers, one with explicit and
1448/// one with implicit type, can resolve the issue.
1449fn parse_data_type<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Type<'n>> {
1450    // Try to parse this as an explicit type.
1451    {
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    // Otherwise simply go with an implicit type, which basically always
1463    // succeeds.
1464    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        // Interfaces allow their internal modports and typedefs to be accessed
1480        // via the `.` operator.
1481        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        // The `::` operator.
1497        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        // Classes can be specialized with a parameter list.
1513        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
1534/// Parse an implicit type (`[signing] {dimensions}`).
1535fn 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
1540/// Parse the optional signing keyword and packed dimensions that may follow a
1541/// data type. Wraps a previously parsed TypeKind in a Type struct.
1542fn 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    // Package up the type kind.
1548    let kind = TypeKind::new(span, kind);
1549
1550    // Parse the optional sign information.
1551    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    // Parse the optional dimensions.
1564    let (dims, _) = parse_optional_dimensions(p)?;
1565    span.expand(p.last_span());
1566
1567    Ok(Type::new(span, TypeData { kind, sign, dims }))
1568}
1569
1570/// Parse the core type data of a type.
1571fn 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::Signed) => {
1591        //     p.bump();
1592        //     Ok(ast::ImplicitSignedType)
1593        // }
1594        // Keyword(Kw::Unsigned) => {
1595        //     p.bump();
1596        //     Ok(ast::ImplicitUnsignedType)
1597        // }
1598
1599        // Integer Vector Types
1600        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        // Integer Atom Types
1614        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        // Non-integer Types
1640        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        // Enumerations
1654        Keyword(Kw::Enum) => parse_enum_type(p),
1655        Keyword(Kw::Struct) | Keyword(Kw::Union) => parse_struct_type(p),
1656
1657        // Built-in types
1658        Ident(n) if &*n.as_str() == "mailbox" => {
1659            p.bump();
1660            Ok(ast::MailboxType)
1661        }
1662
1663        // Named types
1664        Ident(n) | EscIdent(n) => {
1665            p.bump();
1666            Ok(ast::NamedType(Spanned::new(n, sp)))
1667        }
1668
1669        // Virtual Interface Type
1670        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        // type_reference ::= `type` `(` expression `)`
1678        // type_reference ::= `type` `(` data_type `)`
1679        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    // Consume the enum keyword.
1697    p.bump();
1698
1699    // Parse the optional enum base type.
1700    let base = if p.peek(0).0 != OpenDelim(Brace) {
1701        Some(Box::new(parse_data_type(p)?))
1702    } else {
1703        None
1704    };
1705
1706    // Parse the name declarations.
1707    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    // Eat the name.
1725    let name = parse_identifier_name(p, "enum name")?;
1726
1727    // Parse the optional range.
1728    let range = try_flanked(p, Brack, parse_expr)?;
1729
1730    // Parse the optional value.
1731    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    // Consume the "struct", "union", or "union tagged" keywords.
1745    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    // Consume the optional "packed" keyword, followed by an optional signing
1768    // indication.
1769    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        // Parse the struct members.
1777        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        // Handle as forward declaration
1793        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    // Parse the optional random qualifier.
1816    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    // Parse the data type of the member.
1829    let ty = parse_data_type(p)?;
1830
1831    // Parse the list of names and assignments.
1832    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            // unsized_dimension ::= `[` `]`
1890            CloseDelim(Brack) => TypeDim::Unsized,
1891            // associative_dimension ::= `[` `*` `]`
1892            Operator(Op::Mul) => {
1893                p.bump();
1894                TypeDim::Associative(None)
1895            }
1896            // queue_dimension ::= `[` `$` `]`
1897            // queue_dimension ::= `[` `$` `:` constant_expression `]`
1898            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                // associative_dimension ::= '[' data_type ']'
1909                TypeOrExpr::Type(ty) => TypeDim::Associative(Some(ty.clone())),
1910                // unpacked_dimension ::= '[' constant_expression ']'
1911                // unpacked_dimension ::= '[' constant_range ']'
1912                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        // A period introduces a named port connection. Otherwise this is an
1934        // unnamed connection.
1935        let kind = if p.try_eat(Period) {
1936            if p.try_eat(Operator(Op::Mul)) {
1937                // handle .* case
1938                ast::PortConnData::Auto
1939            } else {
1940                let name = parse_identifier_name(p, "port name")?;
1941                // handle .name, .name(), and .name(expr) cases
1942                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
1961/// Parse either an expression or a type. Prefers expressions over types.
1962fn 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    // TODO: Keep track of the location here and pass that to the
1990    // parse_expr_first and parse_expr_suffix calls further down. This will
1991    // allow the spans of those expressions to properly reflect the full span of
1992    // the expression, mitigating the following issue:
1993    //
1994    // assign foo = (operator_i = ALU_ABS) ? operand_a_neg : operand_a_i;
1995    //               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1996    //
1997    // Note the opening parenthesis `(` is not included in the expression's
1998    // span.
1999
2000    // Parse class-new and dynamic-array-new expressions, which are used on the
2001    // right hand side of assignments.
2002    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                // Parse the optional expression.
2017                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    // Try to parse a cast or pattern expression, which starts with an explicit
2032    // type, followed by an apostrophe.
2033    // pattern_expr ::= type? pattern
2034    // cast ::= type `'` `(` expr `)`
2035    {
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            // type `'` `(` ...
2041            (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            // type `'` `{` ...
2050            (Ok(ty), Apostrophe, OpenDelim(Brace)) => {
2051                bp.commit();
2052                // Don't consume the apostrophe -- it's part of the pattern.
2053                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    // Try to parse a sign cast expression, which starts with a `unsigned` or
2063    // `signed` keyword.
2064    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    // Otherwise treat this as a normal expression.
2075    let q = p.peek(0).1;
2076    // p.add_diag(DiagBuilder2::note(format!("expr_suffix with precedence {:?}", precedence)).span(q));
2077    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    // p.add_diag(DiagBuilder2::note(format!("expr_suffix with precedence {:?}", precedence)).span(prefix.span));
2087
2088    // Try to parse the index and call expressions.
2089    let (tkn, sp) = p.peek(0);
2090    match tkn {
2091        // Index: "[" range_expression "]"
2092        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        // Call: "(" [list_of_arguments] ")"
2113        OpenDelim(Paren) if precedence <= Precedence::Postfix => {
2114            // Special treatment for system tasks with custom syntax. SV is a
2115            // horrible language.
2116            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        // expr "." ident
2131        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        // expr "::" ident
2145        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        // expr "++"
2156        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        // expr "--"
2170        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        // expr "?" expr ":" expr
2184        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        // expr "inside" "{" open_range_list "}"
2201        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        // expr "'" "(" expr ")"
2227        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    // Try assign operators.
2240    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    // Try to parse binary operations.
2257    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    // Certain expressions are introduced by an operator or keyword. Handle
2284    // these cases first, since they are the quickest to decide.
2285    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    // Try the unary operators next.
2321    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    // Since none of the above matched, this must be a primary expression.
2335    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        // Primary Literals
2342        Literal(lit) => {
2343            p.bump();
2344            return Ok(Expr::new(sp, LiteralExpr(lit)));
2345        }
2346
2347        // Identifiers
2348        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        // `this`
2358        Keyword(Kw::This) => {
2359            p.bump();
2360            return Ok(Expr::new(sp, ThisExpr));
2361        }
2362
2363        // `$`
2364        Dollar => {
2365            p.bump();
2366            return Ok(Expr::new(sp, DollarExpr));
2367        }
2368
2369        // `null`
2370        Keyword(Kw::Null) => {
2371            p.bump();
2372            return Ok(Expr::new(sp, NullExpr));
2373        }
2374
2375        // Concatenation and empty queue
2376        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        // Parenthesis
2393        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        // Patterns
2407        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    // Handle the trivial case of the "default" pattern.
2432    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    // Otherwise handle the non-trivial cases.
2440    let mut pp = ParallelParser::new();
2441
2442    // Try to parse expression patterns, which are of the form `expr ":" ...`.
2443    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    // Try to parse type patterns, which are of the form `type ":" ...`.
2451    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    // ident ":"
2459    // expression ":"
2460    // type ":"
2461    // "default" ":"
2462
2463    // expr
2464    // expr "{" expr {"," expr} "}"
2465
2466    // Try to parse pattern fields that start with an expression, which may
2467    // either be a simple expression pattern or a repeat pattern.
2468    pp.add("expression or repeat pattern", |p| {
2469        let expr = Box::new(parse_expr(p)?);
2470
2471        // If the expression is followed by an opening brace this is a repeat
2472        // pattern.
2473        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        // Make sure this covers the whole pattern field.
2482        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    // Streaming concatenations have a "<<" or ">>" following the opening "{".
2498    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        // Parse the optional slice size. This can either be an expression or a
2508        // type. We prefer to parse things as expressions, and only if that does
2509        // not succeed do we switch to a type.
2510        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        // Parse the stream expressions.
2528        let exprs = flanked(p, Brace, |p| {
2529            comma_list_nonempty(p, CloseDelim(Brace), "stream expression", |p| {
2530                // Consume the expression.
2531                let expr = Box::new(parse_expr(p)?);
2532
2533                // Consume the optional range.
2534                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    // Parse the expression that follows the opening "{". Depending on whether
2554    // this is a regular concatenation or a multiple concatenation, the meaning
2555    // of the expression changes.
2556    let first_expr = parse_expr_prec(p, Precedence::Concatenation)?;
2557
2558    // If the expression is followed by a "{", this is a multiple concatenation.
2559    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    // Otherwise this is just a regular concatenation, so the first expression
2575    // may be followed by "," and another expression multiple times.
2576    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
2616/// Parse the tail of a primary expression that started with a parenthesis.
2617///
2618/// ## Syntax
2619/// ```text
2620/// "(" expression ")"
2621/// "(" expression ":" expression ":" expression ")"
2622/// ```
2623fn 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
2642/// Parse a range expression.
2643///
2644/// ## Syntax
2645/// ```text
2646/// expression
2647/// expression ":" expression
2648/// expression "+:" expression
2649/// expression "-:" expression
2650/// ```
2651fn 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        // Otherwise the index expression consists only of one expression.
2660        _ => return Ok(first_expr),
2661    };
2662    p.bump(); // skip the operator
2663    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
2675/// Convert a token to the corresponding unary operator. Return `None` if the
2676/// token does not map to a unary operator.
2677fn 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
2698/// Convert a token to the corresponding binary operator. Return `None` if the
2699/// token does not map to a binary operator.
2700fn 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
2741/// Convert a token to the corresponding AssignOp. Return `None` if the token
2742/// does not map to an assignment operator.
2743fn 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
2762/// Parse a comma-separated list of ports, up to a closing parenthesis. Assumes
2763/// that the opening parenthesis has already been consumed.
2764fn parse_port_list<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<Vec<Port<'n>>> {
2765    let mut v = Vec::new();
2766
2767    // In case the port list is empty.
2768    if p.try_eat(CloseDelim(Paren)) {
2769        return Ok(v);
2770    }
2771
2772    loop {
2773        // Parse a port.
2774        match parse_port(p) {
2775            Ok(x) => v.push(x),
2776            Err(()) => p.recover_balanced(&[Comma, CloseDelim(Paren)], false),
2777        }
2778
2779        // Depending on what follows, continue or break out of the loop.
2780        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
2801/// Parse one port in a module or interface port list. The `prev` argument shall
2802/// be a reference to the previously parsed port, or `None` if this is the first
2803/// port in the list. This is required since ports inherit certain information
2804/// from their predecessor if omitted.
2805// fn parse_port(p: &mut dyn AbstractParser<'n>, prev: Option<&Port>) -> ReportedResult<Port> {
2806//  let mut span = p.peek(0).1;
2807
2808//  // TODO: Rewrite this function to leverage the branch parser for the
2809//  // different kinds of port declarations.
2810
2811//  // Consume the optional port direction.
2812//  let mut dir = as_port_direction(p.peek(0).0);
2813//  if dir.is_some() {
2814//      p.bump();
2815//  }
2816
2817//  // Consume the optional net type or var keyword, which determines the port
2818//  // kind.
2819//  let mut kind = match p.peek(0).0 {
2820//      // Net Types
2821//      Keyword(Kw::Supply0) => Some(PortKind::Net(NetType::Wire)),
2822//      Keyword(Kw::Supply1) => Some(PortKind::Net(NetType::Wire)),
2823//      Keyword(Kw::Tri)     => Some(PortKind::Net(NetType::Wire)),
2824//      Keyword(Kw::Triand)  => Some(PortKind::Net(NetType::Wire)),
2825//      Keyword(Kw::Trior)   => Some(PortKind::Net(NetType::Wire)),
2826//      Keyword(Kw::Trireg)  => Some(PortKind::Net(NetType::Wire)),
2827//      Keyword(Kw::Tri0)    => Some(PortKind::Net(NetType::Wire)),
2828//      Keyword(Kw::Tri1)    => Some(PortKind::Net(NetType::Wire)),
2829//      Keyword(Kw::Uwire)   => Some(PortKind::Net(NetType::Wire)),
2830//      Keyword(Kw::Wire)    => Some(PortKind::Net(NetType::Wire)),
2831//      Keyword(Kw::Wand)    => Some(PortKind::Net(NetType::Wire)),
2832//      Keyword(Kw::Wor)     => Some(PortKind::Net(NetType::Wire)),
2833
2834//      // Var Kind
2835//      Keyword(Kw::Var)     => Some(PortKind::Var),
2836//      _ => None
2837//  };
2838//  if kind.is_some() {
2839//      p.bump();
2840//  }
2841
2842//  // Try to parse ports of the form:
2843//  // "." port_identifier "(" [expression] ")"
2844//  if p.try_eat(Period) {
2845//      let q = p.peek(0).1;
2846//      p.add_diag(DiagBuilder2::error("Ports starting with a . not yet supported").span(q));
2847//      return Err(())
2848//  }
2849
2850//  // Otherwise parse the port data type, which may be a whole host of
2851//  // different things.
2852//  let mut ty = parse_data_type(p)?;
2853
2854//  // Here goes the tricky part: If the data type not followed by the name (and
2855//  // optional dimensions) of the port, the data type actually was the port
2856//  // name. These are indistinguishable.
2857//  let (name, name_span, (dims, dims_span)) = if let Some((name, span)) = p.try_eat_ident() {
2858//      (name, span, parse_optional_dimensions(p)?)
2859//  } else {
2860//      if let Type { span: span, data: NamedType(ast::Identifier{name,..}), dims: dims, .. } = ty {
2861//          let r = (name, span, (dims, span));
2862//          ty = Type {
2863//              span: span.begin().into(),
2864//              data: ast::ImplicitType,
2865//              dims: Vec::new(),
2866//              sign: ast::TypeSign::None,
2867//          };
2868//          r
2869//      } else {
2870//          p.add_diag(DiagBuilder2::error("expected port type or name").span(ty.span));
2871//          return Err(());
2872//      }
2873//  };
2874
2875//  // TODO: The following goes into the lowering to HIR phase. Just keep track
2876//  // of what was unspecified here.
2877
2878//  // // Determine the kind of the port based on the optional kind keywords, the
2879//  // // direction, and the type.
2880//  // if dir.is_none() && kind.is_none() && ty.is_none() && prev.is_some() {
2881//  //  dir = Some(prev.unwrap().dir.clone());
2882//  //  kind = Some(prev.unwrap().kind.clone());
2883//  //  ty = Some(prev.unwrap().ty.clone());
2884//  // } else {
2885//  //  // The direction defaults to inout.
2886//  //  if dir.is_none() {
2887//  //      dir = Some(PortDir::Inout);
2888//  //  }
2889
2890//  //  // The type defaults to logic.
2891//  //  if ty.is_none() {
2892//  //      ty = Some(Type {
2893//  //          span: INVALID_SPAN,
2894//  //          data: LogicType,
2895//  //          sign: TypeSign::None,
2896//  //          dims: Vec::new(),
2897//  //      });
2898//  //  }
2899
2900//  //  // The kind defaults to different things based on the direction and
2901//  //  // type:
2902//  //  // - input,inout: default net
2903//  //  // - ref: var
2904//  //  // - output (implicit type): net
2905//  //  // - output (explicit type): var
2906//  //  if kind.is_none() {
2907//  //      kind = Some(match dir.unwrap() {
2908//  //          PortDir::Input | PortDir::Inout => NetPort,
2909//  //          PortDir::Ref => VarPort,
2910//  //          PortDir::Output if ty.clone().unwrap().data == ImplicitType => NetPort,
2911//  //          PortDir::Output => VarPort,
2912//  //      });
2913//  //  }
2914//  // }
2915
2916//  // Parse the optional initial assignment for this port.
2917//  if p.try_eat(Operator(Op::Assign)) {
2918//      let q = p.peek(0).1;
2919//      p.add_diag(DiagBuilder2::error("Ports with initial assignment not yet supported").span(q));
2920//  }
2921
2922//  // Update the port's span to cover all of the tokens consumed.
2923//  span.expand(p.last_span());
2924
2925//  Ok(Port {
2926//      span: span,
2927//      name: name,
2928//      name_span: name_span,
2929//      kind: kind,
2930//      ty: ty,
2931//      dir: dir,
2932//      dims: dims,
2933//  })
2934// }
2935
2936/// Parse a single port declaration. These can take a few different forms.
2937fn 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
2946/// Parse a interface port declaration.
2947/// ```text
2948/// "interface" ["." ident] ident {dimension} ["=" expr]
2949/// ```
2950fn parse_interface_port<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ast::Port<'n>> {
2951    let mut span = p.peek(0).1;
2952
2953    // Consume the interface keyword.
2954    p.require_reported(Keyword(Kw::Interface))?;
2955
2956    // Consume the optional modport name.
2957    let modport = if p.try_eat(Period) {
2958        Some(parse_identifier_name(p, "modport name")?)
2959    } else {
2960        None
2961    };
2962
2963    // Consume the port name.
2964    let name = parse_identifier_name(p, "port name")?;
2965
2966    // Consume the optional dimensions.
2967    let (dims, _) = parse_optional_dimensions(p)?;
2968
2969    // Consume the optional initial expression.
2970    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
2989/// Parse an explicit port declaration.
2990/// ```text
2991/// [direction] "." ident "(" [expr] ")"
2992/// ```
2993fn parse_explicit_port<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ast::Port<'n>> {
2994    let mut span = p.peek(0).1;
2995
2996    // Consume the optional port direction.
2997    let dir = as_port_direction(p.peek(0).0);
2998    if dir.is_some() {
2999        p.bump();
3000    }
3001
3002    // Consume the period and port name.
3003    p.require_reported(Period)?;
3004    let name = parse_identifier_name(p, "port name")?;
3005
3006    // Consume the port expression in parenthesis.
3007    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
3023/// Parse a named port declaration.
3024/// ```text
3025/// [direction] [net_type|"var"] type_or_implicit ident {dimension} ["=" expr]
3026/// ```
3027fn parse_named_port<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<ast::Port<'n>> {
3028    let mut span = p.peek(0).1;
3029
3030    // Consume the optional port direction.
3031    let dir = as_port_direction(p.peek(0).0);
3032    if dir.is_some() {
3033        p.bump();
3034    }
3035
3036    // Consume the optional port kind, which is either a specific net type, a
3037    // "var" keyword, or nothing at all.
3038    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    // Branch to parse ports with explicit and implicit type.
3055    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        // Consume the port name.
3070        let name = parse_identifier_name(p, "port name")?;
3071
3072        // Consume the optional dimensions.
3073        let (dims, _) = parse_optional_dimensions(p)?;
3074
3075        // Consume the optional initial expression.
3076        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
3100/// Parse an implicit port declaration.
3101/// ```text
3102/// expr
3103/// ```
3104fn 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    // If the parameter assignment starts with a ".", this is a named
3130    // assignment. Otherwise it's an ordered assignment.
3131    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    // Consume the subroutine prototype, which covers everything up to the ";"
3167    // after the argument list.
3168    let prototype = parse_subroutine_prototype(p)?;
3169
3170    // Consume the subroutine body, which basically is a list of statements.
3171    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    // Consume the "endfunction" or "endtask" keywords.
3178    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    // Consume the "function" or "task" keyword, which then also decides what
3213    // kind of subroutine we're parsing.
3214    let kind = parse_subroutine_kind(p)?;
3215
3216    // Parse the optional lifetime specifier.
3217    let lifetime = as_lifetime(p.peek(0).0);
3218    if lifetime.is_some() {
3219        p.bump();
3220    }
3221
3222    // Parse the return type (if this is a function), the subroutine name, and
3223    // the optional argument list.
3224    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    // Consume the subroutine name, or "new".
3260    // TODO: Make this accept the full `[interface_identifier "." | class_scope] tf_identifier`.
3261    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    // Consume the port list.
3268    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            // Consume the optional port direction.
3273            let dir = try_subroutine_port_dir(p);
3274
3275            // Consume the optional "var" keyword.
3276            let var = p.try_eat(Keyword(Kw::Var));
3277
3278            // Branch to parse ports with explicit and implicit type.
3279            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            // The `tail` function handles everything that follows the data type. To
3291            // ensure that the ports are parsed correctly, the function must fail if
3292            // the port is not immediately followed by a "," or ")". Otherwise
3293            // implicit and explicit types cannot be distinguished.
3294            fn tail<'n>(
3295                p: &mut dyn AbstractParser<'n>,
3296            ) -> ReportedResult<Option<SubroutinePortName<'n>>> {
3297                // Parse the optional port identifier.
3298                let data = if let Some(name) = try_identifier_name(p)? {
3299                    // Parse the optional dimensions.
3300                    let (dims, _) = parse_optional_dimensions(p)?;
3301
3302                    // Parse the optional initial assignment.
3303                    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                // Ensure that we have consumed all tokens for this port.
3315                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    // Wrap things up.
3335    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    // Try to parse a port declaration of the form:
3370    // direction ["var"] type_or_implicit [name_assignment {"," name_assignment}]
3371    if let Some(dir) = try_subroutine_port_dir(p) {
3372        // Consume the optional "var" keyword.
3373        let var = p.try_eat(Keyword(Kw::Var));
3374
3375        // Branch to handle the cases of implicit and explicit data type.
3376        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        // Wrap things up.
3402        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    // Otherwise simply treat this as a statement.
3415    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    // Null statements simply consist of a semicolon.
3422    if p.try_eat(Semicolon) {
3423        return Ok(Stmt::new_null(span));
3424    }
3425
3426    // Consume the optional statement label.
3427    let mut label = if p.is_ident() && p.peek(1).0 == Colon {
3428        let (n, _) = p.eat_ident("statement label")?;
3429        p.bump(); // eat the colon
3430        Some(n)
3431    } else {
3432        None
3433    };
3434
3435    // Parse the actual statement item.
3436    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    // See if this is a timing-controlled statement as per IEEE 1800-2009
3449    // section 9.4.
3450    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        // Sequential blocks
3465        OpenDelim(Bgend) => {
3466            p.bump();
3467            let (stmts, _) = parse_block(p, label, &[CloseDelim(Bgend)])?;
3468            SequentialBlock(stmts)
3469        }
3470
3471        // Parallel blocks
3472        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        // If and case statements
3493        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        // Loops, as per IEEE 1800-2009 section 12.7.
3510        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        // Generate variables
3581        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        // Flow control
3589        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        // Import statements
3611        Keyword(Kw::Import) => ImportStmt(parse_import_decl(p)?),
3612
3613        // Assertion statements
3614        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        // Wait statements
3621        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        // Disable statements
3654        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        // Everything else needs special treatment as things such as variable
3667        // declarations look very similar to other expressions.
3668        _ => {
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    // Consume the optional block label. If the block has already been labelled
3697    // via a statement label, an additional block label is illegal.
3698    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    // Parse the block statements.
3720    let mut v = Vec::new();
3721    let terminator;
3722    'outer: loop {
3723        // Check if we have reached one of the terminators.
3724        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        // Otherwise parse the next statement.
3734        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    // Consume the optional block label after the terminator and verify that it
3746    // matches the label provided at the beginning of the block.
3747    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
3774/// Parse a continuous assignment.
3775/// ```text
3776/// "assign" [drive_strength] [delay3] list_of_assignments ";"
3777/// "assign" [delay_control] list_of_assignments ";"
3778/// ```
3779fn 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    // Consume the optional drive strength.
3784    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    // Parse the optional delay control.
3796    let delay_control = try_delay_control(p)?;
3797
3798    // Parse the names and assignments.
3799    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        // Case statements
3821        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        // If statement
3835        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
3850/// Parse a case statement as per IEEE 1800-2009 section 12.5.
3851fn 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    // Parse the case expression.
3859    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    // The case expression may be followed by a "matches" or "inside" keyword
3870    // which changes the kind of operation the statement performs.
3871    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    // Parse the case items.
3884    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        // Handle the default case items.
3889        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        // Handle regular case items.
3896        else {
3897            let mut exprs = Vec::new();
3898            loop {
3899                if p.peek(0).0 == OpenDelim(Brack) {
3900                    // TODO(fschuiki): Keep track of results
3901                    // TODO(fschuiki): Error recovery
3902                    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            // Parse the statement.
3938            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    // Parse the condition expression surrounded by parenthesis.
3960    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    // Parse the main statement.
3971    let main_stmt = Box::new(parse_stmt(p)?);
3972
3973    // Parse the optional "else" branch.
3974    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    // Try to consume the hashtag which introduces the delay control.
3993    if !p.try_eat(Hashtag) {
3994        return Ok(None);
3995    }
3996    let mut span = p.last_span();
3997
3998    // Parse the delay value. This may either be a literal delay value,
3999    // or a min-typ-max expression in parenthesis.
4000    let (tkn, sp) = p.peek(0);
4001    let expr = match tkn {
4002        // Expression
4003        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        // Literals
4011        Literal(Number(..)) | Literal(Time(..)) | Ident(..) => {
4012            parse_expr_first(p, Precedence::Max)?
4013        }
4014
4015        // TODO: Parse "1step" keyword
4016        _ => {
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
4029/// Try to parse an event control as described in IEEE 1800-2009 section 9.4.2.
4030fn 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    // @*
4039    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    // @(*)
4049    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    // Parse the leading expression.
4091    let expr = parse_expr_prec(p, Precedence::Postfix)?;
4092    let (tkn, sp) = p.peek(0);
4093
4094    // Handle blocking assignments (IEEE 1800-2009 section 10.4.1), where the
4095    // expression is followed by an assignment operator.
4096    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    // Handle non-blocking assignments (IEEE 1800-2009 section 10.4.2).
4108    if tkn == Operator(Op::Leq) {
4109        p.bump();
4110
4111        // Parse the optional delay and event control.
4112        let delay_control = try_delay_control(p)?;
4113        let event_control = /*try_event_control(p)?*/ None;
4114
4115        // Parse the right-hand side of the assignment.
4116        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    // Try parsing an event expression in parentheses.
4144    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    // Consume the optional edge identifier.
4158    let edge = as_edge_ident(p.peek(0).0);
4159    if edge != EdgeIdent::Implicit {
4160        p.bump();
4161    }
4162
4163    // Parse the value.
4164    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    // p.add_diag(DiagBuilder2::error("expected event expression").span(span));
4175    // Err(())
4176}
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        // event_expr "iff" expr
4185        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        // event_expr "or" event_expr
4195        // event_expr "," event_expr
4196        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    // Parse the variable name.
4289    let (name, name_span) = p.eat_ident("variable name")?;
4290
4291    // Parse the optional dimensions.
4292    let (dims, _) = parse_optional_dimensions(p)?;
4293
4294    // Parse the optional initial expression.
4295    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    // Parse the genvar name.
4317    let name = parse_identifier_name(p, "genvar name")?;
4318
4319    // Parse the optional initial expression.
4320    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
4342/// Parse a generate-for construct.
4343/// ```text
4344/// "for" "(" stmt expr ";" expr ")" generate_block
4345/// ```
4346fn 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    // Parse the optional block label.
4406    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    // Consume the opening "begin" keyword if present. Otherwise simply parse
4415    // a single generate item.
4416    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    // Consume the optional label after the "begin" keyword.
4440    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    // Consume the optional label after the "end" keyword.
4467    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        // Eat the optional "virtual" or "interface" keyword.
4506        let virt = p.try_eat(Keyword(Kw::Virtual));
4507        let intf = p.try_eat(Keyword(Kw::Interface));
4508
4509        // Eat the "class" keyword.
4510        p.require_reported(Keyword(Kw::Class))?;
4511
4512        // Eat the optional lifetime.
4513        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        // Parse the class name.
4522        let name = parse_identifier_name(p, "class name")?;
4523
4524        // Parse the optional parameter port list.
4525        let params = if p.try_eat(Hashtag) {
4526            parse_parameter_port_list(p)?
4527        } else {
4528            Vec::new()
4529        };
4530
4531        // Parse the optional inheritance clause.
4532        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        // Parse the optional implementation clause.
4541        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        // Parse the class items.
4552        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    // Parse the optional class name after "endclass".
4560    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    // Easy path for null class items.
4596    if p.try_eat(Semicolon) {
4597        return Ok(ClassItem {
4598            span,
4599            qualifiers: vec![],
4600            data: ClassItemData::Null,
4601        });
4602    }
4603
4604    // Parse localparam and parameter declarations.
4605    // TODO: Replace these by calls to parse_param_decl.
4606    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        // Parse "extern" task and function prototypes.
4618        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        // Parse type defs.
4629        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    // Parse the optional class item qualifiers.
4642    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    // Parse the prototype qualifier.
4717    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    // Parse the optional "static" keyword.
4731    let statik = p.try_eat(Keyword(Kw::Static));
4732
4733    // Parse the "constraint" keyword.
4734    p.require_reported(Keyword(Kw::Constraint))?;
4735
4736    // Parse the constraint name.
4737    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        // Make sure that no "extern" or "pure" keyword was used, as these are
4747        // only valid for prototypes.
4748        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    // Handle the trivial cases that start with a keyword first.
4785    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    // If we arrive here, the item starts with an expression.
4800    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            // Sort the errors by score and remove all but the highest scoring
4907            // ones.
4908            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            // Print the errors.
4918            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        // Handle the special case where we have multiple parsers that match the
4950        // exact same token sequence.
4951        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        // Otherwise we handle this just like any other ambiguity.
4960        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    // We might be a declaration of the format "typedef x;", in which case we
5052    // just store what we know and continue. Also handle "typedef enum x;" syntax
5053    // here to avoid the enum parsing code, which has to deal with type specifers.
5054    {
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    // Consume the port direction.
5102    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    // Consume the optional net type or "var" keyword.
5117    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    // Branch to handle explicit and implicit types.
5130    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    // Wrap things up.
5153    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    // Consume the net type.
5187    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    // Consume the optional drive strength or charge strength.
5200    let strength = try_flanked(p, Paren, parse_net_strength)?;
5201
5202    // Consume the optional "vectored" or "scalared" keywords.
5203    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    // Branch to handle explicit and implicit types separately.
5216    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    // This function handles parsing of everything after the type.
5228    fn tail<'n>(
5229        p: &mut dyn AbstractParser<'n>,
5230    ) -> ReportedResult<(Option<DelayControl<'n>>, Vec<VarDeclName<'n>>)> {
5231        // Parse the optional delay.
5232        let delay = try_delay_control(p)?;
5233
5234        // Parse the names and assignments.
5235        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
5316/// Parse a DPI import or export.
5317///
5318/// ```text
5319/// "import" ("DPI-C"|"DPI") ("context"|"pure")? (ident "=")? subroutine_prototype ";"
5320/// "export" ("DPI-C"|"DPI") (ident "=")? ("function"|"task") ident ";"
5321/// ```
5322fn 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        // Semicolon is part of the prototype.
5342        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
5378/// Parse an import declaration.
5379/// ```text
5380/// "import" package_ident "::" "*" ";"
5381/// "import" package_ident "::" ident ";"
5382/// ```
5383fn 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        // package_ident "::" ident
5388        // package_ident "::" "*"
5389        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            // package_ident "::" "*"
5395            Operator(Op::Mul) => {
5396                p.bump();
5397                span.expand(p.last_span());
5398                Ok(ImportItem::new(span, ImportItemData { pkg, name: None }))
5399            }
5400
5401            // package_ident "::" ident
5402            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    // Peek ahead after the current token to see if a "property", "sequence",
5434    // "#0", or "final" follows. This decides what kind of assertion we're
5435    // parsing.
5436    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    // Handle the different combinations of keywords and lookaheads from above.
5448
5449    let data = match p.peek(0).0 {
5450        // Concurrent Assertions
5451        // ---------------------
5452
5453        // `assert property`
5454        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        // `assume property`
5463        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        // `cover property`
5472        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        // `cover sequence`
5481        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            // AssertionData::Concurrent(ConcurrentAssertion::CoverSequence)
5487        }
5488
5489        // `expect`
5490        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        // `restrict property`
5498        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        // Immediate and Deferred Assertions
5506        // ---------------------------------
5507
5508        // `assert`, `assert #0`, and `assert final`
5509        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        // `assume`, `assume #0`, and `assume final`
5528        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        // `cover`, `cover #0`, and `cover final`
5547        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            // TODO: Ensure that `stmt` is not a NullStmt.
5591            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    // TODO: Actually parse this stuff, rather than just chicken out.
5602    p.recover_balanced(&[CloseDelim(Paren)], false);
5603    return Ok(PropSpec);
5604
5605    // // Parse the optional event expression.
5606    // let event = if p.try_eat(At) {
5607    //     Some(parse_event_expr(p, EventPrecedence::Min)?)
5608    // } else {
5609    //     None
5610    // };
5611
5612    // // Parse the optional "disable iff" clause.
5613    // let disable = if p.try_eat(Keyword(Kw::Disable)) {
5614    //     p.require_reported(Keyword(Kw::Iff))?;
5615    //     Some(flanked(p, Paren, parse_expr)?)
5616    // } else {
5617    //     None
5618    // };
5619
5620    // // Parse the property expression.
5621    // let prop = parse_propexpr(p)?;
5622    // Ok(PropSpec)
5623}
5624
5625#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
5626#[allow(dead_code)]
5627enum PropSeqPrecedence {
5628    Min,
5629    AlEvIfAccRejSyn,
5630    ImplFollow, // right-associative
5631    Until,      // right-associative
5632    Iff,        // right-associative
5633    Or,         // left-associative
5634    And,        // left-associative
5635    NotNexttime,
5636    Intersect,  // left-associative
5637    Within,     // left-associative
5638    Throughout, // right-associative
5639    CycleDelay, // left-associative
5640    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    // To parse property expressions we need a parallel parser. For certain
5655    // cases it is unclear if a parenthesized expression is a sequence or a
5656    // property expression, e.g.:
5657    //
5658    // (foo) |=> bar
5659    // ^^^^^ sequence or property?
5660    //
5661    // Both sequences and property expressions support parenthesis. However the
5662    // |=> operator is only defined for sequences on the left hand side. If the
5663    // parenthesis are parsed as a property and foo as a sequence, the above
5664    // code fails to parse since the sequence on the left has effectively become
5665    // a property. If the parenthesis are parsed as a sequence, all is well. To
5666    // resolve these kinds of issues, we need a parallel parser.
5667    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    // Handle the trivial case of expressions introduced by a symbol or keyword.
5689    match p.peek(0).0 {
5690        // Parenthesized property expression.
5691        OpenDelim(Paren) => return flanked(p, Paren, parse_propexpr).map(|pe| pe.data),
5692
5693        // "not" operator
5694        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        // Clocking event
5701        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    // Consume a strong, weak, or regular sequence operator.
5721    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    // Handle the operators that have a sequence expression on their left hand
5734    // side.
5735    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    // Otherwise this is just a simple sequence operator.
5750    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    // Handle the binary operators that have a property expression on both their
5759    // left and right hand side.
5760    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    // See parse_propexpr_prec for an explanation of why we need a parallel
5795    // parser here.
5796    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    // TODO: Handle all the non-trivial cases.
5814    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    // If we arrive here, the only possibility left is that this sequence starts
5829    // with and expression or distribution.
5830    let expr = parse_expr(p)?;
5831
5832    // Handle the case of the "throughout" operator that has an expression on
5833    // its left hand side.
5834    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    // Parse the optional repetition.
5840    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    // TODO: Handle all the binary operators.
5851    Ok(prefix)
5852}
5853
5854fn parse_seqrep<'n>(p: &mut dyn AbstractParser<'n>) -> ReportedResult<SeqRep<'n>> {
5855    match p.peek(0).0 {
5856        // [*]
5857        // [* expr]
5858        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        // [+]
5868        Operator(Op::Add) => {
5869            p.bump();
5870            Ok(SeqRep::ConsecPlus)
5871        }
5872
5873        // [= expr]
5874        Operator(Op::Assign) => {
5875            p.bump();
5876            Ok(SeqRep::Nonconsec(parse_expr(p)?))
5877        }
5878
5879        // [-> expr]
5880        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    // Consume the module identifier.
5902    let target = parse_identifier_name(p, "module name")?;
5903    // TODO: Add support for interface instantiations.
5904
5905    // Consume the optional parameter value assignment.
5906    let params = if p.try_eat(Hashtag) {
5907        parse_parameter_assignments(p)?
5908    } else {
5909        Vec::new()
5910    };
5911
5912    // Consume the instantiations.
5913    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    // Parse the optional `const` keyword.
5941    let konst = p.try_eat(Keyword(Kw::Const));
5942
5943    // Parse the optional `var` keyword.
5944    let var = p.try_eat(Keyword(Kw::Var));
5945
5946    // Parse the optional lifetime specifier.
5947    let lifetime = as_lifetime(p.peek(0).0);
5948    if lifetime.is_some() {
5949        p.bump();
5950    }
5951
5952    // Branch to try the explicit and implicit type version. Note that the
5953    // implicit version is only allowed if the `var` keyword is present. This
5954    // avoids ambiguity with assign statements.
5955    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    // Eat the possibly optional `parameter` or `localparam` keyword. This
5999    // determines whether the parameter is considered local. Omitting the
6000    // keyword makes it non-local.
6001    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    // Define a predicate that checks whether the end of a parameter list has
6024    // been reached. This is somewhat tricky due to the fact that the parameter
6025    // declaration may appear in two contexts: As a standalone statement, or
6026    // inside a parameter port list of a module or interface. The former is
6027    // trivial since it is terminated by a ";". The latter, however, is more
6028    // involved, since it is terminated by a "," or ")". The comma complicates
6029    // things, as it requires us to check beyond the next token to check if the
6030    // end of the list has been reached. The list terminates if after the "," a
6031    // "parameter", "localparam", "type", or explicit type follows.
6032    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    // If the next token is the `type` keyword, this is a type parameter.
6046    // Otherwise this is a value parameter.
6047    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            // Use a parallel parser to distinguish between the explicit and
6068            // implicit type versions of the declaration.
6069            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        // size_function ::= "$bits" "(" (expression|data_type) ")"
6128        "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}