@@ -433,14 +433,15 @@ pub fn parse_name_initial_token(
433433 } ,
434434 RightPar => {
435435 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+ } ) ) ,
443442 } ;
443+
444+ name = WithPos :: new( item, pos) ;
444445 }
445446 )
446447 }
@@ -453,6 +454,31 @@ pub fn parse_name_initial_token(
453454 Ok ( name)
454455}
455456
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+
456482pub fn parse_name ( stream : & mut TokenStream ) -> ParseResult < WithPos < Name > > {
457483 let initial_token = stream. expect ( ) ?;
458484 parse_name_initial_token ( stream, initial_token)
@@ -462,6 +488,7 @@ pub fn parse_name(stream: &mut TokenStream) -> ParseResult<WithPos<Name>> {
462488mod tests {
463489 use super :: * ;
464490 use crate :: syntax:: test:: Code ;
491+ use pretty_assertions:: assert_eq;
465492
466493 #[ test]
467494 fn test_parse_selected_name_single ( ) {
@@ -660,6 +687,23 @@ mod tests {
660687 assert_eq ! ( code. with_stream( parse_name) , slice) ;
661688 }
662689
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+
663707 #[ test]
664708 fn test_attribute_name ( ) {
665709 let code = Code :: new ( "prefix'foo" ) ;
0 commit comments