Skip to content

Commit 8e91c39

Browse files
committed
Refactor disconnect, package body and package declaration
1 parent 10cbd3d commit 8e91c39

File tree

8 files changed

+347
-102
lines changed

8 files changed

+347
-102
lines changed

vhdl_lang/src/analysis/declarative.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,19 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
624624
self.analyze_package_body(unit, diagnostics)?;
625625
}
626626
Declaration::Configuration(..) => {}
627-
Declaration::Disconnection(..) => {} // @TODO
627+
Declaration::Disconnection(ref mut disc) => {
628+
let DisconnectionSpecification {
629+
ident: _,
630+
subtype_indication,
631+
expression,
632+
} = disc;
633+
if let Some(expr) = expression {
634+
self.expr_with_ttyp(scope, self.time(), expr, diagnostics)?;
635+
}
636+
if let Some(ref mut subtype_indication) = subtype_indication {
637+
self.analyze_subtype_indication(scope, subtype_indication, diagnostics)?;
638+
}
639+
}
628640
Declaration::View(view) => {
629641
if let Some(view) = as_fatal(self.analyze_view_declaration(
630642
scope,

vhdl_lang/src/analysis/tests/declarations.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,96 @@ end entity test;
100100
)],
101101
)
102102
}
103+
104+
#[test]
105+
pub fn disconnect_no_analyze_error() {
106+
let mut builder = LibraryBuilder::new();
107+
let _ = builder.code(
108+
"libname",
109+
"\
110+
entity ent is
111+
end entity;
112+
architecture arch of ent is
113+
constant foo : time := 10 ns;
114+
disconnect all : integer after foo;
115+
begin
116+
end arch;
117+
",
118+
);
119+
check_diagnostics(builder.analyze(), vec![])
120+
}
121+
122+
#[test]
123+
pub fn disconnect_expression_error_1() {
124+
let mut builder = LibraryBuilder::new();
125+
let code = builder.code(
126+
"libname",
127+
"\
128+
entity ent is
129+
end entity;
130+
architecture arch of ent is
131+
constant foo : time := 10 ns;
132+
disconnect all : integer after bar;
133+
begin
134+
end arch;
135+
",
136+
);
137+
check_diagnostics(
138+
builder.analyze(),
139+
vec![Diagnostic::new(
140+
code.s1("bar"),
141+
"No declaration of 'bar'",
142+
ErrorCode::Unresolved,
143+
)],
144+
)
145+
}
146+
147+
#[test]
148+
pub fn disconnect_expression_error_2() {
149+
let mut builder = LibraryBuilder::new();
150+
let code = builder.code(
151+
"libname",
152+
"\
153+
entity ent is
154+
end entity;
155+
architecture arch of ent is
156+
signal foo : integer;
157+
disconnect all : integer after foo;
158+
begin
159+
end arch;
160+
",
161+
);
162+
check_diagnostics(
163+
builder.analyze(),
164+
vec![Diagnostic::new(
165+
code.s1("after foo").s1("foo"),
166+
"signal 'foo' of integer type 'INTEGER' does not match physical type 'TIME'",
167+
ErrorCode::TypeMismatch,
168+
)],
169+
)
170+
}
171+
172+
#[test]
173+
pub fn disconnect_type_error_1() {
174+
let mut builder = LibraryBuilder::new();
175+
let code = builder.code(
176+
"libname",
177+
"\
178+
entity ent is
179+
end entity;
180+
architecture arch of ent is
181+
signal foo : integer;
182+
disconnect all : bar after 10 ns;
183+
begin
184+
end arch;
185+
",
186+
);
187+
check_diagnostics(
188+
builder.analyze(),
189+
vec![Diagnostic::new(
190+
code.s1("bar"),
191+
"No declaration of 'bar'",
192+
ErrorCode::Unresolved,
193+
)],
194+
)
195+
}

