mirror of
https://gitlab.cern.ch/wotsubo/endcap-sl-software-ri-generator.git
synced 2025-02-23 17:17: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 {
|
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 {
|
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();
|
let mut out = TokenStream::new();
|
||||||
if !self.elements_bitstring.is_empty() {
|
if !self.elements_bitstring.is_empty() {
|
||||||
todo!("bitstring generation is not yet implemented")
|
todo!("bitstring generation is not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let ident_register_interface = util::parse_to_ident("RegisterInterface").unwrap();
|
||||||
let child_mods = self
|
let child_mods = self
|
||||||
.elements_other
|
.elements_other
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|e| e.generate_register_interface())
|
.map(|e| e.generate_register_interface(ident_register_interface.clone()))
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
for child in child_mods {
|
for child in child_mods {
|
||||||
out.extend(child);
|
out.extend(child);
|
||||||
|
@ -135,10 +143,13 @@ impl CodeGen for Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CodeGen for ModuleBlockElements {
|
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 {
|
match self {
|
||||||
ModuleBlockElements::Block(block) => block.generate_register_interface(),
|
ModuleBlockElements::Block(block) => block.generate_register_interface(parent),
|
||||||
ModuleBlockElements::Register(register) => register.generate_register_interface(),
|
ModuleBlockElements::Register(register) => register.generate_register_interface(parent),
|
||||||
ModuleBlockElements::Memory(_memory) => todo!(),
|
ModuleBlockElements::Memory(_memory) => todo!(),
|
||||||
ModuleBlockElements::Fifo(_fifo) => todo!(),
|
ModuleBlockElements::Fifo(_fifo) => todo!(),
|
||||||
}
|
}
|
||||||
|
@ -146,7 +157,10 @@ impl CodeGen for ModuleBlockElements {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CodeGen for Block {
|
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 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 upper_camel_name = util::parse_to_ident(&self.name.to_upper_camel_case())?;
|
||||||
let addr = util::parse_to_literal(&format!("0x{:x}", self.addr))?;
|
let addr = util::parse_to_literal(&format!("0x{:x}", self.addr))?;
|
||||||
|
@ -154,13 +168,22 @@ impl CodeGen for Block {
|
||||||
|
|
||||||
let accessor_methods = {
|
let accessor_methods = {
|
||||||
let mut out = TokenStream::new();
|
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 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! {
|
out.extend(quote! {
|
||||||
pub fn #snake_case_name(&self) -> #snake_case_name::#upper_camel_name {
|
pub fn #snake_case_name(&self) -> #snake_case_name::#child_upper_camel_name {
|
||||||
#snake_case_name::#upper_camel_name::new(self.mem_ptr)
|
#snake_case_name::#child_upper_camel_name::new(self.mem_ptr)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -171,9 +194,15 @@ impl CodeGen for Block {
|
||||||
let code_children = self
|
let code_children = self
|
||||||
.elements
|
.elements
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|e| e.generate_register_interface())
|
.map(|e| e.generate_register_interface(upper_camel_name.clone()))
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
|
let parent_struct = if parent == util::parse_to_ident("RegisterInterface").unwrap() {
|
||||||
|
quote! {#parent}
|
||||||
|
} else {
|
||||||
|
quote! {#parent<'a>}
|
||||||
|
};
|
||||||
|
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
pub mod #snake_case_name {
|
pub mod #snake_case_name {
|
||||||
#[doc = #desc]
|
#[doc = #desc]
|
||||||
|
@ -211,7 +240,10 @@ mod codegen_registerspec_impl;
|
||||||
|
|
||||||
/// Internally calls functions in [`codegen_register`]
|
/// Internally calls functions in [`codegen_register`]
|
||||||
impl CodeGen for 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 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 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}"))?;
|
let reg_name = util::parse_to_ident(&format!("Reg{upper_camel_name}"))?;
|
||||||
|
|
Loading…
Reference in a new issue