Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4fa9c88

Browse files
authored
Merge pull request #679 from nazar-pc/macro-cleanups
Macro cleanups
2 parents 6bc846c + 52f98fe commit 4fa9c88

5 files changed

Lines changed: 192 additions & 233 deletions

File tree

crates/execution/ab-riscv-macros/src/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
mod enum_definition;
22
mod enum_impl;
33
mod execution_impl;
4+
mod shared_impl;
45
mod state;
56

67
use crate::build::enum_definition::{

crates/execution/ab-riscv-macros/src/build/enum_definition.rs

Lines changed: 23 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -299,39 +299,10 @@ pub(super) fn process_enum_definition(
299299
item_enum.attrs.push(parse_quote! { #[repr(u16)] });
300300
}
301301

302-
let dependencies = match attribute.meta {
303-
Meta::Path(_) => {
304-
process_enum_definition_with_variants(&mut item_enum, state)?;
305-
Vec::new()
306-
}
307-
Meta::List(meta_list) => {
308-
let instruction_definition = parse2::<InstructionDefinition>(meta_list.tokens)
309-
.context("Failed to parse `#[instruction(...)]` attribute")?;
310-
311-
if instruction_definition.items.iter().any(|item| match item {
312-
InstructionDefinitionItem::Reorder(_) | InstructionDefinitionItem::Ignore(_) => {
313-
false
314-
}
315-
InstructionDefinitionItem::Inherit(enums) => enums
316-
.iter()
317-
.any(|enum_name| state.get_known_enum_definition(enum_name).is_none()),
318-
}) {
319-
state.add_pending_enum_definition(PendingEnumDefinition {
320-
instruction_definition,
321-
item_enum,
322-
});
323-
return Ok(());
324-
}
325-
326-
let Some(result) =
327-
process_enum_definition_inherited(instruction_definition, item_enum, state)?
328-
else {
329-
return Ok(());
330-
};
331-
let dependencies;
332-
(item_enum, dependencies) = result;
333-
dependencies
334-
}
302+
let instruction_definition = match attribute.meta {
303+
Meta::Path(_) => InstructionDefinition::default(),
304+
Meta::List(meta_list) => parse2::<InstructionDefinition>(meta_list.tokens)
305+
.context("Failed to parse `#[instruction(...)]` attribute")?,
335306
Meta::NameValue(meta_name_value) => {
336307
return Err(anyhow::anyhow!(
337308
"Unexpected `#[instruction = {}]` attribute",
@@ -340,15 +311,26 @@ pub(super) fn process_enum_definition(
340311
}
341312
};
342313

343-
output_processed_enum_definition(item_enum, dependencies, out_dir, state)
344-
}
314+
if instruction_definition.items.iter().any(|item| match item {
315+
InstructionDefinitionItem::Reorder(_) | InstructionDefinitionItem::Ignore(_) => false,
316+
InstructionDefinitionItem::Inherit(enums) => enums
317+
.iter()
318+
.any(|enum_name| state.get_known_enum_definition(enum_name).is_none()),
319+
}) {
320+
state.add_pending_enum_definition(PendingEnumDefinition {
321+
instruction_definition,
322+
item_enum,
323+
});
324+
return Ok(());
325+
}
345326

346-
fn process_enum_definition_with_variants(
347-
_item_enum: &mut ItemEnum,
348-
_state: &mut State,
349-
) -> anyhow::Result<()> {
350-
// No special processing needed, at least not yet
351-
Ok(())
327+
let Some(result) = process_enum_definition_inherited(instruction_definition, item_enum, state)?
328+
else {
329+
return Ok(());
330+
};
331+
let (item_enum, dependencies) = result;
332+
333+
output_processed_enum_definition(item_enum, dependencies, out_dir, state)
352334
}
353335

354336
fn process_enum_definition_inherited(

crates/execution/ab-riscv-macros/src/build/enum_impl.rs

Lines changed: 53 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod ignored_variants_remover;
55
use crate::build::enum_impl::add_missing_fields::add_missing_rs_fields;
66
use crate::build::enum_impl::forbidden_checker::block_contains_forbidden_syntax;
77
use crate::build::enum_impl::ignored_variants_remover::remove_ignored_variants;
8+
use crate::build::shared_impl::collect_all_dependencies;
89
use crate::build::state::{PendingEnumDisplayImpl, PendingEnumImpl, State};
910
use ab_riscv_macros_common::code_utils::{post_process_rust_code, pre_process_rust_code};
1011
use anyhow::Context;
@@ -295,55 +296,48 @@ pub(super) fn process_enum_decoding_impl(
295296
return Ok(());
296297
};
297298

299+
let all_dependencies =
300+
match collect_all_dependencies(state, enum_definition.dependencies.clone()) {
301+
Ok(all_dependencies) => all_dependencies,
302+
Err(dependency_enum_name) => {
303+
eprintln!("{enum_name} decoding is waiting on {dependency_enum_name} definition");
304+
state.add_pending_enum_impl(PendingEnumImpl { item_impl });
305+
return Ok(());
306+
}
307+
};
308+
298309
let mut all_try_decode_blocks = Vec::new();
299310
let mut all_dependency_alignment_blocks = Vec::new();
300311
let mut all_dependency_size_entries = Vec::new();
301312
let mut all_where_predicates = Vec::new();
302-
{
303-
let mut all_dependencies = HashSet::new();
304-
all_dependencies.insert(enum_name.clone());
305-
let mut new_dependencies = enum_definition.dependencies.clone();
306-
307-
while !new_dependencies.is_empty() {
308-
for dependency_enum_name in mem::take(&mut new_dependencies) {
309-
let Some(dependency_enum_definition) =
310-
state.get_known_enum_definition(&dependency_enum_name)
311-
else {
312-
state.add_pending_enum_impl(PendingEnumImpl { item_impl });
313-
return Ok(());
314-
};
315-
316-
if !all_dependencies.insert(dependency_enum_name.clone()) {
317-
continue;
318-
}
319313

320-
let Some(dependency_enum_impl) =
321-
state.get_known_original_enum_decoding_impl(&dependency_enum_name)
322-
else {
323-
state.add_pending_enum_impl(PendingEnumImpl { item_impl });
324-
return Ok(());
325-
};
326-
327-
let dependency_blocks =
328-
extract_instruction_blocks_from_impl(&dependency_enum_impl.item_impl.items)
329-
.expect("Dependencies are all valid; qed");
330-
331-
all_try_decode_blocks.push(dependency_blocks.try_decode);
332-
all_dependency_alignment_blocks.push(dependency_blocks.alignment);
333-
334-
let variant_idents = dependency_enum_definition
335-
.instructions
336-
.iter()
337-
.map(|v| &v.ident)
338-
.collect::<Vec<_>>();
339-
all_dependency_size_entries.push((variant_idents, dependency_blocks.size));
340-
341-
if let Some(where_clause) = &dependency_enum_impl.item_impl.generics.where_clause {
342-
all_where_predicates.extend(where_clause.predicates.iter().cloned());
343-
}
314+
for (dependency_enum_name, dependency_enum_definition) in all_dependencies {
315+
let Some(dependency_enum_impl) =
316+
state.get_known_original_enum_decoding_impl(&dependency_enum_name)
317+
else {
318+
eprintln!(
319+
"{enum_name} decoding is waiting on {dependency_enum_name} decoding implementation"
320+
);
321+
state.add_pending_enum_impl(PendingEnumImpl { item_impl });
322+
return Ok(());
323+
};
344324

345-
new_dependencies.extend(dependency_enum_definition.dependencies.iter().cloned());
346-
}
325+
let dependency_blocks =
326+
extract_instruction_blocks_from_impl(&dependency_enum_impl.item_impl.items)
327+
.expect("Dependencies are all valid; qed");
328+
329+
all_try_decode_blocks.push(dependency_blocks.try_decode);
330+
all_dependency_alignment_blocks.push(dependency_blocks.alignment);
331+
332+
let variant_idents = dependency_enum_definition
333+
.instructions
334+
.iter()
335+
.map(|v| &v.ident)
336+
.collect::<Vec<_>>();
337+
all_dependency_size_entries.push((variant_idents, dependency_blocks.size));
338+
339+
if let Some(where_clause) = &dependency_enum_impl.item_impl.generics.where_clause {
340+
all_where_predicates.extend(where_clause.predicates.iter().cloned());
347341
}
348342
}
349343

@@ -496,27 +490,24 @@ pub(super) fn process_enum_display_impl(
496490
return Ok(());
497491
};
498492

493+
let all_dependencies =
494+
match collect_all_dependencies(state, enum_definition.dependencies.clone()) {
495+
Ok(all_dependencies) => all_dependencies,
496+
Err(dependency_enum_name) => {
497+
eprintln!("{enum_name} display is waiting on {dependency_enum_name} definition");
498+
state.add_pending_enum_display_impl(PendingEnumDisplayImpl { item_impl });
499+
return Ok(());
500+
}
501+
};
502+
499503
let mut variants_from_dependencies = HashMap::new();
500-
{
501-
let mut new_dependencies = enum_definition.dependencies.clone();
502-
503-
while !new_dependencies.is_empty() {
504-
for dependency_enum_name in mem::take(&mut new_dependencies) {
505-
let Some(dependency_enum_definition) =
506-
state.get_known_enum_definition(&dependency_enum_name)
507-
else {
508-
state.add_pending_enum_display_impl(PendingEnumDisplayImpl { item_impl });
509-
return Ok(());
510-
};
511-
512-
let dependency_enum_name = Rc::new(dependency_enum_name);
513-
for instruction in &dependency_enum_definition.instructions {
514-
variants_from_dependencies
515-
.insert(Rc::clone(instruction), Rc::clone(&dependency_enum_name));
516-
}
517504

518-
new_dependencies.extend(dependency_enum_definition.dependencies.iter().cloned());
519-
}
505+
for (dependency_enum_name, dependency_enum_definition) in all_dependencies {
506+
let dependency_enum_name = Rc::new(dependency_enum_name);
507+
508+
for instruction in &dependency_enum_definition.instructions {
509+
variants_from_dependencies
510+
.insert(Rc::clone(instruction), Rc::clone(&dependency_enum_name));
520511
}
521512
}
522513

0 commit comments

Comments
 (0)