Skip to content

Commit

Permalink
Refactor disconnect, package body and package declaration
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris44442 committed Jun 2, 2024
1 parent 10cbd3d commit 8e91c39
Show file tree
Hide file tree
Showing 8 changed files with 347 additions and 102 deletions.
14 changes: 13 additions & 1 deletion vhdl_lang/src/analysis/declarative.rs
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,19 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
self.analyze_package_body(unit, diagnostics)?;
}
Declaration::Configuration(..) => {}
Declaration::Disconnection(..) => {} // @TODO
Declaration::Disconnection(ref mut disc) => {
let DisconnectionSpecification {
ident: _,
subtype_indication,
expression,
} = disc;
if let Some(expr) = expression {
self.expr_with_ttyp(scope, self.time(), expr, diagnostics)?;
}
if let Some(ref mut subtype_indication) = subtype_indication {
self.analyze_subtype_indication(scope, subtype_indication, diagnostics)?;
}
}
Declaration::View(view) => {
if let Some(view) = as_fatal(self.analyze_view_declaration(
scope,
Expand Down
93 changes: 93 additions & 0 deletions vhdl_lang/src/analysis/tests/declarations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,96 @@ end entity test;
)],
)
}

#[test]
pub fn disconnect_no_analyze_error() {
let mut builder = LibraryBuilder::new();
let _ = builder.code(
"libname",
"\
entity ent is
end entity;
architecture arch of ent is
constant foo : time := 10 ns;
disconnect all : integer after foo;
begin
end arch;
",
);
check_diagnostics(builder.analyze(), vec![])
}

#[test]
pub fn disconnect_expression_error_1() {
let mut builder = LibraryBuilder::new();
let code = builder.code(
"libname",
"\
entity ent is
end entity;
architecture arch of ent is
constant foo : time := 10 ns;
disconnect all : integer after bar;
begin
end arch;
",
);
check_diagnostics(
builder.analyze(),
vec![Diagnostic::new(
code.s1("bar"),
"No declaration of 'bar'",
ErrorCode::Unresolved,
)],
)
}

#[test]
pub fn disconnect_expression_error_2() {
let mut builder = LibraryBuilder::new();
let code = builder.code(
"libname",
"\
entity ent is
end entity;
architecture arch of ent is
signal foo : integer;
disconnect all : integer after foo;
begin
end arch;
",
);
check_diagnostics(
builder.analyze(),
vec![Diagnostic::new(
code.s1("after foo").s1("foo"),
"signal 'foo' of integer type 'INTEGER' does not match physical type 'TIME'",
ErrorCode::TypeMismatch,
)],
)
}

#[test]
pub fn disconnect_type_error_1() {
let mut builder = LibraryBuilder::new();
let code = builder.code(
"libname",
"\
entity ent is
end entity;
architecture arch of ent is
signal foo : integer;
disconnect all : bar after 10 ns;
begin
end arch;
",
);
check_diagnostics(
builder.analyze(),
vec![Diagnostic::new(
code.s1("bar"),
"No declaration of 'bar'",
ErrorCode::Unresolved,
)],
)
}
6 changes: 5 additions & 1 deletion vhdl_lang/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1380,7 +1380,11 @@ pub struct ConfigurationSpecification {

/// LRM 7.4 Disconnection specification
#[derive(PartialEq, Debug, Clone)]
pub struct DisconnectionSpecification {}
pub struct DisconnectionSpecification {
pub ident: Option<WithDecl<Ident>>,
pub subtype_indication: Option<SubtypeIndication>,
pub expression: Option<WithTokenSpan<Expression>>,
}

/// LRM 3.4 Configuration declarations
#[derive(PartialEq, Debug, Clone)]
Expand Down
10 changes: 10 additions & 0 deletions vhdl_lang/src/ast/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1140,6 +1140,16 @@ impl Display for ConfigurationDeclaration {
}
}

impl Display for DisconnectionSpecification {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
if let Some(ident) = &self.ident {
write!(f, "disconnection {}", ident)
} else {
write!(f, "disconnection")
}
}
}

