Browse Source

Add directionality to electrograph

master
Stephen 3 months ago
parent
commit
48c51fb8a9
3 changed files with 71 additions and 17 deletions
  1. BIN
      example.png
  2. +12
    -4
      src/compiler.rs
  3. +59
    -13
      src/electro_graph.rs

BIN
example.png View File

Before After
Width: 1691  |  Height: 4421  |  Size: 558 KiB

+ 12
- 4
src/compiler.rs View File

@ -42,15 +42,23 @@ impl Compiler {
match &param.param_type {
ModuleParamType::Input | ModuleParamType::Output => {
let signal_id = self.define_signal(param.name.clone());
self.graph.new_main_signal(param.name.clone(), signal_id);
self.graph.new_main_signal(
param.name.clone(),
signal_id,
&param.param_type,
);
main_args.push(Connection::SignalFromSignal {
signal_name: param.name.clone(),
});
}
ModuleParamType::InputBus(meta) | ModuleParamType::OutputBus(meta) => {
let ids = self.define_bus(param.name.clone(), *meta);
self.graph
.new_main_bus(param.name.clone(), &ids, meta.start_index);
self.graph.new_main_bus(
param.name.clone(),
&ids,
meta.start_index,
&param.param_type,
);
main_args.push(Connection::BusFromBus {
bus_name: param.name.clone(),
@ -275,7 +283,7 @@ impl StmtVisitor<()> for Compiler {
.map(|arg| self.resolve_signal_param(arg))
.collect();
self.graph.new_node(em.name.clone(), arg_ids);
self.graph.new_node(em.name.clone(), arg_ids, &em.params);
} else {
// TODO error handler
todo!();


+ 59
- 13
src/electro_graph.rs View File

@ -1,3 +1,4 @@
use crate::module_param::ModuleParamType;
use std::collections::HashMap;
use std::fs::File;
use std::io::prelude::*;
@ -8,18 +9,24 @@ pub struct GraphEdge {
signal_id: usize,
}
#[derive(Debug)]
enum Direction {
Input,
Output,
}
// Kicad schematic and some other bits.
#[derive(Debug)]
pub struct GraphNode {
name: String,
params: Vec<usize>, // signal ids
params: Vec<(usize, Direction)>, // signal ids
}
#[derive(Debug)]
pub struct ElectroGraph {
signal_count: usize, // signals go from 0 to signal_count
nodes: Vec<GraphNode>,
main_signals: HashMap<usize, String>, // Signals that are exposed publically
main_signals: HashMap<usize, (String, Direction)>, // Signals that are exposed publically
}
impl ElectroGraph {
@ -31,8 +38,22 @@ impl ElectroGraph {
}
}
pub fn new_node(&mut self, name: String, params: Vec<usize>) {
self.nodes.push(GraphNode { name, params });
pub fn new_node(&mut self, name: String, params: Vec<usize>, directions: &[ModuleParamType]) {
self.nodes.push(GraphNode {
name,
params: params
.into_iter()
.zip(directions.iter())
.map(|(param, dir)| {
let dir = match dir {
ModuleParamType::Input => Direction::Input,
ModuleParamType::Output => Direction::Output,
_ => unreachable!("Internal compiler error"),
};
(param, dir)
})
.collect(),
});
}
pub fn new_signal(&mut self) -> usize {
@ -41,29 +62,54 @@ impl ElectroGraph {
id
}
pub fn new_main_signal(&mut self, name: String, id: usize) {
self.main_signals.insert(id, name);
pub fn new_main_signal(&mut self, name: String, id: usize, direction: &ModuleParamType) {
let dir = match direction {
ModuleParamType::Input | ModuleParamType::InputBus(_) => Direction::Input,
ModuleParamType::Output | ModuleParamType::OutputBus(_) => Direction::Output,
_ => unreachable!("Internal compiler error"),
};
self.main_signals.insert(id, (name, dir));
}
pub fn new_main_bus(&mut self, name: String, ids: &[usize], start_index: i32) {
pub fn new_main_bus(
&mut self,
name: String,
ids: &[usize],
start_index: i32,
direction: &ModuleParamType,
) {
for (i, id) in ids.iter().enumerate() {
self.new_main_signal(format!("{}[{}]", name, i + start_index as usize), *id);
self.new_main_signal(
format!("{}[{}]", name, i + start_index as usize),
*id,
direction,
);
}
}
// for debugging
pub fn save_graphviz(&self) {
let mut output = "graph {".to_string();
let mut output = "digraph {".to_string();
for (i, node) in self.nodes.iter().enumerate() {
for (j, param) in node.params.iter().enumerate() {
output += &format!("{} -- {}_{} [label=\"{}\"];\r\n", param, node.name, i, j);
for (j, (param_id, param_dir)) in node.params.iter().enumerate() {
output += &match param_dir {
Direction::Input => {
format!("{} -> {}_{} [label=\"{}\"];\r\n", param_id, node.name, i, j)
}
Direction::Output => {
format!("{}_{} -> {} [label=\"{}\"];\r\n", node.name, i, param_id, j)
}
};
}
}
// main params
for (id, name) in &self.main_signals {
for (id, (name, dir)) in &self.main_signals {
output += &format!("\"{}\" [fillcolor = yellow, style=filled]", name);
output += &format!("\"{}\" -- {}\r\n", name, id);
output += &match dir {
Direction::Input => format!("\"{}\" -> {}\r\n", name, id),
Direction::Output => format!("{} -> \"{}\"\r\n", id, name),
};
}
output += "}\r\n";


Loading…
Cancel
Save