forked from libre-chip/fayalite
expand SimValue support
This commit is contained in:
parent
5028401a5a
commit
a40eaaa2da
13 changed files with 864 additions and 342 deletions
|
@ -692,6 +692,12 @@ impl ToTokens for ParsedBundle {
|
|||
v.field_to_bits(&value.#ident);
|
||||
}
|
||||
}));
|
||||
let to_sim_value_fields = Vec::from_iter(fields.named().into_iter().map(|field| {
|
||||
let ident: &Ident = field.ident().as_ref().unwrap();
|
||||
quote_spanned! {span=>
|
||||
#ident: ::fayalite::sim::value::SimValue::ty(&self.#ident),
|
||||
}
|
||||
}));
|
||||
let fields_len = fields.named().into_iter().len();
|
||||
quote_spanned! {span=>
|
||||
#[automatically_derived]
|
||||
|
@ -797,6 +803,51 @@ impl ToTokens for ParsedBundle {
|
|||
}
|
||||
}
|
||||
#[automatically_derived]
|
||||
impl #impl_generics ::fayalite::sim::value::ToSimValue for #mask_type_sim_value_ident #type_generics
|
||||
#where_clause
|
||||
{
|
||||
type Type = #mask_type_ident #type_generics;
|
||||
|
||||
fn to_sim_value(
|
||||
&self,
|
||||
) -> ::fayalite::sim::value::SimValue<
|
||||
<Self as ::fayalite::sim::value::ToSimValue>::Type,
|
||||
> {
|
||||
let ty = #mask_type_ident {
|
||||
#(#to_sim_value_fields)*
|
||||
};
|
||||
::fayalite::sim::value::SimValue::from_value(ty, ::fayalite::__std::clone::Clone::clone(self))
|
||||
}
|
||||
fn into_sim_value(
|
||||
self,
|
||||
) -> ::fayalite::sim::value::SimValue<
|
||||
<Self as ::fayalite::sim::value::ToSimValue>::Type,
|
||||
> {
|
||||
let ty = #mask_type_ident {
|
||||
#(#to_sim_value_fields)*
|
||||
};
|
||||
::fayalite::sim::value::SimValue::from_value(ty, self)
|
||||
}
|
||||
}
|
||||
#[automatically_derived]
|
||||
impl #impl_generics ::fayalite::sim::value::ToSimValueWithType<#mask_type_ident #type_generics>
|
||||
for #mask_type_sim_value_ident #type_generics
|
||||
#where_clause
|
||||
{
|
||||
fn to_sim_value_with_type(
|
||||
&self,
|
||||
ty: #mask_type_ident #type_generics,
|
||||
) -> ::fayalite::sim::value::SimValue<#mask_type_ident #type_generics> {
|
||||
::fayalite::sim::value::SimValue::from_value(ty, ::fayalite::__std::clone::Clone::clone(self))
|
||||
}
|
||||
fn into_sim_value_with_type(
|
||||
self,
|
||||
ty: #mask_type_ident #type_generics,
|
||||
) -> ::fayalite::sim::value::SimValue<#mask_type_ident #type_generics> {
|
||||
::fayalite::sim::value::SimValue::from_value(ty, self)
|
||||
}
|
||||
}
|
||||
#[automatically_derived]
|
||||
impl #impl_generics ::fayalite::ty::Type for #target #type_generics
|
||||
#where_clause
|
||||
{
|
||||
|
@ -900,6 +951,51 @@ impl ToTokens for ParsedBundle {
|
|||
::fayalite::intern::Interned::into_inner(::fayalite::intern::Intern::intern_sized(__retval))
|
||||
}
|
||||
}
|
||||
#[automatically_derived]
|
||||
impl #impl_generics ::fayalite::sim::value::ToSimValue for #sim_value_ident #type_generics
|
||||
#where_clause
|
||||
{
|
||||
type Type = #target #type_generics;
|
||||
|
||||
fn to_sim_value(
|
||||
&self,
|
||||
) -> ::fayalite::sim::value::SimValue<
|
||||
<Self as ::fayalite::sim::value::ToSimValue>::Type,
|
||||
> {
|
||||
let ty = #target {
|
||||
#(#to_sim_value_fields)*
|
||||
};
|
||||
::fayalite::sim::value::SimValue::from_value(ty, ::fayalite::__std::clone::Clone::clone(self))
|
||||
}
|
||||
fn into_sim_value(
|
||||
self,
|
||||
) -> ::fayalite::sim::value::SimValue<
|
||||
<Self as ::fayalite::sim::value::ToSimValue>::Type,
|
||||
> {
|
||||
let ty = #target {
|
||||
#(#to_sim_value_fields)*
|
||||
};
|
||||
::fayalite::sim::value::SimValue::from_value(ty, self)
|
||||
}
|
||||
}
|
||||
#[automatically_derived]
|
||||
impl #impl_generics ::fayalite::sim::value::ToSimValueWithType<#target #type_generics>
|
||||
for #sim_value_ident #type_generics
|
||||
#where_clause
|
||||
{
|
||||
fn to_sim_value_with_type(
|
||||
&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))
|
||||
}
|
||||
fn into_sim_value_with_type(
|
||||
self,
|
||||
ty: #target #type_generics,
|
||||
) -> ::fayalite::sim::value::SimValue<#target #type_generics> {
|
||||
::fayalite::sim::value::SimValue::from_value(ty, self)
|
||||
}
|
||||
}
|
||||
}
|
||||
.to_tokens(tokens);
|
||||
if let Some((cmp_eq,)) = cmp_eq {
|
||||
|
|
|
@ -866,6 +866,24 @@ impl ToTokens for ParsedEnum {
|
|||
][..])
|
||||
}
|
||||
}
|
||||
#[automatically_derived]
|
||||
impl #impl_generics ::fayalite::sim::value::ToSimValueWithType<#target #type_generics>
|
||||
for #sim_value_ident #type_generics
|
||||
#where_clause
|
||||
{
|
||||
fn to_sim_value_with_type(
|
||||
&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))
|
||||
}
|
||||
fn into_sim_value_with_type(
|
||||
self,
|
||||
ty: #target #type_generics,
|
||||
) -> ::fayalite::sim::value::SimValue<#target #type_generics> {
|
||||
::fayalite::sim::value::SimValue::from_value(ty, self)
|
||||
}
|
||||
}
|
||||
}
|
||||
.to_tokens(tokens);
|
||||
if let (None, MaybeParsed::Parsed(generics)) = (no_static, &self.generics) {
|
||||
|
@ -921,6 +939,34 @@ impl ToTokens for ParsedEnum {
|
|||
const MASK_TYPE_PROPERTIES: ::fayalite::ty::TypeProperties =
|
||||
<::fayalite::int::Bool as ::fayalite::ty::StaticType>::TYPE_PROPERTIES;
|
||||
}
|
||||
#[automatically_derived]
|
||||
impl #static_impl_generics ::fayalite::sim::value::ToSimValue
|
||||
for #sim_value_ident #static_type_generics
|
||||
#static_where_clause
|
||||
{
|
||||
type Type = #target #static_type_generics;
|
||||
|
||||
fn to_sim_value(
|
||||
&self,
|
||||
) -> ::fayalite::sim::value::SimValue<
|
||||
<Self as ::fayalite::sim::value::ToSimValue>::Type,
|
||||
> {
|
||||
::fayalite::sim::value::SimValue::from_value(
|
||||
::fayalite::ty::StaticType::TYPE,
|
||||
::fayalite::__std::clone::Clone::clone(self),
|
||||
)
|
||||
}
|
||||
fn into_sim_value(
|
||||
self,
|
||||
) -> ::fayalite::sim::value::SimValue<
|
||||
<Self as ::fayalite::sim::value::ToSimValue>::Type,
|
||||
> {
|
||||
::fayalite::sim::value::SimValue::from_value(
|
||||
::fayalite::ty::StaticType::TYPE,
|
||||
self,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
.to_tokens(tokens);
|
||||
}
|
||||
|
|
|
@ -93,6 +93,7 @@ mod kw {
|
|||
custom_keyword!(output);
|
||||
custom_keyword!(reg_builder);
|
||||
custom_keyword!(reset);
|
||||
custom_keyword!(sim);
|
||||
custom_keyword!(skip);
|
||||
custom_keyword!(target);
|
||||
custom_keyword!(wire);
|
||||
|
|
|
@ -16,7 +16,7 @@ use std::{borrow::Borrow, convert::Infallible};
|
|||
use syn::{
|
||||
fold::{fold_expr, fold_expr_lit, fold_expr_unary, fold_local, fold_stmt, Fold},
|
||||
parenthesized,
|
||||
parse::{Nothing, Parse, ParseStream},
|
||||
parse::{Parse, ParseStream},
|
||||
parse_quote, parse_quote_spanned,
|
||||
spanned::Spanned,
|
||||
token::Paren,
|
||||
|
@ -27,6 +27,13 @@ use syn::{
|
|||
mod expand_aggregate_literals;
|
||||
mod expand_match;
|
||||
|
||||
options! {
|
||||
#[options = ExprOptions]
|
||||
pub(crate) enum ExprOption {
|
||||
Sim(sim),
|
||||
}
|
||||
}
|
||||
|
||||
options! {
|
||||
pub(crate) enum LetFnKind {
|
||||
Input(input),
|
||||
|
@ -952,7 +959,7 @@ with_debug_clone_and_fold! {
|
|||
#[allow(dead_code)]
|
||||
pub(crate) struct HdlLet<Kind = HdlLetKind> {
|
||||
pub(crate) attrs: Vec<Attribute>,
|
||||
pub(crate) hdl_attr: HdlAttr<Nothing, kw::hdl>,
|
||||
pub(crate) hdl_attr: HdlAttr<syn::parse::Nothing, kw::hdl>,
|
||||
pub(crate) let_token: Token![let],
|
||||
pub(crate) mut_token: Option<Token![mut]>,
|
||||
pub(crate) name: Ident,
|
||||
|
@ -1173,7 +1180,7 @@ impl Visitor<'_> {
|
|||
Some(_) => {}
|
||||
}
|
||||
}
|
||||
fn process_hdl_if(&mut self, hdl_attr: HdlAttr<Nothing, kw::hdl>, expr_if: ExprIf) -> Expr {
|
||||
fn process_hdl_if(&mut self, hdl_attr: HdlAttr<ExprOptions, kw::hdl>, expr_if: ExprIf) -> Expr {
|
||||
let ExprIf {
|
||||
attrs,
|
||||
if_token,
|
||||
|
@ -1181,10 +1188,10 @@ impl Visitor<'_> {
|
|||
then_branch,
|
||||
else_branch,
|
||||
} = expr_if;
|
||||
self.require_normal_module_or_fn(if_token);
|
||||
let else_expr = else_branch.unzip().1.map(|else_expr| match *else_expr {
|
||||
Expr::If(expr_if) => self.process_hdl_if(hdl_attr.clone(), expr_if),
|
||||
expr => expr,
|
||||
let (else_token, else_expr) = else_branch.unzip();
|
||||
let else_expr = else_expr.map(|else_expr| match *else_expr {
|
||||
Expr::If(expr_if) => Box::new(self.process_hdl_if(hdl_attr.clone(), expr_if)),
|
||||
_ => else_expr,
|
||||
});
|
||||
if let Expr::Let(ExprLet {
|
||||
attrs: let_attrs,
|
||||
|
@ -1206,7 +1213,19 @@ impl Visitor<'_> {
|
|||
},
|
||||
);
|
||||
}
|
||||
if let Some(else_expr) = else_expr {
|
||||
let ExprOptions { sim } = hdl_attr.body;
|
||||
if sim.is_some() {
|
||||
ExprIf {
|
||||
attrs,
|
||||
if_token,
|
||||
cond: parse_quote_spanned! {if_token.span=>
|
||||
*::fayalite::sim::value::SimValue::<::fayalite::int::Bool>::value(&::fayalite::sim::value::ToSimValue::into_sim_value(#cond))
|
||||
},
|
||||
then_branch,
|
||||
else_branch: else_token.zip(else_expr),
|
||||
}
|
||||
.into()
|
||||
} else if let Some(else_expr) = else_expr {
|
||||
parse_quote_spanned! {if_token.span=>
|
||||
#(#attrs)*
|
||||
{
|
||||
|
@ -1675,7 +1694,7 @@ impl Fold for Visitor<'_> {
|
|||
fn fold_local(&mut self, mut let_stmt: Local) -> Local {
|
||||
match self
|
||||
.errors
|
||||
.ok(HdlAttr::<Nothing, kw::hdl>::parse_and_leave_attr(
|
||||
.ok(HdlAttr::<ExprOptions, kw::hdl>::parse_and_leave_attr(
|
||||
&let_stmt.attrs,
|
||||
)) {
|
||||
None => return empty_let(),
|
||||
|
@ -1694,10 +1713,11 @@ impl Fold for Visitor<'_> {
|
|||
subpat: None,
|
||||
}) = pat
|
||||
else {
|
||||
let hdl_attr = HdlAttr::<Nothing, kw::hdl>::parse_and_take_attr(&mut let_stmt.attrs)
|
||||
.ok()
|
||||
.flatten()
|
||||
.expect("already checked above");
|
||||
let hdl_attr =
|
||||
HdlAttr::<ExprOptions, kw::hdl>::parse_and_take_attr(&mut let_stmt.attrs)
|
||||
.ok()
|
||||
.flatten()
|
||||
.expect("already checked above");
|
||||
let let_stmt = fold_local(self, let_stmt);
|
||||
return self.process_hdl_let_pat(hdl_attr, let_stmt);
|
||||
};
|
||||
|
|
|
@ -1,45 +1,97 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// See Notices.txt for copyright information
|
||||
use crate::{kw, module::transform_body::Visitor, HdlAttr};
|
||||
use crate::{
|
||||
kw,
|
||||
module::transform_body::{ExprOptions, Visitor},
|
||||
HdlAttr,
|
||||
};
|
||||
use quote::{format_ident, quote_spanned};
|
||||
use syn::{
|
||||
parse::Nothing, parse_quote, parse_quote_spanned, spanned::Spanned, Expr, ExprArray, ExprPath,
|
||||
ExprRepeat, ExprStruct, ExprTuple, FieldValue, TypePath,
|
||||
parse_quote_spanned, spanned::Spanned, Expr, ExprArray, ExprPath, ExprRepeat, ExprStruct,
|
||||
ExprTuple, FieldValue, TypePath,
|
||||
};
|
||||
|
||||
impl Visitor<'_> {
|
||||
pub(crate) fn process_hdl_array(
|
||||
&mut self,
|
||||
hdl_attr: HdlAttr<Nothing, kw::hdl>,
|
||||
hdl_attr: HdlAttr<ExprOptions, kw::hdl>,
|
||||
mut expr_array: ExprArray,
|
||||
) -> Expr {
|
||||
self.require_normal_module_or_fn(hdl_attr);
|
||||
for elem in &mut expr_array.elems {
|
||||
*elem = parse_quote_spanned! {elem.span()=>
|
||||
::fayalite::expr::ToExpr::to_expr(&(#elem))
|
||||
};
|
||||
let ExprOptions { sim } = hdl_attr.body;
|
||||
let span = hdl_attr.kw.span;
|
||||
if sim.is_some() {
|
||||
for elem in &mut expr_array.elems {
|
||||
*elem = parse_quote_spanned! {elem.span()=>
|
||||
::fayalite::sim::value::ToSimValue::to_sim_value(&(#elem))
|
||||
};
|
||||
}
|
||||
parse_quote_spanned! {span=>
|
||||
::fayalite::sim::value::ToSimValue::into_sim_value(#expr_array)
|
||||
}
|
||||
} else {
|
||||
for elem in &mut expr_array.elems {
|
||||
*elem = parse_quote_spanned! {elem.span()=>
|
||||
::fayalite::expr::ToExpr::to_expr(&(#elem))
|
||||
};
|
||||
}
|
||||
parse_quote_spanned! {span=>
|
||||
::fayalite::expr::ToExpr::to_expr(&#expr_array)
|
||||
}
|
||||
}
|
||||
parse_quote! {::fayalite::expr::ToExpr::to_expr(&#expr_array)}
|
||||
}
|
||||
pub(crate) fn process_hdl_repeat(
|
||||
&mut self,
|
||||
hdl_attr: HdlAttr<Nothing, kw::hdl>,
|
||||
hdl_attr: HdlAttr<ExprOptions, kw::hdl>,
|
||||
mut expr_repeat: ExprRepeat,
|
||||
) -> Expr {
|
||||
self.require_normal_module_or_fn(hdl_attr);
|
||||
let repeated_value = &expr_repeat.expr;
|
||||
*expr_repeat.expr = parse_quote_spanned! {repeated_value.span()=>
|
||||
::fayalite::expr::ToExpr::to_expr(&(#repeated_value))
|
||||
};
|
||||
parse_quote! {::fayalite::expr::ToExpr::to_expr(&#expr_repeat)}
|
||||
let ExprOptions { sim } = hdl_attr.body;
|
||||
let span = hdl_attr.kw.span;
|
||||
if sim.is_some() {
|
||||
*expr_repeat.expr = parse_quote_spanned! {repeated_value.span()=>
|
||||
::fayalite::sim::value::ToSimValue::to_sim_value(&(#repeated_value))
|
||||
};
|
||||
parse_quote_spanned! {span=>
|
||||
::fayalite::sim::value::ToSimValue::into_sim_value(#expr_repeat)
|
||||
}
|
||||
} else {
|
||||
*expr_repeat.expr = parse_quote_spanned! {repeated_value.span()=>
|
||||
::fayalite::expr::ToExpr::to_expr(&(#repeated_value))
|
||||
};
|
||||
parse_quote_spanned! {span=>
|
||||
::fayalite::expr::ToExpr::to_expr(&#expr_repeat)
|
||||
}
|
||||
}
|
||||
}
|
||||
pub(crate) fn process_hdl_struct(
|
||||
&mut self,
|
||||
hdl_attr: HdlAttr<Nothing, kw::hdl>,
|
||||
expr_struct: ExprStruct,
|
||||
hdl_attr: HdlAttr<ExprOptions, kw::hdl>,
|
||||
mut expr_struct: ExprStruct,
|
||||
) -> Expr {
|
||||
self.require_normal_module_or_fn(&hdl_attr);
|
||||
let name_span = expr_struct.path.segments.last().unwrap().ident.span();
|
||||
let ExprOptions { sim } = hdl_attr.body;
|
||||
if sim.is_some() {
|
||||
let ty_path = TypePath {
|
||||
qself: expr_struct.qself.take(),
|
||||
path: expr_struct.path,
|
||||
};
|
||||
expr_struct.path = parse_quote_spanned! {name_span=>
|
||||
__SimValue::<#ty_path>
|
||||
};
|
||||
for field in &mut expr_struct.fields {
|
||||
let expr = &field.expr;
|
||||
field.expr = parse_quote_spanned! {field.member.span()=>
|
||||
::fayalite::sim::value::ToSimValue::to_sim_value(&(#expr))
|
||||
};
|
||||
}
|
||||
return parse_quote_spanned! {name_span=>
|
||||
{
|
||||
type __SimValue<T> = <T as ::fayalite::ty::Type>::SimValue;
|
||||
let value: ::fayalite::sim::value::SimValue<#ty_path> = ::fayalite::sim::value::ToSimValue::into_sim_value(#expr_struct);
|
||||
value
|
||||
}
|
||||
};
|
||||
}
|
||||
let builder_ident = format_ident!("__builder", span = name_span);
|
||||
let empty_builder = if expr_struct.qself.is_some()
|
||||
|| expr_struct
|
||||
|
@ -91,12 +143,23 @@ impl Visitor<'_> {
|
|||
}
|
||||
pub(crate) fn process_hdl_tuple(
|
||||
&mut self,
|
||||
hdl_attr: HdlAttr<Nothing, kw::hdl>,
|
||||
expr_tuple: ExprTuple,
|
||||
hdl_attr: HdlAttr<ExprOptions, kw::hdl>,
|
||||
mut expr_tuple: ExprTuple,
|
||||
) -> Expr {
|
||||
self.require_normal_module_or_fn(hdl_attr);
|
||||
parse_quote_spanned! {expr_tuple.span()=>
|
||||
::fayalite::expr::ToExpr::to_expr(&#expr_tuple)
|
||||
let ExprOptions { sim } = hdl_attr.body;
|
||||
if sim.is_some() {
|
||||
for element in &mut expr_tuple.elems {
|
||||
*element = parse_quote_spanned! {element.span()=>
|
||||
&(#element)
|
||||
};
|
||||
}
|
||||
parse_quote_spanned! {expr_tuple.span()=>
|
||||
::fayalite::sim::value::ToSimValue::into_sim_value(#expr_tuple)
|
||||
}
|
||||
} else {
|
||||
parse_quote_spanned! {expr_tuple.span()=>
|
||||
::fayalite::expr::ToExpr::to_expr(&#expr_tuple)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
use crate::{
|
||||
fold::{impl_fold, DoFold},
|
||||
kw,
|
||||
module::transform_body::{empty_let, with_debug_clone_and_fold, wrap_ty_with_expr, Visitor},
|
||||
module::transform_body::{
|
||||
empty_let, with_debug_clone_and_fold, wrap_ty_with_expr, ExprOptions, Visitor,
|
||||
},
|
||||
Errors, HdlAttr, PairsIterExt,
|
||||
};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
|
@ -11,7 +13,6 @@ use quote::{format_ident, quote_spanned, ToTokens, TokenStreamExt};
|
|||
use std::collections::BTreeSet;
|
||||
use syn::{
|
||||
fold::{fold_arm, fold_expr_match, fold_local, fold_pat, Fold},
|
||||
parse::Nothing,
|
||||
parse_quote_spanned,
|
||||
punctuated::Punctuated,
|
||||
spanned::Spanned,
|
||||
|
@ -981,7 +982,7 @@ impl<'a> VisitMatchPat<'a> for HdlLetPatVisitState<'a> {
|
|||
impl Visitor<'_> {
|
||||
pub(crate) fn process_hdl_let_pat(
|
||||
&mut self,
|
||||
_hdl_attr: HdlAttr<Nothing, kw::hdl>,
|
||||
hdl_attr: HdlAttr<ExprOptions, kw::hdl>,
|
||||
mut let_stmt: Local,
|
||||
) -> Local {
|
||||
let span = let_stmt.let_token.span();
|
||||
|
@ -996,7 +997,6 @@ impl Visitor<'_> {
|
|||
init,
|
||||
semi_token,
|
||||
} = let_stmt;
|
||||
self.require_normal_module_or_fn(let_token);
|
||||
let Some(syn::LocalInit {
|
||||
eq_token,
|
||||
expr,
|
||||
|
@ -1031,29 +1031,48 @@ impl Visitor<'_> {
|
|||
errors: _,
|
||||
bindings,
|
||||
} = state;
|
||||
let retval = parse_quote_spanned! {span=>
|
||||
let (#(#bindings,)* __scope,) = {
|
||||
type __MatchTy<T> = <T as ::fayalite::ty::Type>::MatchVariant;
|
||||
let __match_expr = ::fayalite::expr::ToExpr::to_expr(&(#expr));
|
||||
::fayalite::expr::check_match_expr(__match_expr, |__match_value, __infallible| {
|
||||
#[allow(unused_variables)]
|
||||
#check_let_stmt
|
||||
match __infallible {}
|
||||
});
|
||||
let mut __match_iter = ::fayalite::module::match_(__match_expr);
|
||||
let ::fayalite::__std::option::Option::Some(__match_variant) = ::fayalite::__std::iter::Iterator::next(&mut __match_iter) else {
|
||||
::fayalite::__std::unreachable!("#[hdl] let with uninhabited type");
|
||||
let ExprOptions { sim } = hdl_attr.body;
|
||||
let retval = if sim.is_some() {
|
||||
parse_quote_spanned! {span=>
|
||||
let (#(#bindings,)*) = {
|
||||
type __MatchTy<T> = <T as ::fayalite::ty::Type>::SimValue;
|
||||
let __match_value = ::fayalite::sim::value::ToSimValue::to_sim_value(&(#expr));
|
||||
#let_token #pat #eq_token ::fayalite::sim::value::SimValue::into_value(__match_value) #semi_token
|
||||
(#(#bindings,)*)
|
||||
};
|
||||
let ::fayalite::__std::option::Option::None = ::fayalite::__std::iter::Iterator::next(&mut __match_iter) else {
|
||||
::fayalite::__std::unreachable!("#[hdl] let with refutable pattern");
|
||||
};
|
||||
let (__match_variant, __scope) =
|
||||
::fayalite::ty::MatchVariantAndInactiveScope::match_activate_scope(
|
||||
__match_variant,
|
||||
}
|
||||
} else {
|
||||
parse_quote_spanned! {span=>
|
||||
let (#(#bindings,)* __scope,) = {
|
||||
type __MatchTy<T> = <T as ::fayalite::ty::Type>::MatchVariant;
|
||||
let __match_expr = ::fayalite::expr::ToExpr::to_expr(&(#expr));
|
||||
::fayalite::expr::check_match_expr(
|
||||
__match_expr,
|
||||
|__match_value, __infallible| {
|
||||
#[allow(unused_variables)]
|
||||
#check_let_stmt
|
||||
match __infallible {}
|
||||
},
|
||||
);
|
||||
#let_token #pat #eq_token __match_variant #semi_token
|
||||
(#(#bindings,)* __scope,)
|
||||
};
|
||||
let mut __match_iter = ::fayalite::module::match_(__match_expr);
|
||||
let ::fayalite::__std::option::Option::Some(__match_variant) =
|
||||
::fayalite::__std::iter::Iterator::next(&mut __match_iter)
|
||||
else {
|
||||
::fayalite::__std::unreachable!("#[hdl] let with uninhabited type");
|
||||
};
|
||||
let ::fayalite::__std::option::Option::None =
|
||||
::fayalite::__std::iter::Iterator::next(&mut __match_iter)
|
||||
else {
|
||||
::fayalite::__std::unreachable!("#[hdl] let with refutable pattern");
|
||||
};
|
||||
let (__match_variant, __scope) =
|
||||
::fayalite::ty::MatchVariantAndInactiveScope::match_activate_scope(
|
||||
__match_variant,
|
||||
);
|
||||
#let_token #pat #eq_token __match_variant #semi_token
|
||||
(#(#bindings,)* __scope,)
|
||||
};
|
||||
}
|
||||
};
|
||||
match retval {
|
||||
syn::Stmt::Local(retval) => retval,
|
||||
|
@ -1062,7 +1081,7 @@ impl Visitor<'_> {
|
|||
}
|
||||
pub(crate) fn process_hdl_match(
|
||||
&mut self,
|
||||
_hdl_attr: HdlAttr<Nothing, kw::hdl>,
|
||||
hdl_attr: HdlAttr<ExprOptions, kw::hdl>,
|
||||
expr_match: ExprMatch,
|
||||
) -> Expr {
|
||||
let span = expr_match.match_token.span();
|
||||
|
@ -1074,7 +1093,6 @@ impl Visitor<'_> {
|
|||
brace_token: _,
|
||||
arms,
|
||||
} = expr_match;
|
||||
self.require_normal_module_or_fn(match_token);
|
||||
let mut state = HdlMatchParseState {
|
||||
match_span: span,
|
||||
errors: &mut self.errors,
|
||||
|
@ -1083,24 +1101,37 @@ impl Visitor<'_> {
|
|||
arms.into_iter()
|
||||
.filter_map(|arm| MatchArm::parse(&mut state, arm).ok()),
|
||||
);
|
||||
let expr = quote_spanned! {span=>
|
||||
{
|
||||
type __MatchTy<T> = <T as ::fayalite::ty::Type>::MatchVariant;
|
||||
let __match_expr = ::fayalite::expr::ToExpr::to_expr(&(#expr));
|
||||
::fayalite::expr::check_match_expr(__match_expr, |__match_value, __infallible| {
|
||||
#[allow(unused_variables)]
|
||||
#check_match
|
||||
});
|
||||
for __match_variant in ::fayalite::module::match_(__match_expr) {
|
||||
let (__match_variant, __scope) =
|
||||
::fayalite::ty::MatchVariantAndInactiveScope::match_activate_scope(
|
||||
__match_variant,
|
||||
);
|
||||
#match_token __match_variant {
|
||||
let ExprOptions { sim } = hdl_attr.body;
|
||||
let expr = if sim.is_some() {
|
||||
quote_spanned! {span=>
|
||||
{
|
||||
type __MatchTy<T> = <T as ::fayalite::ty::Type>::SimValue;
|
||||
let __match_expr = ::fayalite::sim::value::ToSimValue::to_sim_value(&(#expr));
|
||||
#match_token *__match_expr {
|
||||
#(#arms)*
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote_spanned! {span=>
|
||||
{
|
||||
type __MatchTy<T> = <T as ::fayalite::ty::Type>::MatchVariant;
|
||||
let __match_expr = ::fayalite::expr::ToExpr::to_expr(&(#expr));
|
||||
::fayalite::expr::check_match_expr(__match_expr, |__match_value, __infallible| {
|
||||
#[allow(unused_variables)]
|
||||
#check_match
|
||||
});
|
||||
for __match_variant in ::fayalite::module::match_(__match_expr) {
|
||||
let (__match_variant, __scope) =
|
||||
::fayalite::ty::MatchVariantAndInactiveScope::match_activate_scope(
|
||||
__match_variant,
|
||||
);
|
||||
#match_token __match_variant {
|
||||
#(#arms)*
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
syn::parse2(expr).unwrap()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue