use super::tokenize;
use super::Token;
use super::Token::*;
fn generate(tokens: &[Token]) -> String {
let mut output = String::from(include_str!("preface.lua"));
let mut indent = 1;
let mut aritms = 0;
let mut arrows = 0;
for &token in tokens {
match token {
Add => {
if arrows != 0 {
for _ in 0..indent {
output.push('\t');
}
push_arrows(&mut output, arrows);
arrows = 0;
}
aritms += 1;
}
Sub => {
if arrows != 0 {
for _ in 0..indent {
output.push('\t');
}
push_arrows(&mut output, arrows);
arrows = 0;
}
aritms -= 1;
}
Right => {
if aritms != 0 {
for _ in 0..indent {
output.push('\t');
}
push_aritms(&mut output, aritms);
aritms = 0;
}
arrows += 1;
}
Left => {
if aritms != 0 {
for _ in 0..indent {
output.push('\t');
}
push_aritms(&mut output, aritms);
aritms = 0;
}
arrows -= 1;
}
Read => {
if aritms != 0 {
for _ in 0..indent {
output.push('\t');
}
push_aritms(&mut output, aritms);
aritms = 0;
} else if arrows != 0 {
for _ in 0..indent {
output.push('\t');
}
push_arrows(&mut output, arrows);
arrows = 0;
}
for _ in 0..indent {
output.push('\t');
}
output.push_str("tape[idx] = io.read(1)\n");
}
Write => {
if aritms != 0 {
for _ in 0..indent {
output.push('\t');
}
push_aritms(&mut output, aritms);
aritms = 0;
} else if arrows != 0 {
for _ in 0..indent {
output.push('\t');
}
push_arrows(&mut output, arrows);
arrows = 0;
}
for _ in 0..indent {
output.push('\t');
}
output.push_str("print(tape[idx])\n");
}
BeginLoop => {
if aritms != 0 {
for _ in 0..indent {
output.push('\t');
}
push_aritms(&mut output, aritms);
aritms = 0;
} else if arrows != 0 {
for _ in 0..indent {
output.push('\t');
}
push_arrows(&mut output, arrows);
arrows = 0;
}
indent += 1;
for _ in 0..(indent - 1) {
output.push('\t');
}
output.push_str("while tape[idx] do\n");
}
EndLoop => {
if aritms != 0 {
for _ in 0..indent {
output.push('\t');
}
push_aritms(&mut output, aritms);
aritms = 0;
} else if arrows != 0 {
for _ in 0..indent {
output.push('\t');
}
push_arrows(&mut output, arrows);
arrows = 0;
}
indent -= 1;
for _ in 0..indent {
output.push('\t');
}
output.push_str("end\n");
}
}
}
output
}
fn push_aritms(out: &mut String, aritms: isize) {
if aritms > 0 {
out.push_str(format!("tape[idx] = tape[idx] + {}\n", aritms).as_str());
} else {
out.push_str(format!("tape[idx] = tape[idx] - {}\n", -aritms).as_str());
}
}
fn push_arrows(out: &mut String, arrows: isize) {
if arrows > 0 {
out.push_str(format!("idx = idx + {};\n", arrows).as_str());
} else {
out.push_str(format!("idx = idx - {};\n", -arrows).as_str());
}
}
pub fn brains(input: &str) -> String {
let tokens = tokenize(input);
generate(&tokens)
}