Partly support ExtUnits initiation
This commit is contained in:
parent
3d3ed5e4d1
commit
2c654b2b65
|
@ -3,8 +3,12 @@ extern crate clap;
|
|||
extern crate json;
|
||||
|
||||
use clap::Arg;
|
||||
use cst_to_llhd::cst::{DescriptionList, Tag};
|
||||
use std::{fs::File, io::Read, result::Result};
|
||||
use cst_to_llhd::cst::{Tag, Tools};
|
||||
use json::JsonValue;
|
||||
use std::{collections::HashMap, fs::File, io::Read, result::Result};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use log::{debug, error, info, trace, warn};
|
||||
|
||||
fn main() {
|
||||
match main_inner() {
|
||||
|
@ -36,16 +40,23 @@ fn main_inner() -> Result<(), String> {
|
|||
let json_top = json::parse(contents.as_str()).unwrap();
|
||||
assert!(json_top.len() == 1);
|
||||
|
||||
let sv_file_name = json_top.entries().next().unwrap().0;
|
||||
println!(r#"codegen from CST to LLHD for "{}" ..."#, sv_file_name);
|
||||
println!("");
|
||||
let ref json_modules: HashMap<String, &JsonValue> = {
|
||||
let sv_file_name = json_top.entries().next().unwrap().0;
|
||||
info!(r#"codegen from CST to LLHD for "{}" ..."#, sv_file_name);
|
||||
let json_tree = &json_top[sv_file_name]["tree"];
|
||||
|
||||
let json_tree = &json_top[sv_file_name]["tree"];
|
||||
assert!(json_tree["tag"] == Tag::DESCRIPTION_LIST);
|
||||
Tools::match_tags(
|
||||
vec![json_tree],
|
||||
vec![Tag::DESCRIPTION_LIST, Tag::MODULE_DECLARATION],
|
||||
)
|
||||
.iter()
|
||||
.map(|&json| (Tools::module_name(json), json))
|
||||
.collect()
|
||||
};
|
||||
|
||||
let module_list = DescriptionList::codegen(json_tree);
|
||||
for (module, _) in module_list {
|
||||
println!("{}", module.dump());
|
||||
for (_, context_ref) in Tools::resolve_dependencies(json_modules) {
|
||||
let context = context_ref.as_ref().borrow();
|
||||
println!("{}", context.module.dump());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -3,12 +3,10 @@ extern crate clap;
|
|||
extern crate json;
|
||||
|
||||
use clap::Arg;
|
||||
use cst_to_llhd::cst::{DescriptionList, Tag};
|
||||
use cst_to_llhd::cst::{Tag, Tools};
|
||||
use json::JsonValue;
|
||||
use llhd::opt::{Pass, PassContext};
|
||||
use std::{
|
||||
process::{Command, Stdio},
|
||||
result::Result,
|
||||
};
|
||||
use std::{collections::HashMap, iter::FromIterator, result::Result};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use log::{debug, error, info, trace, warn};
|
||||
|
@ -31,72 +29,48 @@ fn main_inner() -> Result<(), std::io::Error> {
|
|||
.arg(
|
||||
Arg::with_name("input")
|
||||
.help("the Verilog file to convert")
|
||||
.multiple(true)
|
||||
.required(true),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
let json_raw = {
|
||||
let mut ret = String::new();
|
||||
let json_top_list: Vec<_> = matches
|
||||
.values_of("input")
|
||||
.unwrap()
|
||||
.map(|input| {
|
||||
let json_raw = Tools::json_raw(input);
|
||||
let json_top = json::parse(json_raw.as_str()).unwrap();
|
||||
assert!(json_top.len() == 1);
|
||||
json_top
|
||||
})
|
||||
.collect();
|
||||
|
||||
let input = matches.value_of("input").unwrap();
|
||||
let ref json_modules: HashMap<String, &JsonValue> =
|
||||
HashMap::from_iter(json_top_list.iter().flat_map(|json_top| {
|
||||
let json_modules: Vec<_> = {
|
||||
let sv_file_name = json_top.entries().next().unwrap().0;
|
||||
let json_tree = &json_top[sv_file_name]["tree"];
|
||||
Tools::match_tags(
|
||||
vec![json_tree],
|
||||
vec![Tag::DESCRIPTION_LIST, Tag::MODULE_DECLARATION],
|
||||
)
|
||||
.iter()
|
||||
.map(|&json| (Tools::module_name(json), json))
|
||||
.collect()
|
||||
};
|
||||
|
||||
let cmd_verible = "verible-verilog-syntax";
|
||||
let cmd_tr = "tr";
|
||||
let cmd_sed = "sed";
|
||||
json_modules
|
||||
}));
|
||||
|
||||
let mut verible_output_child = Command::new(cmd_verible)
|
||||
.args(&["--printtree", "--export_json", input])
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.expect(cmd_not_found(cmd_verible).as_str());
|
||||
|
||||
if let Some(verible_output) = verible_output_child.stdout.take() {
|
||||
let mut tr_output_child = Command::new(cmd_tr)
|
||||
.args(&["-d", r#"' \t\n'"#])
|
||||
.stdin(verible_output)
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.expect(cmd_not_found(cmd_tr).as_str());
|
||||
|
||||
if let Some(tr_output) = tr_output_child.stdout.take() {
|
||||
let sed_output_child = Command::new(cmd_sed)
|
||||
.args(&["-e", r#"s/,null//g"#, "-e", r#"s/null,//g"#])
|
||||
.stdin(tr_output)
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.expect(cmd_not_found(cmd_sed).as_str());
|
||||
|
||||
let sed_output = sed_output_child.wait_with_output()?;
|
||||
|
||||
ret = String::from_utf8(sed_output.stdout).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
ret
|
||||
};
|
||||
|
||||
let json_top = json::parse(json_raw.as_str()).unwrap();
|
||||
assert!(json_top.len() == 1);
|
||||
|
||||
let sv_file_name = json_top.entries().next().unwrap().0;
|
||||
|
||||
let json_tree = &json_top[sv_file_name]["tree"];
|
||||
assert!(json_tree["tag"] == Tag::DESCRIPTION_LIST);
|
||||
|
||||
let module_list = DescriptionList::codegen(json_tree);
|
||||
|
||||
for (mut module, syntax_table) in module_list {
|
||||
let contexts = Tools::resolve_dependencies(json_modules);
|
||||
for (_, context_ref) in contexts {
|
||||
let mut context = context_ref.borrow_mut();
|
||||
let pass_ctx = PassContext;
|
||||
trace!("syntax_table.values {:?}", syntax_table.values);
|
||||
trace!("syntax_table.insts {:?}", syntax_table.insts);
|
||||
llhd::pass::GlobalCommonSubexprElim::run_on_module(&pass_ctx, &mut module);
|
||||
llhd::pass::GlobalCommonSubexprElim::run_on_module(&pass_ctx, &mut context.module);
|
||||
//llhd::pass::InstSimplification::run_on_module(&pass_ctx, &mut module);
|
||||
llhd::assembly::write_module(std::io::stdout(), &module);
|
||||
llhd::assembly::write_module(std::io::stdout(), &context.module);
|
||||
println!();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn cmd_not_found(cmd: &str) -> String {
|
||||
format!(r#"command "{}" not found"#, cmd)
|
||||
}
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
use crate::cst::{ModuleDeclaration, SyntaxTable, Tag, Tools};
|
||||
use json::JsonValue;
|
||||
use llhd::ir::Module;
|
||||
|
||||
pub struct DescriptionList {}
|
||||
|
||||
impl DescriptionList {
|
||||
pub fn codegen(json: &JsonValue) -> Vec<(Module, SyntaxTable)> {
|
||||
Tools::match_tags(
|
||||
vec![json],
|
||||
vec![Tag::DESCRIPTION_LIST, Tag::MODULE_DECLARATION],
|
||||
)
|
||||
.iter()
|
||||
.map(|&x| ModuleDeclaration::codegen(x))
|
||||
.collect()
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ mod always_statement;
|
|||
mod case_statement;
|
||||
mod conditional_statement;
|
||||
mod context;
|
||||
mod description_list;
|
||||
mod expression;
|
||||
mod module_declaration;
|
||||
mod net_variable_assignment;
|
||||
|
@ -16,7 +15,7 @@ mod tools;
|
|||
use always_statement::AlwaysStatement;
|
||||
use case_statement::CaseStatement;
|
||||
use conditional_statement::ConditionalStatement;
|
||||
use context::{ModuleContext, SymbolInfo, SymbolKind, UnitContext};
|
||||
use context::{SymbolInfo, SymbolKind, UnitContext};
|
||||
use expression::Expression;
|
||||
use net_variable_assignment::NetVariableAssignment;
|
||||
use nonblocking_assignment_statement::NonblockingAssignmentStatement;
|
||||
|
@ -24,8 +23,8 @@ use number::Number;
|
|||
use statement::Statement;
|
||||
use symbol_declaration::SymbolDeclaration;
|
||||
|
||||
pub use context::ModuleContext;
|
||||
pub use context::SyntaxTable;
|
||||
pub use description_list::DescriptionList;
|
||||
pub use module_declaration::ModuleDeclaration;
|
||||
pub use tags::Tag;
|
||||
pub use tools::{CodeReporter, Tools};
|
||||
|
|
|
@ -1,37 +1,43 @@
|
|||
use crate::cst::{
|
||||
AlwaysStatement, ModuleContext, NetVariableAssignment, SymbolDeclaration, SymbolKind,
|
||||
SyntaxTable, Tag, Tools, UnitContext,
|
||||
AlwaysStatement, Expression, ModuleContext, NetVariableAssignment, SymbolDeclaration,
|
||||
SymbolKind, Tag, Tools, UnitContext,
|
||||
};
|
||||
use json::JsonValue;
|
||||
use llhd::{
|
||||
ir::{ExtUnit, Module, Signature, UnitId, UnitKind, UnitName, Value},
|
||||
ir::{ExtUnit, Signature, UnitId, UnitKind, UnitName, Value},
|
||||
ty::{int_ty, signal_ty},
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use log::{debug, error, info, trace, warn};
|
||||
|
||||
pub struct ModuleDeclaration {}
|
||||
|
||||
impl ModuleDeclaration {
|
||||
pub fn codegen(json: &JsonValue) -> (Module, SyntaxTable) {
|
||||
let mut context = ModuleContext::new(json);
|
||||
impl<'a> ModuleDeclaration {
|
||||
pub fn codegen(json: &'a JsonValue, context: &mut ModuleContext<'a>) {
|
||||
Self::codegen_with_ext(json, context, Vec::new());
|
||||
}
|
||||
|
||||
SymbolDeclaration::declare_port(json, &mut context);
|
||||
SymbolDeclaration::declare_reg(json, &mut context);
|
||||
SymbolDeclaration::declare_wire(json, &mut context);
|
||||
SymbolDeclaration::declare_param(json, &mut context);
|
||||
pub fn codegen_with_ext(
|
||||
json: &'a JsonValue,
|
||||
context: &mut ModuleContext<'a>,
|
||||
ext_modules: Vec<Rc<RefCell<ModuleContext>>>,
|
||||
) {
|
||||
SymbolDeclaration::declare_port(json, context);
|
||||
SymbolDeclaration::declare_reg(json, context);
|
||||
SymbolDeclaration::declare_wire(json, context);
|
||||
SymbolDeclaration::declare_param(json, context);
|
||||
|
||||
Self::gen_entity_data(json, &mut context);
|
||||
Self::gen_port_names(&mut context);
|
||||
Self::gen_regs_and_wires(&mut context);
|
||||
Self::gen_assignment(json, &mut context);
|
||||
Self::gen_instances(json, &mut context);
|
||||
Self::gen_entity_data(json, context);
|
||||
Self::gen_port_names(context);
|
||||
Self::gen_regs_and_wires(context);
|
||||
Self::gen_assignment(json, context);
|
||||
Self::gen_instances(json, context, ext_modules);
|
||||
|
||||
let mut entity_ctx = context.unit_ctx.drop(); // clear UnitContext before declare processes
|
||||
|
||||
Self::gen_always(json, &mut entity_ctx, &mut context);
|
||||
Self::gen_always(json, &mut entity_ctx, context);
|
||||
Tools::beautify(&mut entity_ctx);
|
||||
|
||||
context.module.add_unit(entity_ctx.data.take().unwrap());
|
||||
|
@ -41,23 +47,10 @@ impl ModuleDeclaration {
|
|||
" module-codegen ",
|
||||
context.module.dump()
|
||||
);
|
||||
|
||||
(context.module, context.syntax_table)
|
||||
}
|
||||
|
||||
fn gen_entity_data(json: &JsonValue, context: &mut ModuleContext) {
|
||||
context.name = {
|
||||
let json_symbol_identifier = Tools::match_tags(
|
||||
vec![json],
|
||||
vec![
|
||||
Tag::MODULE_DECLARATION,
|
||||
Tag::MODULE_HEADER,
|
||||
Tag::SYMBOL_IDENTIFIER,
|
||||
],
|
||||
);
|
||||
assert_eq!(json_symbol_identifier.len(), 1);
|
||||
json_symbol_identifier[0]["text"].to_string()
|
||||
};
|
||||
context.name = Tools::module_name(json);
|
||||
let entity_name = UnitName::global(context.name.clone());
|
||||
|
||||
let entity_signature = {
|
||||
|
@ -136,7 +129,7 @@ impl ModuleDeclaration {
|
|||
}
|
||||
}
|
||||
|
||||
fn gen_assignment<'a>(json: &'a JsonValue, context: &mut ModuleContext<'a>) {
|
||||
fn gen_assignment(json: &'a JsonValue, context: &mut ModuleContext<'a>) {
|
||||
let json_wire_assignments = &Tools::match_tags(
|
||||
vec![json],
|
||||
vec![
|
||||
|
@ -158,7 +151,11 @@ impl ModuleDeclaration {
|
|||
context.unit_ctx.bb_head.pop();
|
||||
}
|
||||
|
||||
fn gen_instances<'a>(json: &'a JsonValue, _context: &mut ModuleContext<'a>) {
|
||||
fn gen_instances(
|
||||
json: &'a JsonValue,
|
||||
context: &mut ModuleContext<'a>,
|
||||
ext_modules: Vec<Rc<RefCell<ModuleContext>>>,
|
||||
) {
|
||||
let base_path = [
|
||||
Tag::MODULE_DECLARATION,
|
||||
Tag::MODULE_ITEM_LIST,
|
||||
|
@ -166,6 +163,7 @@ impl ModuleDeclaration {
|
|||
];
|
||||
let type_path = [
|
||||
Tag::DATA_DECLARATION,
|
||||
Tag::INSTANTIATION_BASE,
|
||||
Tag::INSTANTIATION_TYPE,
|
||||
Tag::DATA_TYPE,
|
||||
Tag::UNQUALIFIED_ID,
|
||||
|
@ -181,32 +179,85 @@ impl ModuleDeclaration {
|
|||
Tag::ACTUAL_NAMED_PORT,
|
||||
];
|
||||
let port_name = [Tag::ACTUAL_NAMED_PORT, Tag::SYMBOL_IDENTIFIER];
|
||||
let port_expr = [Tag::ACTUAL_NAMED_PORT, Tag::PAREN_GROUP, Tag::EXPRESSION];
|
||||
let port_expr = [
|
||||
Tag::ACTUAL_NAMED_PORT,
|
||||
Tag::PAREN_GROUP,
|
||||
Tag::EXPRESSION,
|
||||
Tag::REFERENCE_CALL_BASE,
|
||||
];
|
||||
warn!("FIXME: ExtUnit only supports named ports and direct arguments");
|
||||
|
||||
let _json_instances: Vec<_> = Tools::match_tags(vec![json], base_path.to_vec())
|
||||
let instances: HashMap<String, HashMap<String, &JsonValue>> =
|
||||
Tools::match_tags(vec![json], base_path.to_vec())
|
||||
.iter()
|
||||
.flat_map(|&x| {
|
||||
let json_types = Tools::match_tags(vec![x], type_path.to_vec());
|
||||
if json_types.len() == 1 {
|
||||
let name = json_types[0]["text"].to_string();
|
||||
let json_ports = &Tools::match_tags(vec![x], port_path.to_vec());
|
||||
let json_port_names =
|
||||
Tools::match_tags(json_ports.clone(), port_name.to_vec());
|
||||
let json_port_exprs =
|
||||
Tools::match_tags(json_ports.clone(), port_expr.to_vec());
|
||||
let port_list: HashMap<String, _> = json_port_names
|
||||
.into_iter()
|
||||
.map(|x| x["text"].to_string())
|
||||
.zip(json_port_exprs.into_iter())
|
||||
.collect();
|
||||
Some((name, port_list))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let name_to_ext: HashMap<String, Rc<RefCell<ModuleContext>>> = ext_modules
|
||||
.iter()
|
||||
.flat_map(|&x| {
|
||||
let json_types = Tools::match_tags(vec![x], type_path.to_vec());
|
||||
if json_types.len() == 1 {
|
||||
let json_type = json_types[0];
|
||||
let json_ports = &Tools::match_tags(vec![x], port_path.to_vec());
|
||||
let json_port_names = Tools::match_tags(json_ports.clone(), port_name.to_vec());
|
||||
let json_port_exprs = Tools::match_tags(json_ports.clone(), port_expr.to_vec());
|
||||
let json_port_list: Vec<_> = json_port_names
|
||||
.into_iter()
|
||||
.zip(json_port_exprs.into_iter())
|
||||
.collect();
|
||||
Some((json_type, json_port_list))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.map(|x| (x.as_ref().borrow().name.clone(), x.clone()))
|
||||
.collect();
|
||||
|
||||
warn!("FIXME: gen_instances() work-in-progress");
|
||||
context.unit_ctx.bb_head.push({
|
||||
let builder = UnitContext::builder(&mut context.unit_ctx.data);
|
||||
builder.unit().entry()
|
||||
});
|
||||
|
||||
debug!("#instances = {}", instances.len());
|
||||
for (name, port_list) in instances {
|
||||
debug!("ext_name {}", name);
|
||||
let ext_context = name_to_ext[&name].as_ref().borrow();
|
||||
let ext_entity = ext_context.module.entities().next().unwrap();
|
||||
let inputs: Vec<_> = ext_entity
|
||||
.sig()
|
||||
.inputs()
|
||||
.map(|arg| {
|
||||
let sig_name = ext_entity.get_name(ext_entity.arg_value(arg)).unwrap();
|
||||
let json_expr = port_list[sig_name];
|
||||
let symbol = &Expression::gen_reference_name(json_expr, context);
|
||||
context.unit_ctx.raw_name_to_value[symbol]
|
||||
})
|
||||
.collect();
|
||||
let outputs: Vec<_> = ext_entity
|
||||
.sig()
|
||||
.outputs()
|
||||
.map(|arg| {
|
||||
let sig_name = ext_entity.get_name(ext_entity.arg_value(arg)).unwrap();
|
||||
let json_expr = port_list[sig_name];
|
||||
let symbol = &Expression::gen_reference_name(json_expr, context);
|
||||
context.unit_ctx.raw_name_to_value[symbol]
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut builder = UnitContext::builder(&mut context.unit_ctx.data);
|
||||
let ext_unit = builder.add_extern(ext_entity.name().clone(), ext_entity.sig().clone());
|
||||
builder.ins().inst(ext_unit, inputs, outputs);
|
||||
}
|
||||
|
||||
context.unit_ctx.bb_head.pop();
|
||||
|
||||
warn!("FIXME: gen_instances() for ExtUnit, work-in-progress");
|
||||
}
|
||||
|
||||
fn gen_always<'a>(
|
||||
fn gen_always(
|
||||
json: &'a JsonValue,
|
||||
entity_ctx: &mut UnitContext,
|
||||
context: &mut ModuleContext<'a>,
|
||||
|
|
147
src/cst/tools.rs
147
src/cst/tools.rs
|
@ -1,12 +1,19 @@
|
|||
use crate::cst::UnitContext;
|
||||
use crate::cst::{ModuleContext, ModuleDeclaration, Tag, UnitContext};
|
||||
use json::JsonValue;
|
||||
use llhd::ir::{Block, Inst, Opcode};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
cell::RefCell,
|
||||
collections::{HashMap, HashSet, VecDeque},
|
||||
fs::File,
|
||||
io::{BufRead, BufReader},
|
||||
iter::FromIterator,
|
||||
process::{Command, Stdio},
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use log::{debug, error, info, trace, warn};
|
||||
|
||||
pub struct Tools {}
|
||||
|
||||
impl Tools {
|
||||
|
@ -116,6 +123,142 @@ impl Tools {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn json_raw(verilog_file_name: &str) -> String {
|
||||
let mut ret = String::new();
|
||||
|
||||
let cmd_verible = "verible-verilog-syntax";
|
||||
let cmd_tr = "tr";
|
||||
let cmd_sed = "sed";
|
||||
|
||||
let cmd_not_found = |cmd: &str| -> String { format!(r#"command "{}" not found"#, cmd) };
|
||||
|
||||
let mut verible_output_child = Command::new(cmd_verible)
|
||||
.args(&["--printtree", "--export_json", verilog_file_name])
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.expect(cmd_not_found(cmd_verible).as_str());
|
||||
|
||||
if let Some(verible_output) = verible_output_child.stdout.take() {
|
||||
let mut tr_output_child = Command::new(cmd_tr)
|
||||
.args(&["-d", r#"' \t\n'"#])
|
||||
.stdin(verible_output)
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.expect(cmd_not_found(cmd_tr).as_str());
|
||||
|
||||
if let Some(tr_output) = tr_output_child.stdout.take() {
|
||||
let sed_output_child = Command::new(cmd_sed)
|
||||
.args(&["-e", r#"s/,null//g"#, "-e", r#"s/null,//g"#])
|
||||
.stdin(tr_output)
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.expect(cmd_not_found(cmd_sed).as_str());
|
||||
|
||||
let sed_output = sed_output_child.wait_with_output().unwrap();
|
||||
|
||||
ret = String::from_utf8(sed_output.stdout).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn module_name(json: &JsonValue) -> String {
|
||||
let json_symbol_identifier = {
|
||||
let j = Tools::match_tags(
|
||||
vec![json],
|
||||
vec![
|
||||
Tag::MODULE_DECLARATION,
|
||||
Tag::MODULE_HEADER,
|
||||
Tag::SYMBOL_IDENTIFIER,
|
||||
],
|
||||
);
|
||||
assert_eq!(j.len(), 1, "{}", json);
|
||||
j[0]
|
||||
};
|
||||
json_symbol_identifier["text"].to_string()
|
||||
}
|
||||
|
||||
pub fn module_references(json: &JsonValue) -> HashSet<String> {
|
||||
let path = [
|
||||
Tag::MODULE_DECLARATION,
|
||||
Tag::MODULE_ITEM_LIST,
|
||||
Tag::DATA_DECLARATION,
|
||||
Tag::INSTANTIATION_BASE,
|
||||
Tag::INSTANTIATION_TYPE,
|
||||
Tag::DATA_TYPE,
|
||||
Tag::UNQUALIFIED_ID,
|
||||
Tag::SYMBOL_IDENTIFIER,
|
||||
];
|
||||
HashSet::from_iter(
|
||||
Tools::match_tags(vec![json], path.to_vec())
|
||||
.into_iter()
|
||||
.map(|x| x["text"].to_string()),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn resolve_dependencies<'a>(
|
||||
json_modules: &HashMap<String, &'a JsonValue>,
|
||||
) -> HashMap<String, Rc<RefCell<ModuleContext<'a>>>> {
|
||||
let mut queue = VecDeque::new();
|
||||
let mut successors = HashMap::new();
|
||||
let mut predecessors = HashMap::new();
|
||||
let mut pred_count = HashMap::new();
|
||||
for (name, json_module) in json_modules {
|
||||
let preds = &Tools::module_references(json_module);
|
||||
|
||||
if preds.len() == 0 {
|
||||
queue.push_back(name.clone());
|
||||
} else {
|
||||
pred_count.insert(name.clone(), preds.len());
|
||||
for pred in preds {
|
||||
if !successors.contains_key(pred) {
|
||||
successors.insert(pred.clone(), Vec::new());
|
||||
}
|
||||
if let Some(successors) = successors.get_mut(pred) {
|
||||
successors.push(name.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
predecessors.insert(name.clone(), preds.clone());
|
||||
}
|
||||
info!("dep-resolver: init_queue {:?}", queue);
|
||||
info!("dep-resolver: successors {:?}", successors);
|
||||
info!("dep-resolver: predecessors {:?}", predecessors);
|
||||
info!("dep-resolver: pred_count {:?}", pred_count);
|
||||
|
||||
let modules: HashMap<String, Rc<RefCell<ModuleContext>>> =
|
||||
HashMap::from_iter(json_modules.iter().map(|(name, json)| {
|
||||
(
|
||||
name.clone(),
|
||||
Rc::new(RefCell::new(ModuleContext::new(json))),
|
||||
)
|
||||
}));
|
||||
while let Some(name) = queue.pop_front() {
|
||||
let json_module = json_modules[&name];
|
||||
let context = &mut modules[&name].borrow_mut();
|
||||
let ext_modules: Vec<_> = predecessors[&name]
|
||||
.iter()
|
||||
.map(|x| modules[x].clone())
|
||||
.collect();
|
||||
|
||||
debug!("#ext_modules = {}", ext_modules.len());
|
||||
|
||||
ModuleDeclaration::codegen_with_ext(json_module, context, ext_modules);
|
||||
|
||||
for succr in successors.get(&name).unwrap_or(&Vec::new()) {
|
||||
if let Some(count) = pred_count.get_mut(succr) {
|
||||
*count -= 1;
|
||||
if *count == 0 {
|
||||
queue.push_back(succr.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
modules
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CodeReporter {
|
||||
|
|
Loading…
Reference in New Issue