Skip to content

Commit

Permalink
debug tool: Graphviz
Browse files Browse the repository at this point in the history
`dbg!` on types which are Graphviz will print out the object in dot format.

Most types will only implement visualize or stringify. A way of getting distinguishable colors is also provided.
  • Loading branch information
rpitasky committed Oct 24, 2024
1 parent dd35a18 commit 917afec
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 1 deletion.
56 changes: 56 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion ti-basic-optimizer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ tifloats = { git = "https://github.com/TI-Toolkit/tifloats_lib_rs.git" }
itertools = "0.13.0"
ariadne = "0.4.1"
deku = "0.17.0"
dot-writer = { version = "0.1.3", optional = true }
equidistributed-colors = { version = "0.1.0", optional = true }
test-files = { path = "../test-files", optional = true }

[dev-dependencies]
test-files = { path = "../test-files" }

[features]
round-trip = []
round-trip = []
debug-tools = ["test-files", "dot-writer", "equidistributed-colors"]
47 changes: 47 additions & 0 deletions ti-basic-optimizer/src/analyze/control_flow/graph/graphviz.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use std::fmt::Debug;

use dot_writer::{DotWriter, Scope};

use equidistributed_colors::EquiColor;

static mut COLORS: Option<EquiColor> = None;

pub fn next_color() -> String {
let color = unsafe {
if COLORS.is_none() {
COLORS = Some(EquiColor::new(0.5, 0.5))
}

COLORS.unwrap().next().unwrap()
};

format!("#{:02X}{:02X}{:02X}", color.r, color.g, color.b)
}

pub trait Visualize<T: Sized> {
fn visualize(&self, context: &mut Scope, config: T);
}

pub trait Graphviz {
fn graphviz(&self, writer: &mut DotWriter);
}

impl Debug for dyn Graphviz {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut output_bytes = Vec::new();
{
let mut writer = DotWriter::from(&mut output_bytes);

self.graphviz(&mut writer);
}

f.write_str(&String::from_utf8(output_bytes).unwrap())
}
}

pub fn escape(string: &str) -> String {
string
.replace('\\', "\\\\")
.replace('\n', "\\n")
.replace('"', "\\\"")
}
28 changes: 28 additions & 0 deletions ti-basic-optimizer/src/parse/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use itertools::Itertools;
use titokens::{Token, Tokens};

pub mod commands;
Expand All @@ -16,3 +17,30 @@ pub(crate) trait Parse: Sized {
pub(crate) trait Reconstruct {
fn reconstruct(&self, config: &Config) -> Vec<Token>;
}

#[cfg(feature = "debug-tools")]
pub trait Stringify {
fn stringify(&self, config: Option<&titokens::Tokenizer>) -> String;
}

#[cfg(feature = "debug-tools")]
impl<T> Stringify for T
where
T: Reconstruct,
{
fn stringify(&self, config: Option<&titokens::Tokenizer>) -> String {
match config {
Some(tokenizer) => tokenizer
.stringify(&self.reconstruct(&test_files::test_version!().into()))
.to_string(),
None => self
.reconstruct(&test_files::test_version!().into())
.iter()
.map(|token| match token {
Token::OneByte(b) => format!("{:02X}", b),
Token::TwoByte(a, b) => format!("{:02X}{:02X}", a, b),
})
.join("\u{202f}"), // NNBSP
}
}
}

0 comments on commit 917afec

Please sign in to comment.