vhdl_lang/src/ast.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1380,7 +1380,11 @@ pub struct ConfigurationSpecification {
13801380

13811381
/// LRM 7.4 Disconnection specification
13821382
#[derive(PartialEq, Debug, Clone)]
1383-
pub struct DisconnectionSpecification {}
1383+
pub struct DisconnectionSpecification {
1384+
pub ident: Option<WithDecl<Ident>>,
1385+
pub subtype_indication: Option<SubtypeIndication>,
1386+
pub expression: Option<WithTokenSpan<Expression>>,
1387+
}
13841388

13851389
/// LRM 3.4 Configuration declarations
13861390
#[derive(PartialEq, Debug, Clone)]

vhdl_lang/src/ast/display.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,16 @@ impl Display for ConfigurationDeclaration {
11401140
}
11411141
}
11421142

1143+
impl Display for DisconnectionSpecification {
1144+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
1145+
if let Some(ident) = &self.ident {
1146+
write!(f, "disconnection {}", ident)
1147+
} else {
1148+
write!(f, "disconnection")
1149+
}
1150+
}
1151+
}
1152+
11431153
impl Display for EntityDeclaration {
11441154
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
11451155
// Not used: context_clause, decl, statements

vhdl_lang/src/ast/search.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,8 +1087,14 @@ impl Search for Declaration {
10871087
Declaration::Configuration(_) => {
10881088
// @TODO
10891089
}
1090-
Declaration::Disconnection(_) => {
1091-
// @TODO
1090+
Declaration::Disconnection(disconnect) => {
1091+
let DisconnectionSpecification {
1092+
ident: _,
1093+
subtype_indication,
1094+
expression,
1095+
} = disconnect;
1096+
return_if_found!(subtype_indication.search(ctx, searcher));
1097+
return_if_found!(expression.search(ctx, searcher));
10921098
}
10931099
Declaration::View(view) => {
10941100
return_if_found!(searcher

vhdl_lang/src/syntax/declarative_part.rs

Lines changed: 31 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -68,37 +68,37 @@ pub fn is_declarative_part(ctx: &mut ParsingContext) -> ParseResult<bool> {
6868
))
6969
}
7070

71+
pub fn is_recover_token(kind: Kind) -> bool {
72+
matches!(
73+
kind,
74+
Type | Subtype
75+
| Component
76+
| Impure
77+
| Pure
78+
| Function
79+
| Procedure
80+
| Package
81+
| For
82+
| File
83+
| Shared
84+
| Constant
85+
| Signal
86+
| Variable
87+
| Attribute
88+
| View
89+
| Use
90+
| Alias
91+
| Begin
92+
| End
93+
| Disconnect
94+
)
95+
}
96+
7197
pub fn parse_declarative_part(
7298
ctx: &mut ParsingContext<'_>,
7399
) -> ParseResult<Vec<WithTokenSpan<Declaration>>> {
74100
let mut declarations: Vec<WithTokenSpan<Declaration>> = Vec::new();
75101

76-
fn is_recover_token(kind: Kind) -> bool {
77-
matches!(
78-
kind,
79-
Type | Subtype
80-
| Component
81-
| Impure
82-
| Pure
83-
| Function
84-
| Procedure
85-
| Package
86-
| For
87-
| File
88-
| Shared
89-
| Constant
90-
| Signal
91-
| Variable
92-
| Attribute
93-
| View
94-
| Use
95-
| Alias
96-
| Begin
97-
| End
98-
| Disconnect
99-
)
100-
}
101-
102102
while let Some(token) = ctx.stream.peek() {
103103
let start_token = ctx.stream.get_current_token_id();
104104
match token.kind {
@@ -206,10 +206,12 @@ pub fn parse_declarative_part(
206206
VHDL2008 | VHDL1993 => &[
207207
Type, Subtype, Component, Impure, Pure, Function, Procedure, Package, For,
208208
File, Shared, Constant, Signal, Variable, Attribute, Use, Alias,
209+
Disconnect,
209210
],
210211
VHDL2019 => &[
211212
Type, Subtype, Component, Impure, Pure, Function, Procedure, Package, For,
212213
File, Shared, Constant, Signal, Variable, Attribute, Use, Alias, View,
214+
Disconnect,
213215
],
214216
};
215217
ctx.diagnostics.push(token.kinds_error(expected));
@@ -305,7 +307,7 @@ constant x: natural := 5;
305307
"Expected 'type', 'subtype', 'component', 'impure', 'pure', \
306308
'function', 'procedure', 'package', 'for', 'file', \
307309
'shared', 'constant', 'signal', 'variable', 'attribute', \
308-
'use' or 'alias'"
310+
'use', 'alias' or 'disconnect'"
309311
)]
310312
);
311313
}
@@ -333,7 +335,7 @@ var not_a_var: broken;
333335
"Expected 'type', 'subtype', 'component', 'impure', 'pure', \
334336
'function', 'procedure', 'package', 'for', 'file', \
335337
'shared', 'constant', 'signal', 'variable', 'attribute', \
336-
'use' or 'alias'",
338+
'use', 'alias' or 'disconnect'",
337339
)],
338340
);
339341

