Skip to content

Commit

Permalink
Associate AST elements with tokens (#211)
Browse files Browse the repository at this point in the history
* Implement get_token_id using a Token as parameter and rename the old implementation

* Add the trait TokenSpan which will annotate AST elements with a span of tokens

The macros `with_token_span` and `TokenSpan` of the newly added crate
`vhdl_lang_macros` automatically implement this trait for structs with
named fields.

* Apply the `with_token_span` and `TokenSpan` macros to some AST elements

Namely: TypeDeclaration, ObjectDeclaration, ProcedureSpecification,
FunctionSpecification, SubprogramInstantiation, SubprogramDeclaration,
LibraryClause, UseClause, ContextReference and ContextItem

* Introduce a new AST element SubprogramSpecification, and remove Option<>
from the TokenSpan trait

A SubprogramSpecification is the sole field of SubprogramDeclarations
but with a different meaning and a different token span.

* Apply the TokenSpan macros to further AST elements

The affected elements include:
- Declaration (and all its subelements)
- AnyPrimaryUnit (and all its subelements)
- AnySecondaryUnit (and all its subelements)
- AnyDesignUnit

Small changes to the parsing of file declarations were done for easier
handling and to better represent the official VHDL grammar

* Update version of vhdl_lang_macros crate

* Remove unused function get_token_id

* Rename TokenSpan related fields and structs and introduce helper
functions for unit tests

For consistency reasons rename the trait TokenSpan to HasTokenSpan and
the struct TokenInfo to TokenSpan.
Furthermore, rename the info field to span.

* Remove TokenSpan from subprogram specifications

* Change tests regarding file declarations to test if the parser recovers
successfully when encountering errors

* Introduce helper functions to cut down the size of some subprogram unit
tests

* Rename FoundDeclaration::SubprogramSpec and remove visitor functions for subprogram specifications
  • Loading branch information
skaupper authored Nov 10, 2023
1 parent 27134eb commit f563adb
Show file tree
Hide file tree
Showing 32 changed files with 1,508 additions and 484 deletions.
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@

[workspace]
resolver = "2"
members = ["vhdl_lang", "vhdl_ls"]
members = ["vhdl_lang_macros", "vhdl_lang", "vhdl_ls"]
1 change: 1 addition & 0 deletions vhdl_lang/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ repository = "https://github.com/kraigher/rust_hdl"
edition = "2021"

[dependencies]
vhdl_lang_macros = { version = "^0.73.0", path = "../vhdl_lang_macros" }
pad = "0"
fnv = "1"
clap = { version = "4", features = ["derive"] }
Expand Down
29 changes: 16 additions & 13 deletions vhdl_lang/src/analysis/declarative.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ impl<'a> AnalyzeContext<'a> {
name,
subtype_indication,
signature,
span: _,
} = alias;

let resolved_name = self.name_resolve(scope, &name.pos, &mut name.item, diagnostics);
Expand Down Expand Up @@ -322,6 +323,7 @@ impl<'a> AnalyzeContext<'a> {
subtype_indication,
open_info,
file_name,
span: _,
} = file;

let subtype =
Expand Down Expand Up @@ -394,6 +396,7 @@ impl<'a> AnalyzeContext<'a> {
// @TODO also check the entity class
entity_class: _,
expr,
span: _,
} = attr_spec;

match scope.lookup(
Expand Down Expand Up @@ -478,7 +481,7 @@ impl<'a> AnalyzeContext<'a> {
}
},
Declaration::SubprogramBody(ref mut body) => {
let (subpgm_region, subpgm_ent) = match self.subprogram_declaration(
let (subpgm_region, subpgm_ent) = match self.subprogram_specification(
scope,
parent,
&mut body.specification,
Expand Down Expand Up @@ -515,10 +518,10 @@ impl<'a> AnalyzeContext<'a> {
)?;
}
Declaration::SubprogramDeclaration(ref mut subdecl) => {
match self.subprogram_declaration(
match self.subprogram_specification(
scope,
parent,
subdecl,
&mut subdecl.specification,
Overloaded::SubprogramDecl,
diagnostics,
) {
Expand Down Expand Up @@ -562,10 +565,10 @@ impl<'a> AnalyzeContext<'a> {
Ok(())
}

fn find_subpgm_declaration(
fn find_subpgm_specification(
&self,
scope: &Scope<'a>,
decl: &SubprogramDeclaration,
decl: &SubprogramSpecification,
signature: &Signature,
) -> Option<OverloadedEnt<'a>> {
let des = decl.subpgm_designator().item.clone().into_designator();
Expand Down Expand Up @@ -733,10 +736,10 @@ impl<'a> AnalyzeContext<'a> {
for item in prot_decl.items.iter_mut() {
match item {
ProtectedTypeDeclarativeItem::Subprogram(ref mut subprogram) => {
match self.subprogram_declaration(
match self.subprogram_specification(
scope,
ptype,
subprogram,
&mut subprogram.specification,
Overloaded::SubprogramDecl,
diagnostics,
) {
Expand Down Expand Up @@ -1175,7 +1178,7 @@ impl<'a> AnalyzeContext<'a> {
typ.into()
}
InterfaceDeclaration::Subprogram(ref mut subpgm, ..) => {
let (_, ent) = self.subprogram_declaration(
let (_, ent) = self.subprogram_specification(
scope,
parent,
subpgm,
Expand Down Expand Up @@ -1421,11 +1424,11 @@ impl<'a> AnalyzeContext<'a> {
self.analyze_map_aspect(scope, &mut header.map_aspect, diagnostics)
}

fn subprogram_declaration(
fn subprogram_specification(
&self,
scope: &Scope<'a>,
parent: EntRef<'a>,
subprogram: &mut SubprogramDeclaration,
subprogram: &mut SubprogramSpecification,
to_kind: impl Fn(Signature<'a>) -> Overloaded<'a>,
diagnostics: &mut dyn DiagnosticHandler,
) -> AnalysisResult<(Scope<'a>, OverloadedEnt<'a>)> {
Expand All @@ -1442,7 +1445,7 @@ impl<'a> AnalyzeContext<'a> {
);

let signature = match subprogram {
SubprogramDeclaration::Function(fun) => {
SubprogramSpecification::Function(fun) => {
if let Some(header) = &mut fun.header {
self.subprogram_header(&subpgm_region, ent, header, diagnostics)?;
}
Expand All @@ -1455,7 +1458,7 @@ impl<'a> AnalyzeContext<'a> {
let return_type = self.resolve_type_mark(scope, &mut fun.return_type);
Signature::new(params?, Some(return_type?))
}
SubprogramDeclaration::Procedure(procedure) => {
SubprogramSpecification::Procedure(procedure) => {
if let Some(header) = &mut procedure.header {
self.subprogram_header(&subpgm_region, ent, header, diagnostics)?;
}
Expand All @@ -1472,7 +1475,7 @@ impl<'a> AnalyzeContext<'a> {
let kind = to_kind(signature);

if matches!(kind, Overloaded::Subprogram(_)) {
let declared_by = self.find_subpgm_declaration(scope, subprogram, kind.signature());
let declared_by = self.find_subpgm_specification(scope, subprogram, kind.signature());

if let Some(declared_by) = declared_by {
unsafe {
Expand Down
18 changes: 9 additions & 9 deletions vhdl_lang/src/analysis/named_entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use crate::ast::{
AliasDeclaration, AnyDesignUnit, AnyPrimaryUnit, AnySecondaryUnit, Attribute,
AttributeDeclaration, AttributeSpecification, ComponentDeclaration, Declaration, Designator,
FileDeclaration, HasIdent, Ident, InterfaceFileDeclaration, InterfacePackageDeclaration,
ObjectClass, ObjectDeclaration, PackageInstantiation, SubprogramBody, SubprogramDeclaration,
SubprogramInstantiation, TypeDeclaration, WithDecl,
ObjectClass, ObjectDeclaration, PackageInstantiation, SubprogramBody, SubprogramInstantiation,
SubprogramSpecification, TypeDeclaration, WithDecl,
};
use crate::ast::{ExternalObjectClass, InterfaceDeclaration, InterfaceObjectDeclaration};
use crate::data::*;
Expand Down Expand Up @@ -501,11 +501,11 @@ impl HasEntityId for InterfaceFileDeclaration {
}
}

impl HasEntityId for SubprogramDeclaration {
impl HasEntityId for SubprogramSpecification {
fn ent_id(&self) -> Option<EntityId> {
match self {
SubprogramDeclaration::Procedure(proc) => proc.designator.decl,
SubprogramDeclaration::Function(func) => func.designator.decl,
SubprogramSpecification::Procedure(proc) => proc.designator.decl,
SubprogramSpecification::Function(func) => func.designator.decl,
}
}
}
Expand All @@ -525,7 +525,7 @@ impl HasEntityId for Declaration {
Declaration::Component(comp) => comp.ent_id(),
Declaration::Attribute(attr) => attr.ent_id(),
Declaration::Alias(alias) => alias.ent_id(),
Declaration::SubprogramDeclaration(decl) => decl.ent_id(),
Declaration::SubprogramDeclaration(decl) => decl.specification.ent_id(),
Declaration::SubprogramBody(body) => body.ent_id(),
Declaration::SubprogramInstantiation(decl) => decl.ent_id(),
Declaration::Package(pkg) => pkg.ent_id(),
Expand Down Expand Up @@ -635,11 +635,11 @@ impl WithDecl<WithPos<Designator>> {
}
}

impl SubprogramDeclaration {
impl SubprogramSpecification {
pub fn set_decl_id(&mut self, id: EntityId) {
match self {
SubprogramDeclaration::Function(f) => f.designator.decl = Some(id),
SubprogramDeclaration::Procedure(p) => p.designator.decl = Some(id),
SubprogramSpecification::Function(f) => f.designator.decl = Some(id),
SubprogramSpecification::Procedure(p) => p.designator.decl = Some(id),
}
}
}
Expand Down
Loading

0 comments on commit f563adb

Please sign in to comment.