fix #[hdl(sim)] match on enums
This commit is contained in:
parent
a40eaaa2da
commit
9092e45447
|
@ -83,7 +83,14 @@ visit_trait! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn visit_match_pat_enum_variant(state: _, v: &MatchPatEnumVariant) {
|
fn visit_match_pat_enum_variant(state: _, v: &MatchPatEnumVariant) {
|
||||||
let MatchPatEnumVariant {match_span:_, variant_path: _, enum_path: _, variant_name: _, field } = v;
|
let MatchPatEnumVariant {
|
||||||
|
match_span:_,
|
||||||
|
sim:_,
|
||||||
|
variant_path: _,
|
||||||
|
enum_path: _,
|
||||||
|
variant_name: _,
|
||||||
|
field,
|
||||||
|
} = v;
|
||||||
if let Some((_, v)) = field {
|
if let Some((_, v)) = field {
|
||||||
state.visit_match_pat_simple(v);
|
state.visit_match_pat_simple(v);
|
||||||
}
|
}
|
||||||
|
@ -293,6 +300,7 @@ impl ToTokens for MatchPatTuple {
|
||||||
with_debug_clone_and_fold! {
|
with_debug_clone_and_fold! {
|
||||||
struct MatchPatEnumVariant<> {
|
struct MatchPatEnumVariant<> {
|
||||||
match_span: Span,
|
match_span: Span,
|
||||||
|
sim: Option<(kw::sim,)>,
|
||||||
variant_path: Path,
|
variant_path: Path,
|
||||||
enum_path: Path,
|
enum_path: Path,
|
||||||
variant_name: Ident,
|
variant_name: Ident,
|
||||||
|
@ -304,6 +312,7 @@ impl ToTokens for MatchPatEnumVariant {
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
let Self {
|
let Self {
|
||||||
match_span,
|
match_span,
|
||||||
|
sim,
|
||||||
variant_path: _,
|
variant_path: _,
|
||||||
enum_path,
|
enum_path,
|
||||||
variant_name,
|
variant_name,
|
||||||
|
@ -313,7 +322,28 @@ impl ToTokens for MatchPatEnumVariant {
|
||||||
__MatchTy::<#enum_path>::#variant_name
|
__MatchTy::<#enum_path>::#variant_name
|
||||||
}
|
}
|
||||||
.to_tokens(tokens);
|
.to_tokens(tokens);
|
||||||
if let Some((paren_token, field)) = field {
|
if sim.is_some() {
|
||||||
|
if let Some((paren_token, field)) = field {
|
||||||
|
paren_token.surround(tokens, |tokens| {
|
||||||
|
field.to_tokens(tokens);
|
||||||
|
match field {
|
||||||
|
MatchPatSimple::Paren(_)
|
||||||
|
| MatchPatSimple::Or(_)
|
||||||
|
| MatchPatSimple::Binding(_)
|
||||||
|
| MatchPatSimple::Wild(_) => quote_spanned! {*match_span=>
|
||||||
|
, _
|
||||||
|
}
|
||||||
|
.to_tokens(tokens),
|
||||||
|
MatchPatSimple::Rest(_) => {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
quote_spanned! {*match_span=>
|
||||||
|
(_)
|
||||||
|
}
|
||||||
|
.to_tokens(tokens);
|
||||||
|
}
|
||||||
|
} else if let Some((paren_token, field)) = field {
|
||||||
paren_token.surround(tokens, |tokens| field.to_tokens(tokens));
|
paren_token.surround(tokens, |tokens| field.to_tokens(tokens));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -448,6 +478,7 @@ trait ParseMatchPat: Sized {
|
||||||
state,
|
state,
|
||||||
MatchPatEnumVariant {
|
MatchPatEnumVariant {
|
||||||
match_span: state.match_span,
|
match_span: state.match_span,
|
||||||
|
sim: state.sim,
|
||||||
variant_path,
|
variant_path,
|
||||||
enum_path,
|
enum_path,
|
||||||
variant_name,
|
variant_name,
|
||||||
|
@ -494,6 +525,7 @@ trait ParseMatchPat: Sized {
|
||||||
state,
|
state,
|
||||||
MatchPatEnumVariant {
|
MatchPatEnumVariant {
|
||||||
match_span: state.match_span,
|
match_span: state.match_span,
|
||||||
|
sim: state.sim,
|
||||||
variant_path,
|
variant_path,
|
||||||
enum_path,
|
enum_path,
|
||||||
variant_name,
|
variant_name,
|
||||||
|
@ -578,6 +610,7 @@ trait ParseMatchPat: Sized {
|
||||||
state,
|
state,
|
||||||
MatchPatEnumVariant {
|
MatchPatEnumVariant {
|
||||||
match_span: state.match_span,
|
match_span: state.match_span,
|
||||||
|
sim: state.sim,
|
||||||
variant_path,
|
variant_path,
|
||||||
enum_path,
|
enum_path,
|
||||||
variant_name,
|
variant_name,
|
||||||
|
@ -940,6 +973,7 @@ impl Fold for RewriteAsCheckMatch {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HdlMatchParseState<'a> {
|
struct HdlMatchParseState<'a> {
|
||||||
|
sim: Option<(kw::sim,)>,
|
||||||
match_span: Span,
|
match_span: Span,
|
||||||
errors: &'a mut Errors,
|
errors: &'a mut Errors,
|
||||||
}
|
}
|
||||||
|
@ -986,6 +1020,7 @@ impl Visitor<'_> {
|
||||||
mut let_stmt: Local,
|
mut let_stmt: Local,
|
||||||
) -> Local {
|
) -> Local {
|
||||||
let span = let_stmt.let_token.span();
|
let span = let_stmt.let_token.span();
|
||||||
|
let ExprOptions { sim } = hdl_attr.body;
|
||||||
if let Pat::Type(pat) = &mut let_stmt.pat {
|
if let Pat::Type(pat) = &mut let_stmt.pat {
|
||||||
*pat.ty = wrap_ty_with_expr((*pat.ty).clone());
|
*pat.ty = wrap_ty_with_expr((*pat.ty).clone());
|
||||||
}
|
}
|
||||||
|
@ -1015,6 +1050,7 @@ impl Visitor<'_> {
|
||||||
}
|
}
|
||||||
let Ok(pat) = MatchPat::parse(
|
let Ok(pat) = MatchPat::parse(
|
||||||
&mut HdlMatchParseState {
|
&mut HdlMatchParseState {
|
||||||
|
sim,
|
||||||
match_span: span,
|
match_span: span,
|
||||||
errors: &mut self.errors,
|
errors: &mut self.errors,
|
||||||
},
|
},
|
||||||
|
@ -1031,7 +1067,6 @@ impl Visitor<'_> {
|
||||||
errors: _,
|
errors: _,
|
||||||
bindings,
|
bindings,
|
||||||
} = state;
|
} = state;
|
||||||
let ExprOptions { sim } = hdl_attr.body;
|
|
||||||
let retval = if sim.is_some() {
|
let retval = if sim.is_some() {
|
||||||
parse_quote_spanned! {span=>
|
parse_quote_spanned! {span=>
|
||||||
let (#(#bindings,)*) = {
|
let (#(#bindings,)*) = {
|
||||||
|
@ -1093,7 +1128,9 @@ impl Visitor<'_> {
|
||||||
brace_token: _,
|
brace_token: _,
|
||||||
arms,
|
arms,
|
||||||
} = expr_match;
|
} = expr_match;
|
||||||
|
let ExprOptions { sim } = hdl_attr.body;
|
||||||
let mut state = HdlMatchParseState {
|
let mut state = HdlMatchParseState {
|
||||||
|
sim,
|
||||||
match_span: span,
|
match_span: span,
|
||||||
errors: &mut self.errors,
|
errors: &mut self.errors,
|
||||||
};
|
};
|
||||||
|
@ -1101,13 +1138,12 @@ impl Visitor<'_> {
|
||||||
arms.into_iter()
|
arms.into_iter()
|
||||||
.filter_map(|arm| MatchArm::parse(&mut state, arm).ok()),
|
.filter_map(|arm| MatchArm::parse(&mut state, arm).ok()),
|
||||||
);
|
);
|
||||||
let ExprOptions { sim } = hdl_attr.body;
|
|
||||||
let expr = if sim.is_some() {
|
let expr = if sim.is_some() {
|
||||||
quote_spanned! {span=>
|
quote_spanned! {span=>
|
||||||
{
|
{
|
||||||
type __MatchTy<T> = <T as ::fayalite::ty::Type>::SimValue;
|
type __MatchTy<T> = <T as ::fayalite::ty::Type>::SimValue;
|
||||||
let __match_expr = ::fayalite::sim::value::ToSimValue::to_sim_value(&(#expr));
|
let __match_expr = ::fayalite::sim::value::ToSimValue::to_sim_value(&(#expr));
|
||||||
#match_token *__match_expr {
|
#match_token ::fayalite::sim::value::SimValue::into_value(__match_expr) {
|
||||||
#(#arms)*
|
#(#arms)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -497,6 +497,12 @@ fn test_enums() {
|
||||||
"vcd:\n{}\ncycle: {cycle}",
|
"vcd:\n{}\ncycle: {cycle}",
|
||||||
String::from_utf8(writer.take()).unwrap(),
|
String::from_utf8(writer.take()).unwrap(),
|
||||||
);
|
);
|
||||||
|
// make sure matching on SimValue<SomeEnum> works
|
||||||
|
#[hdl(sim)]
|
||||||
|
match io.b_out {
|
||||||
|
HdlNone => println!("io.b_out is HdlNone"),
|
||||||
|
HdlSome(v) => println!("io.b_out is HdlSome(({:?}, {:?}))", *v.0, *v.1),
|
||||||
|
}
|
||||||
sim.write_clock(sim.io().cd.clk, false);
|
sim.write_clock(sim.io().cd.clk, false);
|
||||||
sim.advance_time(SimDuration::from_micros(1));
|
sim.advance_time(SimDuration::from_micros(1));
|
||||||
sim.write_clock(sim.io().cd.clk, true);
|
sim.write_clock(sim.io().cd.clk, true);
|
||||||
|
|
Loading…
Reference in a new issue