diff --git a/README.md b/README.md index 76dd8ff..3a494e0 100644 --- a/README.md +++ b/README.md @@ -45,10 +45,10 @@ A parser library for System Verilog. | udp_declaration_and_instantiation | udp_ports | | | | | udp_declaration_and_instantiation | udp_body | | | | | udp_declaration_and_instantiation | udp_instantiation | | | | -| behavioral_statements | continuous_assignment_and_net_alias | | | | -| behavioral_statements | procedural_blocks_and_assignments | | | | -| behavioral_statements | parallel_and_sequential_blocks | | | | -| behavioral_statements | statements | | | | +| behavioral_statements | continuous_assignment_and_net_alias | x | x | | +| behavioral_statements | procedural_blocks_and_assignments | x | x | | +| behavioral_statements | parallel_and_sequential_blocks | x | x | | +| behavioral_statements | statements | x | x | | | behavioral_statements | timing_control_statements | | | | | behavioral_statements | conditional_statements | | | | | behavioral_statements | case_statements | | | | diff --git a/src/parser/behavioral_statements/continuous_assignment_and_net_alias_statements.rs b/src/parser/behavioral_statements/continuous_assignment_and_net_alias_statements.rs index c9d5c06..a5f2099 100644 --- a/src/parser/behavioral_statements/continuous_assignment_and_net_alias_statements.rs +++ b/src/parser/behavioral_statements/continuous_assignment_and_net_alias_statements.rs @@ -1,8 +1,6 @@ use crate::parser::*; use nom::branch::*; use nom::combinator::*; -use nom::multi::*; -use nom::sequence::*; use nom::IResult; // ----------------------------------------------------------------------------- @@ -16,25 +14,48 @@ pub enum ContinuousAssign<'a> { #[derive(Debug)] pub struct ContinuousAssignNet<'a> { pub nodes: ( + Symbol<'a>, Option, Option>, - Vec>, + ListOfNetAssignments<'a>, + Symbol<'a>, ), } #[derive(Debug)] pub struct ContinuousAssignVariable<'a> { - pub nodes: (Option>, Vec>), + pub nodes: ( + Symbol<'a>, + Option>, + ListOfVariableAssignments<'a>, + Symbol<'a>, + ), +} + +#[derive(Debug)] +pub struct ListOfNetAssignments<'a> { + pub nodes: (List, NetAssignment<'a>>,), +} + +#[derive(Debug)] +pub struct ListOfVariableAssignments<'a> { + pub nodes: (List, VariableAssignment<'a>>,), } #[derive(Debug)] pub struct NetAlias<'a> { - pub nodes: (NetLvalue<'a>, Vec>), + pub nodes: ( + Symbol<'a>, + NetLvalue<'a>, + Symbol<'a>, + List, NetLvalue<'a>>, + Symbol<'a>, + ), } #[derive(Debug)] pub struct NetAssignment<'a> { - pub nodes: (NetLvalue<'a>, Expression<'a>), + pub nodes: (NetLvalue<'a>, Symbol<'a>, Expression<'a>), } // ----------------------------------------------------------------------------- @@ -44,50 +65,63 @@ pub fn continuous_assign(s: Span) -> IResult { } pub fn continuous_assign_net(s: Span) -> IResult { - let (s, _) = symbol("assign")(s)?; - let (s, x) = opt(drive_strength)(s)?; - let (s, y) = opt(delay3)(s)?; - let (s, z) = list_of_net_assignments(s)?; - let (s, _) = symbol(";")(s)?; + let (s, a) = symbol("assign")(s)?; + let (s, b) = opt(drive_strength)(s)?; + let (s, c) = opt(delay3)(s)?; + let (s, d) = list_of_net_assignments(s)?; + let (s, e) = symbol(";")(s)?; Ok(( s, - ContinuousAssign::Net(ContinuousAssignNet { nodes: (x, y, z) }), + ContinuousAssign::Net(ContinuousAssignNet { + nodes: (a, b, c, d, e), + }), )) } pub fn continuous_assign_variable(s: Span) -> IResult { - let (s, _) = symbol("assign")(s)?; - let (s, x) = opt(delay_control)(s)?; - let (s, y) = list_of_variable_assignments(s)?; - let (s, _) = symbol(";")(s)?; + let (s, a) = symbol("assign")(s)?; + let (s, b) = opt(delay_control)(s)?; + let (s, c) = list_of_variable_assignments(s)?; + let (s, d) = symbol(";")(s)?; Ok(( s, - ContinuousAssign::Variable(ContinuousAssignVariable { nodes: (x, y) }), + ContinuousAssign::Variable(ContinuousAssignVariable { + nodes: (a, b, c, d), + }), )) } -pub fn list_of_net_assignments(s: Span) -> IResult> { - separated_nonempty_list(symbol(","), net_assignment)(s) +pub fn list_of_net_assignments(s: Span) -> IResult { + let (s, a) = list(symbol(","), net_assignment)(s)?; + Ok((s, ListOfNetAssignments { nodes: (a,) })) } -pub fn list_of_variable_assignments(s: Span) -> IResult> { - separated_nonempty_list(symbol(","), variable_assignment)(s) +pub fn list_of_variable_assignments(s: Span) -> IResult { + let (s, a) = list(symbol(","), variable_assignment)(s)?; + Ok((s, ListOfVariableAssignments { nodes: (a,) })) } pub fn net_alias(s: Span) -> IResult { - let (s, _) = symbol("alias")(s)?; - let (s, x) = net_lvalue(s)?; - let (s, y) = many1(preceded(symbol("="), net_lvalue))(s)?; + let (s, a) = symbol("alias")(s)?; + let (s, b) = net_lvalue(s)?; + let (s, c) = symbol("=")(s)?; + let (s, d) = list(symbol("="), net_lvalue)(s)?; + let (s, e) = symbol(";")(s)?; - Ok((s, NetAlias { nodes: (x, y) })) + Ok(( + s, + NetAlias { + nodes: (a, b, c, d, e), + }, + )) } pub fn net_assignment(s: Span) -> IResult { - let (s, x) = net_lvalue(s)?; - let (s, _) = symbol("=")(s)?; - let (s, y) = expression(s)?; + let (s, a) = net_lvalue(s)?; + let (s, b) = symbol("=")(s)?; + let (s, c) = expression(s)?; - Ok((s, NetAssignment { nodes: (x, y) })) + Ok((s, NetAssignment { nodes: (a, b, c) })) } diff --git a/src/parser/behavioral_statements/looping_statements.rs b/src/parser/behavioral_statements/looping_statements.rs index 20c5e70..12f9d96 100644 --- a/src/parser/behavioral_statements/looping_statements.rs +++ b/src/parser/behavioral_statements/looping_statements.rs @@ -58,7 +58,7 @@ pub struct LoopStatementForeach<'a> { #[derive(Debug)] pub enum ForInitialization<'a> { - Assignment(Vec>), + Assignment(ListOfVariableAssignments<'a>), Declaration(Vec>), } diff --git a/src/parser/behavioral_statements/parallel_and_sequential_blocks.rs b/src/parser/behavioral_statements/parallel_and_sequential_blocks.rs index 6d1bbdb..d64ad91 100644 --- a/src/parser/behavioral_statements/parallel_and_sequential_blocks.rs +++ b/src/parser/behavioral_statements/parallel_and_sequential_blocks.rs @@ -9,93 +9,96 @@ use nom::IResult; #[derive(Debug)] pub enum ActionBlock<'a> { - Statement(StatementOrNull<'a>), + StatementOrNull(StatementOrNull<'a>), Else(ActionBlockElse<'a>), } #[derive(Debug)] pub struct ActionBlockElse<'a> { - pub nodes: (Option>, StatementOrNull<'a>), + pub nodes: (Option>, Symbol<'a>, StatementOrNull<'a>), } #[derive(Debug)] pub struct SeqBlock<'a> { pub nodes: ( - Option>, + Symbol<'a>, + Option<(Symbol<'a>, BlockIdentifier<'a>)>, Vec>, Vec>, - Option>, + Symbol<'a>, + Option<(Symbol<'a>, BlockIdentifier<'a>)>, ), } #[derive(Debug)] pub struct ParBlock<'a> { pub nodes: ( - Option>, + Symbol<'a>, + Option<(Symbol<'a>, BlockIdentifier<'a>)>, Vec>, Vec>, - JoinKeyword, - Option>, + JoinKeyword<'a>, + Option<(Symbol<'a>, BlockIdentifier<'a>)>, ), } #[derive(Debug)] -pub enum JoinKeyword { - Join, - JoinAny, - JoinNone, +pub enum JoinKeyword<'a> { + Join(Symbol<'a>), + JoinAny(Symbol<'a>), + JoinNone(Symbol<'a>), } // ----------------------------------------------------------------------------- pub fn action_block(s: Span) -> IResult { alt(( - map(statement_or_null, |x| ActionBlock::Statement(x)), + map(statement_or_null, |x| ActionBlock::StatementOrNull(x)), action_block_else, ))(s) } pub fn action_block_else(s: Span) -> IResult { - let (s, x) = opt(statement)(s)?; - let (s, _) = symbol("else")(s)?; - let (s, y) = statement_or_null(s)?; - Ok((s, ActionBlock::Else(ActionBlockElse { nodes: (x, y) }))) + let (s, a) = opt(statement)(s)?; + let (s, b) = symbol("else")(s)?; + let (s, c) = statement_or_null(s)?; + Ok((s, ActionBlock::Else(ActionBlockElse { nodes: (a, b, c) }))) } pub fn seq_block(s: Span) -> IResult { - let (s, _) = symbol("begin")(s)?; - let (s, x) = opt(preceded(symbol(":"), block_identifier))(s)?; - let (s, y) = many0(block_item_declaration)(s)?; - let (s, z) = many0(statement_or_null)(s)?; - let (s, _) = symbol("end")(s)?; - let (s, v) = opt(preceded(symbol(":"), block_identifier))(s)?; + let (s, a) = symbol("begin")(s)?; + let (s, b) = opt(pair(symbol(":"), block_identifier))(s)?; + let (s, c) = many0(block_item_declaration)(s)?; + let (s, d) = many0(statement_or_null)(s)?; + let (s, e) = symbol("end")(s)?; + let (s, f) = opt(pair(symbol(":"), block_identifier))(s)?; Ok(( s, SeqBlock { - nodes: (x, y, z, v), + nodes: (a, b, c, d, e, f), }, )) } pub fn par_block(s: Span) -> IResult { - let (s, _) = symbol("fork")(s)?; - let (s, x) = opt(preceded(symbol(":"), block_identifier))(s)?; - let (s, y) = many0(block_item_declaration)(s)?; - let (s, z) = many0(statement_or_null)(s)?; - let (s, v) = join_keyword(s)?; - let (s, w) = opt(preceded(symbol(":"), block_identifier))(s)?; + let (s, a) = symbol("fork")(s)?; + let (s, b) = opt(pair(symbol(":"), block_identifier))(s)?; + let (s, c) = many0(block_item_declaration)(s)?; + let (s, d) = many0(statement_or_null)(s)?; + let (s, e) = join_keyword(s)?; + let (s, f) = opt(pair(symbol(":"), block_identifier))(s)?; Ok(( s, ParBlock { - nodes: (x, y, z, v, w), + nodes: (a, b, c, d, e, f), }, )) } pub fn join_keyword(s: Span) -> IResult { alt(( - map(symbol("join_any"), |_| JoinKeyword::JoinAny), - map(symbol("join_none"), |_| JoinKeyword::JoinNone), - map(symbol("join"), |_| JoinKeyword::Join), + map(symbol("join_any"), |x| JoinKeyword::JoinAny(x)), + map(symbol("join_none"), |x| JoinKeyword::JoinNone(x)), + map(symbol("join"), |x| JoinKeyword::Join(x)), ))(s) } diff --git a/src/parser/behavioral_statements/procedural_blocks_and_assignments.rs b/src/parser/behavioral_statements/procedural_blocks_and_assignments.rs index 37a76f8..e650e65 100644 --- a/src/parser/behavioral_statements/procedural_blocks_and_assignments.rs +++ b/src/parser/behavioral_statements/procedural_blocks_and_assignments.rs @@ -1,32 +1,31 @@ use crate::parser::*; use nom::branch::*; use nom::combinator::*; -use nom::sequence::*; use nom::IResult; // ----------------------------------------------------------------------------- #[derive(Debug)] pub struct InitialConstruct<'a> { - pub nodes: (StatementOrNull<'a>,), + pub nodes: (Symbol<'a>, StatementOrNull<'a>), } #[derive(Debug)] pub struct AlwaysConstruct<'a> { - pub nodes: (AlwaysKeyword, Statement<'a>), + pub nodes: (AlwaysKeyword<'a>, Statement<'a>), } #[derive(Debug)] -pub enum AlwaysKeyword { - Always, - AlwaysComb, - AlwaysLatch, - AlwaysFf, +pub enum AlwaysKeyword<'a> { + Always(Symbol<'a>), + AlwaysComb(Symbol<'a>), + AlwaysLatch(Symbol<'a>), + AlwaysFf(Symbol<'a>), } #[derive(Debug)] pub struct FinalConstruct<'a> { - pub nodes: (FunctionStatement<'a>,), + pub nodes: (Symbol<'a>, FunctionStatement<'a>), } #[derive(Debug)] @@ -34,17 +33,22 @@ pub enum BlockingAssignment<'a> { Variable(BlockingAssignmentVariable<'a>), NonrangeVariable(BlockingAssignmentNonrangeVariable<'a>), HierarchicalVariable(BlockingAssignmentHierarchicalVariable<'a>), - Operator(OperatorAssignment<'a>), + OperatorAssignment(OperatorAssignment<'a>), } #[derive(Debug)] pub struct BlockingAssignmentVariable<'a> { - pub nodes: (VariableLvalue<'a>, DelayOrEventControl<'a>, Expression<'a>), + pub nodes: ( + VariableLvalue<'a>, + Symbol<'a>, + DelayOrEventControl<'a>, + Expression<'a>, + ), } #[derive(Debug)] pub struct BlockingAssignmentNonrangeVariable<'a> { - pub nodes: (NonrangeVariableLvalue<'a>, DynamicArrayNew<'a>), + pub nodes: (NonrangeVariableLvalue<'a>, Symbol<'a>, DynamicArrayNew<'a>), } #[derive(Debug)] @@ -53,6 +57,7 @@ pub struct BlockingAssignmentHierarchicalVariable<'a> { Option>, HierarchicalVariableIdentifier<'a>, Select<'a>, + Symbol<'a>, ClassNew<'a>, ), } @@ -71,6 +76,7 @@ pub struct AssignmentOperator<'a> { pub struct NonblockingAssignment<'a> { pub nodes: ( VariableLvalue<'a>, + Symbol<'a>, Option>, Expression<'a>, ), @@ -78,46 +84,76 @@ pub struct NonblockingAssignment<'a> { #[derive(Debug)] pub enum ProceduralContinuousAssignment<'a> { - Assign(VariableAssignment<'a>), - Deassign(VariableLvalue<'a>), - ForceVariable(VariableAssignment<'a>), - ForceNet(NetAssignment<'a>), - ReleaseVariable(VariableLvalue<'a>), - ReleaseNet(NetLvalue<'a>), + Assign(ProceduralContinuousAssignmentAssign<'a>), + Deassign(ProceduralContinuousAssignmentDeassign<'a>), + ForceVariable(ProceduralContinuousAssignmentForceVariable<'a>), + ForceNet(ProceduralContinuousAssignmentForceNet<'a>), + ReleaseVariable(ProceduralContinuousAssignmentReleaseVariable<'a>), + ReleaseNet(ProceduralContinuousAssignmentReleaseNet<'a>), +} + +#[derive(Debug)] +pub struct ProceduralContinuousAssignmentAssign<'a> { + pub nodes: (Symbol<'a>, VariableAssignment<'a>), +} + +#[derive(Debug)] +pub struct ProceduralContinuousAssignmentDeassign<'a> { + pub nodes: (Symbol<'a>, VariableLvalue<'a>), +} + +#[derive(Debug)] +pub struct ProceduralContinuousAssignmentForceVariable<'a> { + pub nodes: (Symbol<'a>, VariableAssignment<'a>), +} + +#[derive(Debug)] +pub struct ProceduralContinuousAssignmentForceNet<'a> { + pub nodes: (Symbol<'a>, NetAssignment<'a>), +} + +#[derive(Debug)] +pub struct ProceduralContinuousAssignmentReleaseVariable<'a> { + pub nodes: (Symbol<'a>, VariableLvalue<'a>), +} + +#[derive(Debug)] +pub struct ProceduralContinuousAssignmentReleaseNet<'a> { + pub nodes: (Symbol<'a>, NetLvalue<'a>), } #[derive(Debug)] pub struct VariableAssignment<'a> { - pub nodes: (VariableLvalue<'a>, Expression<'a>), + pub nodes: (VariableLvalue<'a>, Symbol<'a>, Expression<'a>), } // ----------------------------------------------------------------------------- pub fn initial_construct(s: Span) -> IResult { - let (s, _) = symbol("initial")(s)?; - let (s, x) = statement_or_null(s)?; - Ok((s, InitialConstruct { nodes: (x,) })) + let (s, a) = symbol("initial")(s)?; + let (s, b) = statement_or_null(s)?; + Ok((s, InitialConstruct { nodes: (a, b) })) } pub fn always_construct(s: Span) -> IResult { - let (s, x) = always_keyword(s)?; - let (s, y) = statement(s)?; - Ok((s, AlwaysConstruct { nodes: (x, y) })) + let (s, a) = always_keyword(s)?; + let (s, b) = statement(s)?; + Ok((s, AlwaysConstruct { nodes: (a, b) })) } pub fn always_keyword(s: Span) -> IResult { alt(( - map(symbol("always_comb"), |_| AlwaysKeyword::AlwaysComb), - map(symbol("always_latch"), |_| AlwaysKeyword::AlwaysLatch), - map(symbol("always_ff"), |_| AlwaysKeyword::AlwaysFf), - map(symbol("always"), |_| AlwaysKeyword::Always), + map(symbol("always_comb"), |x| AlwaysKeyword::AlwaysComb(x)), + map(symbol("always_latch"), |x| AlwaysKeyword::AlwaysLatch(x)), + map(symbol("always_ff"), |x| AlwaysKeyword::AlwaysFf(x)), + map(symbol("always"), |x| AlwaysKeyword::Always(x)), ))(s) } pub fn final_construct(s: Span) -> IResult { - let (s, _) = symbol("final")(s)?; - let (s, x) = function_statement(s)?; - Ok((s, FinalConstruct { nodes: (x,) })) + let (s, a) = symbol("final")(s)?; + let (s, b) = function_statement(s)?; + Ok((s, FinalConstruct { nodes: (a, b) })) } pub fn blocking_assignment(s: Span) -> IResult { @@ -125,50 +161,56 @@ pub fn blocking_assignment(s: Span) -> IResult { blocking_assignment_variable, blocking_assignment_nonrange_variable, blocking_assignment_hierarchical_variable, - map(operator_assignment, |x| BlockingAssignment::Operator(x)), + map(operator_assignment, |x| { + BlockingAssignment::OperatorAssignment(x) + }), ))(s) } pub fn blocking_assignment_variable(s: Span) -> IResult { - let (s, x) = variable_lvalue(s)?; - let (s, _) = symbol("=")(s)?; - let (s, y) = delay_or_event_control(s)?; - let (s, z) = expression(s)?; + let (s, a) = variable_lvalue(s)?; + let (s, b) = symbol("=")(s)?; + let (s, c) = delay_or_event_control(s)?; + let (s, d) = expression(s)?; Ok(( s, - BlockingAssignment::Variable(BlockingAssignmentVariable { nodes: (x, y, z) }), + BlockingAssignment::Variable(BlockingAssignmentVariable { + nodes: (a, b, c, d), + }), )) } pub fn blocking_assignment_nonrange_variable(s: Span) -> IResult { - let (s, x) = nonrange_variable_lvalue(s)?; - let (s, _) = symbol("=")(s)?; - let (s, y) = dynamic_array_new(s)?; + let (s, a) = nonrange_variable_lvalue(s)?; + let (s, b) = symbol("=")(s)?; + let (s, c) = dynamic_array_new(s)?; Ok(( s, - BlockingAssignment::NonrangeVariable(BlockingAssignmentNonrangeVariable { nodes: (x, y) }), + BlockingAssignment::NonrangeVariable(BlockingAssignmentNonrangeVariable { + nodes: (a, b, c), + }), )) } pub fn blocking_assignment_hierarchical_variable(s: Span) -> IResult { - let (s, x) = opt(implicit_class_handle_or_class_scope_or_package_scope)(s)?; - let (s, y) = hierarchical_variable_identifier(s)?; - let (s, z) = select(s)?; - let (s, _) = symbol("=")(s)?; - let (s, v) = class_new(s)?; + let (s, a) = opt(implicit_class_handle_or_class_scope_or_package_scope)(s)?; + let (s, b) = hierarchical_variable_identifier(s)?; + let (s, c) = select(s)?; + let (s, d) = symbol("=")(s)?; + let (s, e) = class_new(s)?; Ok(( s, BlockingAssignment::HierarchicalVariable(BlockingAssignmentHierarchicalVariable { - nodes: (x, y, z, v), + nodes: (a, b, c, d, e), }), )) } pub fn operator_assignment(s: Span) -> IResult { - let (s, x) = variable_lvalue(s)?; - let (s, y) = assignment_operator(s)?; - let (s, z) = expression(s)?; - Ok((s, OperatorAssignment { nodes: (x, y, z) })) + let (s, a) = variable_lvalue(s)?; + let (s, b) = assignment_operator(s)?; + let (s, c) = expression(s)?; + Ok((s, OperatorAssignment { nodes: (a, b, c) })) } pub fn assignment_operator(s: Span) -> IResult { @@ -190,39 +232,110 @@ pub fn assignment_operator(s: Span) -> IResult { } pub fn nonblocking_assignment(s: Span) -> IResult { - let (s, x) = variable_lvalue(s)?; - let (s, _) = symbol("<=")(s)?; - let (s, y) = opt(delay_or_event_control)(s)?; - let (s, z) = expression(s)?; - Ok((s, NonblockingAssignment { nodes: (x, y, z) })) + let (s, a) = variable_lvalue(s)?; + let (s, b) = symbol("<=")(s)?; + let (s, c) = opt(delay_or_event_control)(s)?; + let (s, d) = expression(s)?; + Ok(( + s, + NonblockingAssignment { + nodes: (a, b, c, d), + }, + )) } pub fn procedural_continuous_assignment(s: Span) -> IResult { alt(( - map(preceded(symbol("assign"), variable_assignment), |x| { - ProceduralContinuousAssignment::Assign(x) - }), - map(preceded(symbol("deassign"), variable_lvalue), |x| { - ProceduralContinuousAssignment::Deassign(x) - }), - map(preceded(symbol("force"), variable_assignment), |x| { - ProceduralContinuousAssignment::ForceVariable(x) - }), - map(preceded(symbol("force"), net_assignment), |x| { - ProceduralContinuousAssignment::ForceNet(x) - }), - map(preceded(symbol("release"), variable_lvalue), |x| { - ProceduralContinuousAssignment::ReleaseVariable(x) - }), - map(preceded(symbol("release"), net_lvalue), |x| { - ProceduralContinuousAssignment::ReleaseNet(x) - }), + procedural_continuous_assignment_assign, + procedural_continuous_assignment_deassign, + procedural_continuous_assignment_force_variable, + procedural_continuous_assignment_force_net, + procedural_continuous_assignment_release_variable, + procedural_continuous_assignment_release_net, ))(s) } -pub fn variable_assignment(s: Span) -> IResult { - let (s, x) = variable_lvalue(s)?; - let (s, _) = symbol("=")(s)?; - let (s, y) = expression(s)?; - Ok((s, VariableAssignment { nodes: (x, y) })) +pub fn procedural_continuous_assignment_assign( + s: Span, +) -> IResult { + let (s, a) = symbol("assign")(s)?; + let (s, b) = variable_assignment(s)?; + Ok(( + s, + ProceduralContinuousAssignment::Assign(ProceduralContinuousAssignmentAssign { + nodes: (a, b), + }), + )) +} + +pub fn procedural_continuous_assignment_deassign( + s: Span, +) -> IResult { + let (s, a) = symbol("deassign")(s)?; + let (s, b) = variable_lvalue(s)?; + Ok(( + s, + ProceduralContinuousAssignment::Deassign(ProceduralContinuousAssignmentDeassign { + nodes: (a, b), + }), + )) +} + +pub fn procedural_continuous_assignment_force_variable( + s: Span, +) -> IResult { + let (s, a) = symbol("force")(s)?; + let (s, b) = variable_assignment(s)?; + Ok(( + s, + ProceduralContinuousAssignment::ForceVariable( + ProceduralContinuousAssignmentForceVariable { nodes: (a, b) }, + ), + )) +} + +pub fn procedural_continuous_assignment_force_net( + s: Span, +) -> IResult { + let (s, a) = symbol("force")(s)?; + let (s, b) = net_assignment(s)?; + Ok(( + s, + ProceduralContinuousAssignment::ForceNet(ProceduralContinuousAssignmentForceNet { + nodes: (a, b), + }), + )) +} + +pub fn procedural_continuous_assignment_release_variable( + s: Span, +) -> IResult { + let (s, a) = symbol("release")(s)?; + let (s, b) = variable_lvalue(s)?; + Ok(( + s, + ProceduralContinuousAssignment::ReleaseVariable( + ProceduralContinuousAssignmentReleaseVariable { nodes: (a, b) }, + ), + )) +} + +pub fn procedural_continuous_assignment_release_net( + s: Span, +) -> IResult { + let (s, a) = symbol("release")(s)?; + let (s, b) = net_lvalue(s)?; + Ok(( + s, + ProceduralContinuousAssignment::ReleaseNet(ProceduralContinuousAssignmentReleaseNet { + nodes: (a, b), + }), + )) +} + +pub fn variable_assignment(s: Span) -> IResult { + let (s, a) = variable_lvalue(s)?; + let (s, b) = symbol("=")(s)?; + let (s, c) = expression(s)?; + Ok((s, VariableAssignment { nodes: (a, b, c) })) } diff --git a/src/parser/behavioral_statements/statements.rs b/src/parser/behavioral_statements/statements.rs index eb7eeb3..7aeee47 100644 --- a/src/parser/behavioral_statements/statements.rs +++ b/src/parser/behavioral_statements/statements.rs @@ -10,13 +10,18 @@ use nom::IResult; #[derive(Debug)] pub enum StatementOrNull<'a> { Statement(Statement<'a>), - Attribute(Vec>), + Attribute(StatementOrNullAttribute<'a>), +} + +#[derive(Debug)] +pub struct StatementOrNullAttribute<'a> { + pub nodes: (Vec>, Symbol<'a>), } #[derive(Debug)] pub struct Statement<'a> { pub nodes: ( - Option>, + Option<(BlockIdentifier<'a>, Symbol<'a>)>, Vec>, StatementItem<'a>, ), @@ -24,12 +29,12 @@ pub struct Statement<'a> { #[derive(Debug)] pub enum StatementItem<'a> { - BlockingAssignment(Box>), - NonblockingAssignment(Box>), - ProceduralContinuousAssignment(Box>), + BlockingAssignment(Box<(BlockingAssignment<'a>, Symbol<'a>)>), + NonblockingAssignment(Box<(NonblockingAssignment<'a>, Symbol<'a>)>), + ProceduralContinuousAssignment(Box<(ProceduralContinuousAssignment<'a>, Symbol<'a>)>), CaseStatement(Box>), ConditionalStatement(Box>), - IncOrDecExpression(Box>), + IncOrDecExpression(Box<(IncOrDecExpression<'a>, Symbol<'a>)>), SubroutineCallStatement(Box>), DisableStatement(Box>), EventTrigger(Box>), @@ -40,7 +45,7 @@ pub enum StatementItem<'a> { SeqBlock(Box>), WaitStatement(Box>), ProceduralAssertionStatement(Box>), - ClockingDrive(Box>), + ClockingDrive(Box<(ClockingDrive<'a>, Symbol<'a>)>), RandsequenceStatement(Box>), RandcaseStatement(Box>), ExpectPropertyStatement(Box>), @@ -54,12 +59,17 @@ pub struct FunctionStatement<'a> { #[derive(Debug)] pub enum FunctionStatementOrNull<'a> { Statement(FunctionStatement<'a>), - Attribute(Vec>), + Attribute(FunctionStatementOrNullAttribute<'a>), +} + +#[derive(Debug)] +pub struct FunctionStatementOrNullAttribute<'a> { + pub nodes: (Vec>, Symbol<'a>), } #[derive(Debug)] pub struct VariableIdentifierList<'a> { - pub nodes: (Vec>,), + pub nodes: (List, VariableIdentifier<'a>>,), } // ----------------------------------------------------------------------------- @@ -67,38 +77,44 @@ pub struct VariableIdentifierList<'a> { pub fn statement_or_null(s: Span) -> IResult { alt(( map(statement, |x| StatementOrNull::Statement(x)), - map(terminated(many0(attribute_instance), symbol(";")), |x| { - StatementOrNull::Attribute(x) - }), + statement_or_null_attribute, ))(s) } +pub fn statement_or_null_attribute(s: Span) -> IResult { + let (s, a) = many0(attribute_instance)(s)?; + let (s, b) = symbol(";")(s)?; + Ok(( + s, + StatementOrNull::Attribute(StatementOrNullAttribute { nodes: (a, b) }), + )) +} + pub fn statement(s: Span) -> IResult { - let (s, x) = opt(terminated(block_identifier, symbol(":")))(s)?; - let (s, y) = many0(attribute_instance)(s)?; - let (s, z) = statement_item(s)?; - Ok((s, Statement { nodes: (x, y, z) })) + let (s, a) = opt(pair(block_identifier, symbol(":")))(s)?; + let (s, b) = many0(attribute_instance)(s)?; + let (s, c) = statement_item(s)?; + Ok((s, Statement { nodes: (a, b, c) })) } pub fn statement_item(s: Span) -> IResult { alt(( - map(terminated(blocking_assignment, symbol(";")), |x| { + map(pair(blocking_assignment, symbol(";")), |x| { StatementItem::BlockingAssignment(Box::new(x)) }), - map(terminated(nonblocking_assignment, symbol(";")), |x| { + map(pair(nonblocking_assignment, symbol(";")), |x| { StatementItem::NonblockingAssignment(Box::new(x)) }), - map( - terminated(procedural_continuous_assignment, symbol(";")), - |x| StatementItem::ProceduralContinuousAssignment(Box::new(x)), - ), + map(pair(procedural_continuous_assignment, symbol(";")), |x| { + StatementItem::ProceduralContinuousAssignment(Box::new(x)) + }), map(case_statement, |x| { StatementItem::CaseStatement(Box::new(x)) }), map(conditional_statement, |x| { StatementItem::ConditionalStatement(Box::new(x)) }), - map(terminated(inc_or_dec_expression, symbol(";")), |x| { + map(pair(inc_or_dec_expression, symbol(";")), |x| { StatementItem::IncOrDecExpression(Box::new(x)) }), map(subroutine_call_statement, |x| { @@ -125,7 +141,7 @@ pub fn statement_item(s: Span) -> IResult { map(procedural_assertion_statement, |x| { StatementItem::ProceduralAssertionStatement(Box::new(x)) }), - map(terminated(clocking_drive, symbol(";")), |x| { + map(pair(clocking_drive, symbol(";")), |x| { StatementItem::ClockingDrive(Box::new(x)) }), map(randsequence_statement, |x| { @@ -141,8 +157,8 @@ pub fn statement_item(s: Span) -> IResult { } pub fn function_statement(s: Span) -> IResult { - let (s, x) = statement(s)?; - Ok((s, FunctionStatement { nodes: (x,) })) + let (s, a) = statement(s)?; + Ok((s, FunctionStatement { nodes: (a,) })) } pub fn function_statement_or_null(s: Span) -> IResult { @@ -150,13 +166,20 @@ pub fn function_statement_or_null(s: Span) -> IResult IResult { - let (s, x) = separated_nonempty_list(symbol(","), variable_identifier)(s)?; - Ok((s, VariableIdentifierList { nodes: (x,) })) +pub fn function_statement_or_null_attribute(s: Span) -> IResult { + let (s, a) = many0(attribute_instance)(s)?; + let (s, b) = symbol(";")(s)?; + Ok(( + s, + FunctionStatementOrNull::Attribute(FunctionStatementOrNullAttribute { nodes: (a, b) }), + )) +} + +pub fn variable_identifier_list(s: Span) -> IResult { + let (s, a) = list(symbol(","), variable_identifier)(s)?; + Ok((s, VariableIdentifierList { nodes: (a,) })) } diff --git a/src/parser/general/identifiers.rs b/src/parser/general/identifiers.rs index 1e7f601..688399c 100644 --- a/src/parser/general/identifiers.rs +++ b/src/parser/general/identifiers.rs @@ -497,20 +497,20 @@ pub struct VariableIdentifier<'a> { #[derive(Debug)] pub enum ImplicitClassHandleOrClassScopeOrPackageScope<'a> { - ImplicitClassHandle(ImplicitClassHandle<'a>), + ImplicitClassHandle((ImplicitClassHandle<'a>, Symbol<'a>)), ClassScope(ClassScope<'a>), PackageScope(PackageScope<'a>), } #[derive(Debug)] pub enum ImplicitClassHandleOrPackageScope<'a> { - ImplicitClassHandle(ImplicitClassHandle<'a>), + ImplicitClassHandle((ImplicitClassHandle<'a>, Symbol<'a>)), PackageScope(PackageScope<'a>), } #[derive(Debug)] pub enum ImplicitClassHandleOrClassScope<'a> { - ImplicitClassHandle(ImplicitClassHandle<'a>), + ImplicitClassHandle((ImplicitClassHandle<'a>, Symbol<'a>)), ClassScope(ClassScope<'a>), } @@ -959,7 +959,7 @@ pub fn implicit_class_handle_or_class_scope_or_package_scope( s: Span, ) -> IResult { alt(( - map(terminated(implicit_class_handle, symbol(".")), |x| { + map(pair(implicit_class_handle, symbol(".")), |x| { ImplicitClassHandleOrClassScopeOrPackageScope::ImplicitClassHandle(x) }), map(class_scope, |x| { @@ -975,7 +975,7 @@ pub fn implicit_class_handle_or_package_scope( s: Span, ) -> IResult { alt(( - map(terminated(implicit_class_handle, symbol(".")), |x| { + map(pair(implicit_class_handle, symbol(".")), |x| { ImplicitClassHandleOrPackageScope::ImplicitClassHandle(x) }), map(package_scope, |x| { @@ -988,7 +988,7 @@ pub fn implicit_class_handle_or_class_scope( s: Span, ) -> IResult { alt(( - map(terminated(implicit_class_handle, symbol(".")), |x| { + map(pair(implicit_class_handle, symbol(".")), |x| { ImplicitClassHandleOrClassScope::ImplicitClassHandle(x) }), map(class_scope, |x| {