Extract non-expanding instructions to to_bf
This commit is contained in:
+129
-123
@@ -66,6 +66,132 @@ fn parse_constant(text: &str) -> Result<i32, std::num::ParseIntError> {
|
||||
}
|
||||
}
|
||||
|
||||
fn to_bf(rule: Rule, operand: &str, state: &mut State, out: &mut Builder) {
|
||||
match rule {
|
||||
Rule::var => {
|
||||
let variable_name = operand;
|
||||
println!("Creation of variable '{}'", variable_name);
|
||||
if let Some(_v) = state.variables.insert(
|
||||
String::from(variable_name),
|
||||
MemCell::allocate(state.alloc_cnt),
|
||||
) {
|
||||
panic!("Variable {} already exists", variable_name);
|
||||
}
|
||||
state.alloc_cnt += 1;
|
||||
}
|
||||
Rule::delvar => {
|
||||
let variable_name = operand;
|
||||
println!("Deletion of variable '{}'", variable_name);
|
||||
if let None = state.variables.remove(&String::from(variable_name)) {
|
||||
panic!("Variable '{}' did not exists", variable_name);
|
||||
}
|
||||
}
|
||||
Rule::point => {
|
||||
let variable_name = operand;
|
||||
println!("Pointing to variable '{}'", variable_name);
|
||||
let address = state
|
||||
.variables
|
||||
.get(variable_name)
|
||||
.unwrap_or_else(|| panic!("Variable '{}' did not exists", variable_name))
|
||||
.address;
|
||||
if address < state.mem_pointer {
|
||||
out.append("<".repeat((state.mem_pointer - address) as usize))
|
||||
} else if address > state.mem_pointer {
|
||||
out.append(">".repeat((address - state.mem_pointer) as usize))
|
||||
}
|
||||
state.mem_pointer = address;
|
||||
}
|
||||
Rule::pointm => {
|
||||
let variable_name = operand;
|
||||
println!("Pointing back to marker variable {}", variable_name);
|
||||
let address = state
|
||||
.variables
|
||||
.get(variable_name)
|
||||
.unwrap_or_else(|| panic!("Marker variable '{}' did not exists", variable_name))
|
||||
.address;
|
||||
// thank you mixtela
|
||||
out.append("<+[-<+]-");
|
||||
state.mem_pointer = address;
|
||||
}
|
||||
Rule::add => {
|
||||
let constant = operand;
|
||||
let constant_parsed = parse_constant(constant).unwrap();
|
||||
println!(
|
||||
"Addition of '{}', decimal value is {}",
|
||||
constant, constant_parsed
|
||||
);
|
||||
out.append("+".repeat(constant_parsed as usize));
|
||||
}
|
||||
Rule::addb => {
|
||||
let constant = operand;
|
||||
let constant_parsed = parse_constant(constant).unwrap();
|
||||
println!(
|
||||
"Big Addition of '{}', decimal value is {}",
|
||||
constant, constant_parsed
|
||||
);
|
||||
out.append("addb\n");
|
||||
}
|
||||
Rule::addv => {
|
||||
let variable_name = operand;
|
||||
println!("Addition to variable '{}'", variable_name);
|
||||
out.append("addv\n");
|
||||
}
|
||||
Rule::sub => {
|
||||
let constant = operand;
|
||||
let constant_parsed = parse_constant(constant).unwrap();
|
||||
println!(
|
||||
"Subtraction of '{}', decimal value is {}",
|
||||
constant, constant_parsed
|
||||
);
|
||||
out.append("-".repeat(constant_parsed as usize));
|
||||
}
|
||||
Rule::subb => {
|
||||
let constant = operand;
|
||||
let constant_parsed = parse_constant(constant).unwrap();
|
||||
println!(
|
||||
"Big Subtraction of '{}', decimal value is {}",
|
||||
constant, constant_parsed
|
||||
);
|
||||
out.append("subb\n");
|
||||
}
|
||||
Rule::subv => {
|
||||
let variable_name = operand;
|
||||
println!("Subtraction from variable '{}'", variable_name);
|
||||
out.append("subv\n");
|
||||
}
|
||||
Rule::copy => {
|
||||
let variable_name = operand;
|
||||
println!("Copy to variable '{}'", variable_name);
|
||||
out.append("copy\n");
|
||||
}
|
||||
Rule::setz => {
|
||||
println!("Set current variable to zero");
|
||||
out.append("[-]");
|
||||
}
|
||||
Rule::getchr => {
|
||||
println!("Reading char from user input into current variable");
|
||||
out.append(",");
|
||||
}
|
||||
Rule::print => {
|
||||
println!("Printing current variable");
|
||||
out.append(".");
|
||||
}
|
||||
Rule::loopBlockStart => {
|
||||
println!("Start of loopBlock");
|
||||
out.append("[");
|
||||
}
|
||||
Rule::loopBlockEnd => {
|
||||
println!("End of loopBlock");
|
||||
out.append("]");
|
||||
}
|
||||
Rule::EOI => {
|
||||
println!("End of Input");
|
||||
out.append("\n");
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn instruct(statement: Pair<Rule>, state: &mut State, out: &mut Builder) {
|
||||
match statement.as_rule() {
|
||||
Rule::include => {
|
||||
@@ -83,132 +209,12 @@ fn instruct(statement: Pair<Rule>, state: &mut State, out: &mut Builder) {
|
||||
instruct(statement, state, out);
|
||||
}
|
||||
}
|
||||
Rule::var => {
|
||||
let variable_name = extract_operand(statement);
|
||||
println!("Creation of variable '{}'", variable_name);
|
||||
if let Some(_v) = state.variables.insert(
|
||||
String::from(variable_name),
|
||||
MemCell::allocate(state.alloc_cnt),
|
||||
) {
|
||||
panic!("Variable {} already exists", variable_name);
|
||||
}
|
||||
state.alloc_cnt += 1;
|
||||
}
|
||||
Rule::delvar => {
|
||||
let variable_name = extract_operand(statement);
|
||||
println!("Deletion of variable '{}'", variable_name);
|
||||
if let None = state.variables.remove(&String::from(variable_name)) {
|
||||
panic!("Variable '{}' did not exists", variable_name);
|
||||
}
|
||||
}
|
||||
Rule::point => {
|
||||
let variable_name = extract_operand(statement);
|
||||
println!("Pointing to variable '{}'", variable_name);
|
||||
let address = state
|
||||
.variables
|
||||
.get(variable_name)
|
||||
.unwrap_or_else(|| panic!("Variable '{}' did not exists", variable_name))
|
||||
.address;
|
||||
if address < state.mem_pointer {
|
||||
out.append("<".repeat((state.mem_pointer - address) as usize))
|
||||
} else if address > state.mem_pointer {
|
||||
out.append(">".repeat((address - state.mem_pointer) as usize))
|
||||
}
|
||||
state.mem_pointer = address;
|
||||
}
|
||||
Rule::pointm => {
|
||||
let variable_name = extract_operand(statement);
|
||||
println!("Pointing back to marker variable {}", variable_name);
|
||||
let address = state
|
||||
.variables
|
||||
.get(variable_name)
|
||||
.unwrap_or_else(|| panic!("Marker variable '{}' did not exists", variable_name))
|
||||
.address;
|
||||
// thank you mixtela
|
||||
out.append("<+[-<+]-");
|
||||
state.mem_pointer = address;
|
||||
}
|
||||
Rule::add => {
|
||||
let constant = extract_operand(statement);
|
||||
let constant_parsed = parse_constant(constant).unwrap();
|
||||
println!(
|
||||
"Addition of '{}', decimal value is {}",
|
||||
constant, constant_parsed
|
||||
);
|
||||
out.append("+".repeat(constant_parsed as usize));
|
||||
}
|
||||
Rule::addb => {
|
||||
let constant = extract_operand(statement);
|
||||
let constant_parsed = parse_constant(constant).unwrap();
|
||||
println!(
|
||||
"Big Addition of '{}', decimal value is {}",
|
||||
constant, constant_parsed
|
||||
);
|
||||
out.append("addb\n");
|
||||
}
|
||||
Rule::addv => {
|
||||
let variable_name = extract_operand(statement);
|
||||
println!("Addition to variable '{}'", variable_name);
|
||||
out.append("addv\n");
|
||||
}
|
||||
Rule::sub => {
|
||||
let constant = extract_operand(statement);
|
||||
let constant_parsed = parse_constant(constant).unwrap();
|
||||
println!(
|
||||
"Subtraction of '{}', decimal value is {}",
|
||||
constant, constant_parsed
|
||||
);
|
||||
out.append("-".repeat(constant_parsed as usize));
|
||||
}
|
||||
Rule::subb => {
|
||||
let constant = extract_operand(statement);
|
||||
let constant_parsed = parse_constant(constant).unwrap();
|
||||
println!(
|
||||
"Big Subtraction of '{}', decimal value is {}",
|
||||
constant, constant_parsed
|
||||
);
|
||||
out.append("subb\n");
|
||||
}
|
||||
Rule::subv => {
|
||||
let variable_name = extract_operand(statement);
|
||||
println!("Subtraction from variable '{}'", variable_name);
|
||||
out.append("subv\n");
|
||||
}
|
||||
Rule::copy => {
|
||||
let variable_name = extract_operand(statement);
|
||||
println!("Copy to variable '{}'", variable_name);
|
||||
out.append("copy\n");
|
||||
}
|
||||
Rule::setz => {
|
||||
println!("Set current variable to zero");
|
||||
out.append("[-]");
|
||||
}
|
||||
Rule::getchr => {
|
||||
println!("Reading char from user input into current variable");
|
||||
out.append(",");
|
||||
}
|
||||
Rule::print => {
|
||||
println!("Printing current variable");
|
||||
out.append(".");
|
||||
}
|
||||
Rule::loopBlock => {
|
||||
for nested_statement in statement.into_inner() {
|
||||
instruct(nested_statement, state, out);
|
||||
}
|
||||
}
|
||||
Rule::loopBlockStart => {
|
||||
println!("Start of loopBlock");
|
||||
out.append("[");
|
||||
}
|
||||
Rule::loopBlockEnd => {
|
||||
println!("End of loopBlock");
|
||||
out.append("]");
|
||||
}
|
||||
Rule::EOI => {
|
||||
println!("End of Input");
|
||||
out.append("\n");
|
||||
}
|
||||
_ => unreachable!(),
|
||||
_ => to_bf(statement.as_rule(), extract_operand(statement), state, out),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,8 +236,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
mem_pointer: 0,
|
||||
variables: HashMap::new(),
|
||||
};
|
||||
for statement in parsed_file.into_inner() {
|
||||
instruct(statement, &mut state, &mut builder);
|
||||
for stmt in parsed_file.into_inner() {
|
||||
instruct(stmt, &mut state, &mut builder);
|
||||
}
|
||||
|
||||
let bf = builder.string().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user