refactor vhdl parse logic

This commit is contained in:
light-ly 2024-12-25 21:13:38 +08:00
parent 9897594fdb
commit 77624e9a87
6 changed files with 102 additions and 33 deletions

View File

@ -294,6 +294,14 @@ impl Instance {
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Entity {
pub name: String,
pub params: Vec<Parameter>,
pub ports: Vec<Port>,
pub range: Range
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Module {
pub name: String,
@ -357,7 +365,8 @@ pub struct FastHdlparam {
pub fast_macro: Macro,
#[serde(rename = "fileType")]
pub file_type: String,
pub content: Vec<Module>
pub content: Vec<Module>,
pub entitys: Vec<Entity>
}
impl FastHdlparam {
@ -395,6 +404,44 @@ impl FastHdlparam {
self.content.push(module);
}
pub fn new_entity(&mut self, name: String, range: Range) {
let entity = Entity {
name,
params: Vec::new(),
ports: Vec::new(),
range
};
self.entitys.push(entity);
}
pub fn add_entity_parameter(&mut self, name: &str, net_type: &str, init: &str, range: Range) {
if let Some(last_entity) = self.entitys.last_mut() {
let parameter = Parameter {
name: name.to_string(),
net_type: net_type.to_string(),
init: init.to_string(),
range
};
last_entity.params.push(parameter);
last_entity.params.dedup();
}
}
pub fn add_entity_port(&mut self, name: &str, dir_type: &str, net_type: &str, width: &str, range: Range) {
if let Some(last_entity) = self.entitys.last_mut() {
let port = Port {
name: name.to_string(),
dir_type: dir_type.to_string(),
net_type: net_type.to_string(),
width: width.to_string(),
signed: "unsigned".to_string(),
range
};
last_entity.ports.push(port);
last_entity.ports.dedup();
}
}
pub fn update_module_range(&mut self, name: &str, end_line: u32, end_character: u32) {
if let Some(matched_module) = self.content.iter_mut().find(|module| module.name == name) {
matched_module.range.end.line = end_line;

View File

@ -165,6 +165,7 @@ fn xml_parse_text(text: &str) -> Option<(String, String, FastHdlparam)> {
invalid: Vec::new()
},
content: Vec::new(),
entitys: Vec::new(),
file_type: "primitives".to_string()
};
let res_text = syntax_tree.text.text().to_string();

View File

@ -97,6 +97,7 @@ pub fn make_fast_from_syntaxtree(
invalid: Vec::new()
},
content: Vec::new(),
entitys: Vec::new(),
file_type: "common".to_string()
};
let mut ansi_port_last_dir = "";

View File

@ -15,7 +15,7 @@ pub fn vhdl_parse_str(path: &PathBuf, code: &str) -> Option<DesignFile> {
}
pub fn make_fast_from_units(
arch_and_entity: Vec<((ArchitectureBody, Vec<Token>), (EntityDeclaration, Vec<Token>))>,
arch_and_entity: Vec<(Option<(ArchitectureBody, Vec<Token>)>, Option<(EntityDeclaration, Vec<Token>)>)>,
) -> Option<FastHdlparam> {
let mut hdlparam = FastHdlparam {
fast_macro: Macro {
@ -25,44 +25,63 @@ pub fn make_fast_from_units(
invalid: Vec::new()
},
content: Vec::new(),
entitys: Vec::new(),
file_type: "common".to_string()
};
// info!("arch and entity {arch_and_entity:#?}");
arch_and_entity.iter().for_each(|((arch, arch_tokens), (entity, entity_tokens))| {
let name = entity.ident.tree.item.name_utf8();
let arch_name = arch.ident.tree.item.name_utf8();
let range = get_range_from_token(
arch_tokens.get_token(arch.span().get_start_token()),
arch_tokens.get_token(arch.span().get_end_token())
);
arch_and_entity.iter().for_each(|units| {
match units {
(Some((arch, arch_tokens)), entity_units) => {
let name = if let Some((entity, _)) = entity_units {
entity.ident.tree.item.name_utf8()
} else {
"".to_string()
};
let arch_name = arch.ident.tree.item.name_utf8();
let range = get_range_from_token(
arch_tokens.get_token(arch.span().get_start_token()),
arch_tokens.get_token(arch.span().get_end_token())
);
hdlparam.new_vhdl_module(name, arch_name, range);
hdlparam.new_vhdl_module(name, arch_name, range);
if let Some(param_list) = &entity.generic_clause {
parse_interface_list(param_list, &entity_tokens).iter().for_each(|(name, _, net_type, _, init, range)| {
hdlparam.add_parameter(name, net_type, init, range.clone());
});
}
let instances = arch.statements.iter().filter(|statement| {
match statement.statement.item {
ConcurrentStatement::Instance(_) => true,
_ => false
}
})
.map(|statement| parse_instance(statement, arch_tokens))
.collect::<Vec<Instance>>();
if let Some(port_list) = &entity.port_clause {
parse_interface_list(port_list, &entity_tokens).iter().for_each(|(name, dir_type, net_type, width, init, range)| {
hdlparam.add_port(name, dir_type, net_type, width, range.clone());
});
}
let instances = arch.statements.iter().filter(|statement| {
match statement.statement.item {
ConcurrentStatement::Instance(_) => true,
_ => false
if let Some(last_module) = hdlparam.content.last_mut() {
last_module.instances = instances
}
}
})
.map(|statement| parse_instance(statement, arch_tokens))
.collect::<Vec<Instance>>();
(None, Some((entity, entity_tokens))) => {
let name = entity.ident.tree.item.name_utf8();
let range = get_range_from_token(
entity_tokens.get_token(entity.span().get_start_token()),
entity_tokens.get_token(entity.span().get_end_token())
);
if let Some(last_module) = hdlparam.content.last_mut() {
last_module.instances = instances
hdlparam.new_entity(name, range);
if let Some(param_list) = &entity.generic_clause {
parse_interface_list(param_list, &entity_tokens).iter().for_each(|(name, _, net_type, _, init, range)| {
hdlparam.add_entity_parameter(name, net_type, init, range.clone());
});
}
if let Some(port_list) = &entity.port_clause {
parse_interface_list(port_list, &entity_tokens).iter().for_each(|(name, dir_type, net_type, width, init, range)| {
hdlparam.add_entity_port(name, dir_type, net_type, width, range.clone());
});
}
}
(None, None) => ()
}
});

View File

@ -255,7 +255,8 @@ fn do_vhdl_fast(
invalid: vec![]
},
file_type: "ip".to_string(),
content: fake_content
content: fake_content,
entitys: vec![]
};
hdl_param.update_hdl_file(

@ -1 +1 @@
Subproject commit 3c806793fa9ba596fbf23b383653ae12204581c5
Subproject commit b4554bcb7b02e7cb3fabaadfa9cdb6e1e551ce1e