Skip to content

Commit b060d5d

Browse files
authored
Merge pull request #62 from Bochlin/master
Allow multiple '^' in relative external name
2 parents cd872d1 + d02a768 commit b060d5d

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

vhdl_lang/src/ast.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ pub enum ExternalObjectClass {
117117
pub enum ExternalPath {
118118
Package(WithPos<Name>),
119119
Absolute(WithPos<Name>),
120-
Relative(WithPos<Name>),
120+
121+
// usize field indicates the number of up-levels ('^')
122+
Relative(WithPos<Name>, usize),
121123
}
122124

123125
/// LRM 8.7 External names

vhdl_lang/src/syntax/names.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,14 +260,19 @@ fn parse_inner_external_name(stream: &mut TokenStream) -> ParseResult<ExternalNa
260260
},
261261
Circ => {
262262
stream.expect_kind(Dot)?;
263+
let mut up_levels = 1;
264+
while stream.skip_if_kind(Circ)? {
265+
stream.expect_kind(Dot)?;
266+
up_levels += 1;
267+
}
263268
let path_name = parse_name(stream)?;
264269
let path_pos = path_name.pos.clone().combine_into(&token);
265-
WithPos::from(ExternalPath::Relative(path_name), path_pos)
270+
WithPos::from(ExternalPath::Relative(path_name, up_levels), path_pos)
266271
},
267272
Identifier => {
268273
let path_name = parse_name_initial_token(stream, token)?;
269274
let path_pos = path_name.pos.clone();
270-
WithPos::from(ExternalPath::Relative(path_name), path_pos)
275+
WithPos::from(ExternalPath::Relative(path_name, 0), path_pos)
271276
}
272277
);
273278

@@ -827,7 +832,7 @@ mod tests {
827832
let external_name = ExternalName {
828833
class: ExternalObjectClass::Signal,
829834
path: WithPos::new(
830-
ExternalPath::Relative(code.s1("dut.foo").name()),
835+
ExternalPath::Relative(code.s1("dut.foo").name(), 0),
831836
code.s1("dut.foo").pos(),
832837
),
833838
subtype: code.s1("std_logic").subtype_indication(),
@@ -844,7 +849,7 @@ mod tests {
844849
let external_name = ExternalName {
845850
class: ExternalObjectClass::Signal,
846851
path: WithPos::new(
847-
ExternalPath::Relative(code.s1("dut.gen(0)").name()),
852+
ExternalPath::Relative(code.s1("dut.gen(0)").name(), 1),
848853
code.s1("^.dut.gen(0)").pos(),
849854
),
850855
subtype: code.s1("std_logic").subtype_indication(),
@@ -855,6 +860,23 @@ mod tests {
855860
);
856861
}
857862

863+
#[test]
864+
fn test_external_name_explicit_relative_multiple_levels() {
865+
let code = Code::new("<< signal ^.^.^.dut.gen(0) : std_logic >>");
866+
let external_name = ExternalName {
867+
class: ExternalObjectClass::Signal,
868+
path: WithPos::new(
869+
ExternalPath::Relative(code.s1("dut.gen(0)").name(), 3),
870+
code.s1("^.^.^.dut.gen(0)").pos(),
871+
),
872+
subtype: code.s1("std_logic").subtype_indication(),
873+
};
874+
assert_eq!(
875+
code.with_stream(parse_name),
876+
WithPos::new(Name::External(Box::new(external_name)), code)
877+
);
878+
}
879+
858880
#[test]
859881
fn test_external_name_absolute() {
860882
let code = Code::new("<< signal .dut.gen(0) : std_logic >>");
@@ -901,7 +923,7 @@ mod tests {
901923
let external_name = ExternalName {
902924
class,
903925
path: WithPos::new(
904-
ExternalPath::Relative(code.s1("dut.foo").name()),
926+
ExternalPath::Relative(code.s1("dut.foo").name(), 0),
905927
code.s1("dut.foo").pos(),
906928
),
907929
subtype: code.s1("std_logic").subtype_indication(),

0 commit comments

Comments
 (0)