main.rs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. //#![feature(plugin)]
  2. //#![plugin(dynasm)]
  3. //#![feature(proc_macro_hygiene)]
  4. #[macro_use]
  5. extern crate dynasm;
  6. //extern crate winapi;
  7. extern crate typed_arena;
  8. use std::io::{self, Read};
  9. use std::fs::File;
  10. use clap::{Arg, App};
  11. use std::str::FromStr;
  12. use std::process::exit;
  13. pub mod options;
  14. pub mod ir;
  15. pub mod parser;
  16. pub mod interpret;
  17. pub mod optimize;
  18. pub mod compile;
  19. pub mod formatter;
  20. pub mod trans;
  21. use crate::ir::MutVisitor;
  22. use typed_arena::Arena;
  23. fn main() -> io::Result<()> {
  24. let matches = App::new("Zombie")
  25. .version("0.1.0")
  26. .author("Nicolas Winkler <nicolas.winkler@gmx.ch>")
  27. .about("Brainfuck interpreter and transpiler")
  28. .arg(Arg::with_name("input")
  29. .takes_value(true)
  30. .help("Input file"))
  31. .arg(Arg::with_name("interpret")
  32. .long("interpret")
  33. .short("i")
  34. .help("No JIT, run only simple interpreter"))
  35. .arg(Arg::with_name("transpile")
  36. .long("transpile")
  37. .short("t")
  38. .takes_value(true)
  39. .help("Transpile to language"))
  40. .arg(Arg::with_name("cell size")
  41. .long("cell-size")
  42. .short("c")
  43. .takes_value(true)
  44. .help("defines the cell size in bits"))
  45. .arg(Arg::with_name("cell modulus")
  46. .long("cell-modulus")
  47. .short("m")
  48. .takes_value(true)
  49. .help("defines the cell modulus"))
  50. .get_matches();
  51. let mut buffer = String::new();
  52. if let Some(input) = matches.value_of("input") {
  53. File::open(&input)?.read_to_string(&mut buffer)?;
  54. }
  55. else {
  56. io::stdin().read_to_string(&mut buffer)?;
  57. }
  58. let mut options = options::Options::default();
  59. if let Some(cell_size) = matches.value_of("cell size") {
  60. match options::CellSize::from_str(cell_size) {
  61. Ok(cs) => options.cell_size = cs,
  62. Err(_e) => {
  63. eprintln!("invalid cell size '{}'", cell_size);
  64. exit(1);
  65. }
  66. }
  67. }
  68. else if let Some(cell_modulus) = matches.value_of("cell modulus") {
  69. match u64::from_str(cell_modulus) {
  70. Ok(cs) => options.cell_size = options::CellSize::Modular(cs),
  71. Err(_e) => {
  72. eprintln!("invalid cell modulus '{}'", cell_modulus);
  73. exit(1);
  74. }
  75. }
  76. }
  77. let insts = parser::parse(&buffer);
  78. if let Ok(mut insts) = insts {
  79. let mut lin_loop_optimizer = optimize::LinOptimizer::new();
  80. lin_loop_optimizer.visit_instructions(&mut insts);
  81. let _ = std::mem::replace(&mut insts, lin_loop_optimizer.instructions);
  82. if matches.is_present("interpret") {
  83. interpret::run(&insts, &options);
  84. }
  85. else {
  86. //for ref inst in &insts {
  87. //println!("{}\n", inst.to_string());
  88. //}
  89. //println!("{}", trans::java::transpile(&insts));
  90. //let c = trans::c::transpile_dfg(&dfg);
  91. //println!("{}", c);
  92. //println!("{}", trans::java::transpile(&insts));
  93. match matches.value_of("transpile") {
  94. Some(lang) => {
  95. //let arena = Arena::new();
  96. //let dfg = optimize::create_dfg(&mut insts, &arena);
  97. let code = if lang == "c" {
  98. //trans::c::transpile_dfg(&dfg)
  99. trans::c::transpile(&options, &insts)
  100. } else if lang == "java" {
  101. trans::java::transpile(&options, &insts)
  102. } else if lang == "python" {
  103. trans::python::transpile(&options, &insts)
  104. } else if lang == "zombie_ir" {
  105. trans::zombie_ir::transpile(&insts)
  106. } else {
  107. eprintln!("invalid transpiler lang '{}'", lang);
  108. "".to_owned()
  109. };
  110. println!("{}", code);
  111. },
  112. None => {
  113. let _code = compile::compile_and_run(&insts, &options);
  114. }
  115. }
  116. }
  117. }
  118. else if let Err(msg) = insts {
  119. println!("error parsing: {}", msg);
  120. }
  121. Ok(())
  122. }