impl Display for EntityDeclaration {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
// Not used: context_clause, decl, statements
Expand Down
10 changes: 8 additions & 2 deletions vhdl_lang/src/ast/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1087,8 +1087,14 @@ impl Search for Declaration {
Declaration::Configuration(_) => {
// @TODO
}
Declaration::Disconnection(_) => {
// @TODO
Declaration::Disconnection(disconnect) => {
let DisconnectionSpecification {
ident: _,
subtype_indication,
expression,
} = disconnect;
return_if_found!(subtype_indication.search(ctx, searcher));
return_if_found!(expression.search(ctx, searcher));
}
Declaration::View(view) => {
return_if_found!(searcher
Expand Down
72 changes: 31 additions & 41 deletions vhdl_lang/src/syntax/declarative_part.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,37 +68,37 @@ pub fn is_declarative_part(ctx: &mut ParsingContext) -> ParseResult<bool> {
))
}

pub fn is_recover_token(kind: Kind) -> bool {
matches!(
kind,
Type | Subtype
| Component
| Impure
| Pure
| Function
| Procedure
| Package
| For
| File
| Shared
| Constant
| Signal
| Variable
| Attribute
| View
| Use
| Alias
| Begin
| End
| Disconnect
)
}

pub fn parse_declarative_part(
ctx: &mut ParsingContext<'_>,
) -> ParseResult<Vec<WithTokenSpan<Declaration>>> {
let mut declarations: Vec<WithTokenSpan<Declaration>> = Vec::new();

fn is_recover_token(kind: Kind) -> bool {
matches!(
kind,
Type | Subtype
| Component
| Impure
| Pure
| Function
| Procedure
| Package
| For
| File
| Shared
| Constant
| Signal
| Variable
| Attribute
| View
| Use
| Alias
| Begin
| End
| Disconnect
)
}

while let Some(token) = ctx.stream.peek() {
let start_token = ctx.stream.get_current_token_id();
match token.kind {
Expand Down Expand Up @@ -206,10 +206,12 @@ pub fn parse_declarative_part(
VHDL2008 | VHDL1993 => &[
Type, Subtype, Component, Impure, Pure, Function, Procedure, Package, For,
File, Shared, Constant, Signal, Variable, Attribute, Use, Alias,
Disconnect,
],
VHDL2019 => &[
Type, Subtype, Component, Impure, Pure, Function, Procedure, Package, For,
File, Shared, Constant, Signal, Variable, Attribute, Use, Alias, View,
Disconnect,
],
};
ctx.diagnostics.push(token.kinds_error(expected));
Expand Down Expand Up @@ -305,7 +307,7 @@ constant x: natural := 5;
"Expected 'type', 'subtype', 'component', 'impure', 'pure', \
'function', 'procedure', 'package', 'for', 'file', \
'shared', 'constant', 'signal', 'variable', 'attribute', \
'use' or 'alias'"
'use', 'alias' or 'disconnect'"
)]
);
}
Expand Down Expand Up @@ -333,7 +335,7 @@ var not_a_var: broken;
"Expected 'type', 'subtype', 'component', 'impure', 'pure', \
'function', 'procedure', 'package', 'for', 'file', \
'shared', 'constant', 'signal', 'variable', 'attribute', \
'use' or 'alias'",
'use', 'alias' or 'disconnect'",
)],
);

Expand All @@ -351,20 +353,8 @@ var not_a_var: broken;
"Expected 'type', 'subtype', 'component', 'impure', 'pure', \
'function', 'procedure', 'package', 'for', 'file', \
'shared', 'constant', 'signal', 'variable', 'attribute', \
'use', 'alias' or 'view'",
'use', 'alias', 'view' or 'disconnect'",
)],
)
}

#[test]
fn parse_declarative_part_with_disconnection() {
let code = Code::new(
"\
constant foo: real := 5.1;
disconnect my_signal : integer after 42 ms;
signal bar: std_logic;
",
);
code.with_stream_no_diagnostics(parse_declarative_part);
}
}
64 changes: 29 additions & 35 deletions vhdl_lang/src/syntax/design_unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -934,39 +934,33 @@ end entity y;
assert_eq!(tok.pos, code.s1("context").pos());
}

#[test]
fn parse_package_declaration_and_body_in_declarative_part() {
let code = Code::new(
"\
entity ent is
end entity;
architecture arch of ent is
package my_pkg is
-- ...
end my_pkg;
package body my_pkg is
-- ...
end package body;
begin
end arch;
",
);
let file = code.design_file();
let (tokens, _) = &file.design_units[1];
assert_eq!(tokens[0].kind, Architecture);
assert_eq!(tokens[5].kind, Package);
assert_eq!(tokens[6].kind, Identifier);
assert_eq!(tokens[7].kind, Is);
assert_eq!(tokens[8].kind, End);
assert_eq!(tokens[9].kind, Identifier);
assert_eq!(tokens[10].kind, SemiColon);
assert_eq!(tokens[11].kind, Package);
assert_eq!(tokens[12].kind, Body);
assert_eq!(tokens[13].kind, Identifier);
assert_eq!(tokens[14].kind, Is);
assert_eq!(tokens[15].kind, End);
assert_eq!(tokens[16].kind, Package);
assert_eq!(tokens[17].kind, Body);
}
// #[test]
// fn parse_architecture_body_with_package_decl_and_body() {
// let (code, design_file) = parse_ok(
// "
//architecture arch of ent is
// package my_pkg is
// -- ...
// end my_pkg;
// package body my_pkg is
// -- ...
// end package body;
//begin
//end arch;
//",
// );
//
//assert_eq!(
// code.with_stream_no_diagnostics(parse_architecture_body()),
// ArchitectureBody {
// span: code.token_span(),
// context_clause: ContextClause::default(),
// ident: code.s1("arch").decl_ident(),
// entity_name: None, // TODO
// begin_token : code.s1("architecture").token(),
// decl : None,
// statements : None,
// end_ident_pos : None,
// })
// }
}
Loading

0 comments on commit 8e91c39

Please sign in to comment.