fayalite::expr::ops: add and automatically generate ops::StructuralEq
This commit is contained in:
parent
ffca1a279d
commit
98e7e91fc9
18 changed files with 1030 additions and 220 deletions
|
|
@ -1133,6 +1133,7 @@ impl ToTokens for ParsedBundle {
|
|||
let mut fields_expr_ne = vec![];
|
||||
let mut fields_valueless_eq = vec![];
|
||||
let mut fields_valueless_ne = vec![];
|
||||
let mut fields_structural_eq = vec![];
|
||||
for field in fields.named() {
|
||||
let field_ident = field.ident();
|
||||
let field_ty = field.ty();
|
||||
|
|
@ -1141,6 +1142,9 @@ impl ToTokens for ParsedBundle {
|
|||
.push(parse_quote_spanned! {cmp_eq.span=>
|
||||
#field_ty: ::fayalite::expr::HdlPartialEqImpl<#field_ty>
|
||||
});
|
||||
fields_structural_eq.push(quote_spanned! {cmp_eq.span=>
|
||||
<#field_ty as ::fayalite::expr::HdlPartialEqImpl<#field_ty>>::TRY_STRUCTURAL_EQ
|
||||
});
|
||||
fields_value_eq.push(quote_spanned! {span=>
|
||||
::fayalite::expr::HdlPartialEqImpl::cmp_value_eq(
|
||||
__lhs.#field_ident,
|
||||
|
|
@ -1188,6 +1192,7 @@ impl ToTokens for ParsedBundle {
|
|||
let expr_ne_body;
|
||||
let valueless_eq_body;
|
||||
let valueless_ne_body;
|
||||
let structural_eq;
|
||||
if fields_len == 0 {
|
||||
value_eq_body = quote_spanned! {span=>
|
||||
true
|
||||
|
|
@ -1207,6 +1212,9 @@ impl ToTokens for ParsedBundle {
|
|||
valueless_ne_body = quote_spanned! {span=>
|
||||
::fayalite::expr::Valueless::new(::fayalite::int::Bool)
|
||||
};
|
||||
structural_eq = quote_spanned! {span=>
|
||||
true
|
||||
};
|
||||
} else {
|
||||
value_eq_body = quote_spanned! {span=>
|
||||
#(#fields_value_eq)&*
|
||||
|
|
@ -1230,12 +1238,17 @@ impl ToTokens for ParsedBundle {
|
|||
let __rhs = ::fayalite::expr::ValueType::ty(&__rhs);
|
||||
#(#fields_valueless_ne)|*
|
||||
};
|
||||
structural_eq = quote_spanned! {span=>
|
||||
#(#fields_structural_eq)&&*
|
||||
};
|
||||
};
|
||||
quote_spanned! {span=>
|
||||
#[automatically_derived]
|
||||
impl #impl_generics ::fayalite::expr::HdlPartialEqImpl<Self> for #target #type_generics
|
||||
#cmp_eq_where_clause
|
||||
{
|
||||
const TRY_STRUCTURAL_EQ: ::fayalite::__std::primitive::bool = #structural_eq;
|
||||
|
||||
#[track_caller]
|
||||
fn cmp_value_eq(
|
||||
__lhs: Self,
|
||||
|
|
@ -1261,6 +1274,16 @@ impl ToTokens for ParsedBundle {
|
|||
__lhs: ::fayalite::expr::Expr<Self>,
|
||||
__rhs: ::fayalite::expr::Expr<Self>,
|
||||
) -> ::fayalite::expr::Expr<::fayalite::int::Bool> {
|
||||
if <Self as ::fayalite::expr::HdlPartialEqImpl<Self>>::TRY_STRUCTURAL_EQ {
|
||||
if let ::fayalite::__std::result::Result::Ok(__retval) =
|
||||
::fayalite::expr::ops::StructuralEq::try_new(
|
||||
::fayalite::expr::Expr::canonical(__lhs),
|
||||
::fayalite::expr::Expr::canonical(__rhs),
|
||||
)
|
||||
{
|
||||
return ::fayalite::expr::ToExpr::to_expr(&__retval);
|
||||
}
|
||||
}
|
||||
#expr_eq_body
|
||||
}
|
||||
|
||||
|
|
@ -1269,6 +1292,14 @@ impl ToTokens for ParsedBundle {
|
|||
__lhs: ::fayalite::expr::Expr<Self>,
|
||||
__rhs: ::fayalite::expr::Expr<Self>,
|
||||
) -> ::fayalite::expr::Expr<::fayalite::int::Bool> {
|
||||
if <Self as ::fayalite::expr::HdlPartialEqImpl<Self>>::TRY_STRUCTURAL_EQ {
|
||||
return !::fayalite::expr::ToExpr::to_expr(
|
||||
&::fayalite::expr::ops::StructuralEq::new(
|
||||
::fayalite::expr::Expr::canonical(__lhs),
|
||||
::fayalite::expr::Expr::canonical(__rhs),
|
||||
),
|
||||
);
|
||||
}
|
||||
#expr_ne_body
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -643,7 +643,9 @@ impl ToTokens for ParsedEnum {
|
|||
#where_clause
|
||||
{
|
||||
#[allow(non_snake_case, dead_code)]
|
||||
#vis fn #ident(#self_token) -> ::fayalite::sim::value::SimValue<#target #type_generics> {
|
||||
#vis fn #ident(
|
||||
#self_token,
|
||||
) -> ::fayalite::sim::value::SimValue<#target #type_generics> {
|
||||
::fayalite::sim::value::SimValue::from_value(
|
||||
#self_token.#sim_builder_ty_field_ident,
|
||||
#sim_value_ident::#ident(::fayalite::enum_::EnumPaddingSimValue::new()),
|
||||
|
|
@ -929,8 +931,14 @@ impl ToTokens for ParsedEnum {
|
|||
impl #impl_generics ::fayalite::__std::fmt::Display for #sim_value_ident #type_generics
|
||||
#where_clause
|
||||
{
|
||||
fn fmt(&self, f: &mut ::fayalite::__std::fmt::Formatter<'_>) -> ::fayalite::__std::fmt::Result {
|
||||
<#target #type_generics as ::fayalite::ty::SimValueDisplay>::sim_value_display(self, f)
|
||||
fn fmt(
|
||||
&self,
|
||||
f: &mut ::fayalite::__std::fmt::Formatter<'_>,
|
||||
) -> ::fayalite::__std::fmt::Result {
|
||||
<#target #type_generics as ::fayalite::ty::SimValueDisplay>::sim_value_display(
|
||||
self,
|
||||
f,
|
||||
)
|
||||
}
|
||||
}
|
||||
}.to_tokens(tokens);
|
||||
|
|
@ -946,6 +954,7 @@ impl ToTokens for ParsedEnum {
|
|||
let mut variants_value_eq = vec![];
|
||||
let mut variants_expr_eq = vec![];
|
||||
let mut fields_valueless_eq = vec![];
|
||||
let mut structural_eq: Option<TokenStream> = None;
|
||||
for (
|
||||
variant_index,
|
||||
ParsedVariant {
|
||||
|
|
@ -971,8 +980,23 @@ impl ToTokens for ParsedEnum {
|
|||
.push(parse_quote_spanned! {cmp_eq.span=>
|
||||
#field_ty: ::fayalite::expr::HdlPartialEqImpl<#field_ty>
|
||||
});
|
||||
match &mut structural_eq {
|
||||
Some(structural_eq) => {
|
||||
structural_eq.extend(quote_spanned! {cmp_eq.span=>
|
||||
&& <#field_ty as ::fayalite::expr::HdlPartialEqImpl<#field_ty>>::TRY_STRUCTURAL_EQ
|
||||
});
|
||||
}
|
||||
None => {
|
||||
structural_eq = Some(quote_spanned! {cmp_eq.span=>
|
||||
<#field_ty as ::fayalite::expr::HdlPartialEqImpl<#field_ty>>::TRY_STRUCTURAL_EQ
|
||||
});
|
||||
}
|
||||
}
|
||||
variants_value_eq.push(quote_spanned! {span=>
|
||||
(#sim_value_ident::#variant_ident(__lhs_field, _), #sim_value_ident::#variant_ident(__rhs_field, _)) => {
|
||||
(
|
||||
#sim_value_ident::#variant_ident(__lhs_field, _),
|
||||
#sim_value_ident::#variant_ident(__rhs_field, _),
|
||||
) => {
|
||||
::fayalite::expr::HdlPartialEqImpl::cmp_value_eq(
|
||||
__lhs.#variant_ident,
|
||||
::fayalite::__std::borrow::Cow::Borrowed(__lhs_field),
|
||||
|
|
@ -1002,7 +1026,10 @@ impl ToTokens for ParsedEnum {
|
|||
else {
|
||||
::fayalite::__std::unreachable!();
|
||||
};
|
||||
::fayalite::module::connect(__retval, ::fayalite::expr::HdlPartialEqImpl::cmp_expr_eq(__lhs, __rhs));
|
||||
::fayalite::module::connect(
|
||||
__retval,
|
||||
::fayalite::expr::HdlPartialEqImpl::cmp_expr_eq(__lhs, __rhs),
|
||||
);
|
||||
}
|
||||
});
|
||||
fields_valueless_eq.push(quote_spanned! {span=>
|
||||
|
|
@ -1043,7 +1070,10 @@ impl ToTokens for ParsedEnum {
|
|||
}
|
||||
if let Some(sim_value_unknown_variant_name) = &sim_value_unknown_variant_name {
|
||||
variants_value_eq.push(quote_spanned! {span=>
|
||||
(#sim_value_ident::#sim_value_unknown_variant_name(__lhs_unknown), #sim_value_ident::#sim_value_unknown_variant_name(__rhs_unknown)) => {
|
||||
(
|
||||
#sim_value_ident::#sim_value_unknown_variant_name(__lhs_unknown),
|
||||
#sim_value_ident::#sim_value_unknown_variant_name(__rhs_unknown),
|
||||
) => {
|
||||
__lhs_unknown == __rhs_unknown
|
||||
}
|
||||
});
|
||||
|
|
@ -1060,17 +1090,26 @@ impl ToTokens for ParsedEnum {
|
|||
}
|
||||
};
|
||||
let cmp_expr_eq_wire_name = format!("{ident}_cmp_eq");
|
||||
let structural_eq = structural_eq.unwrap_or_else(|| {
|
||||
quote_spanned! {span=>
|
||||
true
|
||||
}
|
||||
});
|
||||
quote_spanned! {span=>
|
||||
#[automatically_derived]
|
||||
impl #impl_generics ::fayalite::expr::HdlPartialEqImpl<Self> for #target #type_generics
|
||||
#cmp_eq_where_clause
|
||||
{
|
||||
const TRY_STRUCTURAL_EQ: ::fayalite::__std::primitive::bool = #structural_eq;
|
||||
|
||||
#[track_caller]
|
||||
fn cmp_value_eq(
|
||||
__lhs: Self,
|
||||
__lhs_value: ::fayalite::__std::borrow::Cow<'_, <Self as ::fayalite::ty::Type>::SimValue>,
|
||||
__lhs_value: ::fayalite::__std::borrow::Cow<'_,
|
||||
<Self as ::fayalite::ty::Type>::SimValue>,
|
||||
__rhs: Self,
|
||||
__rhs_value: ::fayalite::__std::borrow::Cow<'_, <Self as ::fayalite::ty::Type>::SimValue>,
|
||||
__rhs_value: ::fayalite::__std::borrow::Cow<'_,
|
||||
<Self as ::fayalite::ty::Type>::SimValue>,
|
||||
) -> ::fayalite::__std::primitive::bool {
|
||||
match (&*__lhs_value, &*__rhs_value) {
|
||||
#(#variants_value_eq)*
|
||||
|
|
@ -1083,7 +1122,20 @@ impl ToTokens for ParsedEnum {
|
|||
__lhs: ::fayalite::expr::Expr<Self>,
|
||||
__rhs: ::fayalite::expr::Expr<Self>,
|
||||
) -> ::fayalite::expr::Expr<::fayalite::int::Bool> {
|
||||
let __retval = ::fayalite::module::wire(::fayalite::module::ImplicitName(#cmp_expr_eq_wire_name), ::fayalite::int::Bool);
|
||||
if <Self as ::fayalite::expr::HdlPartialEqImpl<Self>>::TRY_STRUCTURAL_EQ {
|
||||
if let ::fayalite::__std::result::Result::Ok(__retval) =
|
||||
::fayalite::expr::ops::StructuralEq::try_new(
|
||||
::fayalite::expr::Expr::canonical(__lhs),
|
||||
::fayalite::expr::Expr::canonical(__rhs),
|
||||
)
|
||||
{
|
||||
return ::fayalite::expr::ToExpr::to_expr(&__retval);
|
||||
}
|
||||
}
|
||||
let __retval = ::fayalite::module::wire(
|
||||
::fayalite::module::ImplicitName(#cmp_expr_eq_wire_name),
|
||||
::fayalite::int::Bool,
|
||||
);
|
||||
::fayalite::module::connect(__retval, false);
|
||||
let mut __lhs_match_variant_iter = ::fayalite::module::match_(__lhs);
|
||||
#(#variants_expr_eq)*
|
||||
|
|
@ -1112,7 +1164,8 @@ impl ToTokens for ParsedEnum {
|
|||
type SimValue = #sim_value_ident #type_generics;
|
||||
type MatchVariant = #match_variant_ident #type_generics;
|
||||
type MatchActiveScope = ::fayalite::module::Scope;
|
||||
type MatchVariantAndInactiveScope = ::fayalite::enum_::EnumMatchVariantAndInactiveScope<Self>;
|
||||
type MatchVariantAndInactiveScope =
|
||||
::fayalite::enum_::EnumMatchVariantAndInactiveScope<Self>;
|
||||
type MatchVariantsIter = ::fayalite::enum_::EnumMatchVariantsIter<Self>;
|
||||
|
||||
fn match_variants(
|
||||
|
|
@ -1125,7 +1178,9 @@ impl ToTokens for ParsedEnum {
|
|||
::fayalite::int::Bool
|
||||
}
|
||||
fn canonical(&#self_token) -> ::fayalite::ty::CanonicalType {
|
||||
::fayalite::ty::CanonicalType::Enum(::fayalite::enum_::Enum::new(::fayalite::enum_::EnumType::variants(#self_token)))
|
||||
::fayalite::ty::CanonicalType::Enum(::fayalite::enum_::Enum::new(
|
||||
::fayalite::enum_::EnumType::variants(#self_token),
|
||||
))
|
||||
}
|
||||
#[track_caller]
|
||||
#[allow(non_snake_case)]
|
||||
|
|
@ -1134,7 +1189,11 @@ impl ToTokens for ParsedEnum {
|
|||
::fayalite::__std::panic!("expected enum");
|
||||
};
|
||||
let #variants_token = ::fayalite::enum_::EnumType::variants(&enum_);
|
||||
::fayalite::__std::assert_eq!(#variants_token.len(), #variants_len, "enum has wrong number of variants");
|
||||
::fayalite::__std::assert_eq!(
|
||||
#variants_token.len(),
|
||||
#variants_len,
|
||||
"enum has wrong number of variants",
|
||||
);
|
||||
Self {
|
||||
#(#from_canonical_body_fields)*
|
||||
}
|
||||
|
|
@ -1180,7 +1239,10 @@ impl ToTokens for ParsedEnum {
|
|||
type SimBuilder = #sim_builder_ident #type_generics;
|
||||
fn match_activate_scope(
|
||||
v: <Self as ::fayalite::ty::Type>::MatchVariantAndInactiveScope,
|
||||
) -> (<Self as ::fayalite::ty::Type>::MatchVariant, <Self as ::fayalite::ty::Type>::MatchActiveScope) {
|
||||
) -> (
|
||||
<Self as ::fayalite::ty::Type>::MatchVariant,
|
||||
<Self as ::fayalite::ty::Type>::MatchActiveScope,
|
||||
) {
|
||||
let (#variant_access_token, scope) = v.activate();
|
||||
(
|
||||
match #variant_access_token.variant_index() {
|
||||
|
|
@ -1200,7 +1262,10 @@ impl ToTokens for ParsedEnum {
|
|||
impl #impl_generics ::fayalite::__std::fmt::Debug for #sim_value_ident #type_generics
|
||||
#where_clause
|
||||
{
|
||||
fn fmt(&self, f: &mut ::fayalite::__std::fmt::Formatter<'_>) -> ::fayalite::__std::fmt::Result {
|
||||
fn fmt(
|
||||
&self,
|
||||
f: &mut ::fayalite::__std::fmt::Formatter<'_>,
|
||||
) -> ::fayalite::__std::fmt::Result {
|
||||
<#target #type_generics as ::fayalite::ty::SimValueDebug>::sim_value_debug(self, f)
|
||||
}
|
||||
}
|
||||
|
|
@ -1213,7 +1278,10 @@ impl ToTokens for ParsedEnum {
|
|||
&self,
|
||||
ty: #target #type_generics,
|
||||
) -> ::fayalite::sim::value::SimValue<#target #type_generics> {
|
||||
::fayalite::sim::value::SimValue::from_value(ty, ::fayalite::__std::clone::Clone::clone(self))
|
||||
::fayalite::sim::value::SimValue::from_value(
|
||||
ty,
|
||||
::fayalite::__std::clone::Clone::clone(self),
|
||||
)
|
||||
}
|
||||
fn into_sim_value_with_type(
|
||||
self,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue