-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.rs
165 lines (145 loc) · 6.42 KB
/
main.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
extern crate tydi_lang_front_end;
extern crate chrono;
extern crate til_vhdl;
extern crate tydi_common;
extern crate til_parser;
use std::ffi::OsStr;
use std::path::Path;
use std::sync::{Arc, RwLock};
use chrono::{Datelike, Timelike};
use tydi_lang_raw_ast::project_arch::Project;
mod test_tydi;
fn source(path: impl AsRef<Path>) -> String {
std::fs::read_to_string(path).unwrap()
}
fn parse_to_output(src: impl Into<String>, dst: String) -> tydi_common::error::Result<()> {
// let db = til_parser::query::into_query_storage_default_with_output(src, dst)?;
let db = til_parser::query::into_query_storage(src)?;
til_vhdl::canonical(&db, dst)
}
pub fn tydi_compile(project_name: String, src_file_path: Vec<String>, output_path: String, worker: Option<usize>, generate_drc: bool) -> Arc<RwLock<Project>> {
let compile_result = tydi_lang_front_end::tydi_frontend_compile(Some(project_name.clone()), src_file_path, Some(output_path.clone()), worker.clone());
if compile_result.is_err() {
let (project_arch, err_msg) = compile_result.err().unwrap();
match project_arch {
Some(project_arch) => {
use tydi_lang_raw_ast::util::PrettyPrint;
std::fs::write(format!("{}/{}", output_path.clone(), "err_arch.txt"), project_arch.read().unwrap().pretty_print(0, false)).expect("error to write the err_arch.txt");
}
None => {}
}
panic!("{}", err_msg);
}
println!("generating Tydi IR - done");
let project_arch = compile_result.ok().unwrap();
//drc
if generate_drc {
let drc_msg = tydi_lang_front_end::drc::tydi_design_rule_check(project_arch.clone());
let mut drc_file_content = String::from("");
drc_file_content.push_str(&format!("drc messages: {}\n", drc_msg.len()));
for msg in drc_msg {
drc_file_content.push_str(&format!("{:?}\n", msg));
}
std::fs::write(format!("{}/{}", output_path.clone(), "drc_report.txt"), drc_file_content).expect("error to write the drc report content");
}
println!("generating Tydi DRC report - done");
//vhdl
let output_folder_path = format!("{}/{}", output_path.clone(), "4_vhdl");
let output_folder = Path::new(&output_folder_path);
if !output_folder.exists() { std::fs::create_dir(output_folder).expect("cannot create VHDl output folder"); }
let til_folder_path = format!("{}/{}", output_path.clone(), "3_til");
let til_folder = Path::new(&til_folder_path);
for til_file_result in til_folder.read_dir().expect("cannot read til folder") {
match til_file_result {
Ok(file) => {
let result = parse_to_output(source(file.path()), format!("{}", output_folder_path.clone()));
if result.is_err() { panic!("{}", result.err().unwrap().to_string()) }
}
Err(err) => {
panic!("{}", err);
}
}
}
println!("generating VHDL - done");
return project_arch;
}
fn main() {
let args: Vec<String> = std::env::args().collect();
let mut src_file_path: Vec<String> = vec![];
let mut project_name: Option<String> = None;
let mut output_path: Option<String> = None;
let mut worker: Option<usize> = None;
let mut generate_drc_report = false;
//parse args
let mut arg_index = 1; // ignore the first arg because it's the env root
while arg_index < args.len() {
let arg = &args[arg_index];
if arg == "-n" {
arg_index = arg_index + 1; // get the next input
let arg = &args[arg_index];
if project_name == None { project_name = Some(arg.clone()); }
else { panic!("project name override"); }
}
else if arg == "-o" {
arg_index = arg_index + 1; // get the next input
let arg = &args[arg_index];
if output_path == None { output_path = Some(arg.clone()); }
else { panic!("output path override"); }
}
else if arg == "-j" {
arg_index = arg_index + 1; // get the next input
let arg = &args[arg_index];
if worker == None { worker = Some(arg.parse().unwrap()); }
else { panic!("output path override"); }
}
else if arg == "-drc" {
generate_drc_report = true;
}
else {
let src_file = Path::new(arg);
if !src_file.exists() { panic!("path ({}) doesn't exist", arg); }
if src_file.is_file() {
if src_file.extension() == Some(OsStr::new("td")){
src_file_path.push(arg.clone());
}
else {
panic!("file ({}) should have extension \"td\"", arg);
}
}
if src_file.is_dir() {
let inner_srcs = src_file.read_dir();
if inner_srcs.is_err() { panic!("unable to read dir ({:?})", inner_srcs); }
let inner_srcs = inner_srcs.unwrap();
for inner_src in inner_srcs.into_iter() {
let inner_src = inner_src.unwrap().path();
if inner_src.extension() == Some(OsStr::new("td")){
src_file_path.push(inner_src.to_str().unwrap().to_string().clone());
}
}
}
}
arg_index = arg_index + 1;
}
//set default project names and output path
let real_project_name = match project_name {
None => {
let now = chrono::Local::now();
format!("project_{}_{:02}_{:02}_{:02}_{:02}_{:02}", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second())
}
Some(name) => { name }
};
let real_output_path = match output_path {
None => { format!("./{}", real_project_name.clone()) }
Some(path) => { path }
};
if src_file_path.len() == 0 { panic!("no given source file"); }
//ready for compiling
const VERSION: &'static str = env!("CARGO_PKG_VERSION");
println!("Tydi compiler version: {}", VERSION);
println!("env root path: {:?}", std::env::current_dir());
println!("project name: {}", real_project_name.clone());
println!("project output path: {}", real_output_path.clone());
println!("src files: {:?}", src_file_path.clone());
println!("worker: {:?}", worker.clone());
tydi_compile(real_project_name.clone(), src_file_path.clone(), real_output_path.clone(), worker.clone(), generate_drc_report);
}