This commit is contained in:
dalance 2019-08-06 19:05:41 +09:00
parent 0c58a10f36
commit 6a3127951c
5 changed files with 321 additions and 185 deletions

View File

@ -84,7 +84,7 @@ A parser library for System Verilog.
| 3 | x | x | 13 | x | | 23 | | | 33 | | | | 3 | x | x | 13 | x | | 23 | | | 33 | | |
| 4 | x | x | 14 | x | | 24 | | | 34 | | | | 4 | x | x | 14 | x | | 24 | | | 34 | | |
| 5 | x | x | 15 | x | | 25 | | | 35 | | | | 5 | x | x | 15 | x | | 25 | | | 35 | | |
| 6 | x | | 16 | x | | 26 | | | 36 | | | | 6 | x | x | 16 | x | | 26 | | | 36 | | |
| 7 | x | | 17 | | | 27 | | | 37 | | | | 7 | x | | 17 | | | 27 | | | 37 | | |
| 8 | x | | 18 | | | 28 | | | 38 | | | | 8 | x | | 18 | | | 28 | | | 38 | | |
| 9 | x | | 19 | | | 29 | | | 39 | | | | 9 | x | | 19 | | | 29 | | | 39 | | |

View File

@ -161,7 +161,13 @@ pub(crate) fn primary(s: Span) -> IResult<Span, Primary> {
}), }),
map(primary_literal, |x| Primary::PrimaryLiteral(Box::new(x))), map(primary_literal, |x| Primary::PrimaryLiteral(Box::new(x))),
map(cast, |x| Primary::Cast(Box::new(x))), map(cast, |x| Primary::Cast(Box::new(x))),
terminated(primary_hierarchical, peek(none_of("("))), terminated(
primary_hierarchical,
peek(not(alt((
map(one_of("(."), |_| ()),
map(keyword("with"), |_| ()),
)))),
),
map(empty_unpacked_array_concatenation, |x| { map(empty_unpacked_array_concatenation, |x| {
Primary::EmptyUnpackedArrayConcatenation(Box::new(x)) Primary::EmptyUnpackedArrayConcatenation(Box::new(x))
}), }),

View File