@@ -351,20 +353,8 @@ var not_a_var: broken;
351353
"Expected 'type', 'subtype', 'component', 'impure', 'pure', \
352354
'function', 'procedure', 'package', 'for', 'file', \
353355
'shared', 'constant', 'signal', 'variable', 'attribute', \
354-
'use', 'alias' or 'view'",
356+
'use', 'alias', 'view' or 'disconnect'",
355357
)],
356358
)
357359
}
358-
359-
#[test]
360-
fn parse_declarative_part_with_disconnection() {
361-
let code = Code::new(
362-
"\
363-
constant foo: real := 5.1;
364-
disconnect my_signal : integer after 42 ms;
365-
signal bar: std_logic;
366-
",
367-
);
368-
code.with_stream_no_diagnostics(parse_declarative_part);
369-
}
370360
}

vhdl_lang/src/syntax/design_unit.rs

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -934,39 +934,33 @@ end entity y;
934934
assert_eq!(tok.pos, code.s1("context").pos());
935935
}
936936

937-
#[test]
938-
fn parse_package_declaration_and_body_in_declarative_part() {
939-
let code = Code::new(
940-
"\
941-
entity ent is
942-
end entity;
943-
944-
architecture arch of ent is
945-
package my_pkg is
946-
-- ...
947-
end my_pkg;
948-
package body my_pkg is
949-
-- ...
950-
end package body;
951-
begin
952-
end arch;
953-
",
954-
);
955-
let file = code.design_file();
956-
let (tokens, _) = &file.design_units[1];
957-
assert_eq!(tokens[0].kind, Architecture);
958-
assert_eq!(tokens[5].kind, Package);
959-
assert_eq!(tokens[6].kind, Identifier);
960-
assert_eq!(tokens[7].kind, Is);
961-
assert_eq!(tokens[8].kind, End);
962-
assert_eq!(tokens[9].kind, Identifier);
963-
assert_eq!(tokens[10].kind, SemiColon);
964-
assert_eq!(tokens[11].kind, Package);
965-
assert_eq!(tokens[12].kind, Body);
966-
assert_eq!(tokens[13].kind, Identifier);
967-
assert_eq!(tokens[14].kind, Is);
968-
assert_eq!(tokens[15].kind, End);
969-
assert_eq!(tokens[16].kind, Package);
970-
assert_eq!(tokens[17].kind, Body);
971-
}
937+
// #[test]
938+
// fn parse_architecture_body_with_package_decl_and_body() {
939+
// let (code, design_file) = parse_ok(
940+
// "
941+
//architecture arch of ent is
942+
// package my_pkg is
943+
// -- ...
944+
// end my_pkg;
945+
// package body my_pkg is
946+
// -- ...
947+
// end package body;
948+
//begin
949+
//end arch;
950+
//",
951+
// );
952+
//
953+
//assert_eq!(
954+
// code.with_stream_no_diagnostics(parse_architecture_body()),
955+
// ArchitectureBody {
956+
// span: code.token_span(),
957+
// context_clause: ContextClause::default(),
958+
// ident: code.s1("arch").decl_ident(),
959+
// entity_name: None, // TODO
960+
// begin_token : code.s1("architecture").token(),
961+
// decl : None,
962+
// statements : None,
963+
// end_ident_pos : None,
964+
// })
965+
// }
972966
}

0 commit comments

Comments
 (0)