mirror of
https://gitlab.cern.ch/wotsubo/endcap-sl-software-ri-generator.git
synced 2025-02-23 00:57:08 +09:00
fix: add parent_name to CodeGen to properly refer to parent name, and add Reg
to register children
One more: if parent is RegisterInterface, lifetime param is omitted
This commit is contained in:
parent
5f7db47fcf
commit
9e7a83242b
1 changed files with 45 additions and 13 deletions
|
@ -111,20 +111,28 @@ mod util {
|
|||
}
|
||||
|
||||
pub trait CodeGen {
|
||||
fn generate_register_interface(self) -> Result<proc_macro2::TokenStream, CodeGenError>;
|
||||
/// `parent_name` in UpperCamelCase.
|
||||
fn generate_register_interface(
|
||||
self,
|
||||
parent_name: proc_macro2::Ident,
|
||||
) -> Result<proc_macro2::TokenStream, CodeGenError>;
|
||||
}
|
||||
|
||||
impl CodeGen for Module {
|
||||
fn generate_register_interface(self) -> Result<proc_macro2::TokenStream, CodeGenError> {
|
||||
fn generate_register_interface(
|
||||
self,
|
||||
_: proc_macro2::Ident,
|
||||
) -> Result<proc_macro2::TokenStream, CodeGenError> {
|
||||
let mut out = TokenStream::new();
|
||||
if !self.elements_bitstring.is_empty() {
|
||||
todo!("bitstring generation is not yet implemented")
|
||||
}
|
||||
|
||||
let ident_register_interface = util::parse_to_ident("RegisterInterface").unwrap();
|
||||
let child_mods = self
|
||||
.elements_other
|
||||
.into_iter()
|
||||
.map(|e| e.generate_register_interface())
|
||||
.map(|e| e.generate_register_interface(ident_register_interface.clone()))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
for child in child_mods {
|
||||
out.extend(child);
|
||||
|
@ -135,10 +143,13 @@ impl CodeGen for Module {
|
|||
}
|
||||
|
||||
impl CodeGen for ModuleBlockElements {
|
||||
fn generate_register_interface(self) -> Result<proc_macro2::TokenStream, CodeGenError> {
|
||||
fn generate_register_interface(
|
||||
self,
|
||||
parent: proc_macro2::Ident,
|
||||
) -> Result<proc_macro2::TokenStream, CodeGenError> {
|
||||
match self {
|
||||
ModuleBlockElements::Block(block) => block.generate_register_interface(),
|
||||
ModuleBlockElements::Register(register) => register.generate_register_interface(),
|
||||
ModuleBlockElements::Block(block) => block.generate_register_interface(parent),
|
||||
ModuleBlockElements::Register(register) => register.generate_register_interface(parent),
|
||||
ModuleBlockElements::Memory(_memory) => todo!(),
|
||||
ModuleBlockElements::Fifo(_fifo) => todo!(),
|
||||
}
|
||||
|
@ -146,7 +157,10 @@ impl CodeGen for ModuleBlockElements {
|
|||
}
|
||||
|
||||
impl CodeGen for Block {
|
||||
fn generate_register_interface(self) -> Result<proc_macro2::TokenStream, CodeGenError> {
|
||||
fn generate_register_interface(
|
||||
self,
|
||||
parent: proc_macro2::Ident,
|
||||
) -> Result<proc_macro2::TokenStream, CodeGenError> {
|
||||
let snake_case_name = util::parse_to_ident(&self.name.to_snake_case())?;
|
||||
let upper_camel_name = util::parse_to_ident(&self.name.to_upper_camel_case())?;
|
||||
let addr = util::parse_to_literal(&format!("0x{:x}", self.addr))?;
|
||||
|
@ -154,13 +168,22 @@ impl CodeGen for Block {
|
|||
|
||||
let accessor_methods = {
|
||||
let mut out = TokenStream::new();
|
||||
for child_name in self.elements.iter().map(|e| e.get_name()) {
|
||||
for e in self.elements.iter() {
|
||||
let child_name = e.get_name();
|
||||
let snake_case_name = util::parse_to_ident(&child_name.to_snake_case())?;
|
||||
let upper_camel_name = util::parse_to_ident(&child_name.to_upper_camel_case())?;
|
||||
let child_type_name = match e {
|
||||
ModuleBlockElements::Block(_) => &child_name.to_upper_camel_case(),
|
||||
ModuleBlockElements::Register(_) => {
|
||||
&format!("Reg{}", child_name.to_upper_camel_case())
|
||||
}
|
||||
ModuleBlockElements::Memory(_) => todo!(),
|
||||
ModuleBlockElements::Fifo(_) => todo!(),
|
||||
};
|
||||
let child_upper_camel_name = util::parse_to_ident(child_type_name)?;
|
||||
|
||||
out.extend(quote! {
|
||||
pub fn #snake_case_name(&self) -> #snake_case_name::#upper_camel_name {
|
||||
#snake_case_name::#upper_camel_name::new(self.mem_ptr)
|
||||
pub fn #snake_case_name(&self) -> #snake_case_name::#child_upper_camel_name {
|
||||
#snake_case_name::#child_upper_camel_name::new(self.mem_ptr)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -171,9 +194,15 @@ impl CodeGen for Block {
|
|||
let code_children = self
|
||||
.elements
|
||||
.into_iter()
|
||||
.map(|e| e.generate_register_interface())
|
||||
.map(|e| e.generate_register_interface(upper_camel_name.clone()))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
let parent_struct = if parent == util::parse_to_ident("RegisterInterface").unwrap() {
|
||||
quote! {#parent}
|
||||
} else {
|
||||
quote! {#parent<'a>}
|
||||
};
|
||||
|
||||
Ok(quote! {
|
||||
pub mod #snake_case_name {
|
||||
#[doc = #desc]
|
||||
|
@ -211,7 +240,10 @@ mod codegen_registerspec_impl;
|
|||
|
||||
/// Internally calls functions in [`codegen_register`]
|
||||
impl CodeGen for Register {
|
||||
fn generate_register_interface(self) -> Result<proc_macro2::TokenStream, CodeGenError> {
|
||||
fn generate_register_interface(
|
||||
self,
|
||||
parent: proc_macro2::Ident,
|
||||
) -> Result<proc_macro2::TokenStream, CodeGenError> {
|
||||
let snake_case_name = util::parse_to_ident(&self.name.to_snake_case())?;
|
||||
let upper_camel_name = util::parse_to_ident(&self.name.to_upper_camel_case())?;
|
||||
let reg_name = util::parse_to_ident(&format!("Reg{upper_camel_name}"))?;
|
||||
|
|
Loading…
Reference in a new issue