futilehdl/src/main.rs

102 lines
3.5 KiB
Rust
Raw Normal View History

2022-01-05 01:09:08 +00:00
mod builtin_cells;
mod frontend;
2022-01-23 21:52:06 +00:00
mod package;
2022-01-01 21:43:38 +00:00
mod parser;
mod rtlil;
2021-12-30 19:46:28 +00:00
2022-02-02 23:05:10 +00:00
use ariadne::Source;
2022-01-04 16:24:21 +00:00
use std::fs::File;
use std::io::prelude::*;
2022-01-04 18:09:33 +00:00
use std::path::PathBuf;
2022-02-01 01:00:27 +00:00
2022-02-01 18:46:06 +00:00
use structopt::StructOpt;
2021-12-30 19:46:28 +00:00
2022-01-04 16:24:21 +00:00
#[derive(Debug, StructOpt)]
#[structopt(name = "example", about = "An example of StructOpt usage.")]
struct Opt {
/// Input file
#[structopt(parse(from_os_str))]
input: PathBuf,
2022-01-17 23:11:37 +00:00
/// Debug AST
#[structopt(short)]
debug: bool,
/// Output file, stdout if not present
#[structopt(short, parse(from_os_str))]
output: Option<PathBuf>,
2022-01-04 16:24:21 +00:00
}
2021-12-30 19:46:28 +00:00
fn main() {
2022-01-04 16:24:21 +00:00
let opt = Opt::from_args();
2022-02-01 01:00:27 +00:00
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");
2022-01-23 21:51:39 +00:00
2022-01-04 16:24:21 +00:00
let mut input = String::new();
2022-01-04 18:09:33 +00:00
infile
.read_to_string(&mut input)
.expect("error reading file");
2022-01-04 16:24:21 +00:00
let input: &str = input.as_str();
2022-01-04 19:05:10 +00:00
let input = parser::Span::new(input);
2022-04-04 22:03:48 +00:00
let lexed = parser::tokens::lex(input).expect("failed to lex");
2022-02-02 00:00:11 +00:00
let tokens = parser::tokens::TokenSpan::new(&lexed.1);
let parsed = parser::parse(tokens);
2021-12-30 19:46:28 +00:00
match parsed {
2022-01-16 20:46:44 +00:00
Err(nom::Err::Error(err) | nom::Err::Failure(err)) => {
2022-02-01 18:46:06 +00:00
if opt.debug {
println!("{err:#?}");
}
parser::error::convert_error(input, err)
.eprint(Source::from(input.fragment()))
.unwrap();
2021-12-30 19:46:28 +00:00
}
2022-02-01 18:46:06 +00:00
Err(_) => (unreachable!()),
2022-01-01 21:43:38 +00:00
Ok(res) => {
2022-01-17 23:11:37 +00:00
if opt.debug {
println!("{:#?}", res);
}
2022-02-06 22:19:55 +00:00
let mut frontendcontext = crate::frontend::Context::new();
let typed = frontendcontext.type_module(res.1);
2022-02-23 22:36:01 +00:00
if let Ok(module) = typed {
2022-04-04 22:03:48 +00:00
let mut typed_modules = vec![];
2022-02-23 22:36:01 +00:00
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);
}
2022-04-04 22:03:48 +00:00
typed_modules.push(typed_inferred);
2022-02-21 12:04:05 +00:00
}
2022-04-04 22:03:48 +00:00
let typed_inferred = typed_modules.first().unwrap();
2022-02-23 22:36:01 +00:00
// TODO: be able to determine modules that are fully parameterized
2022-02-21 12:04:05 +00:00
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");
2022-02-20 21:44:58 +00:00
}
2022-02-21 12:04:05 +00:00
Err(err) => eprintln!("{:#?}", err),
2022-02-15 22:56:52 +00:00
}
2022-02-23 22:36:01 +00:00
} else {
eprintln!("{:#?}", typed);
2022-02-06 22:19:55 +00:00
}
2022-01-01 21:43:38 +00:00
}
2021-12-30 19:46:28 +00:00
}
}