Nicolas Winkler 4 лет назад
Родитель
Сommit
e5b16f2db8
7 измененных файлов с 70 добавлено и 33 удалено
  1. 4 4
      src/interpret.rs
  2. 2 2
      src/main.rs
  3. 15 11
      src/options.rs
  4. 4 4
      src/trans/c.rs
  5. 13 3
      src/trans/java.rs
  6. 13 0
      src/trans/mod.rs
  7. 19 9
      src/trans/python.rs

+ 4 - 4
src/interpret.rs

@@ -3,14 +3,14 @@ use std::io::Read;
 use std::io::Write;
 use std::io;
 
-struct Data {
-    memory: Vec<u8>,
+struct Data<T> {
+    memory: Vec<T>,
     ptr: i64,
 }
 
 pub fn run(instructions: &Vec<Instruction>) {
     let len = 1024;
-    let mut data = Data {
+    let mut data = Data<u8> {
         memory: vec![0; len],
         ptr: 0,
     };
@@ -18,7 +18,7 @@ pub fn run(instructions: &Vec<Instruction>) {
     run_instrs(instructions, &mut data);
 }
 
-fn run_instrs(instructions: &Vec<Instruction>, data: &mut Data) {
+fn run_instrs<T>(instructions: &Vec<Instruction>, data: &mut Data<T>) {
     let len = data.memory.len();
     for inst in instructions {
         match inst {

+ 2 - 2
src/main.rs

@@ -88,9 +88,9 @@ fn main() -> io::Result<()> {
                     //trans::c::transpile_dfg(&dfg)
                     trans::c::transpile(&options, &insts)
                 } else if lang == "java" {
-                    trans::java::transpile(&insts)
+                    trans::java::transpile(&options, &insts)
                 } else if lang == "python" {
-                    trans::python::transpile(&insts)
+                    trans::python::transpile(&options, &insts)
                 } else if lang == "zombie_ir" {
                     trans::zombie_ir::transpile(&insts)
                 } else {

+ 15 - 11
src/options.rs

@@ -2,14 +2,14 @@ use std::str::FromStr;
 
 pub enum CellLayout {
     Trusting,
-    Wrapping
+    Wrapping,
+    Unbounded
 }
 
 
 pub enum CellSize {
-    Int8,
-    Int16,
-    Int32,
+    Bits(usize),
+    Modular(usize),
     Int
 }
 
@@ -26,7 +26,7 @@ impl Default for Options {
         Options {
             cell_layout: CellLayout::Trusting,
             memory_size: 0x10000,
-            cell_size: CellSize::Int8,
+            cell_size: CellSize::Bits(8),
         }
     }
 }
@@ -47,12 +47,16 @@ impl FromStr for CellSize {
     type Err = &'static str;
 
     fn from_str(s: &str) -> Result<Self, Self::Err> {
-        match s {
-            "8" => Ok(CellSize::Int8),
-            "16" => Ok(CellSize::Int16),
-            "32" => Ok(CellSize::Int32),
-            "int" => Ok(CellSize::Int),
-            _ => Err("invalid cell size"),
+        let integer = s.parse::<usize>();
+        match integer {
+            Ok(i) => Ok(CellSize::Bits(i)),
+            Err(e) => match s {
+                "8" => Ok(CellSize::Bits(8)),
+                "16" => Ok(CellSize::Bits(16)),
+                "32" => Ok(CellSize::Bits(16)),
+                "int" => Ok(CellSize::Int),
+                _ => Err("invalid cell size"),
+            }
         }
     }
 }

+ 4 - 4
src/trans/c.rs

@@ -107,10 +107,10 @@ impl CTranspiler {
         let mut transpiler = CTranspiler{ code_buf: Formatter::new() };
 
         let cell_type = match opts.cell_size {
-            CellSize::Int8 => "uint8_t",
-            CellSize::Int16 => "uint16_t",
-            CellSize::Int32 => "uint32_t",
-            CellSize::Int => "uint64_t"
+            CellSize::Bits(8) => "uint8_t",
+            CellSize::Bits(16) => "uint16_t",
+            CellSize::Bits(32) => "uint32_t",
+            _ => "uint64_t"
         };
 
 

+ 13 - 3
src/trans/java.rs

@@ -1,16 +1,26 @@
-use super::super::{ir, formatter};
+use super::super::{ir, formatter, options};
 
 use ir::Instruction;
 use formatter::Formatter;
+use options::*;
 
-pub fn transpile(instrs: &Vec<ir::Instruction>) -> String {
+pub fn transpile(opts: &Options, instrs: &Vec<ir::Instruction>) -> String {
     let mut formatter = Formatter::new();
 
+
+    let cell_type = match opts.cell_size {
+        CellSize::Bits(8) => "byte",
+        CellSize::Bits(16) => "short",
+        CellSize::Bits(32) => "int",
+        CellSize::Int => "long",
+        _ => "long"
+    };
+
     formatter.add_line("class Brainfuck {");
     formatter.indent();
     formatter.add_line("public static void main(String[] args) {");
     formatter.indent();
-    formatter.add_line("byte[] mem = new byte[0x10000];");
+    formatter.add_line(&format!("{ct}[] mem = new {ct}[0x10000];", ct = cell_type));
     formatter.add_line("int ptr = 0;");
     formatter.add_line("");
 

+ 13 - 0
src/trans/mod.rs

@@ -6,3 +6,16 @@ pub mod java;
 pub mod python;
 pub mod zombie_ir;
 
+
+
+fn hex_bitmask(bits: usize) -> String {
+    let fs = bits / 4;
+    let leftover = bits % 4;
+
+    match leftover {
+        1 => "1",
+        2 => "3",
+        3 => "7",
+        _ => ""
+    }.to_owned() + &"F".repeat(fs)
+}

+ 19 - 9
src/trans/python.rs

@@ -1,35 +1,45 @@
-use super::super::{ir, formatter};
+use super::super::{ir, formatter, options};
+use super::hex_bitmask;
 
 use ir::Instruction;
 use formatter::Formatter;
+use options::*;
 
-pub fn transpile(instrs: &Vec<ir::Instruction>) -> String {
+pub fn transpile(opts: &Options, instrs: &Vec<ir::Instruction>) -> String {
     let mut formatter = Formatter::new();
 
     formatter.add_line("import sys");
     formatter.add_line("mem = [0] * 0x10000");
     formatter.add_line("ptr = 0");
 
-    generate(&mut formatter, instrs);
+    generate(&mut formatter, instrs, opts);
 
     formatter.get_code()
 }
 
 
-fn generate(formatter: &mut Formatter, instrs: &Vec<Instruction>) {
+fn generate(formatter: &mut Formatter, instrs: &Vec<Instruction>, opts: &Options) {
+
+    let cell_mask = match opts.cell_size {
+        CellSize::Bits(n) => {
+            "0x".to_owned() + &hex_bitmask(n)
+        },
+        CellSize::Modular(n) => n.to_string(),
+        CellSize::Int => "-1".to_owned()
+    };
     for instr in instrs {
         match instr {
             Instruction::Nop => {},
             Instruction::Add{ offset, value } => {
-                formatter.add_line(&format!("mem[(ptr + {}) & 0xFFFF] = (mem[(ptr + {}) & 0xFFFF] + {}) & 0xFF", offset, offset, value));
+                formatter.add_line(&format!("mem[(ptr + {}) & 0xFFFF] = (mem[(ptr + {}) & 0xFFFF] + {}) & {}", offset, offset, value, cell_mask));
             },
             Instruction::Set{ offset, value } => {
-                formatter.add_line(&format!("mem[(ptr + {}) & 0xFFFF] = {}", offset, value));
+                formatter.add_line(&format!("mem[(ptr + {}) & 0xFFFF] = {} & {}", offset, value, cell_mask));
             },
             Instruction::LinearLoop{ offset, factors } => {
                 for (off, factor) in factors {
-                    formatter.add_line(&format!("mem[(ptr + {}) & 0xFFFF] = (mem[(ptr + {}) & 0xFFFF] + {} * mem[(ptr + {}) & 0xFFFF]) & 0xFF",
-                                                offset + off, offset + off, factor, offset));
+                    formatter.add_line(&format!("mem[(ptr + {}) & 0xFFFF] = (mem[(ptr + {}) & 0xFFFF] + {} * mem[(ptr + {}) & 0xFFFF]) & {}",
+                                                offset + off, offset + off, factor, offset, cell_mask));
                 }
                 formatter.add_line(&format!("mem[(ptr + {}) & 0xFFFF] = 0", offset));
             },
@@ -39,7 +49,7 @@ fn generate(formatter: &mut Formatter, instrs: &Vec<Instruction>) {
             Instruction::Loop(instructions) => {
                 formatter.add_line("while mem[ptr & 0xFFFF] != 0:");
                 formatter.indent();
-                generate(formatter, instructions);
+                generate(formatter, instructions, opts);
                 formatter.unindent();
             },
             Instruction::Read(offset) => {