123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- //#![feature(plugin)]
- //#![plugin(dynasm)]
- //#![feature(proc_macro_hygiene)]
- #[macro_use]
- extern crate dynasm;
- //extern crate winapi;
- extern crate typed_arena;
- use std::io::{self, Read};
- use std::fs::File;
- use clap::{Arg, App};
- use std::str::FromStr;
- use std::process::exit;
- pub mod options;
- pub mod ir;
- pub mod parser;
- pub mod interpret;
- pub mod optimize;
- pub mod compile;
- pub mod formatter;
- pub mod trans;
- use crate::ir::MutVisitor;
- use typed_arena::Arena;
- fn main() -> io::Result<()> {
- let matches = App::new("Zombie")
- .version("0.1.0")
- .author("Nicolas Winkler <nicolas.winkler@gmx.ch>")
- .about("Brainfuck interpreter and transpiler")
- .arg(Arg::with_name("input")
- .takes_value(true)
- .help("Input file"))
- .arg(Arg::with_name("interpret")
- .long("interpret")
- .short("i")
- .help("No JIT, run only simple interpreter"))
- .arg(Arg::with_name("transpile")
- .long("transpile")
- .short("t")
- .takes_value(true)
- .help("Transpile to language"))
- .arg(Arg::with_name("cell size")
- .long("cell-size")
- .short("c")
- .takes_value(true)
- .help("defines the cell size in bits"))
- .arg(Arg::with_name("cell modulus")
- .long("cell-modulus")
- .short("m")
- .takes_value(true)
- .help("defines the cell modulus"))
- .get_matches();
-
- let mut buffer = String::new();
- if let Some(input) = matches.value_of("input") {
- File::open(&input)?.read_to_string(&mut buffer)?;
- }
- else {
- io::stdin().read_to_string(&mut buffer)?;
- }
- let mut options = options::Options::default();
- if let Some(cell_size) = matches.value_of("cell size") {
- match options::CellSize::from_str(cell_size) {
- Ok(cs) => options.cell_size = cs,
- Err(_e) => {
- eprintln!("invalid cell size '{}'", cell_size);
- exit(1);
- }
- }
- }
- else if let Some(cell_modulus) = matches.value_of("cell modulus") {
- match u64::from_str(cell_modulus) {
- Ok(cs) => options.cell_size = options::CellSize::Modular(cs),
- Err(_e) => {
- eprintln!("invalid cell modulus '{}'", cell_modulus);
- exit(1);
- }
- }
- }
- let insts = parser::parse(&buffer);
- if let Ok(mut insts) = insts {
- let mut lin_loop_optimizer = optimize::LinOptimizer::new();
- lin_loop_optimizer.visit_instructions(&mut insts);
- let _ = std::mem::replace(&mut insts, lin_loop_optimizer.instructions);
-
- if matches.is_present("interpret") {
- interpret::run(&insts, &options);
- }
- else {
- //for ref inst in &insts {
- //println!("{}\n", inst.to_string());
- //}
- //println!("{}", trans::java::transpile(&insts));
- //let c = trans::c::transpile_dfg(&dfg);
- //println!("{}", c);
- //println!("{}", trans::java::transpile(&insts));
-
- match matches.value_of("transpile") {
- Some(lang) => {
- //let arena = Arena::new();
- //let dfg = optimize::create_dfg(&mut insts, &arena);
- let code = if lang == "c" {
- //trans::c::transpile_dfg(&dfg)
- trans::c::transpile(&options, &insts)
- } else if lang == "java" {
- trans::java::transpile(&options, &insts)
- } else if lang == "python" {
- trans::python::transpile(&options, &insts)
- } else if lang == "zombie_ir" {
- trans::zombie_ir::transpile(&insts)
- } else {
- eprintln!("invalid transpiler lang '{}'", lang);
- "".to_owned()
- };
- println!("{}", code);
- },
- None => {
- let _code = compile::compile_and_run(&insts, &options);
- }
- }
- }
- }
- else if let Err(msg) = insts {
- println!("error parsing: {}", msg);
- }
- Ok(())
- }
|