@@ -433,14 +433,15 @@ pub fn parse_name_initial_token(
433
433
} ,
434
434
RightPar => {
435
435
let pos = sep_token. pos. combine_into( & name) ;
436
- name = WithPos {
437
- item: Name :: FunctionCall ( Box :: new(
438
- FunctionCall {
439
- name,
440
- parameters: vec![ assoc]
441
- } ) ) ,
442
- pos,
436
+ let item = match into_range( assoc) {
437
+ Ok ( range) => Name :: Slice ( Box :: new( name) , Box :: new( DiscreteRange :: Range ( range) ) ) ,
438
+ Err ( assoc) => Name :: FunctionCall ( Box :: new( FunctionCall {
439
+ name,
440
+ parameters: vec![ assoc] ,
441
+ } ) ) ,
443
442
} ;
443
+
444
+ name = WithPos :: new( item, pos) ;
444
445
}
445
446
)
446
447
}
@@ -453,6 +454,31 @@ pub fn parse_name_initial_token(
453
454
Ok ( name)
454
455
}
455
456
457
+ pub fn into_range ( assoc : AssociationElement ) -> Result < ast:: Range , AssociationElement > {
458
+ if assoc. formal . is_some ( ) {
459
+ return Err ( assoc) ;
460
+ }
461
+
462
+ if let ActualPart :: Expression ( Expression :: Name ( ref name) ) = & assoc. actual . item {
463
+ if let Name :: Attribute ( attr) = name. as_ref ( ) {
464
+ if attr. is_range ( ) {
465
+ if let ActualPart :: Expression ( Expression :: Name ( name) ) = assoc. actual . item {
466
+ if let Name :: Attribute ( attr) = * name {
467
+ return Ok ( ast:: Range :: Attribute ( attr) ) ;
468
+ }
469
+ }
470
+ unreachable ! ( ) ;
471
+ } else {
472
+ Err ( assoc)
473
+ }
474
+ } else {
475
+ Err ( assoc)
476
+ }
477
+ } else {
478
+ Err ( assoc)
479
+ }
480
+ }
481
+
456
482
pub fn parse_name ( stream : & mut TokenStream ) -> ParseResult < WithPos < Name > > {
457
483
let initial_token = stream. expect ( ) ?;
458
484
parse_name_initial_token ( stream, initial_token)
@@ -462,6 +488,7 @@ pub fn parse_name(stream: &mut TokenStream) -> ParseResult<WithPos<Name>> {
462
488
mod tests {
463
489
use super :: * ;
464
490
use crate :: syntax:: test:: Code ;
491
+ use pretty_assertions:: assert_eq;
465
492
466
493
#[ test]
467
494
fn test_parse_selected_name_single ( ) {
@@ -660,6 +687,23 @@ mod tests {
660
687
assert_eq ! ( code. with_stream( parse_name) , slice) ;
661
688
}
662
689
690
+ #[ test]
691
+ fn test_slice_range_attribute ( ) {
692
+ let code = Code :: new ( "prefix(foo(0)'range)" ) ;
693
+ let prefix = WithPos {
694
+ item : Name :: Designator ( Designator :: Identifier ( code. symbol ( "prefix" ) ) . into_ref ( ) ) ,
695
+ pos : code. s1 ( "prefix" ) . pos ( ) ,
696
+ } ;
697
+ let slice = WithPos {
698
+ item : Name :: Slice (
699
+ Box :: new ( prefix) ,
700
+ Box :: new ( code. s1 ( "foo(0)'range" ) . discrete_range ( ) ) ,
701
+ ) ,
702
+ pos : code. s1 ( "prefix(foo(0)'range)" ) . pos ( ) ,
703
+ } ;
704
+ assert_eq ! ( code. with_stream( parse_name) , slice) ;
705
+ }
706
+
663
707
#[ test]
664
708
fn test_attribute_name ( ) {
665
709
let code = Code :: new ( "prefix'foo" ) ;
0 commit comments