Skip to content

Commit 0e7a8ff

Browse files
authored
Refactor map aspects (#382)
* Separate port formal regions from generic formal regions * Remove the GpkgRegion in favor of the FormalRegion * Modify generic map to use already existing infrastructure * Enable generic functions, types and packages in entity and component instantiations * Restructure generic_map into association.rs * Enable ports to lookup the types from generics
1 parent 35072bc commit 0e7a8ff

21 files changed

+841
-521
lines changed

vhdl_lang/src/analysis/association.rs

Lines changed: 282 additions & 110 deletions
Large diffs are not rendered by default.

vhdl_lang/src/analysis/concurrent.rs

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::data::*;
1313
use crate::named_entity::*;
1414
use crate::{HasTokenSpan, TokenSpan};
1515
use analyze::*;
16+
use fnv::FnvHashMap;
1617

1718
impl<'a> AnalyzeContext<'a, '_> {
1819
pub fn analyze_concurrent_part(
@@ -303,29 +304,13 @@ impl<'a> AnalyzeContext<'a, '_> {
303304
}
304305
}
305306

306-
let (generic_region, port_region) = ent_region.to_entity_formal();
307-
308-
self.check_association(
309-
&entity_name.pos(self.ctx),
310-
&generic_region,
307+
self.analyze_generics_and_ports(
311308
scope,
312-
instance
313-
.generic_map
314-
.as_mut()
315-
.map(|it| it.list.items.as_mut_slice())
316-
.unwrap_or(&mut []),
317-
diagnostics,
318-
)?;
319-
self.check_association(
320-
&entity_name.pos(self.ctx),
321-
&port_region,
322-
scope,
323-
instance
324-
.port_map
325-
.as_mut()
326-
.map(|it| it.list.items.as_mut_slice())
327-
.unwrap_or(&mut []),
309+
instance.generic_map.as_mut(),
310+
instance.port_map.as_mut(),
328311
diagnostics,
312+
entity_name,
313+
ent_region,
329314
)?;
330315
Ok(())
331316
}
@@ -368,28 +353,13 @@ impl<'a> AnalyzeContext<'a, '_> {
368353
};
369354

370355
if let AnyEntKind::Component(ent_region) = ent.kind() {
371-
let (generic_region, port_region) = ent_region.to_entity_formal();
372-
self.check_association(
373-
&component_name.pos(self.ctx),
374-
&generic_region,
375-
scope,
376-
instance
377-
.generic_map
378-
.as_mut()
379-
.map(|it| it.list.items.as_mut_slice())
380-
.unwrap_or(&mut []),
381-
diagnostics,
382-
)?;
383-
self.check_association(
384-
&component_name.pos(self.ctx),
385-
&port_region,
356+
self.analyze_generics_and_ports(
386357
scope,
387-
instance
388-
.port_map
389-
.as_mut()
390-
.map(|it| it.list.items.as_mut_slice())
391-
.unwrap_or(&mut []),
358+
instance.generic_map.as_mut(),
359+
instance.port_map.as_mut(),
392360
diagnostics,
361+
component_name,
362+
ent_region,
393363
)?;
394364
Ok(())
395365
} else {
@@ -428,6 +398,45 @@ impl<'a> AnalyzeContext<'a, '_> {
428398
}
429399
}
430400

401+
pub fn analyze_generics_and_ports(
402+
&self,
403+
scope: &Scope<'a>,
404+
generic_map_aspect: Option<&mut MapAspect>,
405+
port_map_aspect: Option<&mut MapAspect>,
406+
diagnostics: &mut dyn DiagnosticHandler,
407+
entity_name: &mut WithTokenSpan<Name>,
408+
ent_region: &Region<'a>,
409+
) -> FatalResult {
410+
let (generic_region, port_region) = ent_region.to_entity_formal();
411+
412+
let mut mapping = FnvHashMap::default();
413+
as_fatal(
414+
self.check_association(
415+
&entity_name.pos(self.ctx),
416+
&generic_region,
417+
&mut mapping,
418+
scope,
419+
generic_map_aspect
420+
.map(|it| it.list.items.as_mut_slice())
421+
.unwrap_or(&mut []),
422+
diagnostics,
423+
),
424+
)?;
425+
as_fatal(
426+
self.check_association(
427+
&entity_name.pos(self.ctx),
428+
&port_region,
429+
&mut mapping,
430+
scope,
431+
port_map_aspect
432+
.map(|it| it.list.items.as_mut_slice())
433+
.unwrap_or(&mut []),
434+
diagnostics,
435+
),
436+
)?;
437+
Ok(())
438+
}
439+
431440
pub fn analyze_map_aspect(
432441
&self,
433442
scope: &Scope<'a>,

vhdl_lang/src/analysis/declarative.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ impl<'a> AnalyzeContext<'a, '_> {
564564
&mut instance.ident,
565565
parent,
566566
AnyEntKind::Overloaded(Overloaded::Subprogram(Signature::new(
567-
FormalRegion::new_params(),
567+
ParameterRegion::default(),
568568
None,
569569
))),
570570
src_span,

vhdl_lang/src/analysis/overloaded.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@
44
//
55
// Copyright (c) 2023, Olof Kraigher olof.kraigher@gmail.com
66

7-
use fnv::FnvHashSet;
7+
use fnv::{FnvHashMap, FnvHashSet};
88
use vhdl_lang::TokenAccess;
99

1010
use super::analyze::*;
1111
use super::expression::ExpressionType;
1212
use super::scope::*;
13-
use crate::ast::search::clear_references;
1413
use crate::ast::token_range::WithToken;
1514
use crate::ast::*;
1615
use crate::data::error_codes::ErrorCode;
@@ -44,7 +43,7 @@ enum Rejection<'a> {
4443
Procedure,
4544

4645
// The amount of actuals or named actuals do not match formals
47-
MissingFormals(Vec<InterfaceEnt<'a>>),
46+
MissingFormals(Vec<ParameterEnt<'a>>),
4847
}
4948

5049
struct Candidate<'a> {
@@ -196,7 +195,14 @@ impl<'a> AnalyzeContext<'a, '_> {
196195
assocs: &mut [AssociationElement],
197196
diagnostics: &mut dyn DiagnosticHandler,
198197
) -> FatalResult {
199-
self.check_association(error_pos, ent.formals(), scope, assocs, diagnostics)?;
198+
as_fatal(self.check_association(
199+
error_pos,
200+
ent.formals().as_formal_region(),
201+
&mut FnvHashMap::default(),
202+
scope,
203+
assocs,
204+
diagnostics,
205+
))?;
200206
Ok(())
201207
}
202208

@@ -218,20 +224,25 @@ impl<'a> AnalyzeContext<'a, '_> {
218224
for ent in candidates.iter() {
219225
if let Some(resolved) = as_fatal(self.resolve_association_formals(
220226
call_pos,
221-
ent.formals(),
227+
ent.formals().as_formal_region(),
222228
scope,
223229
assocs,
224230
&mut NullDiagnostics,
225231
))? {
232+
// Since we are in a ParameterRegion, we should only get back Parameter Entities
233+
// that are all convertible to types.
234+
let resolved = resolved
235+
.into_iter()
236+
.map(|ent| {
237+
ent.require_type_mark()
238+
.expect("Resolved formal should have type")
239+
})
240+
.collect();
226241
result.push(ResolvedCall {
227242
subpgm: *ent,
228243
formals: resolved,
229244
});
230245
}
231-
232-
for elem in assocs.iter_mut() {
233-
clear_references(elem, self.ctx);
234-
}
235246
}
236247

237248
Ok(result)

0 commit comments

Comments
 (0)