소스 검색

adding python transpilation support

Nicolas Winkler 4 년 전
부모
커밋
a2e1fdd5e3
3개의 변경된 파일57개의 추가작업 그리고 0개의 파일을 삭제
  1. 2 0
      src/main.rs
  2. 1 0
      src/trans/mod.rs
  3. 54 0
      src/trans/python.rs

+ 2 - 0
src/main.rs

@@ -70,6 +70,8 @@ fn main() -> io::Result<()> {
                     trans::c::transpile(&insts)
                 } else if lang == "java" {
                     trans::java::transpile(&insts)
+                } else if lang == "python" {
+                    trans::python::transpile(&insts)
                 } else if lang == "zombie_ir" {
                     trans::zombie_ir::transpile(&insts)
                 } else {

+ 1 - 0
src/trans/mod.rs

@@ -3,5 +3,6 @@
 
 pub mod c;
 pub mod java;
+pub mod python;
 pub mod zombie_ir;
 

+ 54 - 0
src/trans/python.rs

@@ -0,0 +1,54 @@
+use super::super::{ir, formatter};
+
+use ir::Instruction;
+use formatter::Formatter;
+
+pub fn transpile(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);
+
+    formatter.get_code()
+}
+
+
+fn generate(formatter: &mut Formatter, instrs: &Vec<Instruction>) {
+    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));
+            },
+            Instruction::Set{ offset, value } => {
+                formatter.add_line(&format!("mem[(ptr + {}) & 0xFFFF] = {}", offset, value));
+            },
+            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] = 0", offset));
+            },
+            Instruction::MovePtr(offset) => {
+                formatter.add_line(&format!("ptr += {}", offset));
+            },
+            Instruction::Loop(instructions) => {
+                formatter.add_line("while mem[ptr & 0xFFFF] != 0:");
+                formatter.indent();
+                generate(formatter, instructions);
+                formatter.unindent();
+            },
+            Instruction::Read(offset) => {
+                formatter.add_line(&format!("mem[(ptr + {}) & 0xFFFF] = sys.stdin.buffer.read(1)", offset));
+            },
+            Instruction::Write(offset) => {
+                formatter.add_line(&format!("sys.stdout.buffer.write(mem[(ptr + {}) & 0xFFFF].to_bytes(1, 'little'))", offset));
+                formatter.add_line("sys.stdout.buffer.flush()");
+            }
+        }
+    }
+}