@ -68,12 +68,12 @@ pub(crate) fn system_tf_call_arg_expression(s: Span) -> IResult<Span, SystemTfCa
#[packrat_parser] #[packrat_parser]
pub(crate) fn subroutine_call(s: Span) -> IResult<Span, SubroutineCall> { pub(crate) fn subroutine_call(s: Span) -> IResult<Span, SubroutineCall> {
alt(( alt((
subroutine_call_randomize,
map(method_call, |x| SubroutineCall::MethodCall(Box::new(x))), map(method_call, |x| SubroutineCall::MethodCall(Box::new(x))),
map(tf_call, |x| SubroutineCall::TfCall(Box::new(x))), map(tf_call, |x| SubroutineCall::TfCall(Box::new(x))),
map(system_tf_call, |x| { map(system_tf_call, |x| {
SubroutineCall::SystemTfCall(Box::new(x)) SubroutineCall::SystemTfCall(Box::new(x))
}), }),
subroutine_call_randomize,
))(s) ))(s)
} }
@ -152,10 +152,10 @@ pub(crate) fn method_call(s: Span) -> IResult<Span, MethodCall> {
#[packrat_parser] #[packrat_parser]
pub(crate) fn method_call_body(s: Span) -> IResult<Span, MethodCallBody> { pub(crate) fn method_call_body(s: Span) -> IResult<Span, MethodCallBody> {
alt(( alt((
method_call_body_user,
map(built_in_method_call, |x| { map(built_in_method_call, |x| {
MethodCallBody::BuiltInMethodCall(Box::new(x)) MethodCallBody::BuiltInMethodCall(Box::new(x))
}), }),
method_call_body_user,
))(s) ))(s)
} }
@ -237,13 +237,92 @@ pub(crate) fn variable_identifier_list_or_null(
#[packrat_parser] #[packrat_parser]
pub(crate) fn method_call_root(s: Span) -> IResult<Span, MethodCallRoot> { pub(crate) fn method_call_root(s: Span) -> IResult<Span, MethodCallRoot> {
alt(( alt((
map(primary, |x| MethodCallRoot::Primary(Box::new(x))), map(primary_method_call_root, |x| {
MethodCallRoot::Primary(Box::new(x))
}),
map(implicit_class_handle, |x| { map(implicit_class_handle, |x| {
MethodCallRoot::ImplicitClassHandle(Box::new(x)) MethodCallRoot::ImplicitClassHandle(Box::new(x))
}), }),
))(s) ))(s)
} }
#[tracable_parser]
#[packrat_parser]
pub(crate) fn primary_method_call_root(s: Span) -> IResult<Span, Primary> {
alt((
map(keyword("this"), |x| Primary::This(Box::new(x))),
map(keyword("$"), |x| Primary::Dollar(Box::new(x))),
map(keyword("null"), |x| Primary::Null(Box::new(x))),
map(assignment_pattern_expression, |x| {
Primary::AssignmentPatternExpression(Box::new(x))
}),
map(primary_literal, |x| Primary::PrimaryLiteral(Box::new(x))),
map(cast, |x| Primary::Cast(Box::new(x))),
terminated(primary_hierarchical_method_call_root, peek(none_of("("))),
map(empty_unpacked_array_concatenation, |x| {
Primary::EmptyUnpackedArrayConcatenation(Box::new(x))
}),
primary_concatenation,
primary_multiple_concatenation,
map(function_subroutine_call, |x| {
Primary::FunctionSubroutineCall(Box::new(x))
}),
map(let_expression, |x| Primary::LetExpression(Box::new(x))),
primary_mintypmax_expression,
map(streaming_concatenation, |x| {
Primary::StreamingConcatenation(Box::new(x))
}),
map(sequence_method_call, |x| {
Primary::SequenceMethodCall(Box::new(x))
}),
))(s)
}
#[tracable_parser]
#[packrat_parser]
pub(crate) fn primary_hierarchical_method_call_root(s: Span) -> IResult<Span, Primary> {
let (s, a) = opt(class_qualifier_or_package_scope)(s)?;
let (s, b) = hierarchical_identifier_method_call_root(s)?;
let (s, c) = select_method_call_root(s)?;
Ok((
s,
Primary::Hierarchical(Box::new(PrimaryHierarchical { nodes: (a, b, c) })),
))
}
#[tracable_parser]
#[packrat_parser]
pub(crate) fn hierarchical_identifier_method_call_root(
s: Span,
) -> IResult<Span, HierarchicalIdentifier> {
let (s, a) = opt(root)(s)?;
let (s, b) = many0(terminated(
triple(identifier, constant_bit_select, symbol(".")),
peek(pair(identifier, symbol("."))),
))(s)?;
let (s, c) = identifier(s)?;
Ok((s, HierarchicalIdentifier { nodes: (a, b, c) }))
}
#[tracable_parser]
#[packrat_parser]
pub(crate) fn select_method_call_root(s: Span) -> IResult<Span, Select> {
let (s, a) = opt(terminated(
triple(
many0(terminated(
triple(symbol("."), member_identifier, bit_select),
peek(triple(symbol("."), member_identifier, symbol("."))),
)),
symbol("."),
member_identifier,
),
peek(symbol(".")),
))(s)?;
let (s, b) = bit_select(s)?;
let (s, c) = opt(bracket(part_select_range))(s)?;
Ok((s, Select { nodes: (a, b, c) }))
}
#[tracable_parser] #[tracable_parser]
#[packrat_parser] #[packrat_parser]
pub(crate) fn array_method_name(s: Span) -> IResult<Span, ArrayMethodName> { pub(crate) fn array_method_name(s: Span) -> IResult<Span, ArrayMethodName> {

View File

@ -205,7 +205,10 @@ pub(crate) fn hierarchical_event_identifier(s: Span) -> IResult<Span, Hierarchic
#[packrat_parser] #[packrat_parser]
pub(crate) fn hierarchical_identifier(s: Span) -> IResult<Span, HierarchicalIdentifier> { pub(crate) fn hierarchical_identifier(s: Span) -> IResult<Span, HierarchicalIdentifier> {
let (s, a) = opt(root)(s)?; let (s, a) = opt(root)(s)?;
let (s, b) = many0(triple(identifier, constant_bit_select, symbol(".")))(s)?; let (s, b) = many0(terminated(
triple(identifier, constant_bit_select, symbol(".")),
peek(identifier),
))(s)?;
let (s, c) = identifier(s)?; let (s, c) = identifier(s)?;
Ok((s, HierarchicalIdentifier { nodes: (a, b, c) })) Ok((s, HierarchicalIdentifier { nodes: (a, b, c) }))
} }
@ -561,10 +564,10 @@ pub(crate) fn ps_or_hierarchical_tf_identifier(
s: Span, s: Span,
) -> IResult<Span, PsOrHierarchicalTfIdentifier> { ) -> IResult<Span, PsOrHierarchicalTfIdentifier> {
alt(( alt((
ps_or_hierarchical_tf_identifier_package_scope,
map(hierarchical_tf_identifier, |x| { map(hierarchical_tf_identifier, |x| {
PsOrHierarchicalTfIdentifier::HierarchicalTfIdentifier(Box::new(x)) PsOrHierarchicalTfIdentifier::HierarchicalTfIdentifier(Box::new(x))
}), }),
ps_or_hierarchical_tf_identifier_package_scope,
))(s) ))(s)
} }
@ -606,10 +609,13 @@ pub(crate) fn ps_parameter_identifier_scope(s: Span) -> IResult<Span, PsParamete
#[tracable_parser] #[tracable_parser]
#[packrat_parser] #[packrat_parser]
pub(crate) fn ps_parameter_identifier_generate(s: Span) -> IResult<Span, PsParameterIdentifier> { pub(crate) fn ps_parameter_identifier_generate(s: Span) -> IResult<Span, PsParameterIdentifier> {
let (s, a) = many0(triple( let (s, a) = many0(terminated(
triple(
generate_block_identifier, generate_block_identifier,
opt(bracket(constant_expression)), opt(bracket(constant_expression)),
symbol("."), symbol("."),
),
peek(parameter_identifier),
))(s)?; ))(s)?;
let (s, b) = parameter_identifier(s)?; let (s, b) = parameter_identifier(s)?;
Ok(( Ok((

View File

@ -1529,6 +1529,7 @@ mod spec {
r##"localparam type T = type(bit[12:0]);"##, r##"localparam type T = type(bit[12:0]);"##,
Ok((_, _)) Ok((_, _))
); );
// TODO
// What is addfixed_int/add_float? UDP? // What is addfixed_int/add_float? UDP?
//test!( //test!(
// many1(module_item), // many1(module_item),
@ -1616,26 +1617,31 @@ mod spec {
dest_t b = dest_t'(a);"##, dest_t b = dest_t'(a);"##,
Ok((_, _)) Ok((_, _))
); );
//test!( test!(
// many1(module_item), many1(module_item),
// r##"typedef struct { r##"typedef struct {
// shortint address; shortint address;
// logic [3:0] code; logic [3:0] code;
// byte command [2]; byte command [2];
// } Control; } Control;
// typedef bit Bits [36:1]; typedef bit Bits [36:1];
// Control p; Control p;
// Bits stream[$]; Bits stream[$];
// stream.push_back(Bits'(p)); // append packet to unpacked queue of Bits initial begin
// Bits b; stream.push_back(Bits'(p)); // append packet to unpacked queue of Bits
// Control q; end
// b = stream.pop_front(); // get packet (as Bits) from stream
// q = Control'(b); // convert packet bits back to a Control packet"##, initial begin
// Ok((_, _)) Bits b;
//); Control q;
b = stream.pop_front(); // get packet (as Bits) from stream
q = Control'(b); // convert packet bits back to a Control packet
end"##,
Ok((_, _))
);
test!( test!(
many1(module_item), many1(module_item),
r##"typedef struct { r##"typedef struct {
@ -1646,6 +1652,8 @@ mod spec {
} Packet;"##, } Packet;"##,
Ok((_, _)) Ok((_, _))
); );
// TODO
// randomize can't take hierarchical identifier
//test!( //test!(
// many1(module_item), // many1(module_item),
// r##"function Packet genPkt(); // r##"function Packet genPkt();
@ -1665,15 +1673,19 @@ mod spec {
channel = {channel, channel_type'(genPkt())};"##, channel = {channel, channel_type'(genPkt())};"##,
Ok((_, _)) Ok((_, _))
); );
// TODO
// $ can't be parsed because it is not constant_primary
//test!( //test!(
// many1(module_item), // many1(module_item),
// r##"Packet p; // r##"initial begin
// Packet p;
// int size; // int size;
// size = channel[0] + 4; // size = channel[0] + 4;
// p = Packet'( channel[0 : size - 1] ); // convert stream to Packet // p = Packet'( channel[0 : size - 1] ); // convert stream to Packet
// channel = channel[ size : $ ]; // update the stream so it now // channel = channel[ size : $ ]; // update the stream so it now
// // lacks that packet"##, // // lacks that packet
// end"##,
// Ok((_, _)) // Ok((_, _))
//); //);
test!( test!(
@ -1702,19 +1714,21 @@ mod spec {
#[test] #[test]
fn clause7() { fn clause7() {
//test!( test!(
// many1(module_item), many1(module_item),
// r##"struct { bit [7:0] opcode; bit [23:0] addr; }IR; // anonymous structure r##"struct { bit [7:0] opcode; bit [23:0] addr; }IR; // anonymous structure
// // defines variable IR // defines variable IR
// IR.opcode = 1; // set field in IR. initial begin
IR.opcode = 1; // set field in IR.
end
// typedef struct { typedef struct {
// bit [7:0] opcode; bit [7:0] opcode;
// bit [23:0] addr; bit [23:0] addr;
// } instruction; // named structure type } instruction; // named structure type
// instruction IR; // define variable"##, instruction IR; // define variable"##,
// Ok((_, _)) Ok((_, _))
//); );
test!( test!(
many1(module_item), many1(module_item),
r##"struct packed signed { r##"struct packed signed {
@ -1765,18 +1779,21 @@ mod spec {
r##"packet1 pi = '{1,2,'{2,3,4,5}}; //suppresses the typedef initialization"##, r##"packet1 pi = '{1,2,'{2,3,4,5}}; //suppresses the typedef initialization"##,
Ok((_, _)) Ok((_, _))
); );
//test!( test!(
// many1(module_item), many1(module_item),
// r##"typedef union { int i; shortreal f; } num; // named union type r##"typedef union { int i; shortreal f; } num; // named union type
// num n; num n;
// n.f = 0.0; // set n in floating point format
// typedef struct { initial begin
// bit isfloat; n.f = 0.0; // set n in floating point format
// union { int i; shortreal f; } n; // anonymous union type end
// } tagged_st; // named structure"##,
// Ok((_, _)) typedef struct {
//); bit isfloat;
union { int i; shortreal f; } n; // anonymous union type
} tagged_st; // named structure"##,
Ok((_, _))
);
test!( test!(
many1(module_item), many1(module_item),
r##"typedef union packed { // default unsigned r##"typedef union packed { // default unsigned
@ -1940,57 +1957,69 @@ mod spec {
// remain unsized and uninitialized"##, // remain unsized and uninitialized"##,
Ok((_, _)) Ok((_, _))
); );
//test!( test!(
// many1(module_item), many1(module_item),
// r##"int arr[2][][]; r##"int arr[2][][];
// arr[0] = new [4]; // dynamic subarray arr[0] sized to length 4 initial begin
arr[0] = new [4]; // dynamic subarray arr[0] sized to length 4
// arr[0][0] = new [2]; // legal, arr[0][n] created above for n = 0..3 arr[0][0] = new [2]; // legal, arr[0][n] created above for n = 0..3
// arr[1][0] = new [2]; // illegal, arr[1] not initialized so arr[1][0] does arr[1][0] = new [2]; // illegal, arr[1] not initialized so arr[1][0] does
// // not exist // not exist
// arr[0][1][1] = new[2]; // illegal, arr[0][1][1] is an int, not a dynamic arr[0][1][1] = new[2]; // illegal, arr[0][1][1] is an int, not a dynamic
// // array"##, // array
// Ok((_, _)) end"##,
//); Ok((_, _))
//test!( );
// many1(module_item), test!(
// r##"int idest[], isrc[3] = '{5, 6, 7}; many1(module_item),
// idest = new [3] (isrc); // set size and array element data values (5, 6, 7)"##, r##"int idest[], isrc[3] = '{5, 6, 7};
// Ok((_, _)) initial begin
//); idest = new [3] (isrc); // set size and array element data values (5, 6, 7)
//test!( end"##,
// many1(module_item), Ok((_, _))
// r##"int src[3], dest1[], dest2[]; );
// src = '{2, 3, 4}; test!(
// dest1 = new[2] (src); // dest1's elements are {2, 3}. many1(module_item),
// dest2 = new[4] (src); // dest2's elements are {2, 3, 4, 0}."##, r##"int src[3], dest1[], dest2[];
// Ok((_, _)) initial begin
//); src = '{2, 3, 4};
//test!( dest1 = new[2] (src); // dest1's elements are {2, 3}.
// many1(module_item), dest2 = new[4] (src); // dest2's elements are {2, 3, 4, 0}.
// r##"integer addr[]; // Declare the dynamic array. end"##,
// addr = new[100]; // Create a 100-element array. Ok((_, _))
// // Double the array size, preserving previous values. );
// // Preexisting references to elements of addr are outdated. test!(
// addr = new[200](addr);"##, many1(module_item),
// Ok((_, _)) r##"integer addr[]; // Declare the dynamic array.
//); initial begin
//test!( addr = new[100]; // Create a 100-element array.
// many1(module_item), // Double the array size, preserving previous values.
// r##"int j = addr.size; // Preexisting references to elements of addr are outdated.
// addr = new[ addr.size() * 4 ] (addr); // quadruple addr array"##, addr = new[200](addr);
// Ok((_, _)) end"##,
//); Ok((_, _))
//test!( );
// many1(module_item), test!(
// r##"int ab [] = new[ N ]; // create a temporary array of size N many1(module_item),
// // use ab r##"initial begin
// ab.delete; // delete the array contents int j = addr.size;
// $display( "%d", ab.size ); // prints 0"##, addr = new[ addr.size() * 4 ] (addr); // quadruple addr array
// Ok((_, _)) end"##,
//); Ok((_, _))
);
test!(
many1(module_item),
r##"initial begin
int ab [] = new[ N ]; // create a temporary array of size N
// use ab
ab.delete; // delete the array contents
$display( "%d", ab.size ); // prints 0
end"##,
Ok((_, _))
);
test!( test!(
many1(module_item), many1(module_item),
r##"int A[10:1]; // fixed-size array of 10 elements r##"int A[10:1]; // fixed-size array of 10 elements
@ -2009,35 +2038,41 @@ mod spec {
initial #10 V2 = W;"##, initial #10 V2 = W;"##,
Ok((_, _)) Ok((_, _))
); );
//test!( test!(
// many1(module_item), many1(module_item),
// r##"int A[2][100:1]; r##"int A[2][100:1];
// int B[] = new[100]; // dynamic array of 100 elements int B[] = new[100]; // dynamic array of 100 elements
// int C[] = new[8]; // dynamic array of 8 elements int C[] = new[8]; // dynamic array of 8 elements
// int D [3][][]; // multidimensional array with dynamic subarrays int D [3][][]; // multidimensional array with dynamic subarrays
// D[2] = new [2]; // initialize one of D's dynamic subarrays initial begin
// D[2][0] = new [100]; D[2] = new [2]; // initialize one of D's dynamic subarrays
// A[1] = B; // OK. Both are arrays of 100 ints D[2][0] = new [100];
// A[1] = C; // type check error: different sizes (100 vs. 8 ints) A[1] = B; // OK. Both are arrays of 100 ints
// A = D[2]; // A[0:1][100:1] and subarray D[2][0:1][0:99] both A[1] = C; // type check error: different sizes (100 vs. 8 ints)
// // comprise 2 subarrays of 100 ints"##, A = D[2]; // A[0:1][100:1] and subarray D[2][0:1][0:99] both
// Ok((_, _)) // comprise 2 subarrays of 100 ints
//); end"##,
//test!( Ok((_, _))
// many1(module_item), );
// r##"int A[100:1]; // fixed-size array of 100 elements test!(
// int B[]; // empty dynamic array many1(module_item),
// int C[] = new[8]; // dynamic array of size 8 r##"int A[100:1]; // fixed-size array of 100 elements
int B[]; // empty dynamic array
int C[] = new[8]; // dynamic array of size 8
// B = A; // ok. B has 100 elements initial begin
// B = C; // ok. B has 8 elements"##, B = A; // ok. B has 100 elements
// Ok((_, _)) B = C; // ok. B has 8 elements
//); end"##,
//test!( Ok((_, _))
// many1(module_item), );
// r##"B = new[ C.size ] (C);"##, test!(
// Ok((_, _)) many1(module_item),
//); r##"initial begin
B = new[ C.size ] (C);
end"##,
Ok((_, _))
);
test!( test!(
many1(module_item), many1(module_item),
r##"string d[1:5] = '{ "a", "b", "c", "d", "e" }; r##"string d[1:5] = '{ "a", "b", "c", "d", "e" };
@ -2131,18 +2166,18 @@ mod spec {
end"##, end"##,
Ok((_, _)) Ok((_, _))
); );
//test!( test!(
// many1(module_item), many1(module_item),
// r##"initial begin r##"initial begin
// int map[ string ]; int map[ string ];
// map[ "hello" ] = 1; map[ "hello" ] = 1;
// map[ "sad" ] = 2; map[ "sad" ] = 2;
// map[ "world" ] = 3; map[ "world" ] = 3;
// map.delete( "sad" ); // remove entry whose index is "sad" from "map" map.delete( "sad" ); // remove entry whose index is "sad" from "map"
// map.delete; // remove all entries from the associative array "map" map.delete; // remove all entries from the associative array "map"
// end"##, end"##,
// Ok((_, _)) Ok((_, _))
//); );
test!( test!(
many1(module_item), many1(module_item),
r##"initial begin r##"initial begin
@ -2238,6 +2273,8 @@ mod spec {
end"##, end"##,
Ok((_, _)) Ok((_, _))
); );
// TODO
// $ can't be parsed because it is not constant_primary
//test!( //test!(
// many1(module_item), // many1(module_item),
// r##"initial begin // r##"initial begin
@ -2257,6 +2294,8 @@ mod spec {
// end"##, // end"##,
// Ok((_, _)) // Ok((_, _))
//); //);
// TODO
// $ can't be parsed because it is not constant_primary
//test!( //test!(
// many1(module_item), // many1(module_item),
// r##"initial begin // r##"initial begin
@ -2265,51 +2304,55 @@ mod spec {
// end"##, // end"##,
// Ok((_, _)) // Ok((_, _))
//); //);
//test!( test!(
// many1(module_item), many1(module_item),
// r##"initial begin r##"initial begin
// string SA[10], qs[$]; string SA[10], qs[$];
// int IA[int], qi[$]; int IA[int], qi[$];
// // Find all items greater than 5 // Find all items greater than 5
// qi = IA.find( x ) with ( x > 5 ); qi = IA.find( x ) with ( x > 5 );
// qi = IA.find( x ); // shall be an error qi = IA.find( x ); // shall be an error
// // Find indices of all items equal to 3 // Find indices of all items equal to 3
// qi = IA.find_index with ( item == 3 ); qi = IA.find_index with ( item == 3 );
// // Find first item equal to Bob // Find first item equal to Bob
// qs = SA.find_first with ( item == "Bob" ); qs = SA.find_first with ( item == "Bob" );
// // Find last item equal to Henry // Find last item equal to Henry
// qs = SA.find_last( y ) with ( y == "Henry" ); qs = SA.find_last( y ) with ( y == "Henry" );
// // Find index of last item greater than Z // Find index of last item greater than Z
// qi = SA.find_last_index( s ) with ( s > "Z" ); qi = SA.find_last_index( s ) with ( s > "Z" );
// // Find smallest item // Find smallest item
// qi = IA.min; qi = IA.min;
// // Find string with largest numerical value // Find string with largest numerical value
// qs = SA.max with ( item.atoi ); qs = SA.max with ( item.atoi );
// // Find all unique string elements // Find all unique string elements
// qs = SA.unique; qs = SA.unique;
// // Find all unique strings in lowercase // Find all unique strings in lowercase
// qs = SA.unique( s ) with ( s.tolower ); qs = SA.unique( s ) with ( s.tolower );
// end"##, end"##,
// Ok((_, _)) Ok((_, _))
//); );
//test!( //test!(
// many1(module_item), // many1(module_item),
// r##"initial begin // r##"initial begin
// string s[] = { "hello", "sad", "world" }; // string s[] = { "hello", "sad", "world" };
// s.reverse; // s becomes { "world", "sad", "hello" }; // s.reverse; // s becomes { "world", "sad", "hello" };
// end
// initial begin
// int q[$] = { 4, 5, 3, 1 }; // int q[$] = { 4, 5, 3, 1 };
// q.sort; // q becomes { 1, 3, 4, 5 } // q.sort; // q becomes { 1, 3, 4, 5 }
// end
// initial begin
// struct { byte red, green, blue; } c [512]; // struct { byte red, green, blue; } c [512];
// c.sort with ( item.red ); // sort c using the red field only // c.sort with ( item.red ); // sort c using the red field only
// c.sort( x ) with ( {x.blue, x.green} ); // sort by blue then green // c.sort( x ) with ( {x.blue, x.green} ); // sort by blue then green
@ -2324,28 +2367,32 @@ mod spec {
// y = b.sum ; // y becomes 10 => 1 + 2 + 3 + 4 // y = b.sum ; // y becomes 10 => 1 + 2 + 3 + 4
// y = b.product ; // y becomes 24 => 1 * 2 * 3 * 4 // y = b.product ; // y becomes 24 => 1 * 2 * 3 * 4
// y = b.xor with ( item + 4 ); // y becomes 12 => 5 ^ 6 ^ 7 ^ 8 // y = b.xor with ( item + 4 ); // y becomes 12 => 5 ^ 6 ^ 7 ^ 8
// end
// initial begin
// logic [7:0] m [2][2] = '{ '{5, 10}, '{15, 20} }; // logic [7:0] m [2][2] = '{ '{5, 10}, '{15, 20} };
// int y; // int y;
// y = m.sum with (item.sum with (item)); // y becomes 50 => 5+10+15+20 // y = m.sum with (item.sum with (item)); // y becomes 50 => 5+10+15+20
// end
// initial begin
// logic bit_arr [1024]; // logic bit_arr [1024];
// int y; // int y;
// y = bit_arr.sum with ( int'(item) ); // forces result to be 32-bit // y = bit_arr.sum with ( int'(item) ); // forces result to be 32-bit
// end"##, // end"##,
// Ok((_, _)) // Ok((_, _))
//); //);
//test!( test!(
// many1(module_item), many1(module_item),
// r##"initial begin r##"initial begin
// int arr[]; int arr[];
// int q[$]; int q[$];
// // find all items equal to their position (index) // find all items equal to their position (index)
// q = arr.find with ( item == item.index ); q = arr.find with ( item == item.index );
// end"##, end"##,
// Ok((_, _)) Ok((_, _))
//); );
} }
#[test] #[test]
@ -9057,6 +9104,4 @@ mod spec {
} }
#[test] #[test]
fn debug() { fn debug() {}
//nom_tracable::statistics(Span::new_extra("", SpanInfo::default()));
}