#[hdl] match works!
This commit is contained in:
parent
9887d70f41
commit
2d293ae87b
4 changed files with 83 additions and 24 deletions
|
@ -224,6 +224,7 @@ forward_fold!(syn::ExprPath => fold_expr_path);
|
|||
forward_fold!(syn::ExprRepeat => fold_expr_repeat);
|
||||
forward_fold!(syn::ExprStruct => fold_expr_struct);
|
||||
forward_fold!(syn::ExprTuple => fold_expr_tuple);
|
||||
forward_fold!(syn::FieldPat => fold_field_pat);
|
||||
forward_fold!(syn::Ident => fold_ident);
|
||||
forward_fold!(syn::Member => fold_member);
|
||||
forward_fold!(syn::Path => fold_path);
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// See Notices.txt for copyright information
|
||||
use crate::{
|
||||
fold::impl_fold,
|
||||
fold::{impl_fold, DoFold},
|
||||
module::transform_body::{with_debug_clone_and_fold, Visitor},
|
||||
Errors, HdlAttr, PairsIterExt,
|
||||
};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::{format_ident, ToTokens, TokenStreamExt};
|
||||
use quote::{format_ident, quote_spanned, ToTokens, TokenStreamExt};
|
||||
use syn::{
|
||||
fold::{fold_arm, fold_expr_match, fold_pat, Fold},
|
||||
parse::Nothing,
|
||||
|
@ -130,6 +130,7 @@ impl MatchPatStructField {
|
|||
|
||||
with_debug_clone_and_fold! {
|
||||
struct MatchPatStruct<> {
|
||||
match_span: Span,
|
||||
path: Path,
|
||||
brace_token: Brace,
|
||||
fields: Punctuated<MatchPatStructField, Token![,]>,
|
||||
|
@ -140,12 +141,16 @@ with_debug_clone_and_fold! {
|
|||
impl ToTokens for MatchPatStruct {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
let Self {
|
||||
match_span,
|
||||
path,
|
||||
brace_token,
|
||||
fields,
|
||||
rest,
|
||||
} = self;
|
||||
path.to_tokens(tokens);
|
||||
quote_spanned! {*match_span=>
|
||||
__MatchTy::<#path>
|
||||
}
|
||||
.to_tokens(tokens);
|
||||
brace_token.surround(tokens, |tokens| {
|
||||
fields.to_tokens(tokens);
|
||||
rest.to_tokens(tokens);
|
||||
|
@ -155,6 +160,7 @@ impl ToTokens for MatchPatStruct {
|
|||
|
||||
with_debug_clone_and_fold! {
|
||||
struct MatchPatEnumVariant<> {
|
||||
match_span: Span,
|
||||
variant_path: Path,
|
||||
enum_path: Path,
|
||||
variant_name: Ident,
|
||||
|
@ -165,12 +171,16 @@ with_debug_clone_and_fold! {
|
|||
impl ToTokens for MatchPatEnumVariant {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
let Self {
|
||||
variant_path,
|
||||
enum_path: _,
|
||||
variant_name: _,
|
||||
match_span,
|
||||
variant_path: _,
|
||||
enum_path,
|
||||
variant_name,
|
||||
field,
|
||||
} = self;
|
||||
variant_path.to_tokens(tokens);
|
||||
quote_spanned! {*match_span=>
|
||||
__MatchTy::<#enum_path>::#variant_name
|
||||
}
|
||||
.to_tokens(tokens);
|
||||
if let Some((paren_token, field)) = field {
|
||||
paren_token.surround(tokens, |tokens| field.to_tokens(tokens));
|
||||
}
|
||||
|
@ -301,6 +311,7 @@ trait ParseMatchPat: Sized {
|
|||
}) => Self::enum_variant(
|
||||
state,
|
||||
MatchPatEnumVariant {
|
||||
match_span: state.match_span,
|
||||
variant_path,
|
||||
enum_path,
|
||||
variant_name,
|
||||
|
@ -346,6 +357,7 @@ trait ParseMatchPat: Sized {
|
|||
Self::enum_variant(
|
||||
state,
|
||||
MatchPatEnumVariant {
|
||||
match_span: state.match_span,
|
||||
variant_path,
|
||||
enum_path,
|
||||
variant_name,
|
||||
|
@ -376,6 +388,7 @@ trait ParseMatchPat: Sized {
|
|||
Self::struct_(
|
||||
state,
|
||||
MatchPatStruct {
|
||||
match_span: state.match_span,
|
||||
path,
|
||||
brace_token,
|
||||
fields,
|
||||
|
@ -428,6 +441,7 @@ trait ParseMatchPat: Sized {
|
|||
Self::enum_variant(
|
||||
state,
|
||||
MatchPatEnumVariant {
|
||||
match_span: state.match_span,
|
||||
variant_path,
|
||||
enum_path,
|
||||
variant_name,
|
||||
|
@ -626,6 +640,44 @@ impl Fold for RewriteAsCheckMatch {
|
|||
Pat::Ident(self.fold_pat_ident(pat_ident))
|
||||
}
|
||||
},
|
||||
Pat::Path(PatPath {
|
||||
attrs: _,
|
||||
qself,
|
||||
path,
|
||||
}) => match parse_enum_path(TypePath { qself, path }) {
|
||||
Ok(EnumPath {
|
||||
variant_path: _,
|
||||
enum_path,
|
||||
variant_name,
|
||||
}) => parse_quote_spanned! {self.span=>
|
||||
__MatchTy::<#enum_path>::#variant_name {}
|
||||
},
|
||||
Err(type_path) => parse_quote_spanned! {self.span=>
|
||||
__MatchTy::<#type_path> {}
|
||||
},
|
||||
},
|
||||
Pat::Struct(PatStruct {
|
||||
attrs: _,
|
||||
qself,
|
||||
path,
|
||||
brace_token,
|
||||
fields,
|
||||
rest,
|
||||
}) => {
|
||||
let type_path = TypePath { qself, path };
|
||||
let path = parse_quote_spanned! {self.span=>
|
||||
__MatchTy::<#type_path>
|
||||
};
|
||||
let fields = fields.do_fold(self);
|
||||
Pat::Struct(PatStruct {
|
||||
attrs: vec![],
|
||||
qself: None,
|
||||
path,
|
||||
brace_token,
|
||||
fields,
|
||||
rest,
|
||||
})
|
||||
}
|
||||
Pat::TupleStruct(PatTupleStruct {
|
||||
attrs,
|
||||
qself,
|
||||
|
@ -690,6 +742,7 @@ impl Fold for RewriteAsCheckMatch {
|
|||
}
|
||||
|
||||
struct HdlMatchParseState<'a> {
|
||||
match_span: Span,
|
||||
errors: &'a mut Errors,
|
||||
}
|
||||
|
||||
|
@ -710,13 +763,14 @@ impl Visitor<'_> {
|
|||
} = expr_match;
|
||||
self.require_normal_module(match_token);
|
||||
let mut state = HdlMatchParseState {
|
||||
match_span: span,
|
||||
errors: &mut self.errors,
|
||||
};
|
||||
let arms = Vec::from_iter(
|
||||
arms.into_iter()
|
||||
.filter_map(|arm| MatchArm::parse(&mut state, arm).ok()),
|
||||
);
|
||||
let expr = quote::quote_spanned! {span=>
|
||||
let expr = quote_spanned! {span=>
|
||||
{
|
||||
type __MatchTy<T> = <T as ::fayalite::ty::Type>::MatchVariant;
|
||||
let __match_expr = ::fayalite::expr::ToExpr::to_expr(&(#expr));
|
||||
|
@ -735,7 +789,6 @@ impl Visitor<'_> {
|
|||
}
|
||||
}
|
||||
};
|
||||
println!("{}", expr);
|
||||
syn::parse2(expr).unwrap()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue