use super::tokenize;
use super::Token;
use super::Token::*;
fn generate(tokens: &[Token]) -> String {
let mut output = String::from(include_str!("preface.c"));
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;
}
others => {
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;
}
match others {
EndLoop => {
indent -= 1;
for _ in 0..indent {
output.push('\t');
}
output.push_str("}\n");
}
Read => {
for _ in 0..indent {
output.push('\t');
}
output.push_str("*ptr = getchar();\n");
}
Write => {
for _ in 0..indent {
output.push('\t');
}
output.push_str("putchar(*ptr);\n");
}
BeginLoop => {
indent += 1;
for _ in 0..(indent - 1) {
output.push('\t');
}
output.push_str("while (*ptr) {\n");
}
_ => {}
}
}
}
}
output.push_str("}\n");
output
}
fn push_aritms(out: &mut String, aritms: isize) {
if aritms > 0 {
out.push_str(format!("*ptr += {};\n", aritms).as_str());
} else {
out.push_str(format!("*ptr -= {};\n", -aritms).as_str());
}
}
fn push_arrows(out: &mut String, arrows: isize) {
if arrows > 0 {
out.push_str(format!("ptr += {};\n", arrows).as_str());
} else {
out.push_str(format!("ptr -= {};\n", -arrows).as_str());
}
}
pub fn brains(input: &str) -> String {
let tokens = tokenize(input);
generate(&tokens)
}