use quote::quote_spanned;
use syn::parse_quote;
use syn::spanned::Spanned;
use super::{
DelayType, OpInstGenerics, OperatorCategory, OperatorConstraints,
OperatorInstance, OperatorWriteOutput, WriteContextArgs, RANGE_1,
};
pub const _LATTICE_JOIN_FUSED_JOIN: OperatorConstraints = OperatorConstraints {
name: "_lattice_join_fused_join",
categories: &[OperatorCategory::CompilerFusionOperator],
hard_range_inn: &(2..=2),
soft_range_inn: &(2..=2),
hard_range_out: RANGE_1,
soft_range_out: RANGE_1,
num_args: 0,
persistence_args: &(0..=2),
type_args: &(2..=2),
is_external_input: false,
has_singleton_output: false,
ports_inn: Some(|| super::PortListSpec::Fixed(parse_quote! { 0, 1 })),
ports_out: None,
input_delaytype_fn: |_| Some(DelayType::MonotoneAccum),
write_fn: |wc @ &WriteContextArgs {
root,
context,
op_span,
ident,
inputs,
is_pull,
op_inst:
OperatorInstance {
generics:
OpInstGenerics {
type_args,
persistence_args,
..
},
..
},
..
},
diagnostics| {
let lhs_type = &type_args[0];
let rhs_type = &type_args[1];
let wc = WriteContextArgs {
arguments: &parse_quote! {
FoldFrom(<#lhs_type as #root::lattices::LatticeFrom::<_>>::lattice_from, #root::lattices::Merge::merge),
FoldFrom(<#rhs_type as #root::lattices::LatticeFrom::<_>>::lattice_from, #root::lattices::Merge::merge)
},
..wc.clone()
};
let OperatorWriteOutput {
write_prologue,
write_iterator: _,
write_iterator_after,
} = (super::join_fused::JOIN_FUSED.write_fn)(&wc, diagnostics).unwrap();
assert!(is_pull);
let persistences = super::join_fused::parse_persistences(persistence_args);
let lhs_join_options = super::join_fused::parse_argument(&wc.arguments[0])
.map_err(|err| diagnostics.push(err))?;
let rhs_join_options = super::join_fused::parse_argument(&wc.arguments[1])
.map_err(|err| diagnostics.push(err))?;
let (lhs_joindata_ident, lhs_borrow_ident, _lhs_prologue, lhs_borrow) =
super::join_fused::make_joindata(&wc, persistences[0], &lhs_join_options, "lhs")
.map_err(|err| diagnostics.push(err))?;
let (rhs_joindata_ident, rhs_borrow_ident, _rhs_prologue, rhs_borrow) =
super::join_fused::make_joindata(&wc, persistences[1], &rhs_join_options, "rhs")
.map_err(|err| diagnostics.push(err))?;
let lhs = &inputs[0];
let rhs = &inputs[1];
let arg0_span = wc.arguments[0].span();
let arg1_span = wc.arguments[1].span();
let lhs_tokens = quote_spanned! {arg0_span=>
#lhs_borrow.fold_into(#lhs, #root::lattices::Merge::merge,
<#lhs_type as #root::lattices::LatticeFrom::<_>>::lattice_from);
};
let rhs_tokens = quote_spanned! {arg1_span=>
#rhs_borrow.fold_into(#rhs, #root::lattices::Merge::merge,
<#rhs_type as #root::lattices::LatticeFrom::<_>>::lattice_from);
};
let write_iterator = quote_spanned! {op_span=>
let mut #lhs_borrow_ident = #context.state_ref(#lhs_joindata_ident).borrow_mut();
let mut #rhs_borrow_ident = #context.state_ref(#rhs_joindata_ident).borrow_mut();
let #ident = {
#lhs_tokens
#rhs_tokens
#[allow(clippy::clone_on_copy)]
#[allow(suspicious_double_ref_op)]
#rhs_borrow
.table
.iter()
.filter_map(|(k, v2)| #lhs_borrow.table.get(k).map(|v1| (k.clone(), lattices::Pair::<#lhs_type, #rhs_type>::new_from(v1.clone(), v2.clone()))))
.map(|(key, p)| #root::lattices::map_union::MapUnionSingletonMap::new_from((key, p)))
};
};
Ok(OperatorWriteOutput {
write_prologue,
write_iterator,
write_iterator_after,
})
},
};