new(generator): top level module

This commit is contained in:
Wataru Otsubo 2025-01-31 02:17:48 +09:00
parent ac72b3638e
commit dfd28782dd
7 changed files with 95 additions and 2 deletions

2
Cargo.lock generated
View file

@ -80,6 +80,8 @@ dependencies = [
"anyhow", "anyhow",
"env_logger", "env_logger",
"log", "log",
"proc-macro2",
"quote",
"roxmltree", "roxmltree",
"thiserror", "thiserror",
] ]

View file

@ -15,5 +15,7 @@ path = "src/lib.rs"
anyhow = "1.0.95" anyhow = "1.0.95"
env_logger = "0.11.6" env_logger = "0.11.6"
log = "0.4" log = "0.4"
proc-macro2 = "1.0.93"
quote = "1.0"
roxmltree = "0.20" roxmltree = "0.20"
thiserror = "2.0" thiserror = "2.0"

View file

@ -1,4 +1,4 @@
//! Convert DOM to register interface, complementing optional parameters. //! Convert DOM to register interface defined in [`crate::types`], complementing optional parameters.
use std::{num, str}; use std::{num, str};

84
src/generator.rs Normal file
View file

@ -0,0 +1,84 @@
//! Generate register interface rust code from types in [`crate::types`].
use crate::types::{Block, Module, ModuleBlockElements};
use proc_macro2::TokenStream;
use quote::quote;
pub trait CodeGen {
fn generate_register_interface(self) -> proc_macro2::TokenStream;
}
impl CodeGen for Module {
fn generate_register_interface(self) -> proc_macro2::TokenStream {
let mut out = TokenStream::new();
if !self.elements_bitstring.is_empty() {
todo!("bitstring generation is not yet implemented")
}
let child_mods = self
.elements_other
.into_iter()
.map(|e| e.generate_register_interface());
for child in child_mods {
out.extend(child);
}
out
}
}
impl CodeGen for ModuleBlockElements {
fn generate_register_interface(self) -> proc_macro2::TokenStream {
match self {
ModuleBlockElements::Block(block) => block.generate_register_interface(),
ModuleBlockElements::Register(register) => todo!(),
ModuleBlockElements::Memory(memory) => todo!(),
ModuleBlockElements::Fifo(fifo) => todo!(),
}
}
}
impl CodeGen for Block {
fn generate_register_interface(self) -> proc_macro2::TokenStream {
let name = self.name;
let desc = self.desc.unwrap_or("".to_string());
quote! {
pub mod #name {
#[doc = #desc]
use std::marker::PhantomData;
use super::RegisterInterface;
pub mod control;
pub mod status;
pub(crate) const SLR0_OFFSET: usize = 0x0000;
pub(crate) const SLR0_SIZE: usize = 0x4000;
/// Access to SLR0.
pub struct Slr0<'a> {
mem_ptr: *mut u32,
_marker: PhantomData<&'a mut RegisterInterface>,
}
impl Slr0<'_> {
pub(crate) fn new(ptr: *mut u32) -> Self {
Slr0 {
mem_ptr: ptr,
_marker: PhantomData,
}
}
pub fn control(&self) -> control::Control {
control::Control::new(unsafe { self.mem_ptr.add(control::OFFSET) })
}
pub fn status(&self) -> status::Status {
status::Status::new(unsafe { self.mem_ptr.add(status::OFFSET) })
}
}
}
}
}
}

View file

@ -3,3 +3,4 @@
pub mod types; pub mod types;
pub mod parser; pub mod parser;
pub mod converter; pub mod converter;
pub mod generator;

View file

@ -1,7 +1,7 @@
use std::fs; use std::fs;
use anyhow::Result; use anyhow::Result;
use endcap_sl_software_ri_generator::types; use endcap_sl_software_ri_generator::{generator::CodeGen, types};
fn main() -> Result<()> { fn main() -> Result<()> {
env_logger::init(); env_logger::init();
@ -21,5 +21,7 @@ fn main() -> Result<()> {
let register_map = types::Module::from_xml_dom(doc.root_element())?; let register_map = types::Module::from_xml_dom(doc.root_element())?;
println!("read: {:#?}", register_map); println!("read: {:#?}", register_map);
println!("{}", register_map.generate_register_interface());
Ok(()) Ok(())
} }

View file

@ -1,3 +1,5 @@
//! Register type definition.
#[derive(Debug)] #[derive(Debug)]
pub struct Module { pub struct Module {
pub name: String, pub name: String,