add include and define parse
This commit is contained in:
parent
bcb5788cf2
commit
4b6f6a365d
@ -61,12 +61,65 @@ pub struct Module {
|
|||||||
pub range: Range
|
pub range: Range
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub struct DefineParam {
|
||||||
|
pub name: String,
|
||||||
|
pub value: String
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub struct Define {
|
||||||
|
name: String,
|
||||||
|
replacement: String,
|
||||||
|
range: Range,
|
||||||
|
params: Vec<DefineParam>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub struct Include {
|
||||||
|
pub path: String,
|
||||||
|
pub range: Range
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub struct Error {
|
||||||
|
severity: String,
|
||||||
|
message: String,
|
||||||
|
source: String,
|
||||||
|
range: Position,
|
||||||
|
running_mode: Option<String>,
|
||||||
|
running_phase: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub struct Macro {
|
||||||
|
pub defines: Vec<Define>,
|
||||||
|
pub includes: Vec<Include>,
|
||||||
|
pub errors: Vec<Error>,
|
||||||
|
pub invalid: Vec<Range>
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct FastHdlparam {
|
pub struct FastHdlparam {
|
||||||
pub fast: Vec<Module>
|
pub fast_macro: Macro,
|
||||||
|
pub content: Vec<Module>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FastHdlparam {
|
impl FastHdlparam {
|
||||||
|
pub fn add_define(&mut self, name: &str, replacement: &str, start_line: u32, start_character: u32,
|
||||||
|
end_line: u32, end_character: u32, params: Vec<DefineParam>) {
|
||||||
|
let define = Define {
|
||||||
|
name: name.to_string(),
|
||||||
|
replacement: replacement.to_string(),
|
||||||
|
range: Range {
|
||||||
|
start: Position { line: start_line, character: start_character },
|
||||||
|
end: Position { line: end_line, character: end_character }
|
||||||
|
},
|
||||||
|
params
|
||||||
|
};
|
||||||
|
self.fast_macro.defines.push(define);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new_module(&mut self, name: &str, line: u32, character: u32, end_character: u32) {
|
pub fn new_module(&mut self, name: &str, line: u32, character: u32, end_character: u32) {
|
||||||
let module = Module {
|
let module = Module {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
@ -82,12 +135,12 @@ impl FastHdlparam {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.fast.push(module);
|
self.content.push(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_parameter(&mut self, name: &str, net_type: &str, init: &str,
|
pub fn add_parameter(&mut self, name: &str, net_type: &str, init: &str,
|
||||||
start_line: u32, start_character: u32, end_line: u32, end_character: u32) {
|
start_line: u32, start_character: u32, end_line: u32, end_character: u32) {
|
||||||
let last_module = self.fast.last_mut().unwrap();
|
let last_module = self.content.last_mut().unwrap();
|
||||||
let parameter = Parameter {
|
let parameter = Parameter {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
net_type: net_type.to_string(),
|
net_type: net_type.to_string(),
|
||||||
@ -106,7 +159,7 @@ impl FastHdlparam {
|
|||||||
|
|
||||||
pub fn add_port(&mut self, name: &str, dir_type: &str, net_type: &str, width: &str,
|
pub fn add_port(&mut self, name: &str, dir_type: &str, net_type: &str, width: &str,
|
||||||
start_line: u32, start_character: u32, end_line: u32, end_character: u32) {
|
start_line: u32, start_character: u32, end_line: u32, end_character: u32) {
|
||||||
let last_module = self.fast.last_mut().unwrap();
|
let last_module = self.content.last_mut().unwrap();
|
||||||
let port = Port {
|
let port = Port {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
dir_type: dir_type.to_string(),
|
dir_type: dir_type.to_string(),
|
||||||
@ -129,7 +182,7 @@ impl FastHdlparam {
|
|||||||
pub fn add_instance(&mut self, name: &str, inst_type: &str, line: u32, character: u32, end_character: u32,
|
pub fn add_instance(&mut self, name: &str, inst_type: &str, line: u32, character: u32, end_character: u32,
|
||||||
param_start_line: u32, param_start_character: u32, param_end_line: u32, param_end_character: u32,
|
param_start_line: u32, param_start_character: u32, param_end_line: u32, param_end_character: u32,
|
||||||
port_start_line: u32, port_start_character: u32, port_end_line: u32, port_end_character: u32 ) {
|
port_start_line: u32, port_start_character: u32, port_end_line: u32, port_end_character: u32 ) {
|
||||||
let last_module = self.fast.last_mut().unwrap();
|
let last_module = self.content.last_mut().unwrap();
|
||||||
let instance = Instance {
|
let instance = Instance {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
inst_type: inst_type.to_string(),
|
inst_type: inst_type.to_string(),
|
||||||
@ -174,10 +227,10 @@ impl FastHdlparam {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_fast(&self) {
|
pub fn print_fast(&self) {
|
||||||
if self.fast.is_empty() {
|
if self.content.is_empty() {
|
||||||
println!("none module");
|
println!("none module");
|
||||||
} else {
|
} else {
|
||||||
for module in &self.fast {
|
for module in &self.content {
|
||||||
println!("module {}", module.name);
|
println!("module {}", module.name);
|
||||||
if !module.params.is_empty() {
|
if !module.params.is_empty() {
|
||||||
println!(" params:");
|
println!(" params:");
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
use std::collections::HashMap;
|
use std::fs::File;
|
||||||
|
use std::io::BufRead;
|
||||||
|
use std::{collections::HashMap, io::BufReader};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use sv_parser::{parse_sv, unwrap_node, ConstantMintypmaxExpression, GateInstantiation, ListOfParameterAssignments, ListOfPortConnections, Locate, PackedDimensionRange, RefNode, SyntaxTree};
|
use sv_parser::{parse_sv, unwrap_node, ConstantMintypmaxExpression, GateInstantiation, ListOfParameterAssignments, ListOfPortConnections, Locate, PackedDimensionRange, RefNode, SyntaxTree};
|
||||||
use super::fast_hdlparam::FastHdlparam;
|
use super::fast_hdlparam::{FastHdlparam, Macro};
|
||||||
|
|
||||||
pub fn sv_parser(path: &str) -> Option<FastHdlparam> {
|
pub fn sv_parser(path: &str) -> Option<FastHdlparam> {
|
||||||
// The path of SystemVerilog source file
|
// The path of SystemVerilog source file
|
||||||
@ -13,16 +15,22 @@ pub fn sv_parser(path: &str) -> Option<FastHdlparam> {
|
|||||||
|
|
||||||
let result = parse_sv(&path, &defines, &includes, false, true);
|
let result = parse_sv(&path, &defines, &includes, false, true);
|
||||||
if let Ok((syntax_tree, _)) = result {
|
if let Ok((syntax_tree, _)) = result {
|
||||||
let hdlparam = make_fast_from_syntaxtree(syntax_tree);
|
let hdlparam = make_fast_from_syntaxtree(syntax_tree, path);
|
||||||
return Some(hdlparam);
|
return Some(hdlparam);
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_fast_from_syntaxtree(syntax_tree: SyntaxTree) -> FastHdlparam {
|
pub fn make_fast_from_syntaxtree(syntax_tree: SyntaxTree, path: PathBuf) -> FastHdlparam {
|
||||||
let mut hdlparam = FastHdlparam {
|
let mut hdlparam = FastHdlparam {
|
||||||
fast: Vec::new()
|
fast_macro: Macro {
|
||||||
|
defines: Vec::new(),
|
||||||
|
errors: Vec::new(),
|
||||||
|
includes: get_includes(path),
|
||||||
|
invalid: Vec::new()
|
||||||
|
},
|
||||||
|
content: Vec::new()
|
||||||
};
|
};
|
||||||
let mut ansi_port_last_dir = "";
|
let mut ansi_port_last_dir = "";
|
||||||
|
|
||||||
@ -32,6 +40,40 @@ pub fn make_fast_from_syntaxtree(syntax_tree: SyntaxTree) -> FastHdlparam {
|
|||||||
// &SyntaxTree is iterable
|
// &SyntaxTree is iterable
|
||||||
for node in &syntax_tree {
|
for node in &syntax_tree {
|
||||||
match node {
|
match node {
|
||||||
|
RefNode::TextMacroDefinition(x) => {
|
||||||
|
let start = unwrap_node!(x, TextMacroDefinition).unwrap();
|
||||||
|
let start = get_identifier(start).unwrap();
|
||||||
|
let (start_line, start_character) = (start.line, get_column_by_offset(&content, start.offset));
|
||||||
|
|
||||||
|
let name = unwrap_node!(x, TextMacroName).unwrap();
|
||||||
|
let name = get_identifier(name).unwrap();
|
||||||
|
let name = syntax_tree.get_str(&name).unwrap();
|
||||||
|
|
||||||
|
let mut params_vec = Vec::new();
|
||||||
|
if let Some(RefNode::ListOfFormalArguments(x)) = unwrap_node!(x, ListOfFormalArguments) {
|
||||||
|
for node in x {
|
||||||
|
if let RefNode::FormalArgument(x) = node {
|
||||||
|
let param_name = unwrap_node!(x, SimpleIdentifier).unwrap();
|
||||||
|
let param_name = get_identifier(param_name).unwrap();
|
||||||
|
let param_name = syntax_tree.get_str(¶m_name).unwrap();
|
||||||
|
let param_val = match unwrap_node!(x, DefaultText) {
|
||||||
|
Some(RefNode::DefaultText(x)) => syntax_tree.get_str(&x.nodes.0).unwrap(),
|
||||||
|
_ => "Unknown"
|
||||||
|
};
|
||||||
|
params_vec.push(crate::core::fast_hdlparam::DefineParam { name: param_name.to_string(), value: param_val.to_string() });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let replacement = match unwrap_node!(x, MacroText) {
|
||||||
|
Some(RefNode::MacroText(x)) => Some(x.nodes.0),
|
||||||
|
_ => None
|
||||||
|
}.unwrap();
|
||||||
|
let (end_line, end_character) = (replacement.line, get_column_by_offset(&content, replacement.offset) + replacement.len);
|
||||||
|
let replacement = syntax_tree.get_str(&replacement).unwrap();
|
||||||
|
|
||||||
|
hdlparam.add_define(name, replacement, start_line, start_character as u32, end_line, end_character as u32, params_vec);
|
||||||
|
}
|
||||||
RefNode::ModuleDeclaration(x) => {
|
RefNode::ModuleDeclaration(x) => {
|
||||||
let id = unwrap_node!(x, ModuleIdentifier).unwrap();
|
let id = unwrap_node!(x, ModuleIdentifier).unwrap();
|
||||||
let id = get_identifier(id).unwrap();
|
let id = get_identifier(id).unwrap();
|
||||||
@ -490,6 +532,41 @@ fn get_identifier(node: RefNode) -> Option<Locate> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_includes(path: PathBuf) -> Vec<crate::core::fast_hdlparam::Include> {
|
||||||
|
let mut includes = Vec::new();
|
||||||
|
|
||||||
|
let file = File::open(path).unwrap();
|
||||||
|
let reader = BufReader::new(file);
|
||||||
|
|
||||||
|
for (line_number, line_content) in reader.lines().enumerate() {
|
||||||
|
let line_content = line_content.unwrap();
|
||||||
|
|
||||||
|
if line_content.trim().starts_with("`include") {
|
||||||
|
|
||||||
|
let parts: Vec<&str> = line_content.split_whitespace().collect();
|
||||||
|
|
||||||
|
if parts.len() >= 2 {
|
||||||
|
let path = parts[1];
|
||||||
|
let last_character = line_content.find(path).unwrap() + path.len();
|
||||||
|
|
||||||
|
includes.push(crate::core::fast_hdlparam::Include {
|
||||||
|
path: path.to_string(),
|
||||||
|
range: crate::core::fast_hdlparam::Range {
|
||||||
|
start: crate::core::fast_hdlparam::Position {
|
||||||
|
line: (line_number + 1) as u32, character: 1
|
||||||
|
},
|
||||||
|
end: crate::core::fast_hdlparam::Position {
|
||||||
|
line: (line_number + 1) as u32, character: last_character as u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
includes
|
||||||
|
}
|
||||||
|
|
||||||
fn get_column_by_offset(content: &[String], offset: usize) -> usize {
|
fn get_column_by_offset(content: &[String], offset: usize) -> usize {
|
||||||
let mut current_offset = 0;
|
let mut current_offset = 0;
|
||||||
|
|
||||||
|
@ -8,7 +8,13 @@ pub fn vhdl_parser(path: &str) -> FastHdlparam {
|
|||||||
let path = PathBuf::from(path);
|
let path = PathBuf::from(path);
|
||||||
|
|
||||||
let mut hdlparam = FastHdlparam {
|
let mut hdlparam = FastHdlparam {
|
||||||
fast: Vec::new()
|
fast_macro: Macro {
|
||||||
|
defines: Vec::new(),
|
||||||
|
errors: Vec::new(),
|
||||||
|
includes: Vec::new(),
|
||||||
|
invalid: Vec::new()
|
||||||
|
},
|
||||||
|
content: Vec::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
let parser = VHDLParser::new(VHDLStandard::VHDL2008);
|
let parser = VHDLParser::new(VHDLStandard::VHDL2008);
|
||||||
@ -20,7 +26,7 @@ pub fn vhdl_parser(path: &str) -> FastHdlparam {
|
|||||||
all_tockens.extend(tokens);
|
all_tockens.extend(tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
hdlparam.fast.extend(parse_tokens(all_tockens));
|
hdlparam.content.extend(parse_tokens(all_tockens));
|
||||||
hdlparam
|
hdlparam
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ pub fn do_fast(path: String) -> Result<FastHdlparam> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if let Some(syntax_tree) = parse_result {
|
if let Some(syntax_tree) = parse_result {
|
||||||
let hdlparam = make_fast_from_syntaxtree(syntax_tree);
|
let hdlparam = make_fast_from_syntaxtree(syntax_tree, path_buf);
|
||||||
return Ok(hdlparam);
|
return Ok(hdlparam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user