Add preprocessor_text

This commit is contained in:
dalance 2019-08-26 10:22:09 +09:00
parent c9456ee993
commit 6cd5d30e66
11 changed files with 513 additions and 110 deletions

View File

@ -5,10 +5,14 @@ use crate::*;
#[tracable_parser] #[tracable_parser]
#[packrat_parser] #[packrat_parser]
pub(crate) fn compiler_directive(s: Span) -> IResult<Span, CompilerDirective> { pub(crate) fn compiler_directive(s: Span) -> IResult<Span, CompilerDirective> {
alt(( begin_directive();
let ret = alt((
map(resetall_compiler_directive, |x| { map(resetall_compiler_directive, |x| {
CompilerDirective::ResetallCompilerDirective(Box::new(x)) CompilerDirective::ResetallCompilerDirective(Box::new(x))
}), }),
map(include_compiler_directive, |x| {
CompilerDirective::IncludeCompilerDirective(Box::new(x))
}),
map(text_macro_definition, |x| { map(text_macro_definition, |x| {
CompilerDirective::TextMacroDefinition(Box::new(x)) CompilerDirective::TextMacroDefinition(Box::new(x))
}), }),
@ -18,6 +22,9 @@ pub(crate) fn compiler_directive(s: Span) -> IResult<Span, CompilerDirective> {
map(undefineall_compiler_directive, |x| { map(undefineall_compiler_directive, |x| {
CompilerDirective::UndefineallCompilerDirective(Box::new(x)) CompilerDirective::UndefineallCompilerDirective(Box::new(x))
}), }),
map(conditional_compiler_directive, |x| {
CompilerDirective::ConditionalCompilerDirective(Box::new(x))
}),
map(timescale_compiler_directive, |x| { map(timescale_compiler_directive, |x| {
CompilerDirective::TimescaleCompilerDirective(Box::new(x)) CompilerDirective::TimescaleCompilerDirective(Box::new(x))
}), }),
@ -40,13 +47,21 @@ pub(crate) fn compiler_directive(s: Span) -> IResult<Span, CompilerDirective> {
map(line_compiler_directive, |x| { map(line_compiler_directive, |x| {
CompilerDirective::LineCompilerDirective(Box::new(x)) CompilerDirective::LineCompilerDirective(Box::new(x))
}), }),
map(position_compiler_directive, |x| {
CompilerDirective::PositionCompilerDirective(Box::new(x))
}),
map(keywords_directive, |x| { map(keywords_directive, |x| {
CompilerDirective::KeywordsDirective(Box::new(x)) CompilerDirective::KeywordsDirective(Box::new(x))
}), }),
map(endkeywords_directive, |x| { map(endkeywords_directive, |x| {
CompilerDirective::EndkeywordsDirective(Box::new(x)) CompilerDirective::EndkeywordsDirective(Box::new(x))
}), }),
))(s) map(text_macro_usage, |x| {
CompilerDirective::TextMacroUsage(Box::new(x))
}),
))(s);
end_directive();
ret
} }
#[tracable_parser] #[tracable_parser]
@ -57,6 +72,66 @@ pub(crate) fn resetall_compiler_directive(s: Span) -> IResult<Span, ResetallComp
Ok((s, ResetallCompilerDirective { nodes: (a, b) })) 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,
))(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 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] #[tracable_parser]
#[packrat_parser] #[packrat_parser]
pub(crate) fn text_macro_definition(s: Span) -> IResult<Span, TextMacroDefinition> { pub(crate) fn text_macro_definition(s: Span) -> IResult<Span, TextMacroDefinition> {
@ -136,6 +211,29 @@ pub(crate) fn default_text(s: Span) -> IResult<Span, DefaultText> {
)) ))
} }
#[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) = expression(s)?;
Ok((s, ActualArgument { nodes: (a,) }))
}
#[tracable_parser] #[tracable_parser]
#[packrat_parser] #[packrat_parser]
pub(crate) fn undefine_compiler_directive(s: Span) -> IResult<Span, UndefineCompilerDirective> { pub(crate) fn undefine_compiler_directive(s: Span) -> IResult<Span, UndefineCompilerDirective> {
@ -155,6 +253,143 @@ pub(crate) fn undefineall_compiler_directive(
Ok((s, UndefineallCompilerDirective { nodes: (a, b) })) 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) = many1(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) = many1(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) = many1(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) = many1(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] #[tracable_parser]
#[packrat_parser] #[packrat_parser]
pub(crate) fn timescale_compiler_directive(s: Span) -> IResult<Span, TimescaleCompilerDirective> { pub(crate) fn timescale_compiler_directive(s: Span) -> IResult<Span, TimescaleCompilerDirective> {
@ -364,6 +599,14 @@ pub(crate) fn line_compiler_directive(s: Span) -> IResult<Span, LineCompilerDire
)) ))
} }
#[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] #[tracable_parser]
#[packrat_parser] #[packrat_parser]
pub(crate) fn level(s: Span) -> IResult<Span, Level> { pub(crate) fn level(s: Span) -> IResult<Span, Level> {

View File

@ -11,6 +11,7 @@ pub mod declarations;
pub mod expressions; pub mod expressions;
pub mod general; pub mod general;
pub mod instantiations; pub mod instantiations;
pub mod preprocessor;
pub mod primitive_instances; pub mod primitive_instances;
pub mod source_text; pub mod source_text;
pub mod specify_section; pub mod specify_section;
@ -20,6 +21,7 @@ pub(crate) use declarations::*;
pub(crate) use expressions::*; pub(crate) use expressions::*;
pub(crate) use general::*; pub(crate) use general::*;
pub(crate) use instantiations::*; pub(crate) use instantiations::*;
pub(crate) use preprocessor::*;
pub(crate) use primitive_instances::*; pub(crate) use primitive_instances::*;
pub(crate) use source_text::*; pub(crate) use source_text::*;
pub(crate) use specify_section::*; pub(crate) use specify_section::*;
@ -74,15 +76,15 @@ impl HasTracableInfo for SpanInfo {
} }
} }
impl HasExtraState<()> for SpanInfo { impl HasExtraState<bool> for SpanInfo {
fn get_extra_state(&self) -> () { fn get_extra_state(&self) -> bool {
() in_directive()
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
nom_packrat::storage!(AnyNode, 1024); nom_packrat::storage!(AnyNode, bool, 1024);
pub fn sv_parser(s: Span) -> IResult<Span, SourceText> { pub fn sv_parser(s: Span) -> IResult<Span, SourceText> {
source_text(s) source_text(s)
@ -91,3 +93,7 @@ pub fn sv_parser(s: Span) -> IResult<Span, SourceText> {
pub fn lib_parser(s: Span) -> IResult<Span, LibraryText> { pub fn lib_parser(s: Span) -> IResult<Span, LibraryText> {
library_text(s) library_text(s)
} }
pub fn pp_parser(s: Span) -> IResult<Span, PreprocessorText> {
preprocessor_text(s)
}

View File

@ -0,0 +1,2 @@
pub mod preprocessor;
pub(crate) use preprocessor::*;

View File

@ -0,0 +1,10 @@
use crate::*;
// -----------------------------------------------------------------------------
#[tracable_parser]
#[packrat_parser]
pub(crate) fn preprocessor_text(s: Span) -> IResult<Span, PreprocessorText> {
let (s, a) = many0(source_description)(s)?;
Ok((s, PreprocessorText { nodes: (a,) }))
}

View File

@ -11797,6 +11797,76 @@ mod spec {
r##"`define home(filename) `"/home/mydir/filename`""##, r##"`define home(filename) `"/home/mydir/filename`""##,
Ok((_, _)) Ok((_, _))
); );
test!(
source_text,
r##"module and_op (a, b, c);
output a;
input b, c;
`ifdef behavioral
wire a = b & c;
`else
and a1 (a,b,c);
`endif
endmodule"##,
Ok((_, _))
);
test!(
source_text,
r##"module test(out);
output out;
`define wow
`define nest_one
`define second_nest
`define nest_two
`ifdef wow
initial $display("wow is defined");
`ifdef nest_one
initial $display("nest_one is defined");
`ifdef nest_two
initial $display("nest_two is defined");
`else
initial $display("nest_two is not defined");
`endif
`else
initial $display("nest_one is not defined");
`endif
`else
initial $display("wow is not defined");
`ifdef second_nest
initial $display("second_nest is defined");
`else
initial $display("second_nest is not defined");
`endif
`endif
endmodule"##,
Ok((_, _))
);
test!(
source_text,
r##"module test;
`ifdef first_block
`ifndef second_nest
initial $display("first_block is defined");
`else
initial $display("first_block and second_nest defined");
`endif
`elsif second_block
initial $display("second_block defined, first_block is not");
`else
`ifndef last_result
initial $display("first_block, second_block,",
" last_result not defined.");
`elsif real_last
initial $display("first_block, second_block not defined,",
" last_result and real_last defined.");
`else
initial $display("Only last_result defined!");
`endif
`endif
endmodule"##,
Ok((_, _))
);
test!(source_text, r##"`timescale 1 ns / 1 ps"##, Ok((_, _))); test!(source_text, r##"`timescale 1 ns / 1 ps"##, Ok((_, _)));
test!(source_text, r##"`timescale 10 us / 100 ns"##, Ok((_, _))); test!(source_text, r##"`timescale 10 us / 100 ns"##, Ok((_, _)));
test!( test!(
@ -15704,5 +15774,10 @@ mod spec {
#[test] #[test]
fn debug() { fn debug() {
test!(
source_text,
r##"module secret (a, b); `pragma protect encoding=(enctype="raw") `pragma protect data_method="x-caesar", data_keyname="rot13", begin endmodule"##,
Ok((_, _))
);
nom_tracable::cumulative_histogram(); nom_tracable::cumulative_histogram();
} }

View File

@ -256,6 +256,16 @@ where
#[tracable_parser] #[tracable_parser]
#[packrat_parser] #[packrat_parser]
pub(crate) fn white_space(s: Span) -> IResult<Span, WhiteSpace> { pub(crate) fn white_space(s: Span) -> IResult<Span, WhiteSpace> {
if in_directive() {
alt((
map(multispace1, |x: Span| {
WhiteSpace::Space(Box::new(into_locate(x)))
}),
map(preceded(peek(char('/')), comment), |x| {
WhiteSpace::Comment(Box::new(x))
}),
))(s)
} else {
alt(( alt((
map(multispace1, |x: Span| { map(multispace1, |x: Span| {
WhiteSpace::Space(Box::new(into_locate(x))) WhiteSpace::Space(Box::new(into_locate(x)))
@ -267,6 +277,28 @@ pub(crate) fn white_space(s: Span) -> IResult<Span, WhiteSpace> {
WhiteSpace::CompilerDirective(Box::new(x)) WhiteSpace::CompilerDirective(Box::new(x))
}), }),
))(s) ))(s)
}
}
thread_local!(
static IN_DIRECTIVE: core::cell::RefCell<Vec<()>> = {
core::cell::RefCell::new(Vec::new())
}
);
pub(crate) fn in_directive() -> bool {
IN_DIRECTIVE.with(|x| match x.borrow().last() {
Some(_) => true,
None => false,
})
}
pub(crate) fn begin_directive() {
IN_DIRECTIVE.with(|x| x.borrow_mut().push(()));
}
pub(crate) fn end_directive() {
IN_DIRECTIVE.with(|x| x.borrow_mut().pop());
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -1,96 +1,3 @@
use nom::branch::*;
use nom::bytes::complete::*;
use nom::character::complete::*;
use nom::combinator::*;
use nom::multi::*;
use nom::sequence::*;
use nom::IResult;
use str_concat::concat;
pub fn preprocessor_text(s: &str) -> IResult<&str, &str> {
alt((multispace1, comment, string_literal, other))(s)
}
fn comment(s: &str) -> IResult<&str, &str> {
alt((one_line_comment, block_comment))(s)
}
fn one_line_comment(s: &str) -> IResult<&str, &str> {
let (s, a) = tag("//")(s)?;
let (s, b) = is_not("\n")(s)?;
let a = concat(a, b).unwrap();
Ok((s, a))
}
fn block_comment(s: &str) -> IResult<&str, &str> {
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, a))
}
fn string_literal(s: &str) -> IResult<&str, &str> {
let (s, a) = tag("\"")(s)?;
let (s, b) = many0(alt((
is_not("\\\""),
map(pair(tag("\\"), take(1usize)), |(x, y)| {
concat(x, y).unwrap()
}),
)))(s)?;
let (s, c) = tag("\"")(s)?;
let mut ret = None;
for x in b {
ret = if let Some(ret) = ret {
Some(concat(ret, x).unwrap())
} else {
Some(x)
};
}
let a = if let Some(b) = ret {
let a = concat(a, b).unwrap();
let a = concat(a, c).unwrap();
a
} else {
let a = concat(a, c).unwrap();
a
};
Ok((s, a))
}
fn other(s: &str) -> IResult<&str, &str> {
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, a))
}
fn ws<'a, F>(f: F) -> impl Fn(&'a str) -> IResult<&'a str, &'a str>
where
F: Fn(&'a str) -> IResult<&'a str, &'a str>,
{
move |s: &'a str| {
let (s, x) = f(s)?;
let (s, y) = multispace0(s)?;
Ok((s, concat(x, y).unwrap()))
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
#[test] #[test]

View File

@ -5,9 +5,12 @@ use crate::*;
#[derive(Clone, Debug, Node)] #[derive(Clone, Debug, Node)]
pub enum CompilerDirective { pub enum CompilerDirective {
ResetallCompilerDirective(Box<ResetallCompilerDirective>), ResetallCompilerDirective(Box<ResetallCompilerDirective>),
IncludeCompilerDirective(Box<IncludeCompilerDirective>),
TextMacroDefinition(Box<TextMacroDefinition>), TextMacroDefinition(Box<TextMacroDefinition>),
TextMacroUsage(Box<TextMacroUsage>),
UndefineCompilerDirective(Box<UndefineCompilerDirective>), UndefineCompilerDirective(Box<UndefineCompilerDirective>),
UndefineallCompilerDirective(Box<UndefineallCompilerDirective>), UndefineallCompilerDirective(Box<UndefineallCompilerDirective>),
ConditionalCompilerDirective(Box<ConditionalCompilerDirective>),
TimescaleCompilerDirective(Box<TimescaleCompilerDirective>), TimescaleCompilerDirective(Box<TimescaleCompilerDirective>),
DefaultNettypeCompilerDirective(Box<DefaultNettypeCompilerDirective>), DefaultNettypeCompilerDirective(Box<DefaultNettypeCompilerDirective>),
UnconnectedDriveCompilerDirective(Box<UnconnectedDriveCompilerDirective>), UnconnectedDriveCompilerDirective(Box<UnconnectedDriveCompilerDirective>),
@ -16,6 +19,7 @@ pub enum CompilerDirective {
EndcelldefineDriveCompilerDirective(Box<EndcelldefineDriveCompilerDirective>), EndcelldefineDriveCompilerDirective(Box<EndcelldefineDriveCompilerDirective>),
Pragma(Box<Pragma>), Pragma(Box<Pragma>),
LineCompilerDirective(Box<LineCompilerDirective>), LineCompilerDirective(Box<LineCompilerDirective>),
PositionCompilerDirective(Box<PositionCompilerDirective>),
KeywordsDirective(Box<KeywordsDirective>), KeywordsDirective(Box<KeywordsDirective>),
EndkeywordsDirective(Box<EndkeywordsDirective>), EndkeywordsDirective(Box<EndkeywordsDirective>),
} }
@ -25,6 +29,27 @@ pub struct ResetallCompilerDirective {
pub nodes: (Symbol, Keyword), pub nodes: (Symbol, Keyword),
} }
#[derive(Clone, Debug, Node)]
pub enum IncludeCompilerDirective {
DoubleQuote(Box<IncludeCompilerDirectiveDoubleQuote>),
AngleBracket(Box<IncludeCompilerDirectiveAngleBracket>),
}
#[derive(Clone, Debug, Node)]
pub struct IncludeCompilerDirectiveDoubleQuote {
pub nodes: (Symbol, Keyword, StringLiteral),
}
#[derive(Clone, Debug, Node)]
pub struct IncludeCompilerDirectiveAngleBracket {
pub nodes: (Symbol, Keyword, AngleBracketLiteral),
}
#[derive(Clone, Debug, Node)]
pub struct AngleBracketLiteral {
pub nodes: (Locate, Vec<WhiteSpace>),
}
#[derive(Clone, Debug, Node)] #[derive(Clone, Debug, Node)]
pub struct TextMacroDefinition { pub struct TextMacroDefinition {
pub nodes: (Symbol, Keyword, TextMacroName, Option<MacroText>), pub nodes: (Symbol, Keyword, TextMacroName, Option<MacroText>),
@ -60,6 +85,25 @@ pub struct DefaultText {
pub nodes: (Locate,), pub nodes: (Locate,),
} }
#[derive(Clone, Debug, Node)]
pub struct TextMacroUsage {
pub nodes: (
Symbol,
TextMacroIdentifier,
Option<Paren<ListOfActualArguments>>,
),
}
#[derive(Clone, Debug, Node)]
pub struct ListOfActualArguments {
pub nodes: (List<Symbol, ActualArgument>,),
}
#[derive(Clone, Debug, Node)]
pub struct ActualArgument {
pub nodes: (Expression,),
}
#[derive(Clone, Debug, Node)] #[derive(Clone, Debug, Node)]
pub struct UndefineCompilerDirective { pub struct UndefineCompilerDirective {
pub nodes: (Symbol, Keyword, TextMacroIdentifier), pub nodes: (Symbol, Keyword, TextMacroIdentifier),
@ -70,6 +114,72 @@ pub struct UndefineallCompilerDirective {
pub nodes: (Symbol, Keyword), pub nodes: (Symbol, Keyword),
} }
#[derive(Clone, Debug, Node)]
pub enum ConditionalCompilerDirective {
IfdefDirective(Box<IfdefDirective>),
IfndefDirective(Box<IfndefDirective>),
}
#[derive(Clone, Debug, Node)]
pub struct IfdefDirective {
pub nodes: (
Symbol,
Keyword,
TextMacroIdentifier,
IfdefGroupOfLines,
Vec<(Symbol, Keyword, TextMacroIdentifier, ElsifGroupOfLines)>,
Option<(Symbol, Keyword, ElseGroupOfLines)>,
Symbol,
Keyword,
),
}
#[derive(Clone, Debug, Node)]
pub struct IfndefDirective {
pub nodes: (
Symbol,
Keyword,
TextMacroIdentifier,
IfndefGroupOfLines,
Vec<(Symbol, Keyword, TextMacroIdentifier, ElsifGroupOfLines)>,
Option<(Symbol, Keyword, ElseGroupOfLines)>,
Symbol,
Keyword,
),
}
#[derive(Clone, Debug, Node)]
pub struct IfdefGroupOfLines {
pub nodes: (Vec<SourceDescription>,),
}
#[derive(Clone, Debug, Node)]
pub struct IfndefGroupOfLines {
pub nodes: (Vec<SourceDescription>,),
}
#[derive(Clone, Debug, Node)]
pub struct ElsifGroupOfLines {
pub nodes: (Vec<SourceDescription>,),
}
#[derive(Clone, Debug, Node)]
pub struct ElseGroupOfLines {
pub nodes: (Vec<SourceDescription>,),
}
#[derive(Clone, Debug, Node)]
pub enum SourceDescription {
Comment(Box<Comment>),
NotDirective(Box<SourceDescriptionNotDirective>),
CompilerDirective(Box<CompilerDirective>),
}
#[derive(Clone, Debug, Node)]
pub struct SourceDescriptionNotDirective {
pub nodes: (Locate,),
}
#[derive(Clone, Debug, Node)] #[derive(Clone, Debug, Node)]
pub struct TimescaleCompilerDirective { pub struct TimescaleCompilerDirective {
pub nodes: (Symbol, Keyword, TimeLiteral, Symbol, TimeLiteral), pub nodes: (Symbol, Keyword, TimeLiteral, Symbol, TimeLiteral),
@ -155,6 +265,11 @@ pub struct LineCompilerDirective {
pub nodes: (Symbol, Keyword, Number, StringLiteral, Level), pub nodes: (Symbol, Keyword, Number, StringLiteral, Level),
} }
#[derive(Clone, Debug, Node)]
pub struct PositionCompilerDirective {
pub nodes: (Symbol, Keyword),
}
#[derive(Clone, Debug, Node)] #[derive(Clone, Debug, Node)]
pub struct Level { pub struct Level {
pub nodes: (Symbol,), pub nodes: (Symbol,),

View File

@ -6,6 +6,7 @@ pub mod declarations;
pub mod expressions; pub mod expressions;
pub mod general; pub mod general;
pub mod instantiations; pub mod instantiations;
pub mod preprocessor;
pub mod primitive_instances; pub mod primitive_instances;
pub mod source_text; pub mod source_text;
pub mod special_node; pub mod special_node;
@ -17,6 +18,7 @@ pub use declarations::*;
pub use expressions::*; pub use expressions::*;
pub use general::*; pub use general::*;
pub use instantiations::*; pub use instantiations::*;
pub use preprocessor::*;
pub use primitive_instances::*; pub use primitive_instances::*;
pub use source_text::*; pub use source_text::*;
pub use special_node::*; pub use special_node::*;

View File

@ -0,0 +1,2 @@
pub mod preprocessor;
pub use preprocessor::*;

View File

@ -0,0 +1,9 @@
use crate::*;
// -----------------------------------------------------------------------------
#[derive(Clone, Debug, Node)]
pub struct PreprocessorText {
pub nodes: (Vec<SourceDescription>,),
}