789 lines
23 KiB
Rust
789 lines
23 KiB
Rust
use crate::*;
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
#[tracable_parser]
|
|
#[packrat_parser]
|
|
pub(crate) fn compiler_directive(s: Span) -> IResult<Span, CompilerDirective> {
|
|
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<Span, ResetallCompilerDirective> {
|
|
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<Span, IncludeCompilerDirective> {
|
|
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<Span, IncludeCompilerDirective> {
|
|
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<Span, IncludeCompilerDirective> {
|
|
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<Span, IncludeCompilerDirective> {
|
|
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<Span, AngleBracketLiteral> {
|
|
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<Span, Locate> {
|
|
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<Span, TextMacroDefinition> {
|
|
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<Span, TextMacroName> {
|
|
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<Span, ListOfFormalArguments> {
|
|
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<Span, FormalArgument> {
|
|
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<Span, TextMacroIdentifier> {
|
|
let (s, a) = identifier(s)?;
|
|
Ok((s, TextMacroIdentifier { nodes: (a,) }))
|
|
}
|
|
|
|
#[tracable_parser]
|
|
#[packrat_parser]
|
|
pub(crate) fn macro_text(s: Span) -> IResult<Span, MacroText> {
|
|
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<Span, DefaultText> {
|
|
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<Span, TextMacroUsage> {
|
|
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<Span, ListOfActualArguments> {
|
|
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<Span, ActualArgument> {
|
|
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<Span, UndefineCompilerDirective> {
|
|
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<Span, UndefineallCompilerDirective> {
|
|
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<Span, ConditionalCompilerDirective> {
|
|
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<Span, IfdefDirective> {
|
|
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<Span, IfndefDirective> {
|
|
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<Span, IfdefGroupOfLines> {
|
|
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<Span, IfndefGroupOfLines> {
|
|
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<Span, ElsifGroupOfLines> {
|
|
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<Span, ElseGroupOfLines> {
|
|
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<Span, SourceDescription> {
|
|
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<Span, SourceDescription> {
|
|
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<Span, TimescaleCompilerDirective> {
|
|
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<Span, DefaultNettypeCompilerDirective> {
|
|
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<Span, DefaultNettypeValue> {
|
|
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<Span, UnconnectedDriveCompilerDirective> {
|
|
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<Span, NounconnectedDriveCompilerDirective> {
|
|
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<Span, CelldefineDriveCompilerDirective> {
|
|
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<Span, EndcelldefineDriveCompilerDirective> {
|
|
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<Span, Pragma> {
|
|
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<Span, PragmaName> {
|
|
let (s, a) = simple_identifier(s)?;
|
|
Ok((s, PragmaName { nodes: (a,) }))
|
|
}
|
|
|
|
#[tracable_parser]
|
|
#[packrat_parser]
|
|
pub(crate) fn pragma_expression(s: Span) -> IResult<Span, PragmaExpression> {
|
|
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<Span, PragmaExpression> {
|
|
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<Span, PragmaValue> {
|
|
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<Span, PragmaValue> {
|
|
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<Span, PragmaKeyword> {
|
|
let (s, a) = simple_identifier_pragma(s)?;
|
|
Ok((s, PragmaKeyword { nodes: (a,) }))
|
|
}
|
|
|
|
#[tracable_parser]
|
|
#[packrat_parser]
|
|
pub(crate) fn identifier_pragma(s: Span) -> IResult<Span, Identifier> {
|
|
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<Span, SimpleIdentifier> {
|
|
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<Span, Locate> {
|
|
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<Span, LineCompilerDirective> {
|
|
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<Span, PositionCompilerDirective> {
|
|
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<Span, Level> {
|
|
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<Span, KeywordsDirective> {
|
|
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<Span, VersionSpecifier> {
|
|
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<Span, EndkeywordsDirective> {
|
|
let (s, a) = symbol("`")(s)?;
|
|
let (s, b) = keyword("end_keywords")(s)?;
|
|
end_keywords();
|
|
Ok((s, EndkeywordsDirective { nodes: (a, b) }))
|
|
}
|