Skip to content

Commit

Permalink
Add zip_eq
Browse files Browse the repository at this point in the history
  • Loading branch information
VonTum committed Feb 1, 2025
1 parent cc65428 commit 56a4dd3
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 17 deletions.
96 changes: 96 additions & 0 deletions src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -734,3 +734,99 @@ impl<'a, T, IndexMarker> IntoIterator for &'a mut FlatAlloc<T, IndexMarker> {
}
}
}

#[derive(Debug)]
pub struct ZippedIterator<
IDMarker,
OA,
OB,
IterA: Iterator<Item = (UUID<IDMarker>, OA)>,
IterB: Iterator<Item = (UUID<IDMarker>, OB)>,
> {
iter_a: IterA,
iter_b: IterB,
}

impl<
IDMarker,
OA,
OB,
IterA: Iterator<Item = (UUID<IDMarker>, OA)>,
IterB: Iterator<Item = (UUID<IDMarker>, OB)>,
> Iterator for ZippedIterator<IDMarker, OA, OB, IterA, IterB>
{
type Item = (UUID<IDMarker>, OA, OB);

fn next(&mut self) -> Option<Self::Item> {
match (self.iter_a.next(), self.iter_b.next()) {
(None, None) => None,
(Some((id_a, a)), Some((id_b, b))) => {
assert!(id_a == id_b);
Some((id_a, a, b))
}
_ => unreachable!("Unbalanced Iterators"),
}
}
}

pub fn zip_eq<IDMarker, OA, OB>(
iter_a: impl IntoIterator<Item = (UUID<IDMarker>, OA)>,
iter_b: impl IntoIterator<Item = (UUID<IDMarker>, OB)>,
) -> impl Iterator<Item = (UUID<IDMarker>, OA, OB)> {
ZippedIterator {
iter_a: iter_a.into_iter(),
iter_b: iter_b.into_iter(),
}
}

#[derive(Debug)]
pub struct ZippedIterator3<
IDMarker,
OA,
OB,
OC,
IterA: Iterator<Item = (UUID<IDMarker>, OA)>,
IterB: Iterator<Item = (UUID<IDMarker>, OB)>,
IterC: Iterator<Item = (UUID<IDMarker>, OC)>,
> {
iter_a: IterA,
iter_b: IterB,
iter_c: IterC,
}

impl<
IDMarker,
OA,
OB,
OC,
IterA: Iterator<Item = (UUID<IDMarker>, OA)>,
IterB: Iterator<Item = (UUID<IDMarker>, OB)>,
IterC: Iterator<Item = (UUID<IDMarker>, OC)>,
> Iterator for ZippedIterator3<IDMarker, OA, OB, OC, IterA, IterB, IterC>
{
type Item = (UUID<IDMarker>, OA, OB, OC);

fn next(&mut self) -> Option<Self::Item> {
match (self.iter_a.next(), self.iter_b.next(), self.iter_c.next()) {
(None, None, None) => None,
(Some((id_a, a)), Some((id_b, b)), Some((id_c, c))) => {
assert!(id_a == id_b);
assert!(id_a == id_c);
Some((id_a, a, b, c))
}
_ => unreachable!("Unbalanced Iterators"),
}
}
}

