Skip to content

Commit 10cbd3d

Browse files
committed
Add disconnect specification
1 parent 1ab2839 commit 10cbd3d

File tree

8 files changed

+137
-1
lines changed

8 files changed

+137
-1
lines changed

vhdl_lang/src/analysis/declarative.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ impl Declaration {
4444
| PackageDeclaration(_)
4545
| PackageBody(_)
4646
| Configuration(_)
47+
| Disconnection(_)
4748
| View(_)
4849
),
4950
// LRM: configuration_declarative_item
@@ -65,6 +66,7 @@ impl Declaration {
6566
| Package(_)
6667
| PackageDeclaration(_)
6768
| PackageBody(_)
69+
| Disconnection(_)
6870
| View(_)
6971
),
7072
// LRM: package_body_declarative_item
@@ -76,6 +78,7 @@ impl Declaration {
7678
| Overloaded::UninstSubprogram(..),
7779
)
7880
| AnyEntKind::Concurrent(Some(Concurrent::Process))
81+
// LRM protected type body declarative item
7982
| AnyEntKind::Type(named_entity::Type::Protected(..)) => matches!(
8083
self,
8184
Object(ObjectDeclaration {
@@ -107,7 +110,7 @@ impl Declaration {
107110
| Use(_)
108111
| Package(_)
109112
| PackageDeclaration(_)
110-
| PackageBody(_)
113+
| Disconnection(_)
111114
| View(_)
112115
),
113116
_ => {
@@ -621,6 +624,7 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
621624
self.analyze_package_body(unit, diagnostics)?;
622625
}
623626
Declaration::Configuration(..) => {}
627+
Declaration::Disconnection(..) => {} // @TODO
624628
Declaration::View(view) => {
625629
if let Some(view) = as_fatal(self.analyze_view_declaration(
626630
scope,

vhdl_lang/src/analysis/names.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1848,6 +1848,7 @@ impl Declaration {
18481848
Declaration::PackageDeclaration(_) => "package",
18491849
Declaration::PackageBody(_) => "package body",
18501850
Declaration::Configuration(_) => "configuration",
1851+
Declaration::Disconnection(_) => "disconnection",
18511852
Declaration::View(_) => "view",
18521853
}
18531854
}

vhdl_lang/src/ast.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,7 @@ pub enum Declaration {
855855
PackageDeclaration(PackageDeclaration),
856856
PackageBody(PackageBody),
857857
Configuration(ConfigurationSpecification),
858+
Disconnection(DisconnectionSpecification),
858859
View(ModeViewDeclaration),
859860
}
860861

@@ -1377,6 +1378,10 @@ pub struct ConfigurationSpecification {
13771378
pub vunit_bind_inds: Vec<VUnitBindingIndication>,
13781379
}
13791380

1381+
/// LRM 7.4 Disconnection specification
1382+
#[derive(PartialEq, Debug, Clone)]
1383+
pub struct DisconnectionSpecification {}
1384+
13801385
/// LRM 3.4 Configuration declarations
13811386
#[derive(PartialEq, Debug, Clone)]
13821387
pub enum ConfigurationDeclarativeItem {

vhdl_lang/src/ast/search.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,9 @@ impl Search for Declaration {
10871087
Declaration::Configuration(_) => {
10881088
// @TODO
10891089
}
1090+
Declaration::Disconnection(_) => {
1091+
// @TODO
1092+
}
10901093
Declaration::View(view) => {
10911094
return_if_found!(searcher
10921095
.search_decl(ctx, FoundDeclaration::View(view))

vhdl_lang/src/named_entity.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,7 @@ impl HasEntityId for Declaration {
636636
Declaration::PackageBody(pkg) => pkg.ent_id(),
637637
Declaration::Use(_) => None,
638638
Declaration::Configuration(_) => None,
639+
Declaration::Disconnection(_) => None, // TODO
639640
Declaration::View(decl) => decl.ent_id(),
640641
}
641642
}

vhdl_lang/src/syntax.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ mod configuration;
1616
mod context;
1717
mod declarative_part;
1818
mod design_unit;
19+
mod disconnection;
1920
mod expression;
2021
mod interface_declaration;
2122
mod names;

vhdl_lang/src/syntax/declarative_part.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use super::type_declaration::parse_type_declaration;
1919
use crate::ast::token_range::WithTokenSpan;
2020
use crate::ast::{ContextClause, Declaration, PackageInstantiation};
2121
use crate::syntax::concurrent_statement::parse_map_aspect;
22+
use crate::syntax::disconnection::parse_disconnection_specification;
2223
use crate::syntax::view::parse_mode_view_declaration;
2324
use vhdl_lang::syntax::parser::ParsingContext;
2425

@@ -63,6 +64,7 @@ pub fn is_declarative_part(ctx: &mut ParsingContext) -> ParseResult<bool> {
6364
| For
6465
| View
6566
| Begin
67+
| Disconnect
6668
))
6769
}
6870

@@ -93,6 +95,7 @@ pub fn parse_declarative_part(
9395
| Alias
9496
| Begin
9597
| End
98+
| Disconnect
9699
)
97100
}
98101

@@ -186,6 +189,17 @@ pub fn parse_declarative_part(
186189
}
187190
}
188191

192+
Disconnect => {
193+
match parse_disconnection_specification(ctx).or_recover_until(ctx, is_recover_token)
194+
{
195+
Ok(decl) => declarations.push(decl.map_into(Declaration::Disconnection)),
196+
Err(err) => {
197+
ctx.diagnostics.push(err);
198+
continue;
199+
}
200+
}
201+
}
202+
189203
_ => {
190204
use crate::VHDLStandard::*;
191205
let expected: &[Kind] = match ctx.standard {
@@ -341,4 +355,16 @@ var not_a_var: broken;
341355
)],
342356
)
343357
}
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+
}
344370
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public
2+
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
3+
// You can obtain one at http://mozilla.org/MPL/2.0/.
4+
//
5+
// Copyright (c) 2018, Olof Kraigher olof.kraigher@gmail.com
6+
7+
use super::common::ParseResult;
8+
use super::expression::parse_expression;
9+
use super::names::parse_name;
10+
use super::separated_list::parse_ident_list;
11+
use super::tokens::{Kind::*, TokenSpan};
12+
use crate::ast::token_range::WithTokenSpan;
13+
use crate::ast::*;
14+
use vhdl_lang::syntax::parser::ParsingContext;
15+
16+
/// LRM 7.4 Disconnection Specification
17+
pub fn parse_disconnection_specification(
18+
ctx: &mut ParsingContext<'_>,
19+
) -> ParseResult<WithTokenSpan<DisconnectionSpecification>> {
20+
let start_token = ctx.stream.expect_kind(Disconnect)?;
21+
if ctx.stream.next_kind_is(Identifier) {
22+
let _ = parse_ident_list(ctx);
23+
} else if ctx.stream.next_kind_is(All) {
24+
ctx.stream.expect_kind(All)?;
25+
} else {
26+
ctx.stream.expect_kind(Others)?;
27+
}
28+
ctx.stream.expect_kind(Colon)?;
29+
let _ = parse_name(ctx);
30+
ctx.stream.expect_kind(After)?;
31+
let _ = parse_expression(ctx);
32+
let end_token = ctx.stream.expect_kind(SemiColon)?;
33+
Ok(WithTokenSpan::new(
34+
DisconnectionSpecification {},
35+
TokenSpan::new(start_token, end_token),
36+
))
37+
}
38+
39+
#[cfg(test)]
40+
mod tests {
41+
use super::*;
42+
use crate::syntax::test::Code;
43+
44+
#[test]
45+
fn disconnect_spec_with_scalar_or_composite_signal() {
46+
let code = Code::new(
47+
"\
48+
disconnect S: T after 42 ms;
49+
",
50+
);
51+
assert_eq!(
52+
code.with_stream_no_diagnostics(parse_disconnection_specification),
53+
WithTokenSpan::new(DisconnectionSpecification {}, code.token_span())
54+
);
55+
}
56+
57+
#[test]
58+
fn disconnect_spec_with_scalar_or_composite_signal_variant() {
59+
let code = Code::new(
60+
"\
61+
disconnect foo, bar, foobar : unsigned(3 downto 0) after CLK_PERIOD;
62+
",
63+
);
64+
assert_eq!(
65+
code.with_stream_no_diagnostics(parse_disconnection_specification),
66+
WithTokenSpan::new(DisconnectionSpecification {}, code.token_span())
67+
);
68+
}
69+
70+
#[test]
71+
fn disconnect_spec_explicit_with_others() {
72+
let code = Code::new(
73+
"\
74+
disconnect others: std_logic after 42 ms;
75+
",
76+
);
77+
assert_eq!(
78+
code.with_stream_no_diagnostics(parse_disconnection_specification),
79+
WithTokenSpan::new(DisconnectionSpecification {}, code.token_span())
80+
);
81+
}
82+
83+
#[test]
84+
fn disconnect_spec_explicit_with_all() {
85+
let code = Code::new(
86+
"\
87+
disconnect all : T after 42 ms;
88+
",
89+
);
90+
assert_eq!(
91+
code.with_stream_no_diagnostics(parse_disconnection_specification),
92+
WithTokenSpan::new(DisconnectionSpecification {}, code.token_span())
93+
);
94+
}
95+
}

0 commit comments

Comments
 (0)