add support for incomplete_wire -- a wire that you can supply the type of later
This commit is contained in:
parent
ff94dda922
commit
df55a514e4
5 changed files with 231 additions and 8 deletions
|
@ -65,6 +65,7 @@ mod kw {
|
|||
custom_keyword!(hdl);
|
||||
custom_keyword!(hdl_module);
|
||||
custom_keyword!(input);
|
||||
custom_keyword!(incomplete_wire);
|
||||
custom_keyword!(instance);
|
||||
custom_keyword!(m);
|
||||
custom_keyword!(memory);
|
||||
|
|
|
@ -34,6 +34,7 @@ options! {
|
|||
Instance(instance),
|
||||
RegBuilder(reg_builder),
|
||||
Wire(wire),
|
||||
IncompleteWire(incomplete_wire),
|
||||
Memory(memory),
|
||||
MemoryArray(memory_array),
|
||||
MemoryWithInit(memory_with_init),
|
||||
|
@ -533,6 +534,41 @@ impl HdlLetKindToTokens for HdlLetKindWire {
|
|||
}
|
||||
}
|
||||
|
||||
options! {
|
||||
pub(crate) enum LetFnKindIncomplete {
|
||||
IncompleteWire(incomplete_wire),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct HdlLetKindIncomplete {
|
||||
pub(crate) kind: LetFnKindIncomplete,
|
||||
pub(crate) paren: Paren,
|
||||
}
|
||||
|
||||
impl ParseTypes<Self> for HdlLetKindIncomplete {
|
||||
fn parse_types(input: &mut Self, _parser: &mut TypesParser<'_>) -> Result<Self, ParseFailed> {
|
||||
Ok(input.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl_fold! {
|
||||
struct HdlLetKindIncomplete<> {
|
||||
kind: LetFnKindIncomplete,
|
||||
paren: Paren,
|
||||
}
|
||||
}
|
||||
|
||||
impl HdlLetKindToTokens for HdlLetKindIncomplete {
|
||||
fn ty_to_tokens(&self, _tokens: &mut TokenStream) {}
|
||||
|
||||
fn expr_to_tokens(&self, tokens: &mut TokenStream) {
|
||||
let Self { kind, paren } = self;
|
||||
kind.to_tokens(tokens);
|
||||
paren.surround(tokens, |_| {});
|
||||
}
|
||||
}
|
||||
|
||||
options! {
|
||||
pub(crate) enum MemoryFnName {
|
||||
Memory(memory),
|
||||
|
@ -697,6 +733,7 @@ impl HdlLetKindMemory {
|
|||
#[derive(Clone, Debug)]
|
||||
pub(crate) enum HdlLetKind<IOType = ParsedType> {
|
||||
IO(HdlLetKindIO<ModuleIOKind, IOType>),
|
||||
Incomplete(HdlLetKindIncomplete),
|
||||
Instance(HdlLetKindInstance),
|
||||
RegBuilder(HdlLetKindRegBuilder),
|
||||
Wire(HdlLetKindWire),
|
||||
|
@ -706,6 +743,7 @@ pub(crate) enum HdlLetKind<IOType = ParsedType> {
|
|||
impl_fold! {
|
||||
enum HdlLetKind<IOType,> {
|
||||
IO(HdlLetKindIO<ModuleIOKind, IOType>),
|
||||
Incomplete(HdlLetKindIncomplete),
|
||||
Instance(HdlLetKindInstance),
|
||||
RegBuilder(HdlLetKindRegBuilder),
|
||||
Wire(HdlLetKindWire),
|
||||
|
@ -720,6 +758,9 @@ impl<T: ParseTypes<I>, I> ParseTypes<HdlLetKind<I>> for HdlLetKind<T> {
|
|||
) -> Result<Self, ParseFailed> {
|
||||
match input {
|
||||
HdlLetKind::IO(input) => ParseTypes::parse_types(input, parser).map(HdlLetKind::IO),
|
||||
HdlLetKind::Incomplete(input) => {
|
||||
ParseTypes::parse_types(input, parser).map(HdlLetKind::Incomplete)
|
||||
}
|
||||
HdlLetKind::Instance(input) => {
|
||||
ParseTypes::parse_types(input, parser).map(HdlLetKind::Instance)
|
||||
}
|
||||
|
@ -871,6 +912,20 @@ impl HdlLetKindParse for HdlLetKind<Type> {
|
|||
ty_expr: paren_contents.call(parse_optional_fn_arg)?,
|
||||
}))
|
||||
}
|
||||
LetFnKind::IncompleteWire(incomplete_wire) => {
|
||||
if let Some(parsed_ty) = parsed_ty {
|
||||
return Err(Error::new_spanned(
|
||||
parsed_ty.1,
|
||||
"type annotation not allowed for incomplete_wire",
|
||||
));
|
||||
}
|
||||
check_empty_m_dot(m_dot, kind)?;
|
||||
let _paren_contents;
|
||||
Ok(Self::Incomplete(HdlLetKindIncomplete {
|
||||
kind: LetFnKindIncomplete::IncompleteWire(incomplete_wire),
|
||||
paren: parenthesized!(_paren_contents in input),
|
||||
}))
|
||||
}
|
||||
LetFnKind::Memory(fn_name) => HdlLetKindMemory::rest_of_parse(
|
||||
input,
|
||||
parsed_ty,
|
||||
|
@ -903,6 +958,7 @@ impl HdlLetKindToTokens for HdlLetKind {
|
|||
fn ty_to_tokens(&self, tokens: &mut TokenStream) {
|
||||
match self {
|
||||
HdlLetKind::IO(v) => v.ty_to_tokens(tokens),
|
||||
HdlLetKind::Incomplete(v) => v.ty_to_tokens(tokens),
|
||||
HdlLetKind::Instance(v) => v.ty_to_tokens(tokens),
|
||||
HdlLetKind::RegBuilder(v) => v.ty_to_tokens(tokens),
|
||||
HdlLetKind::Wire(v) => v.ty_to_tokens(tokens),
|
||||
|
@ -913,6 +969,7 @@ impl HdlLetKindToTokens for HdlLetKind {
|
|||
fn expr_to_tokens(&self, tokens: &mut TokenStream) {
|
||||
match self {
|
||||
HdlLetKind::IO(v) => v.expr_to_tokens(tokens),
|
||||
HdlLetKind::Incomplete(v) => v.expr_to_tokens(tokens),
|
||||
HdlLetKind::Instance(v) => v.expr_to_tokens(tokens),
|
||||
HdlLetKind::RegBuilder(v) => v.expr_to_tokens(tokens),
|
||||
HdlLetKind::Wire(v) => v.expr_to_tokens(tokens),
|
||||
|
@ -1369,6 +1426,31 @@ impl Visitor<'_> {
|
|||
semi_token: hdl_let.semi_token,
|
||||
}
|
||||
}
|
||||
fn process_hdl_let_incomplete(&mut self, hdl_let: HdlLet<HdlLetKindIncomplete>) -> Local {
|
||||
let name = &hdl_let.name;
|
||||
let kind = hdl_let.kind.kind;
|
||||
self.require_normal_module_or_fn(kind);
|
||||
let mut expr = kind.to_token_stream();
|
||||
hdl_let.kind.paren.surround(&mut expr, |expr| {
|
||||
ImplicitName {
|
||||
name,
|
||||
span: name.span(),
|
||||
}
|
||||
.to_tokens(expr);
|
||||
});
|
||||
let mut_token = &hdl_let.mut_token;
|
||||
Local {
|
||||
attrs: hdl_let.attrs.clone(),
|
||||
let_token: hdl_let.let_token,
|
||||
pat: parse_quote! { #mut_token #name },
|
||||
init: Some(LocalInit {
|
||||
eq_token: hdl_let.eq_token,
|
||||
expr: parse_quote! { #expr },
|
||||
diverge: None,
|
||||
}),
|
||||
semi_token: hdl_let.semi_token,
|
||||
}
|
||||
}
|
||||
fn process_hdl_let_memory(&mut self, hdl_let: HdlLet<HdlLetKindMemory>) -> Local {
|
||||
let name = &hdl_let.name;
|
||||
let memory_fn = hdl_let.kind.memory_fn;
|
||||
|
@ -1438,6 +1520,7 @@ impl Visitor<'_> {
|
|||
}
|
||||
the_match! {
|
||||
IO => process_hdl_let_io,
|
||||
Incomplete => process_hdl_let_incomplete,
|
||||
Instance => process_hdl_let_instance,
|
||||
RegBuilder => process_hdl_let_reg_builder,
|
||||
Wire => process_hdl_let_wire,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue