diff --git a/.gitignore b/.gitignore index ea8c4bf7f35f6f77f75d92ad8ce8349f6e81ddba..507684b6bfd3372427f56fbe2cea93961333b2a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +*.dot diff --git a/Cargo.lock b/Cargo.lock index ace37b6a49a23baec0d94db39d85290696a2d58e..bfb5320c6fffa6fdedf2475f23c8c6436f9a9739 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,12 +2,112 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "anstream" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" + +[[package]] +name = "anstyle-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" +dependencies = [ + "anstyle", + "windows-sys", +] + [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "clap" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a13b88d2c62ff462f88e4a121f17a82c1af05693a2f192b5c38d14de73c19f6" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hercules_ir" version = "0.1.0" @@ -16,6 +116,14 @@ dependencies = [ "ordered-float", ] +[[package]] +name = "hercules_tools" +version = "0.1.0" +dependencies = [ + "clap", + "hercules_ir", +] + [[package]] name = "memchr" version = "2.6.3" @@ -55,3 +163,116 @@ checksum = "2a54938017eacd63036332b4ae5c8a49fc8c0c1d6d629893057e4f13609edd06" dependencies = [ "num-traits", ] + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "2.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/Cargo.toml b/Cargo.toml index c93ca7055db1b397d0e103312a52772af7c4386a..a5227e311467bcf857ec0d14c6e36b2d337b95b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,6 @@ [workspace] members = [ - "hercules_ir" + "hercules_ir", + "hercules_tools" ] diff --git a/hercules_ir/src/parse.rs b/hercules_ir/src/parse.rs index 9f401ea99dfbf417d7fc630711f73ea531a9b7a4..ff3bfa4d2eba9b48feac2d3d6fd014bdb4444ec8 100644 --- a/hercules_ir/src/parse.rs +++ b/hercules_ir/src/parse.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use crate::*; -fn parse(ir_test: &str) -> Module { +pub fn parse(ir_test: &str) -> Module { parse_module(ir_test, Context::default()).unwrap().1 } @@ -347,9 +347,5 @@ fn add(x: i32, y: i32) -> i32 z = add(start, x, y) ", ); - println!("{:?}", module); - let mut dot = String::new(); - write_dot(&module, &mut dot).unwrap(); - println!("{}", dot); } } diff --git a/hercules_tools/Cargo.toml b/hercules_tools/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..260db105d3af6ecdceadcc7a1c1d37e64be4f1e7 --- /dev/null +++ b/hercules_tools/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "hercules_tools" +version = "0.1.0" +authors = ["Russel Arbore <rarbore2@illinois.edu>"] + +[[bin]] +name = "hercules_dot" +path = "src/hercules_dot/main.rs" + +[dependencies] +clap = { version = "*", features = ["derive"] } +hercules_ir = { path = "../hercules_ir" } diff --git a/hercules_tools/src/hercules_dot/main.rs b/hercules_tools/src/hercules_dot/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..a9153689434d50bb7cb288d2068acb9cffd35372 --- /dev/null +++ b/hercules_tools/src/hercules_dot/main.rs @@ -0,0 +1,51 @@ +extern crate clap; + +use std::env::temp_dir; +use std::fs::File; +use std::io::prelude::*; +use std::process::Command; + +use clap::Parser; + +#[derive(Parser, Debug)] +#[command(author, version, about, long_about = None)] +struct Args { + hir_file: String, + + #[arg(short, long, default_value_t = String::new())] + output: String, +} + +fn main() { + let args = Args::parse(); + if !args.hir_file.ends_with(".hir") { + eprintln!("WARNING: Running hercules_dot on a file without a .hir extension - interpreting as a textual Hercules IR file."); + } + + let mut file = File::open(args.hir_file).expect("PANIC: Unable to open input file."); + let mut contents = String::new(); + file.read_to_string(&mut contents) + .expect("PANIC: Unable to read input file contents."); + let module = hercules_ir::parse::parse(&contents); + if args.output.is_empty() { + let mut tmp_path = temp_dir(); + tmp_path.push("hercules_dot.dot"); + let mut file = File::create(tmp_path.clone()).expect("PANIC: Unable to open output file."); + let mut contents = String::new(); + hercules_ir::dot::write_dot(&module, &mut contents) + .expect("PANIC: Unable to generate output file contents."); + file.write_all(contents.as_bytes()) + .expect("PANIC: Unable to write output file contents."); + Command::new("xdot") + .args([tmp_path]) + .output() + .expect("PANIC: Couldn't execute xdot."); + } else { + let mut file = File::create(args.output).expect("PANIC: Unable to open output file."); + let mut contents = String::new(); + hercules_ir::dot::write_dot(&module, &mut contents) + .expect("PANIC: Unable to generate output file contents."); + file.write_all(contents.as_bytes()) + .expect("PANIC: Unable to write output file contents."); + } +} diff --git a/samples/simple1.dot b/samples/simple1.dot new file mode 100644 index 0000000000000000000000000000000000000000..0b74f0cf7507d8c25baf20fd32887a78613425d4 --- /dev/null +++ b/samples/simple1.dot @@ -0,0 +1,38 @@ +digraph "Module" { +compound=true +subgraph add { +label="add" +bgcolor=ivory4 +cluster=true +start_0_0 [label="start"]; +parameter_0_1 [label="param #1"]; +parameter_0_2 [label="param #2"]; +constant_0_3 [label="Integer8(5)"]; +add_0_6 [label="add"]; +start_0_0 -> add_0_6 [style="dashed"]; +parameter_0_1 -> add_0_6; +parameter_0_2 -> add_0_6; +add_0_4 [label="add"]; +start_0_0 -> add_0_4 [style="dashed"]; +add_0_6 -> add_0_4; +constant_0_3 -> add_0_4; +return_0_5 [label="return"]; +start_0_0 -> return_0_5 [style="dashed"]; +add_0_4 -> return_0_5; +} +subgraph myfunc { +label="myfunc" +bgcolor=ivory4 +cluster=true +start_1_0 [label="start"]; +parameter_1_1 [label="param #1"]; +parameter_1_1 -> call_1_2; +parameter_1_1 -> call_1_2; +call_1_2 [label="call(add)"]; +start_1_0 -> call_1_2 [style="dashed"]; +call_1_2 -> start_0_0 [lhead=add]; +return_1_3 [label="return"]; +start_1_0 -> return_1_3 [style="dashed"]; +call_1_2 -> return_1_3; +} +} diff --git a/samples/simple1.hir b/samples/simple1.hir new file mode 100644 index 0000000000000000000000000000000000000000..23e4d3b32456a16abdb4ef7a0321c62c5579a909 --- /dev/null +++ b/samples/simple1.hir @@ -0,0 +1,10 @@ +fn myfunc(x: i32) -> i32 + y = call(start, add, x, x) + r = return(start, y) + +fn add(x: i32, y: i32) -> i32 + c = constant(i8, 5) + r = return(start, w) + w = add(start, z, c) + z = add(start, x, y) +