use crate::*; // ----------------------------------------------------------------------------- #[tracable_parser] #[packrat_parser] pub(crate) fn compiler_directive(s: Span) -> IResult { begin_directive(); let ret = alt(( map(resetall_compiler_directive, |x| { CompilerDirective::ResetallCompilerDirective(Box::new(x)) }), map(include_compiler_directive, |x| { CompilerDirective::IncludeCompilerDirective(Box::new(x)) }), map(text_macro_definition, |x| { CompilerDirective::TextMacroDefinition(Box::new(x)) }), map(undefine_compiler_directive, |x| { CompilerDirective::UndefineCompilerDirective(Box::new(x)) }), map(undefineall_compiler_directive, |x| { CompilerDirective::UndefineallCompilerDirective(Box::new(x)) }), map(conditional_compiler_directive, |x| { CompilerDirective::ConditionalCompilerDirective(Box::new(x)) }), map(timescale_compiler_directive, |x| { CompilerDirective::TimescaleCompilerDirective(Box::new(x)) }), map(default_nettype_compiler_directive, |x| { CompilerDirective::DefaultNettypeCompilerDirective(Box::new(x)) }), map(unconnected_drive_compiler_directive, |x| { CompilerDirective::UnconnectedDriveCompilerDirective(Box::new(x)) }), map(nounconnected_drive_compiler_directive, |x| { CompilerDirective::NounconnectedDriveCompilerDirective(Box::new(x)) }), map(celldefine_compiler_directive, |x| { CompilerDirective::CelldefineDriveCompilerDirective(Box::new(x)) }), map(endcelldefine_compiler_directive, |x| { CompilerDirective::EndcelldefineDriveCompilerDirective(Box::new(x)) }), map(pragma, |x| CompilerDirective::Pragma(Box::new(x))), map(line_compiler_directive, |x| { CompilerDirective::LineCompilerDirective(Box::new(x)) }), map(position_compiler_directive, |x| { CompilerDirective::PositionCompilerDirective(Box::new(x)) }), map(keywords_directive, |x| { CompilerDirective::KeywordsDirective(Box::new(x)) }), map(endkeywords_directive, |x| { CompilerDirective::EndkeywordsDirective(Box::new(x)) }), map(text_macro_usage, |x| { CompilerDirective::TextMacroUsage(Box::new(x)) }), ))(s); end_directive(); ret } #[tracable_parser] #[packrat_parser] pub(crate) fn resetall_compiler_directive(s: Span) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("resetall")(s)?; Ok((s, ResetallCompilerDirective { nodes: (a, b) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn include_compiler_directive(s: Span) -> IResult { alt(( include_compiler_directive_double_quote, include_compiler_directive_angle_bracket, include_compiler_directive_text_macro_usage, ))(s) } #[tracable_parser] #[packrat_parser] pub(crate) fn include_compiler_directive_double_quote( s: Span, ) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("include")(s)?; let (s, c) = string_literal(s)?; Ok(( s, IncludeCompilerDirective::DoubleQuote(Box::new(IncludeCompilerDirectiveDoubleQuote { nodes: (a, b, c), })), )) } #[tracable_parser] #[packrat_parser] pub(crate) fn include_compiler_directive_angle_bracket( s: Span, ) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("include")(s)?; let (s, c) = angle_bracket_literal(s)?; Ok(( s, IncludeCompilerDirective::AngleBracket(Box::new(IncludeCompilerDirectiveAngleBracket { nodes: (a, b, c), })), )) } #[tracable_parser] #[packrat_parser] pub(crate) fn include_compiler_directive_text_macro_usage( s: Span, ) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("include")(s)?; let (s, c) = text_macro_usage(s)?; Ok(( s, IncludeCompilerDirective::TextMacroUsage(Box::new( IncludeCompilerDirectiveTextMacroUsage { nodes: (a, b, c) }, )), )) } #[tracable_parser] #[packrat_parser] pub(crate) fn angle_bracket_literal(s: Span) -> IResult { let (s, a) = ws(angle_bracket_literal_impl)(s)?; Ok((s, AngleBracketLiteral { nodes: a })) } #[tracable_parser] pub(crate) fn angle_bracket_literal_impl(s: Span) -> IResult { let (s, a) = tag("<")(s)?; let (s, b) = is_not(">")(s)?; let (s, c) = tag(">")(s)?; let a = concat(a, b).unwrap(); let a = concat(a, c).unwrap(); Ok((s, into_locate(a))) } #[tracable_parser] #[packrat_parser] pub(crate) fn text_macro_definition(s: Span) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("define")(s)?; begin_lb_not_space(); let (s, c) = text_macro_name(s)?; end_lb_not_space(); let (s, d) = opt(macro_text)(s)?; Ok(( s, TextMacroDefinition { nodes: (a, b, c, d), }, )) } #[tracable_parser] #[packrat_parser] pub(crate) fn text_macro_name(s: Span) -> IResult { let (s, a) = text_macro_identifier(s)?; let (s, b) = opt(paren(list_of_formal_arguments))(s)?; Ok((s, TextMacroName { nodes: (a, b) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn list_of_formal_arguments(s: Span) -> IResult { let (s, a) = list(symbol(","), formal_argument)(s)?; Ok((s, ListOfFormalArguments { nodes: (a,) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn formal_argument(s: Span) -> IResult { let (s, a) = simple_identifier(s)?; let (s, b) = opt(pair(symbol("="), default_text))(s)?; Ok((s, FormalArgument { nodes: (a, b) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn text_macro_identifier(s: Span) -> IResult { let (s, a) = identifier(s)?; Ok((s, TextMacroIdentifier { nodes: (a,) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn macro_text(s: Span) -> IResult { let (s, a) = many1(alt((tag("\\\n"), tag("\\"), is_not("\\\n"))))(s)?; let mut ret = None; for x in a { ret = if let Some(ret) = ret { Some(concat(ret, x).unwrap()) } else { Some(x) } } let a = ret.unwrap(); Ok(( s, MacroText { nodes: (into_locate(a),), }, )) } #[tracable_parser] #[packrat_parser] pub(crate) fn default_text(s: Span) -> IResult { let (s, a) = many1(alt(( is_not(",)([{\""), map(triple(tag("("), opt(is_not(")")), tag(")")), |(x, y, z)| { if let Some(y) = y { concat(concat(x, y).unwrap(), z).unwrap() } else { concat(x, z).unwrap() } }), map(triple(tag("["), opt(is_not("]")), tag("]")), |(x, y, z)| { if let Some(y) = y { concat(concat(x, y).unwrap(), z).unwrap() } else { concat(x, z).unwrap() } }), map(triple(tag("{"), opt(is_not("}")), tag("}")), |(x, y, z)| { if let Some(y) = y { concat(concat(x, y).unwrap(), z).unwrap() } else { concat(x, z).unwrap() } }), map( triple(tag("\""), opt(is_not("\"")), tag("\"")), |(x, y, z)| { if let Some(y) = y { concat(concat(x, y).unwrap(), z).unwrap() } else { concat(x, z).unwrap() } }, ), )))(s)?; let mut ret = None; for x in a { ret = if let Some(ret) = ret { Some(concat(ret, x).unwrap()) } else { Some(x) } } let a = ret.unwrap(); Ok(( s, DefaultText { nodes: (into_locate(a),), }, )) } #[tracable_parser] #[packrat_parser] pub(crate) fn text_macro_usage(s: Span) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = text_macro_identifier(s)?; let (s, c) = opt(paren(list_of_actual_arguments))(s)?; Ok((s, TextMacroUsage { nodes: (a, b, c) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn list_of_actual_arguments(s: Span) -> IResult { let (s, a) = list(symbol(","), actual_argument)(s)?; Ok((s, ListOfActualArguments { nodes: (a,) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn actual_argument(s: Span) -> IResult { let (s, a) = many1(alt(( is_not(",)([{\""), map(triple(tag("("), opt(is_not(")")), tag(")")), |(x, y, z)| { if let Some(y) = y { concat(concat(x, y).unwrap(), z).unwrap() } else { concat(x, z).unwrap() } }), map(triple(tag("["), opt(is_not("]")), tag("]")), |(x, y, z)| { if let Some(y) = y { concat(concat(x, y).unwrap(), z).unwrap() } else { concat(x, z).unwrap() } }), map(triple(tag("{"), opt(is_not("}")), tag("}")), |(x, y, z)| { if let Some(y) = y { concat(concat(x, y).unwrap(), z).unwrap() } else { concat(x, z).unwrap() } }), map( triple(tag("\""), opt(is_not("\"")), tag("\"")), |(x, y, z)| { if let Some(y) = y { concat(concat(x, y).unwrap(), z).unwrap() } else { concat(x, z).unwrap() } }, ), )))(s)?; let mut ret = None; for x in a { ret = if let Some(ret) = ret { Some(concat(ret, x).unwrap()) } else { Some(x) } } let a = ret.unwrap(); Ok(( s, ActualArgument { nodes: (into_locate(a),), }, )) } #[tracable_parser] #[packrat_parser] pub(crate) fn undefine_compiler_directive(s: Span) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("undef")(s)?; let (s, c) = text_macro_identifier(s)?; Ok((s, UndefineCompilerDirective { nodes: (a, b, c) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn undefineall_compiler_directive( s: Span, ) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("undefineall")(s)?; Ok((s, UndefineallCompilerDirective { nodes: (a, b) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn conditional_compiler_directive( s: Span, ) -> IResult { alt(( map(ifdef_directive, |x| { ConditionalCompilerDirective::IfdefDirective(Box::new(x)) }), map(ifndef_directive, |x| { ConditionalCompilerDirective::IfndefDirective(Box::new(x)) }), ))(s) } #[tracable_parser] #[packrat_parser] pub(crate) fn ifdef_directive(s: Span) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("ifdef")(s)?; let (s, c) = text_macro_identifier(s)?; let (s, d) = ifdef_group_of_lines(s)?; let (s, e) = many0(tuple(( symbol("`"), keyword("elsif"), text_macro_identifier, elsif_group_of_lines, )))(s)?; let (s, f) = opt(tuple((symbol("`"), keyword("else"), else_group_of_lines)))(s)?; let (s, g) = symbol("`")(s)?; let (s, h) = keyword("endif")(s)?; Ok(( s, IfdefDirective { nodes: (a, b, c, d, e, f, g, h), }, )) } #[tracable_parser] #[packrat_parser] pub(crate) fn ifndef_directive(s: Span) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("ifndef")(s)?; let (s, c) = text_macro_identifier(s)?; let (s, d) = ifndef_group_of_lines(s)?; let (s, e) = many0(tuple(( symbol("`"), keyword("elsif"), text_macro_identifier, elsif_group_of_lines, )))(s)?; let (s, f) = opt(tuple((symbol("`"), keyword("else"), else_group_of_lines)))(s)?; let (s, g) = symbol("`")(s)?; let (s, h) = keyword("endif")(s)?; Ok(( s, IfndefDirective { nodes: (a, b, c, d, e, f, g, h), }, )) } #[tracable_parser] #[packrat_parser] pub(crate) fn ifdef_group_of_lines(s: Span) -> IResult { let (s, a) = many0(preceded( peek(not(alt((tag("`elsif"), tag("`else"), tag("`endif"))))), source_description, ))(s)?; Ok((s, IfdefGroupOfLines { nodes: (a,) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn ifndef_group_of_lines(s: Span) -> IResult { let (s, a) = many0(preceded( peek(not(alt((tag("`elsif"), tag("`else"), tag("`endif"))))), source_description, ))(s)?; Ok((s, IfndefGroupOfLines { nodes: (a,) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn elsif_group_of_lines(s: Span) -> IResult { let (s, a) = many0(preceded( peek(not(alt((tag("`elsif"), tag("`else"), tag("`endif"))))), source_description, ))(s)?; Ok((s, ElsifGroupOfLines { nodes: (a,) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn else_group_of_lines(s: Span) -> IResult { let (s, a) = many0(preceded(peek(not(tag("`endif"))), source_description))(s)?; Ok((s, ElseGroupOfLines { nodes: (a,) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn source_description(s: Span) -> IResult { alt(( map(comment, |x| SourceDescription::Comment(Box::new(x))), source_description_not_directive, map(compiler_directive, |x| { SourceDescription::CompilerDirective(Box::new(x)) }), ))(s) } #[tracable_parser] #[packrat_parser] pub(crate) fn source_description_not_directive(s: Span) -> IResult { let (s, a) = many1(alt(( is_not("`/"), terminated(tag("/"), peek(not(alt((tag("/"), tag("*")))))), )))(s)?; let mut ret = None; for x in a { ret = if let Some(ret) = ret { Some(concat(ret, x).unwrap()) } else { Some(x) } } let a = ret.unwrap(); Ok(( s, SourceDescription::NotDirective(Box::new(SourceDescriptionNotDirective { nodes: (into_locate(a),), })), )) } #[tracable_parser] #[packrat_parser] pub(crate) fn timescale_compiler_directive(s: Span) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("timescale")(s)?; let (s, c) = time_literal(s)?; let (s, d) = symbol("/")(s)?; let (s, e) = time_literal(s)?; Ok(( s, TimescaleCompilerDirective { nodes: (a, b, c, d, e), }, )) } #[tracable_parser] #[packrat_parser] pub(crate) fn default_nettype_compiler_directive( s: Span, ) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("default_nettype")(s)?; let (s, c) = default_nettype_value(s)?; Ok((s, DefaultNettypeCompilerDirective { nodes: (a, b, c) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn default_nettype_value(s: Span) -> IResult { let (s, a) = alt(( keyword("none"), keyword("tri0"), keyword("tri1"), keyword("trior"), keyword("trireg"), keyword("triwand"), keyword("tri"), keyword("uwire"), keyword("wand"), keyword("wire"), keyword("wor"), ))(s)?; Ok((s, DefaultNettypeValue { nodes: (a,) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn unconnected_drive_compiler_directive( s: Span, ) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("unconnected_drive")(s)?; let (s, c) = alt((keyword("pull0"), keyword("pull1")))(s)?; Ok((s, UnconnectedDriveCompilerDirective { nodes: (a, b, c) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn nounconnected_drive_compiler_directive( s: Span, ) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("nounconnected_drive")(s)?; Ok((s, NounconnectedDriveCompilerDirective { nodes: (a, b) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn celldefine_compiler_directive( s: Span, ) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("celldefine")(s)?; Ok((s, CelldefineDriveCompilerDirective { nodes: (a, b) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn endcelldefine_compiler_directive( s: Span, ) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("endcelldefine")(s)?; Ok((s, EndcelldefineDriveCompilerDirective { nodes: (a, b) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn pragma(s: Span) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("pragma")(s)?; let (s, c) = pragma_name(s)?; let (s, d) = opt(list(symbol(","), pragma_expression))(s)?; Ok(( s, Pragma { nodes: (a, b, c, d), }, )) } #[tracable_parser] #[packrat_parser] pub(crate) fn pragma_name(s: Span) -> IResult { let (s, a) = simple_identifier(s)?; Ok((s, PragmaName { nodes: (a,) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn pragma_expression(s: Span) -> IResult { alt(( pragma_expression_assignment, map(pragma_keyword, |x| { PragmaExpression::PragmaKeyword(Box::new(x)) }), map(pragma_value, |x| PragmaExpression::PragmaValue(Box::new(x))), ))(s) } #[tracable_parser] #[packrat_parser] pub(crate) fn pragma_expression_assignment(s: Span) -> IResult { let (s, a) = pragma_keyword(s)?; let (s, b) = symbol("=")(s)?; let (s, c) = pragma_value(s)?; Ok(( s, PragmaExpression::Assignment(Box::new(PragmaExpressionAssignment { nodes: (a, b, c) })), )) } #[tracable_parser] #[packrat_parser] pub(crate) fn pragma_value(s: Span) -> IResult { alt(( pragma_value_paren, map(number, |x| PragmaValue::Number(Box::new(x))), map(string_literal, |x| PragmaValue::StringLiteral(Box::new(x))), map(identifier_pragma, |x| PragmaValue::Identifier(Box::new(x))), ))(s) } #[tracable_parser] #[packrat_parser] pub(crate) fn pragma_value_paren(s: Span) -> IResult { let (s, a) = paren(list(symbol(","), pragma_expression))(s)?; Ok(( s, PragmaValue::Paren(Box::new(PragmaValueParen { nodes: (a,) })), )) } #[tracable_parser] #[packrat_parser] pub(crate) fn pragma_keyword(s: Span) -> IResult { let (s, a) = simple_identifier_pragma(s)?; Ok((s, PragmaKeyword { nodes: (a,) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn identifier_pragma(s: Span) -> IResult { alt(( map(escaped_identifier, |x| { Identifier::EscapedIdentifier(Box::new(x)) }), map(simple_identifier_pragma, |x| { Identifier::SimpleIdentifier(Box::new(x)) }), ))(s) } #[tracable_parser] #[packrat_parser] pub(crate) fn simple_identifier_pragma(s: Span) -> IResult { let (s, a) = ws(simple_identifier_pragma_impl)(s)?; Ok((s, SimpleIdentifier { nodes: a })) } #[tracable_parser] pub(crate) fn simple_identifier_pragma_impl(s: Span) -> IResult { let (s, a) = is_a(AZ_)(s)?; let (s, b) = opt(is_a(AZ09_DOLLAR))(s)?; let a = if let Some(b) = b { concat(a, b).unwrap() } else { a }; Ok((s, into_locate(a))) } #[tracable_parser] #[packrat_parser] pub(crate) fn line_compiler_directive(s: Span) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("line")(s)?; let (s, c) = number(s)?; let (s, d) = string_literal(s)?; let (s, e) = level(s)?; Ok(( s, LineCompilerDirective { nodes: (a, b, c, d, e), }, )) } #[tracable_parser] #[packrat_parser] pub(crate) fn position_compiler_directive(s: Span) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = alt((keyword("__FILE__"), keyword("__LINE__")))(s)?; Ok((s, PositionCompilerDirective { nodes: (a, b) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn level(s: Span) -> IResult { let (s, a) = alt((symbol("0"), symbol("1"), symbol("2")))(s)?; Ok((s, Level { nodes: (a,) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn keywords_directive(s: Span) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("begin_keywords")(s)?; let (s, c) = symbol("\"")(s)?; let (s, d) = version_specifier(s)?; let (s, e) = symbol("\"")(s)?; Ok(( s, KeywordsDirective { nodes: (a, b, c, d, e), }, )) } #[tracable_parser] #[packrat_parser] pub(crate) fn version_specifier(s: Span) -> IResult { let (s, a) = alt(( map(keyword("1800-2017"), |x| { begin_keywords("1800-2017"); x }), map(keyword("1800-2012"), |x| { begin_keywords("1800-2012"); x }), map(keyword("1800-2009"), |x| { begin_keywords("1800-2009"); x }), map(keyword("1800-2005"), |x| { begin_keywords("1800-2005"); x }), map(keyword("1364-2005"), |x| { begin_keywords("1364-2005"); x }), map(keyword("1364-2001"), |x| { begin_keywords("1364-2001"); x }), map(keyword("1364-2001-noconfig"), |x| { begin_keywords("1364-2001-noconfig"); x }), map(keyword("1364-1995"), |x| { begin_keywords("1364-1995"); x }), ))(s)?; Ok((s, VersionSpecifier { nodes: (a,) })) } #[tracable_parser] #[packrat_parser] pub(crate) fn endkeywords_directive(s: Span) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("end_keywords")(s)?; end_keywords(); Ok((s, EndkeywordsDirective { nodes: (a, b) })) }