Skip to content

Commit 4e6b948

Browse files
bors[bot]burrbull
andauthored
Merge #643
643: register & cluster aliases instead of clone when derive r=therealprof a=burrbull + construct pathes manually instead of parse Co-authored-by: Andrey Zgarbul <[email protected]>
2 parents 8c67a67 + 197623a commit 4e6b948

File tree

4 files changed

+270
-135
lines changed

4 files changed

+270
-135
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
- Create aliases for derived registers & clusters
1011
- Move cluster struct inside mod
1112
- Support non-sequential field arrays
1213
- Use inlined variables in `format!` (Rust 1.58)

src/generate/peripheral.rs

Lines changed: 67 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ use crate::svd::{
88
use log::{debug, trace, warn};
99
use proc_macro2::{Ident, Punct, Spacing, Span, TokenStream};
1010
use quote::{quote, ToTokens};
11-
use syn::{parse_str, Token};
11+
use syn::{punctuated::Punctuated, Token};
1212

13-
use crate::util::{self, unsuffixed, Config, FullName, ToSanitizedCase, BITS_PER_BYTE};
13+
use crate::util::{
14+
self, array_proxy_type, name_to_ty, name_to_wrapped_ty, new_syn_u32, path_segment, type_path,
15+
unsuffixed, Config, FullName, ToSanitizedCase, BITS_PER_BYTE,
16+
};
1417
use anyhow::{anyhow, bail, Context, Result};
1518

1619
use crate::generate::register;
@@ -686,7 +689,7 @@ fn expand_cluster(cluster: &Cluster, config: &Config) -> Result<Vec<RegisterBloc
686689
let span = Span::call_site();
687690
let mut accessors = TokenStream::new();
688691
let nb_name = util::replace_suffix(&info.name, "");
689-
let ty = name_to_ty(&nb_name)?;
692+
let ty = name_to_ty(&nb_name);
690693
let nb_name_cs = nb_name.to_snake_case_ident(span);
691694
for (i, idx) in array_info.indexes().enumerate() {
692695
let idx_name =
@@ -717,14 +720,13 @@ fn expand_cluster(cluster: &Cluster, config: &Config) -> Result<Vec<RegisterBloc
717720
} else if sequential_indexes_from0 && config.const_generic {
718721
// Include a ZST ArrayProxy giving indexed access to the
719722
// elements.
720-
cluster_expanded.push(array_proxy(info, array_info)?);
723+
cluster_expanded.push(array_proxy(info, array_info));
721724
} else {
722725
let ty_name = util::replace_suffix(&info.name, "");
723-
let ty = name_to_ty(&ty_name)?;
726+
let ty = syn::Type::Path(name_to_ty(&ty_name));
724727

725728
for (field_num, idx) in array_info.indexes().enumerate() {
726729
let nb_name = util::replace_suffix(&info.name, &idx);
727-
728730
let syn_field =
729731
new_syn_field(nb_name.to_snake_case_ident(Span::call_site()), ty.clone());
730732

@@ -790,7 +792,7 @@ fn expand_register(register: &Register, config: &Config) -> Result<Vec<RegisterB
790792
let span = Span::call_site();
791793
let mut accessors = TokenStream::new();
792794
let nb_name = util::replace_suffix(&info.fullname(config.ignore_groups), "");
793-
let ty = name_to_wrapped_ty(&nb_name)?;
795+
let ty = name_to_wrapped_ty(&nb_name);
794796
let nb_name_cs = nb_name.to_snake_case_ident(span);
795797
let info_name = info.fullname(config.ignore_groups);
796798
for (i, idx) in array_info.indexes().enumerate() {
@@ -822,11 +824,10 @@ fn expand_register(register: &Register, config: &Config) -> Result<Vec<RegisterB
822824
} else {
823825
let info_name = info.fullname(config.ignore_groups);
824826
let ty_name = util::replace_suffix(&info_name, "");
825-
let ty = name_to_wrapped_ty(&ty_name)?;
827+
let ty = name_to_wrapped_ty(&ty_name);
826828

827829
for (field_num, idx) in array_info.indexes().enumerate() {
828830
let nb_name = util::replace_suffix(&info_name, &idx);
829-
830831
let syn_field =
831832
new_syn_field(nb_name.to_snake_case_ident(Span::call_site()), ty.clone());
832833

@@ -863,8 +864,7 @@ fn render_ercs(
863864
if let Some(dpath) = dpath {
864865
cpath = derive_cluster(c, &dpath, path, index)?;
865866
}
866-
let cpath = cpath.unwrap_or_else(|| path.new_cluster(&c.name));
867-
mod_items.extend(cluster_block(c, &cpath, index, config)?);
867+
mod_items.extend(cluster_block(c, path, cpath, index, config)?);
868868
}
869869

870870
// Generate definition for each of the registers.
@@ -876,10 +876,9 @@ fn render_ercs(
876876
rpath = derive_register(reg, &dpath, path, index)?;
877877
}
878878
let reg_name = &reg.name;
879-
let rpath = rpath.unwrap_or_else(|| path.new_register(reg_name));
880879

881880
let rendered_reg =
882-
register::render(reg, &rpath, index, config).with_context(|| {
881+
register::render(reg, path, rpath, index, config).with_context(|| {
883882
let descrip = reg.description.as_deref().unwrap_or("No description");
884883
format!(
885884
"Error rendering register\nName: {reg_name}\nDescription: {descrip}"
@@ -896,23 +895,57 @@ fn render_ercs(
896895
fn cluster_block(
897896
c: &mut Cluster,
898897
path: &BlockPath,
898+
dpath: Option<BlockPath>,
899899
index: &Index,
900900
config: &Config,
901901
) -> Result<TokenStream> {
902-
let mod_items = render_ercs(&mut c.children, path, index, config)?;
903-
904-
// Generate the register block.
902+
let description =
903+
util::escape_brackets(&util::respace(c.description.as_ref().unwrap_or(&c.name)));
905904
let mod_name = util::replace_suffix(&c.name, "");
906905

907-
let reg_block = register_or_cluster_block(&c.children, Some(&mod_name), config)?;
908-
909906
// name_snake_case needs to take into account array type.
910-
let description =
911-
util::escape_brackets(&util::respace(c.description.as_ref().unwrap_or(&c.name)));
907+
let span = Span::call_site();
908+
let name_snake_case = mod_name.to_snake_case_ident(span);
909+
let name_constant_case = mod_name.to_constant_case_ident(span);
910+
911+
let struct_path = name_to_ty(&mod_name);
912912

913-
let name_snake_case = mod_name.to_snake_case_ident(Span::call_site());
913+
let mod_items = if let Some(dpath) = dpath {
914+
let dparent = util::parent(&dpath);
915+
let mut derived = if &dparent == path {
916+
let mut segments = Punctuated::new();
917+
segments.push(path_segment(Ident::new("super", span)));
918+
type_path(segments)
919+
} else {
920+
util::block_path_to_ty(&dparent, span)
921+
};
922+
let dname = util::replace_suffix(&index.clusters.get(&dpath).unwrap().name, "");
923+
derived
924+
.path
925+
.segments
926+
.push(path_segment(dname.to_snake_case_ident(span)));
927+
derived
928+
.path
929+
.segments
930+
.push(path_segment(dname.to_constant_case_ident(span)));
914931

915-
let struct_path = name_to_ty(&mod_name)?;
932+
quote! {
933+
#[doc = #description]
934+
pub use #derived as #name_constant_case;
935+
}
936+
} else {
937+
let cpath = path.new_cluster(&c.name);
938+
let mod_items = render_ercs(&mut c.children, &cpath, index, config)?;
939+
940+
// Generate the register block.
941+
let reg_block = register_or_cluster_block(&c.children, Some(&mod_name), config)?;
942+
943+
quote! {
944+
#reg_block
945+
946+
#mod_items
947+
}
948+
};
916949

917950
Ok(quote! {
918951
#[doc = #description]
@@ -921,8 +954,6 @@ fn cluster_block(
921954
///Cluster
922955
#[doc = #description]
923956
pub mod #name_snake_case {
924-
#reg_block
925-
926957
#mod_items
927958
}
928959
})
@@ -933,15 +964,13 @@ fn register_to_syn_field(register: &Register, ignore_group: bool) -> Result<syn:
933964
Ok(match register {
934965
Register::Single(info) => {
935966
let info_name = info.fullname(ignore_group);
936-
let ty = name_to_wrapped_ty(&info_name)
937-
.with_context(|| format!("Error converting register name {info_name}"))?;
967+
let ty = name_to_wrapped_ty(&info_name);
938968
new_syn_field(info_name.to_snake_case_ident(Span::call_site()), ty)
939969
}
940970
Register::Array(info, array_info) => {
941971
let info_name = info.fullname(ignore_group);
942972
let nb_name = util::replace_suffix(&info_name, "");
943-
let ty = name_to_wrapped_ty(&nb_name)
944-
.with_context(|| format!("Error converting register name {nb_name}"))?;
973+
let ty = name_to_wrapped_ty(&nb_name);
945974
let array_ty = new_syn_array(ty, array_info.dim);
946975

947976
new_syn_field(nb_name.to_snake_case_ident(Span::call_site()), array_ty)
@@ -950,42 +979,31 @@ fn register_to_syn_field(register: &Register, ignore_group: bool) -> Result<syn:
950979
}
951980

952981
/// Return an syn::Type for an ArrayProxy.
953-
fn array_proxy(
954-
info: &ClusterInfo,
955-
array_info: &DimElement,
956-
) -> Result<RegisterBlockField, syn::Error> {
982+
fn array_proxy(info: &ClusterInfo, array_info: &DimElement) -> RegisterBlockField {
957983
let ty_name = util::replace_suffix(&info.name, "");
958-
let tys = name_to_ty_str(&ty_name);
959-
960-
let ap_path = parse_str::<syn::TypePath>(&format!(
961-
"crate::ArrayProxy<{tys}, {}, {}>",
962-
array_info.dim,
963-
util::hex(array_info.dim_increment as u64).into_token_stream(),
964-
))?;
965-
966-
Ok(RegisterBlockField {
967-
syn_field: new_syn_field(
968-
ty_name.to_snake_case_ident(Span::call_site()),
969-
ap_path.into(),
970-
),
984+
let ty = name_to_ty(&ty_name);
985+
986+
let ap_path = array_proxy_type(ty, array_info);
987+
988+
RegisterBlockField {
989+
syn_field: new_syn_field(ty_name.to_snake_case_ident(Span::call_site()), ap_path),
971990
description: info.description.as_ref().unwrap_or(&info.name).into(),
972991
offset: info.address_offset,
973992
size: 0,
974993
accessors: None,
975-
})
994+
}
976995
}
977996

978997
/// Convert a parsed `Cluster` into its `Field` equivalent
979998
fn cluster_to_syn_field(cluster: &Cluster) -> Result<syn::Field, syn::Error> {
980999
Ok(match cluster {
9811000
Cluster::Single(info) => {
982-
let ty_name = util::replace_suffix(&info.name, "");
983-
let ty = name_to_ty(&ty_name)?;
1001+
let ty = syn::Type::Path(name_to_ty(&info.name));
9841002
new_syn_field(info.name.to_snake_case_ident(Span::call_site()), ty)
9851003
}
9861004
Cluster::Array(info, array_info) => {
9871005
let ty_name = util::replace_suffix(&info.name, "");
988-
let ty = name_to_ty(&ty_name)?;
1006+
let ty = syn::Type::Path(name_to_ty(&ty_name));
9891007
let array_ty = new_syn_array(ty, array_info.dim);
9901008

9911009
new_syn_field(ty_name.to_snake_case_ident(Span::call_site()), array_ty)
@@ -1015,39 +1033,3 @@ fn new_syn_array(ty: syn::Type, len: u32) -> syn::Type {
10151033
len: new_syn_u32(len, span),
10161034
})
10171035
}
1018-
1019-
fn new_syn_u32(len: u32, span: Span) -> syn::Expr {
1020-
syn::Expr::Lit(syn::ExprLit {
1021-
attrs: Vec::new(),
1022-
lit: syn::Lit::Int(syn::LitInt::new(&len.to_string(), span)),
1023-
})
1024-
}
1025-
1026-
fn name_to_ty_str(name: &str) -> String {
1027-
format!(
1028-
"{}::{}",
1029-
name.to_sanitized_snake_case(),
1030-
name.to_sanitized_constant_case()
1031-
)
1032-
}
1033-
1034-
fn name_to_ty(name: &str) -> Result<syn::Type, syn::Error> {
1035-
let ident = name_to_ty_str(name);
1036-
parse_str::<syn::TypePath>(&ident).map(syn::Type::Path)
1037-
}
1038-
1039-
fn name_to_wrapped_ty_str(name: &str) -> String {
1040-
format!(
1041-
"crate::Reg<{}::{}_SPEC>",
1042-
&name.to_sanitized_snake_case(),
1043-
&name.to_sanitized_constant_case(),
1044-
)
1045-
}
1046-
1047-
fn name_to_wrapped_ty(name: &str) -> Result<syn::Type> {
1048-
let ident = name_to_wrapped_ty_str(name);
1049-
parse_str::<syn::TypePath>(&ident)
1050-
.map(syn::Type::Path)
1051-
.map_err(anyhow::Error::from)
1052-
.with_context(|| format!("Determining syn::TypePath from ident \"{ident}\" failed"))
1053-
}

0 commit comments

Comments
 (0)