|
@@ -1,35 +1,45 @@
|
|
-use super::super::{ir, formatter};
|
|
|
|
|
|
+use super::super::{ir, formatter, options};
|
|
|
|
+use super::hex_bitmask;
|
|
|
|
|
|
use ir::Instruction;
|
|
use ir::Instruction;
|
|
use formatter::Formatter;
|
|
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 mut formatter = Formatter::new();
|
|
|
|
|
|
formatter.add_line("import sys");
|
|
formatter.add_line("import sys");
|
|
formatter.add_line("mem = [0] * 0x10000");
|
|
formatter.add_line("mem = [0] * 0x10000");
|
|
formatter.add_line("ptr = 0");
|
|
formatter.add_line("ptr = 0");
|
|
|
|
|
|
- generate(&mut formatter, instrs);
|
|
|
|
|
|
+ generate(&mut formatter, instrs, opts);
|
|
|
|
|
|
formatter.get_code()
|
|
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 {
|
|
for instr in instrs {
|
|
match instr {
|
|
match instr {
|
|
Instruction::Nop => {},
|
|
Instruction::Nop => {},
|
|
Instruction::Add{ offset, value } => {
|
|
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 } => {
|
|
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 } => {
|
|
Instruction::LinearLoop{ offset, factors } => {
|
|
for (off, factor) in 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));
|
|
formatter.add_line(&format!("mem[(ptr + {}) & 0xFFFF] = 0", offset));
|
|
},
|
|
},
|
|
@@ -39,7 +49,7 @@ fn generate(formatter: &mut Formatter, instrs: &Vec<Instruction>) {
|
|
Instruction::Loop(instructions) => {
|
|
Instruction::Loop(instructions) => {
|
|
formatter.add_line("while mem[ptr & 0xFFFF] != 0:");
|
|
formatter.add_line("while mem[ptr & 0xFFFF] != 0:");
|
|
formatter.indent();
|
|
formatter.indent();
|
|
- generate(formatter, instructions);
|
|
|
|
|
|
+ generate(formatter, instructions, opts);
|
|
formatter.unindent();
|
|
formatter.unindent();
|
|
},
|
|
},
|
|
Instruction::Read(offset) => {
|
|
Instruction::Read(offset) => {
|