Skip to content

Commit e24b473

Browse files
author
yousifB
committed
Fix parsing type equality
1 parent 2a4d5d0 commit e24b473

6 files changed

Lines changed: 102 additions & 21 deletions

File tree

sv-parser-parser/src/behavioral_statements/case_statements.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,14 @@ pub(crate) fn case_keyword(s: Span) -> IResult<Span, CaseKeyword> {
7575
#[tracable_parser]
7676
#[packrat_parser]
7777
pub(crate) fn case_expression(s: Span) -> IResult<Span, CaseExpression> {
78-
let (s, a) = expression(s)?;
78+
let (s, a) = alt((
79+
map(expression, |x| {
80+
CaseExpressionExpression::Expression(Box::new(x))
81+
}),
82+
map(type_reference, |x| {
83+
CaseExpressionExpression::TypeReference(Box::new(x))
84+
}),
85+
))(s)?;
7986
Ok((s, CaseExpression { nodes: (a,) }))
8087
}
8188

@@ -160,7 +167,14 @@ pub(crate) fn case_inside_item_nondefault(s: Span) -> IResult<Span, CaseInsideIt
160167
#[tracable_parser]
161168
#[packrat_parser]
162169
pub(crate) fn case_item_expression(s: Span) -> IResult<Span, CaseItemExpression> {
163-
let (s, a) = expression(s)?;
170+
let (s, a) = alt((
171+
map(expression, |x| {
172+
CaseExpressionExpression::Expression(Box::new(x))
173+
}),
174+
map(type_reference, |x| {
175+
CaseExpressionExpression::TypeReference(Box::new(x))
176+
}),
177+
))(s)?;
164178
Ok((s, CaseItemExpression { nodes: (a,) }))
165179
}
166180

sv-parser-parser/src/expressions/expressions.rs

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -305,16 +305,40 @@ pub(crate) fn expression_operator_assignment(s: Span) -> IResult<Span, Expressio
305305
#[tracable_parser]
306306
#[packrat_parser]
307307
pub(crate) fn expression_binary(s: Span) -> IResult<Span, Expression> {
308-
let (s, a) = expression(s)?;
308+
let (s, a) = alt((
309+
map(expression, |x| {
310+
ExpressionBinaryOperand::Expression(Box::new(x))
311+
}),
312+
map(type_reference, |x| {
313+
ExpressionBinaryOperand::TypeReference(Box::new(x))
314+
}),
315+
))(s)?;
316+
let is_equality = peek(alt((symbol("=="), symbol("!="))))(s).is_ok();
309317
let (s, b) = binary_operator(s)?;
310318
let (s, c) = many0(attribute_instance)(s)?;
311-
let (s, d) = expression(s)?;
312-
Ok((
313-
s,
314-
Expression::Binary(Box::new(ExpressionBinary {
315-
nodes: (a, b, c, d),
316-
})),
317-
))
319+
let (s, d) = alt((
320+
map(expression, |x| {
321+
ExpressionBinaryOperand::Expression(Box::new(x))
322+
}),
323+
map(type_reference, |x| {
324+
ExpressionBinaryOperand::TypeReference(Box::new(x))
325+
}),
326+
))(s)?;
327+
328+
// Enforces Footnote (40) in IEEE STD 1800 - 2017
329+
let op1_is_type_ref = matches!(a, ExpressionBinaryOperand::TypeReference(_));
330+
let op2_is_type_ref = matches!(d, ExpressionBinaryOperand::TypeReference(_));
331+
if !(op1_is_type_ref || op2_is_type_ref) || (is_equality && op1_is_type_ref && op2_is_type_ref)
332+
{
333+
Ok((
334+
s,
335+
Expression::Binary(Box::new(ExpressionBinary {
336+
nodes: (a, b, c, d),
337+
})),
338+
))
339+
} else {
340+
Err(Err::Error(make_error(s, ErrorKind::Fail)))
341+
}
318342
}
319343

320344
#[tracable_parser]

sv-parser-parser/src/tests.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@ mod unit {
5454

5555
#[test]
5656
fn test_data_declaration() {
57-
// Implicit data_type is not allowed unless the `var` keyword is used.
58-
test!(data_declaration, "logic x = 0;", Ok((_, _)));
59-
test!(data_declaration, " x = 0;", Err(_));
60-
test!(data_declaration, "var logic x = 0;", Ok((_, _)));
61-
test!(data_declaration, "var x = 0;", Ok((_, _)));
62-
test!(data_declaration, "const logic x = 0;", Ok((_, _)));
63-
test!(data_declaration, "const x = 0;", Err(_));
57+
// Implicit data_type is not allowed unless the `var` keyword is used.
58+
test!(data_declaration, "logic x = 0;", Ok((_, _)));
59+
test!(data_declaration, " x = 0;", Err(_));
60+
test!(data_declaration, "var logic x = 0;", Ok((_, _)));
61+
test!(data_declaration, "var x = 0;", Ok((_, _)));
62+
test!(data_declaration, "const logic x = 0;", Ok((_, _)));
63+
test!(data_declaration, "const x = 0;", Err(_));
6464
}
6565

6666
#[test]
@@ -332,6 +332,14 @@ mod unit {
332332
test!(expression, "(!a ? 0 : !b : 1 : c ? 0 : 1)", Ok((_, _)));
333333
}
334334

335+
#[test]
336+
fn test_bin_op_expression() {
337+
test!(expression, "type(logic) == type(logic)", Ok((_, _)));
338+
test!(expression, "type(logic) != type(logic)", Ok((_, _)));
339+
test!(expression, "type(logic) + type(logic)", Err(_));
340+
test!(expression, "type(logic) == a", Err(_));
341+
}
342+
335343
#[test]
336344
fn test_text_macro_definition() {
337345
test!(text_macro_definition, r##"`define a b c"##, Ok((_, _)));

sv-parser-syntaxtree/src/behavioral_statements/case_statements.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,13 @@ pub enum CaseKeyword {
5656

5757
#[derive(Clone, Debug, PartialEq, Node)]
5858
pub struct CaseExpression {
59-
pub nodes: (Expression,),
59+
pub nodes: (CaseExpressionExpression,),
60+
}
61+
62+
#[derive(Clone, Debug, PartialEq, Node)]
63+
pub enum CaseExpressionExpression {
64+
Expression(Box<Expression>),
65+
TypeReference(Box<TypeReference>),
6066
}
6167

6268
#[derive(Clone, Debug, PartialEq, Node)]
@@ -104,7 +110,7 @@ pub struct CaseInsideItemNondefault {
104110

105111
#[derive(Clone, Debug, PartialEq, Node)]
106112
pub struct CaseItemExpression {
107-
pub nodes: (Expression,),
113+
pub nodes: (CaseExpressionExpression,),
108114
}
109115

110116
#[derive(Clone, Debug, PartialEq, Node)]

sv-parser-syntaxtree/src/expressions/expressions.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,19 @@ pub struct ExpressionOperatorAssignment {
149149
#[derive(Clone, Debug, PartialEq, Node)]
150150
pub struct ExpressionBinary {
151151
pub nodes: (
152-
Expression,
152+
ExpressionBinaryOperand,
153153
BinaryOperator,
154154
Vec<AttributeInstance>,
155-
Expression,
155+
ExpressionBinaryOperand,
156156
),
157157
}
158158

159+
#[derive(Clone, Debug, PartialEq, Node)]
160+
pub enum ExpressionBinaryOperand {
161+
Expression(Box<Expression>),
162+
TypeReference(Box<TypeReference>),
163+
}
164+
159165
#[derive(Clone, Debug, PartialEq, Node)]
160166
pub struct TaggedUnionExpression {
161167
pub nodes: (Keyword, MemberIdentifier, Option<Expression>),

sv-parser/src/lib.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,4 +451,27 @@ endmodule"##;
451451
let ret = parse_sv_str(src, &path, &defines, &[""], false, false);
452452
assert!(ret.is_ok());
453453
}
454+
455+
#[test]
456+
fn test_type_equality() {
457+
let src = r##"module top #( parameter type T = type(logic[11:0]) )
458+
();
459+
initial begin
460+
case (type(T))
461+
type(logic[11:0]) : ;
462+
default : $stop;
463+
endcase
464+
if (type(T) == type(logic[12:0])) $stop;
465+
if (type(T) != type(logic[11:0])) $stop;
466+
if (type(T) === type(logic[12:0])) $stop;
467+
if (type(T) !== type(logic[11:0])) $stop;
468+
$finish;
469+
end
470+
endmodule"##;
471+
472+
let path = PathBuf::from("");
473+
let defines = HashMap::new();
474+
let ret = parse_sv_str(src, &path, &defines, &[""], false, false);
475+
assert!(ret.is_ok());
476+
}
454477
}

0 commit comments

Comments
 (0)