diff --git a/Cargo.lock b/Cargo.lock index d1b0db4..f89a67e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -126,9 +126,8 @@ name = "cst-to-llhd" version = "0.1.0" dependencies = [ "clap", + "indexmap", "json", - "linked-hash-map", - "linked_hash_set", "llhd", "log", "num", @@ -155,6 +154,12 @@ dependencies = [ "termcolor", ] +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -183,6 +188,16 @@ dependencies = [ "quick-error", ] +[[package]] +name = "indexmap" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" +dependencies = [ + "autocfg", + "hashbrown", +] + [[package]] name = "itertools" version = "0.9.0" @@ -216,21 +231,6 @@ version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f" -[[package]] -name = "linked-hash-map" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" - -[[package]] -name = "linked_hash_set" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47186c6da4d81ca383c7c47c1bfc80f4b95f4720514d860a5407aaf4233f9588" -dependencies = [ - "linked-hash-map", -] - [[package]] name = "llhd" version = "0.16.0" diff --git a/Cargo.toml b/Cargo.toml index 2464b4e..5555e2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,8 +12,7 @@ llhd = "*" log = "*" num = "0.3.1" num-bigint = "0.3.3" -linked_hash_set = "*" -linked-hash-map = "*" +indexmap = "*" pretty_env_logger = "0.4" [[bin]] diff --git a/src/cst/always_statement.rs b/src/cst/always_statement.rs index 90fd66c..c5107c0 100644 --- a/src/cst/always_statement.rs +++ b/src/cst/always_statement.rs @@ -1,9 +1,9 @@ use crate::{ cst::{Expression, ModuleContext, Statement, SymbolKind, Tag, UnitContext}, - tools::Tools, + tools::{EventControl, Tools}, }; +use indexmap::{map::IndexMap, set::IndexSet}; use json::JsonValue; -use linked_hash_map::LinkedHashMap as HashMap; use llhd::{ ir::{Signature, UnitId, UnitKind, UnitName, Value}, ty::{int_ty, signal_ty}, @@ -55,41 +55,44 @@ impl AlwaysStatement { (json_event_control[0], &json_children[1]) }; - // first traversal - assert!(context.unit_ctx.is_empty()); - Self::gen_event_expression_list(json_event_expression_list, context); - Statement::codegen(json_statement, context); + let proc_names = EventControl::process_names(json); assert!(context.unit_ctx.raw_name_to_arg.is_empty()); let proc_signature = { - let mut ret = Signature::new(); + let mut sig = Signature::new(); - for lvalue in &context.unit_ctx.lvalues { + for lvalue in &proc_names.lvalues { if context.symbol.contains_key(lvalue) { let symbol = &context.symbol[lvalue]; assert_ne!(symbol.kind, SymbolKind::Param); let width = symbol.value.width.clone(); - let arg = ret.add_output(signal_ty(int_ty(width))); + let arg = sig.add_output(signal_ty(int_ty(width))); context.unit_ctx.raw_name_to_arg.insert(lvalue.clone(), arg); } else { error!("FIXME: symbol '{}' not found", lvalue); } } - let rvalues: Vec = context - .unit_ctx - .rvalues - .iter() - .filter(|&x| !context.unit_ctx.lvalues.contains(x)) - .map(|x| x.clone()) + let mut rvalues = [ + proc_names.posedges.clone(), + proc_names.negedges.clone(), + proc_names.levels.clone(), + proc_names.ctrl_values.clone(), + proc_names.rvalues.clone(), + ] + .iter() + .fold(IndexSet::new(), |acc, hs| acc.union(hs).cloned().collect()); + rvalues = rvalues + .into_iter() + .filter(|x| !proc_names.lvalues.contains(x)) .collect(); for rvalue in &rvalues { if context.symbol.contains_key(rvalue) { let symbol = &context.symbol[rvalue]; if symbol.kind != SymbolKind::Param { let width = symbol.value.width.clone(); - let arg = ret.add_input(signal_ty(int_ty(width))); + let arg = sig.add_input(signal_ty(int_ty(width))); context.unit_ctx.raw_name_to_arg.insert(rvalue.clone(), arg); } } else { @@ -97,7 +100,7 @@ impl AlwaysStatement { } } - ret + sig }; context.unit_ctx.new_data( @@ -110,8 +113,15 @@ impl AlwaysStatement { proc_signature, ); - // second traversal - Self::gen_event_expression_list(json_event_expression_list, context); + Self::gen_event_expression_list( + json_event_expression_list, + proc_names + .rvalues + .union(&proc_names.ctrl_values) + .cloned() + .collect(), + context, + ); Statement::codegen(json_statement, context); Tools::beautify(&mut context.unit_ctx); @@ -120,8 +130,12 @@ impl AlwaysStatement { context.module.add_unit(context.unit_ctx.drop_data()) } - fn gen_event_expression_list<'a>(json: &'a JsonValue, context: &mut ModuleContext<'a>) { - let mut sensitivity_list = HashMap::new(); + fn gen_event_expression_list<'a>( + json: &'a JsonValue, + rvalues: IndexSet, + context: &mut ModuleContext<'a>, + ) { + let mut sensitivity_list = IndexMap::new(); let json_expressions = Tools::match_tags( vec![json], @@ -133,18 +147,15 @@ impl AlwaysStatement { match json_children[0]["tag"].as_str() { Some(Tag::POS_EDGE) => { - let symbol = - Expression::gen_reference_name(&json_children[1]["children"][0], context); + let symbol = Expression::gen_reference_name(&json_children[1]["children"][0]); sensitivity_list.insert(symbol, Tag::POS_EDGE); } Some(Tag::NEG_EDGE) => { - let symbol = - Expression::gen_reference_name(&json_children[1]["children"][0], context); + let symbol = Expression::gen_reference_name(&json_children[1]["children"][0]); sensitivity_list.insert(symbol, Tag::NEG_EDGE); } Some(Tag::EXPRESSION) => { - let symbol = - Expression::gen_reference_name(&json_children[0]["children"][0], context); + let symbol = Expression::gen_reference_name(&json_children[0]["children"][0]); sensitivity_list.insert(symbol, Tag::EVENT_EXPRESSION); } _ => panic!("unknown error at CST node '{}'", json), @@ -156,12 +167,11 @@ impl AlwaysStatement { let raw_name_to_value = &mut unit_ctx.raw_name_to_value; let raw_name_to_shadow = &mut unit_ctx.raw_name_to_shadow; let raw_name_to_arg = &unit_ctx.raw_name_to_arg; - let rvalues = &unit_ctx.rvalues; let mut builder = UnitContext::builder(&mut unit_ctx.data); - let mut arg_value_to_raw_name = HashMap::new(); - let mut raw_name_to_prb_init = HashMap::new(); + let mut arg_value_to_raw_name = IndexMap::new(); + let mut raw_name_to_prb_init = IndexMap::new(); for (name, arg) in raw_name_to_arg { let value = builder.arg_value(*arg); context @@ -202,9 +212,9 @@ impl AlwaysStatement { builder.append_to(bb_init); let inputs: Vec = builder.unit().input_args().collect(); let events: Vec = inputs - .iter() - .filter(|x| sensitivity_list.contains_key(&arg_value_to_raw_name[&x])) - .map(|&x| { + .into_iter() + .filter(|&x| sensitivity_list.contains_key(&arg_value_to_raw_name[&x])) + .map(|x| { let raw_name = &arg_value_to_raw_name[&x]; let prb = builder.ins().prb(x); raw_name_to_prb_init.insert(raw_name, prb); diff --git a/src/cst/context.rs b/src/cst/context.rs index 668d07f..00fed4f 100644 --- a/src/cst/context.rs +++ b/src/cst/context.rs @@ -1,6 +1,5 @@ +use indexmap::map::IndexMap; use json::JsonValue; -use linked_hash_map::LinkedHashMap; -use linked_hash_set::LinkedHashSet; use llhd::{ ir::{ Arg, Block, Inst, Module, Signature, Unit, UnitBuilder, UnitData, UnitKind, UnitName, Value, @@ -13,15 +12,12 @@ use std::{collections::HashMap, fmt}; pub struct ModuleContext<'a> { pub name: String, pub module: Module, - pub symbol: LinkedHashMap>, + pub symbol: IndexMap>, pub unit_ctx: UnitContext, pub syntax_table: SyntaxTable<'a>, } pub struct UnitContext { - pub lvalues: LinkedHashSet, - pub rvalues: LinkedHashSet, - pub data: Option, pub raw_name_to_arg: HashMap, @@ -71,7 +67,7 @@ impl<'a> ModuleContext<'a> { Self { name: String::new(), module: Module::new(), - symbol: LinkedHashMap::new(), + symbol: IndexMap::new(), unit_ctx: UnitContext::new(), syntax_table: SyntaxTable::new(json), } @@ -81,8 +77,6 @@ impl<'a> ModuleContext<'a> { impl UnitContext { pub fn new() -> Self { Self { - lvalues: LinkedHashSet::new(), - rvalues: LinkedHashSet::new(), data: None, raw_name_to_arg: HashMap::new(), raw_name_to_value: HashMap::new(), @@ -93,8 +87,6 @@ impl UnitContext { } pub fn drop(&mut self) -> Self { let ret = Self { - lvalues: self.lvalues.iter().map(|x| x.clone()).collect(), - rvalues: self.rvalues.iter().map(|x| x.clone()).collect(), data: self.data.take(), raw_name_to_arg: self.raw_name_to_arg.drain().collect(), raw_name_to_value: self.raw_name_to_value.drain().collect(), @@ -114,8 +106,6 @@ impl UnitContext { } pub fn clear(&mut self) { - self.lvalues.clear(); - self.rvalues.clear(); self.raw_name_to_arg.clear(); self.raw_name_to_value.clear(); self.raw_name_to_shadow.clear(); @@ -125,8 +115,6 @@ impl UnitContext { pub fn is_empty(&self) -> bool { self.data.is_none() - && self.lvalues.is_empty() - && self.rvalues.is_empty() && self.raw_name_to_arg.is_empty() && self.raw_name_to_value.is_empty() && self.raw_name_to_shadow.is_empty() diff --git a/src/cst/expression.rs b/src/cst/expression.rs index 0d79e4d..0da4877 100644 --- a/src/cst/expression.rs +++ b/src/cst/expression.rs @@ -15,8 +15,8 @@ use log::{debug, error, info, trace, warn}; pub struct Expression {} impl Expression { - pub fn gen_reference_name(json: &JsonValue, context: &mut ModuleContext) -> String { - Self::gen_reference_call(json, context).0 + pub fn gen_reference_name(json: &JsonValue) -> String { + Self::gen_reference_call(json).0 } pub fn codegen<'a>(json: &'a JsonValue, context: &mut ModuleContext<'a>) -> Option { @@ -44,10 +44,7 @@ impl Expression { } } - fn gen_reference_call( - json: &JsonValue, - context: &mut ModuleContext, - ) -> (String, Option<(usize, usize)>) { + fn gen_reference_call(json: &JsonValue) -> (String, Option<(usize, usize)>) { let json_symbol_identifier = Tools::match_tags( vec![json], vec![ @@ -97,13 +94,12 @@ impl Expression { }; let symbol = &json_symbol_identifier[0]["text"]; - context.unit_ctx.rvalues.insert(symbol.to_string()); (symbol.to_string(), range) } fn gen_reference_value(json: &JsonValue, context: &mut ModuleContext) -> Option { - let (symbol, range) = Self::gen_reference_call(json, context); + let (symbol, range) = Self::gen_reference_call(json); if context.unit_ctx.data.is_some() { let unit_ctx = &mut context.unit_ctx; diff --git a/src/cst/module_declaration.rs b/src/cst/module_declaration.rs index c1a9cae..f1a85e7 100644 --- a/src/cst/module_declaration.rs +++ b/src/cst/module_declaration.rs @@ -259,7 +259,7 @@ impl<'a> ModuleDeclaration { named_port_symbol_path.to_vec(), ); if json_symbol.len() == 1 { - let symbol = &Expression::gen_reference_name(json_symbol[0], context); + let symbol = &Expression::gen_reference_name(json_symbol[0]); Some(context.unit_ctx.raw_name_to_value[symbol]) } else { let json_number = Tools::match_tags( @@ -303,7 +303,7 @@ impl<'a> ModuleDeclaration { .enumerate() { let json_expr = pos_port_list[&index]; - let arg = &Expression::gen_reference_name(json_expr, context); + let arg = &Expression::gen_reference_name(json_expr); let v = context.unit_ctx.raw_name_to_value[arg]; if arg_info.kind == SymbolKind::Input { inputs.push(v); diff --git a/src/cst/net_variable_assignment.rs b/src/cst/net_variable_assignment.rs index bbaf9ea..dd0a089 100644 --- a/src/cst/net_variable_assignment.rs +++ b/src/cst/net_variable_assignment.rs @@ -43,7 +43,6 @@ impl NetVariableAssignment { }; let lvalue_name = &json_lpvalue["text"].to_string(); - context.unit_ctx.lvalues.insert(lvalue_name.clone()); let lvalue = context.unit_ctx.raw_name_to_value.get(lvalue_name); if lvalue.is_some() { assert!(context.unit_ctx.data.is_some()); diff --git a/src/cst/nonblocking_assignment_statement.rs b/src/cst/nonblocking_assignment_statement.rs index 51a9571..dd27991 100644 --- a/src/cst/nonblocking_assignment_statement.rs +++ b/src/cst/nonblocking_assignment_statement.rs @@ -36,7 +36,6 @@ impl NonblockingAssignmentStatement { (json_symbol_identifier[0], &json_children[2]) }; let lvalue_name = &json_lpvalue["text"].to_string(); - context.unit_ctx.lvalues.insert(lvalue_name.clone()); if context.unit_ctx.raw_name_to_value.contains_key(lvalue_name) { assert!(context.unit_ctx.raw_name_to_arg.contains_key(lvalue_name)); assert!(context.unit_ctx.data.is_some()); diff --git a/src/tools/code_reporter.rs b/src/tools/code_reporter.rs new file mode 100644 index 0000000..e71226b --- /dev/null +++ b/src/tools/code_reporter.rs @@ -0,0 +1,67 @@ +use std::{ + fs::File, + io::{BufRead, BufReader}, +}; + +#[allow(unused_imports)] +use log::{debug, error, info, trace, warn}; + +pub struct CodeReporter { + file_name: String, + line_breakers: Vec, +} + +impl CodeReporter { + pub fn new(file_name: &str) -> Self { + Self { + file_name: file_name.to_string(), + line_breakers: Self::read_line_breakers(file_name), + } + } + + pub fn line_no(&self, key: usize) -> usize { + self.line_no_rec(key, 0, self.line_breakers.len() - 1) + } + + pub fn line(&self, line_no: usize) -> String { + let reader = BufReader::new( + File::open(self.file_name.as_str()) + .expect(format!(r#"file "{}" not found"#, self.file_name.as_str()).as_str()), + ); + + reader.lines().nth(line_no).unwrap().unwrap() + } + + pub fn line_count(&self) -> usize { + self.line_breakers.len() + } + + fn read_line_breakers(file_name: &str) -> Vec { + let reader = BufReader::new( + File::open(file_name).expect(format!(r#"file "{}" not found"#, file_name).as_str()), + ); + + let mut line_breakers = Vec::new(); + line_breakers.push(0); + + for line in reader.lines() { + let line_no = 1 + line_breakers.last().unwrap() + line.unwrap().len(); + line_breakers.push(line_no); + } + + line_breakers + } + + fn line_no_rec(&self, key: usize, left: usize, right: usize) -> usize { + if left + 1 >= right { + left + } else { + let mid = (left + right) / 2; + if key < self.line_breakers[mid] { + self.line_no_rec(key, left, mid) + } else { + self.line_no_rec(key, mid, right) + } + } + } +} diff --git a/src/tools/event_control.rs b/src/tools/event_control.rs index 94ed2c6..7d13333 100644 --- a/src/tools/event_control.rs +++ b/src/tools/event_control.rs @@ -1,54 +1,74 @@ use crate::{cst::Tag, tools::Tools}; +use indexmap::set::IndexSet; use json::JsonValue; -use std::{collections::HashSet, iter::FromIterator}; +use std::iter::FromIterator; #[allow(unused_imports)] use log::{debug, error, info, trace, warn}; +pub struct ProcessNames { + pub posedges: IndexSet, + pub negedges: IndexSet, + pub levels: IndexSet, + pub lvalues: IndexSet, + pub rvalues: IndexSet, + pub ctrl_values: IndexSet, +} + +impl ProcessNames { + pub fn new() -> Self { + Self { + posedges: IndexSet::new(), + negedges: IndexSet::new(), + levels: IndexSet::new(), + lvalues: IndexSet::new(), + rvalues: IndexSet::new(), + ctrl_values: IndexSet::new(), + } + } +} + pub struct EventControl {} impl EventControl { - pub fn clock_and_reset_names(json: &JsonValue) -> (HashSet, HashSet) { - let mut clock_names: HashSet = HashSet::new(); - let mut reset_names: HashSet = HashSet::new(); + pub fn clock_and_reset_names(json: &JsonValue) -> (IndexSet, IndexSet) { + let mut clock_names: IndexSet = IndexSet::new(); + let mut reset_names: IndexSet = IndexSet::new(); let json_always_statements = Tools::collect_tag(json, Tag::ALWAYS_STATEMENT); for json_always_statement in json_always_statements { let (json_events, json_body) = Self::events_and_body(json_always_statement); - let (json_posedge_names, json_negedge_names, json_level_names) = - Self::event_names(json_events); + let (posedge_names, negedge_names, level_names) = Self::event_names(json_events); - let (json_lvalues, json_rvalues, json_ctrl_values) = Self::value_names(json_body); - let json_top_ctrl_values = Self::top_ctrl_values(json_body); + let (lvalues, rvalues, ctrl_values) = Self::value_names(json_body); + let top_ctrl_values = Self::top_ctrl_values(json_body); - let json_edge_names = [json_posedge_names.clone(), json_negedge_names.clone()].concat(); - let json_sens_names = [json_edge_names.clone(), json_level_names.clone()].concat(); + let edge_names: IndexSet<_> = posedge_names.union(&negedge_names).cloned().collect(); + let sens_names: IndexSet<_> = edge_names.union(&level_names).cloned().collect(); - let json_data_values: HashSet = - json_lvalues.union(&json_rvalues).cloned().collect(); - let json_all_values: HashSet = - json_data_values.union(&json_ctrl_values).cloned().collect(); + let data_values: IndexSet = lvalues.union(&rvalues).cloned().collect(); + let all_values: IndexSet = data_values.union(&ctrl_values).cloned().collect(); - let local_clock_names: HashSet = HashSet::from_iter( - json_edge_names + let local_clock_names: IndexSet = IndexSet::from_iter( + edge_names .clone() .into_iter() - .filter(|x| !json_all_values.contains(x)), + .filter(|x| !all_values.contains(x)), ); - let local_reset_names: HashSet = HashSet::from_iter( - json_sens_names + let local_reset_names: IndexSet = IndexSet::from_iter( + sens_names .clone() .into_iter() - .filter(|x| !json_data_values.contains(x) && json_top_ctrl_values.contains(x)), + .filter(|x| !data_values.contains(x) && top_ctrl_values.contains(x)), ); - trace!("edge_names {:?}", json_edge_names); - trace!("sens_names {:?}", json_sens_names); - trace!("data_values {:?}", json_data_values); - trace!("all_values {:?}", json_all_values); - trace!("top_ctrl_values {:?}", json_top_ctrl_values); + trace!("edge_names {:?}", edge_names); + trace!("sens_names {:?}", sens_names); + trace!("data_values {:?}", data_values); + trace!("all_values {:?}", all_values); + trace!("top_ctrl_values {:?}", top_ctrl_values); clock_names = clock_names.union(&local_clock_names).cloned().collect(); reset_names = reset_names.union(&local_reset_names).cloned().collect(); @@ -59,6 +79,24 @@ impl EventControl { (clock_names, reset_names) } + pub fn process_names(json_always_statement: &JsonValue) -> ProcessNames { + let (json_events, json_body) = Self::events_and_body(json_always_statement); + + let (posedge_names, negedge_names, level_names) = Self::event_names(json_events); + + let (lvalues, rvalues, ctrl_values) = Self::value_names(json_body); + + let mut names = ProcessNames::new(); + names.posedges = posedge_names; + names.negedges = negedge_names; + names.levels = level_names; + names.lvalues = lvalues.into_iter().collect(); + names.rvalues = rvalues.into_iter().collect(); + names.ctrl_values = ctrl_values.into_iter().collect(); + + names + } + fn events_and_body(json: &JsonValue) -> (Vec<&JsonValue>, &JsonValue) { assert_eq!(json["tag"], Tag::ALWAYS_STATEMENT); let (json_events, json_body) = { @@ -90,10 +128,12 @@ impl EventControl { (json_events, json_body) } - fn event_names(json_events: Vec<&JsonValue>) -> (Vec, Vec, Vec) { - let mut json_posedge_names = Vec::new(); - let mut json_negedge_names = Vec::new(); - let mut json_level_names = Vec::new(); + fn event_names( + json_events: Vec<&JsonValue>, + ) -> (IndexSet, IndexSet, IndexSet) { + let mut posedge_names = IndexSet::new(); + let mut negedge_names = IndexSet::new(); + let mut level_names = IndexSet::new(); let json_id = |x: &JsonValue| -> String { let json_symbol_identifiers = Tools::collect_tag(&x, Tag::SYMBOL_IDENTIFIER); @@ -104,20 +144,22 @@ impl EventControl { for json_event in json_events { match json_event["children"][0]["tag"].as_str() { Some(Tag::POS_EDGE) => { - json_posedge_names.push(json_id(json_event)); + posedge_names.insert(json_id(json_event)); } Some(Tag::NEG_EDGE) => { - json_negedge_names.push(json_id(json_event)); + negedge_names.insert(json_id(json_event)); } _ => { - json_level_names.push(json_id(json_event)); + level_names.insert(json_id(json_event)); } } } - (json_posedge_names, json_negedge_names, json_level_names) + (posedge_names, negedge_names, level_names) } - fn value_names(json_body: &JsonValue) -> (HashSet, HashSet, HashSet) { + fn value_names( + json_body: &JsonValue, + ) -> (IndexSet, IndexSet, IndexSet) { let json_assignments = [ Tools::collect_tag(json_body, Tag::NONBLOCKING_ASSIGNMENT_STATEMENT), Tools::collect_tag(json_body, Tag::NET_VARIABLE_ASSIGNMENT), @@ -136,21 +178,21 @@ impl EventControl { ] .concat(); - let json_lvalues = HashSet::from_iter( + let json_lvalues = IndexSet::from_iter( json_assignments .iter() .map(|x| Tools::collect_tag(&x["children"][0], Tag::SYMBOL_IDENTIFIER)) .flatten() .map(|x| x["text"].to_string()), ); - let json_rvalues = HashSet::from_iter( + let json_rvalues = IndexSet::from_iter( json_assignments .iter() .map(|x| Tools::collect_tag(&x["children"][2], Tag::SYMBOL_IDENTIFIER)) .flatten() .map(|x| x["text"].to_string()), ); - let json_ctrl_values = HashSet::from_iter( + let json_ctrl_values = IndexSet::from_iter( json_conditions .iter() .map(|x| Tools::collect_tag(x, Tag::SYMBOL_IDENTIFIER)) @@ -161,7 +203,7 @@ impl EventControl { (json_lvalues, json_rvalues, json_ctrl_values) } - fn top_ctrl_values(json_body: &JsonValue) -> HashSet { + fn top_ctrl_values(json_body: &JsonValue) -> IndexSet { let json_statement = { let mut ret = json_body; loop { @@ -182,7 +224,7 @@ impl EventControl { } } }; - HashSet::from_iter( + IndexSet::from_iter( Tools::match_tags( vec![json_statement], vec![ diff --git a/src/tools/mod.rs b/src/tools/mod.rs index 80cea7b..bf194ff 100644 --- a/src/tools/mod.rs +++ b/src/tools/mod.rs @@ -1,5 +1,7 @@ +pub mod code_reporter; pub mod event_control; -mod tools; +pub mod tools; -pub use event_control::EventControl; -pub use tools::{CodeReporter, Tools}; +pub use code_reporter::CodeReporter; +pub use event_control::{EventControl, ProcessNames}; +pub use tools::Tools; diff --git a/src/tools/tools.rs b/src/tools/tools.rs index 8fc5cf6..bf5925c 100644 --- a/src/tools/tools.rs +++ b/src/tools/tools.rs @@ -4,8 +4,6 @@ use llhd::ir::{Block, Inst, Opcode}; use std::{ cell::RefCell, collections::{HashMap, HashSet, VecDeque}, - fs::File, - io::{BufRead, BufReader}, iter::FromIterator, process::{Command, Stdio}, rc::Rc, @@ -279,63 +277,3 @@ impl Tools { modules } } - -pub struct CodeReporter { - file_name: String, - line_breakers: Vec, -} - -impl CodeReporter { - pub fn new(file_name: &str) -> Self { - Self { - file_name: file_name.to_string(), - line_breakers: Self::read_line_breakers(file_name), - } - } - - pub fn line_no(&self, key: usize) -> usize { - self.line_no_rec(key, 0, self.line_breakers.len() - 1) - } - - pub fn line(&self, line_no: usize) -> String { - let reader = BufReader::new( - File::open(self.file_name.as_str()) - .expect(format!(r#"file "{}" not found"#, self.file_name.as_str()).as_str()), - ); - - reader.lines().nth(line_no).unwrap().unwrap() - } - - pub fn line_count(&self) -> usize { - self.line_breakers.len() - } - - fn read_line_breakers(file_name: &str) -> Vec { - let reader = BufReader::new( - File::open(file_name).expect(format!(r#"file "{}" not found"#, file_name).as_str()), - ); - - let mut line_breakers = Vec::new(); - line_breakers.push(0); - - for line in reader.lines() { - let line_no = 1 + line_breakers.last().unwrap() + line.unwrap().len(); - line_breakers.push(line_no); - } - - line_breakers - } - - fn line_no_rec(&self, key: usize, left: usize, right: usize) -> usize { - if left + 1 >= right { - left - } else { - let mid = (left + right) / 2; - if key < self.line_breakers[mid] { - self.line_no_rec(key, left, mid) - } else { - self.line_no_rec(key, mid, right) - } - } - } -}