From 3f57108fdbba26dece97b757e192f5f65519f8b7 Mon Sep 17 00:00:00 2001 From: schilkp Date: Tue, 7 May 2024 14:54:36 +0200 Subject: [PATCH] rust-rewrite: Improved rs-structs comments. --- reginald_codegen/src/builtin/rs/mod.rs | 24 ++++++++------- .../src/builtin/rs/structs/layouts.rs | 30 +++++++++++++++---- .../src/builtin/rs/structs/mod.rs | 6 ++-- .../src/builtin/rs/structs/registers.rs | 6 ++-- 4 files changed, 44 insertions(+), 22 deletions(-) diff --git a/reginald_codegen/src/builtin/rs/mod.rs b/reginald_codegen/src/builtin/rs/mod.rs index 84af04f..943c4f3 100644 --- a/reginald_codegen/src/builtin/rs/mod.rs +++ b/reginald_codegen/src/builtin/rs/mod.rs @@ -5,7 +5,7 @@ use std::fmt::Write; use crate::{ error::Error, - regmap::{Docs, Layout, TypeBitwidth, TypeValue}, + regmap::{Docs, TypeBitwidth, TypeValue}, utils::{grab_byte, Endianess}, }; @@ -60,6 +60,19 @@ fn generate_doc_comment(out: &mut dyn Write, docs: &Docs, prefix: &str) -> Resul Ok(()) } +fn generate_extended_doc_comment(out: &mut dyn Write, docs: &Docs, prefix: &str, extra: &[&str]) -> Result<(), Error> { + let mut comment = String::new(); + generate_doc_comment(&mut comment, docs, prefix)?; + if !comment.is_empty() { + writeln!(&mut comment, "{prefix}///")?; + } + for line in extra { + writeln!(&mut comment, "{prefix}/// {line}")?; + } + write!(out, "{}", comment)?; + Ok(()) +} + fn rs_fitting_unsigned_type(width: TypeBitwidth) -> Result { match width { 1..=8 => Ok("u8".to_string()), @@ -80,15 +93,6 @@ fn rs_generate_header_comment(out: &mut dyn Write, title: &str) -> Result<(), Er Ok(()) } -fn rs_layout_overview_comment(layout: &Layout, prefix: &str) -> String { - layout - .overview_text(true) - .lines() - .map(|x| String::from(prefix) + x) - .collect::>() - .join("\n") -} - /// Convert a value to an array literal of given endianess fn array_literal(endian: Endianess, val: TypeValue, width_bytes: TypeBitwidth) -> String { let mut bytes: Vec = vec![]; diff --git a/reginald_codegen/src/builtin/rs/structs/layouts.rs b/reginald_codegen/src/builtin/rs/structs/layouts.rs index e40d39a..1f4177f 100644 --- a/reginald_codegen/src/builtin/rs/structs/layouts.rs +++ b/reginald_codegen/src/builtin/rs/structs/layouts.rs @@ -3,7 +3,8 @@ use std::fmt::Write; use super::*; use crate::{ - bits::{lsb_pos, mask_to_bit_ranges_str, unpositioned_mask}, + bits::{bitmask_from_range, lsb_pos, mask_to_bit_ranges, mask_to_bit_ranges_str, unpositioned_mask}, + builtin::rs::generate_extended_doc_comment, error::Error, regmap::{FieldType, Layout, RegisterBlockMember}, utils::{ @@ -71,12 +72,12 @@ fn generate_layout_struct( writeln!(out, "///")?; writeln!(out, "/// Address: 0x{:X}", reg.adr)?; if let Some(reset_val) = reg.reset_val { + writeln!(out, "///")?; writeln!(out, "/// Reset Value: 0x{:X}", reset_val)?; } } LayoutStructKind::RegisterBlockMemberStruct(member) => { writeln!(out, "/// `{}` Register Block Member", member.name)?; - // TODO more info here. } LayoutStructKind::Layout => { writeln!(out, "/// `{}`", layout.name)?; @@ -86,9 +87,21 @@ fn generate_layout_struct( writeln!(out, "///")?; write!(out, "{}", layout.docs.as_multiline("/// "))?; } - writeln!(out, "///")?; - writeln!(out, "/// Fields:")?; - writeln!(out, "{}", rs_layout_overview_comment(layout, "/// "))?; + + if layout.contains_fixed_bits() { + writeln!(out, "///")?; + writeln!(out, "/// Fixed bits:")?; + for range in mask_to_bit_ranges(layout.fixed_bits_mask()) { + let range_str = if range.start() == range.end() { + format!("{}", range.start()) + } else { + format!("{}:{}", range.end(), range.start()) + }; + + let value = (layout.fixed_bits_val() >> range.start()) & bitmask_from_range(&range); + writeln!(out, "/// - `[{range_str}]` = 0b{value:b}")?; + } + } // Struct derives: if !inp.opts.struct_derive.is_empty() { @@ -102,7 +115,12 @@ fn generate_layout_struct( for field in layout.fields_with_content() { let field_type = register_layout_member_type(field)?; let field_name = rs_snakecase(&field.name); - generate_doc_comment(out, &field.docs, " ")?; + generate_extended_doc_comment( + out, + &field.docs, + " ", + &[&format!("Bits: `[{}]`", mask_to_bit_ranges_str(field.mask))], + )?; writeln!(out, " pub {field_name}: {field_type},")?; } diff --git a/reginald_codegen/src/builtin/rs/structs/mod.rs b/reginald_codegen/src/builtin/rs/structs/mod.rs index b340331..f35c4b5 100644 --- a/reginald_codegen/src/builtin/rs/structs/mod.rs +++ b/reginald_codegen/src/builtin/rs/structs/mod.rs @@ -17,8 +17,8 @@ use clap::Parser; use self::layouts::LayoutStructKind; use super::{ - generate_doc_comment, rs_fitting_unsigned_type, rs_generate_header_comment, rs_header_comment, - rs_layout_overview_comment, rs_pascalcase, rs_snakecase, CONVERSION_TRAITS, + generate_doc_comment, rs_fitting_unsigned_type, rs_generate_header_comment, rs_header_comment, rs_pascalcase, + rs_snakecase, CONVERSION_TRAITS, }; // ====== Generator Opts ======================================================= @@ -224,7 +224,7 @@ fn generate_header(out: &mut dyn Write, inp: &Input) -> Result<(), Error> { regs.sort_by_key(|x| x.adr); for reg in regs { let adr = format!("0x{:02X}", reg.adr); - let name = format!("[{}]", rs_pascalcase(®.name)); + let name = format!("[`{}`]", rs_pascalcase(®.name)); let brief = reg.docs.brief.clone().unwrap_or("".to_string()); rows.push(vec![adr, name, brief]); } diff --git a/reginald_codegen/src/builtin/rs/structs/registers.rs b/reginald_codegen/src/builtin/rs/structs/registers.rs index 1589f15..d6fedee 100644 --- a/reginald_codegen/src/builtin/rs/structs/registers.rs +++ b/reginald_codegen/src/builtin/rs/structs/registers.rs @@ -30,12 +30,12 @@ pub fn generate_register_newtype(out: &mut dyn Write, inp: &Input, register: &Re writeln!(out, "/// `{}` Register", register.name)?; writeln!(out, "///")?; writeln!(out, "/// Address: 0x{:X}", register.adr)?; - if !register.docs.is_empty() { + if let Some(reset_val) = register.reset_val { writeln!(out, "///")?; - write!(out, "{}", register.docs.as_multiline("/// "))?; + writeln!(out, "/// Reset Value: 0x{:X}", reset_val)?; } writeln!(out, "///")?; - writeln!(out, "/// Uses `{}` layout.", rs_pascalcase(®ister.layout.name))?; + writeln!(out, "/// Uses [`{}`] layout.", rs_pascalcase(®ister.layout.name))?; // Register derives: if !inp.opts.struct_derive.is_empty() {