From 46f61155cb54037cf4d5a2860255a88eb1de3629 Mon Sep 17 00:00:00 2001 From: dalance Date: Mon, 1 Jul 2019 20:02:46 +0900 Subject: [PATCH] Add lvalues --- src/lib.rs | 1 + src/lvalues.rs | 173 +++++++++++++++++++++++++++++++++++++++++++++++ src/primaries.rs | 2 +- src/util.rs | 31 +++++++++ 4 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 src/lvalues.rs diff --git a/src/lib.rs b/src/lib.rs index 63db6b0..4b23b31 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ pub mod attributes; pub mod comments; pub mod identifiers; +pub mod lvalues; pub mod numbers; pub mod operators; pub mod primaries; diff --git a/src/lvalues.rs b/src/lvalues.rs new file mode 100644 index 0000000..581a7f0 --- /dev/null +++ b/src/lvalues.rs @@ -0,0 +1,173 @@ +use crate::identifiers::*; +use crate::primaries::*; +use crate::util::*; +use nom::branch::*; +use nom::bytes::complete::*; +use nom::combinator::*; +use nom::multi::*; +use nom::sequence::*; +use nom::IResult; + +// ----------------------------------------------------------------------------- + +#[derive(Debug)] +pub enum NetLvalue<'a> { + Identifier(NetLvalueIdentifier<'a>), + Lvalue(Vec>), + Pattern(NetLvaluePattern<'a>), +} + +#[derive(Debug)] +pub struct NetLvalueIdentifier<'a> { + identifier: ScopedIdentifier<'a>, + select: ConstantSelect<'a>, +} + +#[derive(Debug)] +pub struct NetLvaluePattern<'a> { + r#type: Option>, + lvalue: AssignmentPatternNetLvalue<'a>, +} + +#[derive(Debug)] +pub enum VariableLvalue<'a> { + Identifier(VariableLvalueIdentifier<'a>), + Lvalue(Vec>), + Pattern(VariableLvaluePattern<'a>), + Concatenation(StreamingConcatenation<'a>), +} + +#[derive(Debug)] +pub struct VariableLvalueIdentifier<'a> { + scope: Option>, + identifier: HierarchicalIdentifier<'a>, + select: Select<'a>, +} + +#[derive(Debug)] +pub struct VariableLvaluePattern<'a> { + r#type: Option>, + lvalue: AssignmentPatternVariableLvalue<'a>, +} + +#[derive(Debug)] +pub struct NonrangeVariableLvalue<'a> { + scope: Option>, + identifier: HierarchicalIdentifier<'a>, + select: Select<'a>, +} + +// ----------------------------------------------------------------------------- + +pub fn net_lvalue(s: &str) -> IResult<&str, NetLvalue> { + alt((net_lvalue_identifier, net_lvalue_lvalue, net_lvalue_pattern))(s) +} + +pub fn net_lvalue_identifier(s: &str) -> IResult<&str, NetLvalue> { + let (s, identifier) = ps_or_hierarchical_net_identifier(s)?; + let (s, select) = sp(constant_select)(s)?; + Ok(( + s, + NetLvalue::Identifier(NetLvalueIdentifier { identifier, select }), + )) +} + +pub fn net_lvalue_pattern(s: &str) -> IResult<&str, NetLvalue> { + let (s, r#type) = opt(assignment_pattern_expression_type)(s)?; + let (s, lvalue) = sp(assignment_pattern_net_lvalue)(s)?; + Ok((s, NetLvalue::Pattern(NetLvaluePattern { r#type, lvalue }))) +} + +pub fn net_lvalue_lvalue(s: &str) -> IResult<&str, NetLvalue> { + let (s, _) = tag("{")(s)?; + let (s, x) = sp(net_lvalue)(s)?; + let (s, y) = many0(preceded(sp(tag(",")), sp(net_lvalue)))(s)?; + let (s, _) = tag("}")(s)?; + + let mut ret = Vec::new(); + ret.push(x); + for y in y { + ret.push(y); + } + + Ok((s, NetLvalue::Lvalue(ret))) +} + +pub fn variable_lvalue(s: &str) -> IResult<&str, VariableLvalue> { + alt(( + variable_lvalue_identifier, + variable_lvalue_lvalue, + variable_lvalue_pattern, + map(streaming_concatenation, |x| { + VariableLvalue::Concatenation(x) + }), + ))(s) +} + +pub fn variable_lvalue_identifier(s: &str) -> IResult<&str, VariableLvalue> { + let (s, scope) = opt(alt(( + terminated(implicit_class_handle, sp(tag("."))), + package_scope, + )))(s)?; + let (s, identifier) = sp(hierarchical_variable_identifier)(s)?; + let (s, select) = sp(select)(s)?; + Ok(( + s, + VariableLvalue::Identifier(VariableLvalueIdentifier { + scope, + identifier, + select, + }), + )) +} + +pub fn variable_lvalue_pattern(s: &str) -> IResult<&str, VariableLvalue> { + let (s, r#type) = opt(assignment_pattern_expression_type)(s)?; + let (s, lvalue) = sp(assignment_pattern_variable_lvalue)(s)?; + Ok(( + s, + VariableLvalue::Pattern(VariableLvaluePattern { r#type, lvalue }), + )) +} + +pub fn variable_lvalue_lvalue(s: &str) -> IResult<&str, VariableLvalue> { + let (s, _) = tag("{")(s)?; + let (s, x) = sp(variable_lvalue)(s)?; + let (s, y) = many0(preceded(sp(tag(",")), sp(variable_lvalue)))(s)?; + let (s, _) = tag("}")(s)?; + + let mut ret = Vec::new(); + ret.push(x); + for y in y { + ret.push(y); + } + + Ok((s, VariableLvalue::Lvalue(ret))) +} + +pub fn nonrange_variable_lvalue(s: &str) -> IResult<&str, NonrangeVariableLvalue> { + let (s, scope) = opt(alt(( + terminated(implicit_class_handle, sp(tag("."))), + package_scope, + )))(s)?; + let (s, identifier) = sp(hierarchical_variable_identifier)(s)?; + let (s, select) = sp(nonrange_select)(s)?; + Ok(( + s, + NonrangeVariableLvalue { + scope, + identifier, + select, + }, + )) +} + +// ----------------------------------------------------------------------------- + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test() {} +} diff --git a/src/primaries.rs b/src/primaries.rs index a39d1ca..637506b 100644 --- a/src/primaries.rs +++ b/src/primaries.rs @@ -526,7 +526,7 @@ pub fn select(s: &str) -> IResult<&str, Select> { )) } -pub fn norange_select(s: &str) -> IResult<&str, Select> { +pub fn nonrange_select(s: &str) -> IResult<&str, Select> { let (s, member) = opt(pair( many0(preceded( sp(tag(".")), diff --git a/src/util.rs b/src/util.rs index 8f04abd..33a24e5 100644 --- a/src/util.rs +++ b/src/util.rs @@ -132,6 +132,21 @@ pub struct SequenceMethodCall<'a> { pub raw: Vec<&'a str>, } +#[derive(Debug)] +pub struct AssignmentPatternExpressionType<'a> { + pub raw: Vec<&'a str>, +} + +#[derive(Debug)] +pub struct AssignmentPatternNetLvalue<'a> { + pub raw: Vec<&'a str>, +} + +#[derive(Debug)] +pub struct AssignmentPatternVariableLvalue<'a> { + pub raw: Vec<&'a str>, +} + pub fn class_scope(s: &str) -> IResult<&str, Scope> { Ok((s, Scope::ClassScope)) } @@ -241,3 +256,19 @@ pub fn streaming_concatenation(s: &str) -> IResult<&str, StreamingConcatenation> pub fn sequence_method_call(s: &str) -> IResult<&str, SequenceMethodCall> { Ok((s, SequenceMethodCall { raw: vec![] })) } + +pub fn assignment_pattern_expression_type( + s: &str, +) -> IResult<&str, AssignmentPatternExpressionType> { + Ok((s, AssignmentPatternExpressionType { raw: vec![] })) +} + +pub fn assignment_pattern_net_lvalue(s: &str) -> IResult<&str, AssignmentPatternNetLvalue> { + Ok((s, AssignmentPatternNetLvalue { raw: vec![] })) +} + +pub fn assignment_pattern_variable_lvalue( + s: &str, +) -> IResult<&str, AssignmentPatternVariableLvalue> { + Ok((s, AssignmentPatternVariableLvalue { raw: vec![] })) +}