digital-lsp-server/src/core/fast_hdlparam.rs
2024-09-19 20:57:38 +08:00

233 lines
8.5 KiB
Rust

use serde::Serialize;
#[derive(Debug, Clone, Serialize)]
pub struct Position {
pub line: u32,
pub character: u32
}
#[derive(Debug, Clone, Serialize)]
pub struct Range {
pub start: Position,
pub end: Position
}
#[derive(Debug, Serialize)]
pub struct Port {
pub name: String,
pub dir_type: String,
pub net_type: String,
pub width: String,
pub signed: String,
pub range: Range
}
#[derive(Debug, Serialize)]
pub struct Parameter {
pub name: String,
pub net_type: String,
pub init: String,
pub range: Range
}
// #[derive(Debug, Serialize)]
// pub struct InstPort {
// pub name: String,
// pub range: Range
// }
// #[derive(Debug, Serialize)]
// pub struct InstParameter {
// pub name: String,
// pub value: String,
// pub range: Range
// }
#[derive(Debug, Serialize)]
pub struct Instance {
pub name: String,
pub inst_type: String,
pub instparams: Option<Range>,
pub instports: Option<Range>,
pub range: Range
}
#[derive(Debug, Serialize)]
pub struct Module {
pub name: String,
pub params: Vec<Parameter>,
pub ports: Vec<Port>,
pub instances: Vec<Instance>,
pub range: Range
}
#[derive(Debug, Serialize)]
pub struct FastHdlparam {
pub fast: Vec<Module>
}
impl FastHdlparam {
pub fn new_module(&mut self, name: &str, line: u32, character: u32, end_character: u32) {
let module = Module {
name: name.to_string(),
params: Vec::new(),
ports: Vec::new(),
instances: Vec::new(),
range: Range {
start: Position {
line, character
},
end: Position {
line, character: end_character
}
}
};
self.fast.push(module);
}
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) {
let last_module = self.fast.last_mut().unwrap();
let parameter = Parameter {
name: name.to_string(),
net_type: net_type.to_string(),
init: init.to_string(),
range: Range {
start: Position {
line: start_line, character: start_character
},
end: Position {
line:end_line, character: end_character
}
}
};
last_module.params.push(parameter);
}
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) {
let last_module = self.fast.last_mut().unwrap();
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: Range {
start: Position {
line: start_line, character: start_character
},
end: Position {
line:end_line, character: end_character
}
}
};
last_module.ports.push(port);
}
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,
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 instance = Instance {
name: name.to_string(),
inst_type: inst_type.to_string(),
instparams: if param_start_line == 0 {
None
} else {
Some(
Range {
start: Position {
line: param_start_line, character: param_start_character
},
end: Position {
line: param_end_line, character: param_end_character
}
}
)
},
instports: if port_start_line == 0 {
None
} else {
Some(
Range {
start: Position {
line: port_start_line, character: port_start_character
},
end: Position {
line: port_end_line, character: port_end_character
}
}
)
},
range: Range {
start: Position {
line, character
},
end: Position {
line, character: end_character
}
}
};
last_module.instances.push(instance);
}
pub fn print_fast(&self) {
if self.fast.is_empty() {
println!("none module");
} else {
for module in &self.fast {
println!("module {}", module.name);
if !module.params.is_empty() {
println!(" params:");
for param in &module.params {
println!(" parameter {} {} {}", param.net_type, param.name, param.init);
println!(" range start {} {}", param.range.start.line, param.range.start.character);
println!(" range end {} {}", param.range.end.line, param.range.end.character);
}
}
if !module.ports.is_empty() {
println!(" ports:");
for port in &module.ports {
if port.width == "1" {
println!(" {} {} {}", port.dir_type, port.net_type, port.name);
} else {
println!(" {} {} {} {}", port.dir_type, port.net_type, port.width, port.name);
}
println!(" range start {} {}", port.range.start.line, port.range.start.character);
println!(" range end {} {}", port.range.end.line, port.range.end.character);
}
}
if !module.instances.is_empty() {
println!(" instances:");
for instance in &module.instances {
println!(" {} {}", instance.inst_type, instance.name);
if instance.instparams.is_none() {
println!(" params: {:?}", instance.instparams);
} else {
println!(" params:");
println!(" range start {} {}", instance.instparams.clone().unwrap().start.line,
instance.instparams.clone().unwrap().start.character);
println!(" range end {} {}", instance.instparams.clone().unwrap().end.line,
instance.instparams.clone().unwrap().end.character);
}
if instance.instports.is_none() {
println!(" ports: {:?}", instance.instports);
} else {
println!(" ports:");
println!(" range start {} {}", instance.instports.clone().unwrap().start.line,
instance.instports.clone().unwrap().start.character);
println!(" range end {} {}", instance.instports.clone().unwrap().end.line,
instance.instports.clone().unwrap().end.character);
}
println!(" range start {} {}", instance.range.start.line, instance.range.start.character);
println!(" range end {} {}", instance.range.end.line, instance.range.end.character);
}
}
println!(" range start {} {}", module.range.start.line, module.range.start.character);
println!(" range end {} {}", module.range.end.line, module.range.end.character);
}
}
}
}