mod builtin_cells; mod frontend; mod package; mod parser; mod rtlil; use ariadne::Source; use std::fs::File; use std::io::prelude::*; use std::path::PathBuf; use structopt::StructOpt; #[derive(Debug, StructOpt)] #[structopt(name = "example", about = "An example of StructOpt usage.")] struct Opt { /// Input file #[structopt(parse(from_os_str))] input: PathBuf, /// Debug AST #[structopt(short)] debug: bool, /// Output file, stdout if not present #[structopt(short, parse(from_os_str))] output: Option, } fn main() { let opt = Opt::from_args(); let mut infile = File::open(opt.input).expect("could not open file"); // let packages = package::PackageRegistry::new(); // let mut infile = packages // .get("builtins") // .expect("no package") // .open() // .expect("could not open file"); let mut input = String::new(); infile .read_to_string(&mut input) .expect("error reading file"); let input: &str = input.as_str(); let input = parser::Span::new(input); let lexed = parser::tokens::lex(input).expect("failed to lex"); let tokens = parser::tokens::TokenSpan::new(&lexed.1); let parsed = parser::parse(tokens); match parsed { Err(nom::Err::Error(err) | nom::Err::Failure(err)) => { if opt.debug { println!("{err:#?}"); } parser::error::convert_error(input, err) .eprint(Source::from(input.fragment())) .unwrap(); } Err(_) => (unreachable!()), Ok(res) => { if opt.debug { println!("{:#?}", res); } let mut frontendcontext = crate::frontend::Context::new(); let typed = frontendcontext.type_module(res.1); if let Ok(module) = typed { let mut typed_modules = vec![]; for block in module.blocks { if opt.debug { let mut pretty_block = String::new(); frontendcontext .pretty_typed_block(&mut pretty_block, &block) .unwrap(); println!("{}", &pretty_block); } let typed_inferred = frontendcontext.infer_types(block); if opt.debug { let mut pretty_block = String::new(); frontendcontext .pretty_typed_block(&mut pretty_block, &typed_inferred) .unwrap(); println!("{}", &pretty_block); } typed_modules.push(typed_inferred); } let typed_inferred = typed_modules.first().unwrap(); // TODO: be able to determine modules that are fully parameterized let lowered = frontend::lowering::lower_block(&mut frontendcontext, typed_inferred); match lowered { Ok(res) => { let mut file = File::create(opt.output.unwrap_or_else(|| "out.rtlil".into())) .expect("could not open file"); file.write_all(res.as_bytes()) .expect("failed to write output file"); } Err(err) => eprintln!("{:#?}", err), } } else { eprintln!("{:#?}", typed); } } } }