pub fn zip_eq3<IDMarker, OA, OB, OC>(
iter_a: impl IntoIterator<Item = (UUID<IDMarker>, OA)>,
iter_b: impl IntoIterator<Item = (UUID<IDMarker>, OB)>,
iter_c: impl IntoIterator<Item = (UUID<IDMarker>, OC)>,
) -> impl Iterator<Item = (UUID<IDMarker>, OA, OB, OC)> {
ZippedIterator3 {
iter_a: iter_a.into_iter(),
iter_b: iter_b.into_iter(),
iter_c: iter_c.into_iter(),
}
}
1 change: 1 addition & 0 deletions src/flattening/initialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ fn initialize_global_object(
builder.add_module(Module {
link_info,
ports: ctx.ports,
latency_inference_info: PortLatencyInferenceInfo::default(),
domains: ctx.domains,
implicit_clk_domain: ctx.implicit_clk_domain,
interfaces: ctx.interfaces,
Expand Down
11 changes: 7 additions & 4 deletions src/flattening/typechecking.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::alloc::ArenaAllocator;
use crate::alloc::{zip_eq3, ArenaAllocator};
use crate::errors::{ErrorInfo, ErrorInfoObject, FileKnowingErrorInfoObject};
use crate::prelude::*;
use crate::typing::abstract_type::AbstractType;
Expand Down Expand Up @@ -324,8 +324,11 @@ impl TypeCheckingContext<'_, '_> {
let global_obj: GlobalUUID = global_ref.id.into();
let target_link_info = self.globals.get_link_info(global_obj);

for (parameter_id, argument_type) in &global_ref.template_arg_types {
let parameter = &target_link_info.template_parameters[parameter_id];
for (_parameter_id, argument_type, parameter, given_template_arg) in zip_eq3(
&global_ref.template_arg_types,
&target_link_info.template_parameters,
&global_ref.template_args,
) {
match &parameter.kind {
ParameterKind::Type(_) => {} // Do nothing, nothing to unify with. Maybe in the future traits?
ParameterKind::Generative(parameter) => {
Expand All @@ -341,7 +344,7 @@ impl TypeCheckingContext<'_, '_> {
}
}

if let Some(given_arg) = &global_ref.template_args[parameter_id] {
if let Some(given_arg) = given_template_arg {
match &given_arg.kind {
TemplateArgKind::Type(wr_typ) => {
self.typecheck_written_type(wr_typ);
Expand Down
22 changes: 11 additions & 11 deletions src/instantiation/concrete_typecheck.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::ops::Deref;

use crate::alloc::{zip_eq, zip_eq3};
use crate::errors::ErrorInfoObject;
use crate::flattening::{DeclarationKind, ExpressionSource, WireReferenceRoot, WrittenType};
use crate::linker::LinkInfo;
Expand Down Expand Up @@ -385,17 +386,16 @@ impl DelayedConstraint<InstantiationContext<'_, '_>> for SubmoduleTypecheckConst
context.linker,
sm.template_args.clone(),
) {
for (port_id, concrete_port) in &instance.interface_ports {
let connecting_wire = &sm.port_map[port_id];

for (_port_id, concrete_port, source_code_port, connecting_wire) in
zip_eq3(&instance.interface_ports, &sub_module.ports, &sm.port_map)
{
match (concrete_port, connecting_wire) {
(None, None) => {} // Invalid port not connected, good!
(None, Some(connecting_wire)) => {
// Port is not enabled, but attempted to be used
// A question may be "What if no port was in the source code? There would be no error reported"
// But this is okay, because nonvisible ports are only possible for function calls
// We have a second routine that reports invalid interfaces.
let source_code_port = &sub_module.ports[port_id];
for span in &connecting_wire.name_refs {
context.errors.error(*span, format!("Port '{}' is used, but the instantiated module has this port disabled", source_code_port.name))
.info_obj_different_file(source_code_port, sub_module.link_info.file)
Expand All @@ -404,7 +404,6 @@ impl DelayedConstraint<InstantiationContext<'_, '_>> for SubmoduleTypecheckConst
}
(Some(_concrete_port), None) => {
// Port is enabled, but not used
let source_code_port = &sub_module.ports[port_id];
context
.errors
.warn(
Expand All @@ -421,22 +420,23 @@ impl DelayedConstraint<InstantiationContext<'_, '_>> for SubmoduleTypecheckConst
&concrete_port.typ,
submod_instr.module_ref.get_total_span(),
|| {
let abstract_port = &sub_module.ports[port_id];
let port_declared_here =
abstract_port.make_info(sub_module.link_info.file).unwrap();
let port_declared_here = source_code_port
.make_info(sub_module.link_info.file)
.unwrap();

(
format!("Port '{}'", abstract_port.name),
format!("Port '{}'", source_code_port.name),
vec![port_declared_here],
)
},
);
}
}
}
for (interface_id, interface_references) in &sm.interface_call_sites {
for (_interface_id, interface_references, sm_interface) in
zip_eq(&sm.interface_call_sites, &sub_module.interfaces)
{
if !interface_references.is_empty() {
let sm_interface = &sub_module.interfaces[interface_id];
let interface_name = &sm_interface.name;
if let Some(representative_port) = sm_interface
.func_call_inputs
Expand Down
6 changes: 4 additions & 2 deletions src/to_string.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::alloc::zip_eq;
use crate::prelude::*;

use crate::typing::template::{Parameter, TVec};
Expand Down Expand Up @@ -304,8 +305,9 @@ pub fn pretty_print_concrete_instance(
}

let mut result = format!("{object_full_name} #(\n");
for (id, arg) in given_template_args {
let arg_in_target = &target_link_info.template_parameters[id];
for (_id, arg, arg_in_target) in
zip_eq(given_template_args, &target_link_info.template_parameters)
{
write!(result, " {}: ", arg_in_target.name).unwrap();
match arg {
ConcreteType::Named(_) | ConcreteType::Array(_) => {
Expand Down

0 comments on commit 56a4dd3

Please sign in to comment.