diff --git a/src/generator.rs b/src/generator.rs index 20b0507..b5eb016 100644 --- a/src/generator.rs +++ b/src/generator.rs @@ -208,30 +208,48 @@ impl CodeGen for Block { let addr = util::parse_to_literal(&format!("0x{:x}", self.addr))?; let desc = self.desc.unwrap_or("".to_string()); - let accessor_methods = { - let mut out = TokenStream::new(); - for e in self.elements.iter() { + let accessors_methods = self.elements.iter().map(|e| { let child_name = e.get_name(); let snake_case_name = util::parse_to_ident(&child_name.to_snake_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::#child_upper_camel_name { - #snake_case_name::#child_upper_camel_name::new(self.mem_ptr) - } - }); - } - - out - }; + match e { + ModuleBlockElements::Block(_) => { + let child_upper_camel_name = util::parse_to_ident(&child_name.to_upper_camel_case())?; + Ok(quote! { + pub fn #snake_case_name(&self) -> #snake_case_name::#child_upper_camel_name { + #snake_case_name::#child_upper_camel_name::new(self.mem_ptr) + } + }) + }, + ModuleBlockElements::Register(register) => { + let child_upper_camel_name = util::parse_to_ident(&format!("Reg{}", child_name.to_upper_camel_case()))?; + match ®ister.multiple { + None => { + Ok(quote! { + pub fn #snake_case_name(&self) -> #snake_case_name::#child_upper_camel_name { + #snake_case_name::#child_upper_camel_name::new(self.mem_ptr) + } + }) + }, + Some(multiple_param) => { + let num_multiple = multiple_param.multiple; + let elements = (0..num_multiple).map(|i| { + let offset = multiple_param.offset * i; + quote! { + #snake_case_name::#child_upper_camel_name::new(unsafe { self.mem_ptr.add(#offset) } ) + } + }); + Ok(quote! { + pub fn #snake_case_name(&self) -> [#snake_case_name::#child_upper_camel_name; #num_multiple] { + [ #(#elements),* ] + } + }) + }, + } + }, + ModuleBlockElements::Memory(_memory) => todo!(), + ModuleBlockElements::Fifo(_fifo) => todo!(), + } + }).collect::, CodeGenError>>()?; let parent_struct = if parent_name == util::parse_to_ident("RegisterInterface").unwrap() { quote! {#parent_name} @@ -275,7 +293,7 @@ impl CodeGen for Block { } } - #accessor_methods + #(#accessors_methods)* } }; let (out_path, next_parent_path) = mod_file_path(parent_path, &snake_case_name);