|
|
|
@ -66,25 +66,10 @@ fn parse_constant(text: &str) -> Result<i32, std::num::ParseIntError> { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn instruct(statement: Pair<Rule>, state: &mut State, out: &mut Builder) { |
|
|
|
|
match statement.as_rule() { |
|
|
|
|
Rule::include => { |
|
|
|
|
let file_path_raw = extract_operand(statement); |
|
|
|
|
let file_path = &file_path_raw[1..file_path_raw.len() - 1]; |
|
|
|
|
println!("Including {} into this src file", file_path); |
|
|
|
|
let content = std::fs::read_to_string(&file_path) |
|
|
|
|
.with_context(|| format!("could not read source file {:?}", file_path)) |
|
|
|
|
.unwrap(); |
|
|
|
|
let parsed_file = MblfParser::parse(Rule::file, &content) |
|
|
|
|
.expect("Parse Error") |
|
|
|
|
.next() |
|
|
|
|
.unwrap(); |
|
|
|
|
for statement in parsed_file.into_inner() { |
|
|
|
|
instruct(statement, state, out); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
fn to_bf(rule: Rule, operand: &str, state: &mut State, out: &mut Builder) { |
|
|
|
|
match rule { |
|
|
|
|
Rule::var => { |
|
|
|
|
let variable_name = extract_operand(statement); |
|
|
|
|
let variable_name = operand; |
|
|
|
|
println!("Creation of variable '{}'", variable_name); |
|
|
|
|
if let Some(_v) = state.variables.insert( |
|
|
|
|
String::from(variable_name), |
|
|
|
@ -95,14 +80,14 @@ fn instruct(statement: Pair<Rule>, state: &mut State, out: &mut Builder) { |
|
|
|
|
state.alloc_cnt += 1; |
|
|
|
|
} |
|
|
|
|
Rule::delvar => { |
|
|
|
|
let variable_name = extract_operand(statement); |
|
|
|
|
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 = extract_operand(statement); |
|
|
|
|
let variable_name = operand; |
|
|
|
|
println!("Pointing to variable '{}'", variable_name); |
|
|
|
|
let address = state |
|
|
|
|
.variables |
|
|
|
@ -117,7 +102,7 @@ fn instruct(statement: Pair<Rule>, state: &mut State, out: &mut Builder) { |
|
|
|
|
state.mem_pointer = address; |
|
|
|
|
} |
|
|
|
|
Rule::pointm => { |
|
|
|
|
let variable_name = extract_operand(statement); |
|
|
|
|
let variable_name = operand; |
|
|
|
|
println!("Pointing back to marker variable {}", variable_name); |
|
|
|
|
let address = state |
|
|
|
|
.variables |
|
|
|
@ -129,7 +114,7 @@ fn instruct(statement: Pair<Rule>, state: &mut State, out: &mut Builder) { |
|
|
|
|
state.mem_pointer = address; |
|
|
|
|
} |
|
|
|
|
Rule::add => { |
|
|
|
|
let constant = extract_operand(statement); |
|
|
|
|
let constant = operand; |
|
|
|
|
let constant_parsed = parse_constant(constant).unwrap(); |
|
|
|
|
println!( |
|
|
|
|
"Addition of '{}', decimal value is {}", |
|
|
|
@ -138,7 +123,7 @@ fn instruct(statement: Pair<Rule>, state: &mut State, out: &mut Builder) { |
|
|
|
|
out.append("+".repeat(constant_parsed as usize)); |
|
|
|
|
} |
|
|
|
|
Rule::addb => { |
|
|
|
|
let constant = extract_operand(statement); |
|
|
|
|
let constant = operand; |
|
|
|
|
let constant_parsed = parse_constant(constant).unwrap(); |
|
|
|
|
println!( |
|
|
|
|
"Big Addition of '{}', decimal value is {}", |
|
|
|
@ -147,12 +132,12 @@ fn instruct(statement: Pair<Rule>, state: &mut State, out: &mut Builder) { |
|
|
|
|
out.append("addb\n"); |
|
|
|
|
} |
|
|
|
|
Rule::addv => { |
|
|
|
|
let variable_name = extract_operand(statement); |
|
|
|
|
let variable_name = operand; |
|
|
|
|
println!("Addition to variable '{}'", variable_name); |
|
|
|
|
out.append("addv\n"); |
|
|
|
|
} |
|
|
|
|
Rule::sub => { |
|
|
|
|
let constant = extract_operand(statement); |
|
|
|
|
let constant = operand; |
|
|
|
|
let constant_parsed = parse_constant(constant).unwrap(); |
|
|
|
|
println!( |
|
|
|
|
"Subtraction of '{}', decimal value is {}", |
|
|
|
@ -161,7 +146,7 @@ fn instruct(statement: Pair<Rule>, state: &mut State, out: &mut Builder) { |
|
|
|
|
out.append("-".repeat(constant_parsed as usize)); |
|
|
|
|
} |
|
|
|
|
Rule::subb => { |
|
|
|
|
let constant = extract_operand(statement); |
|
|
|
|
let constant = operand; |
|
|
|
|
let constant_parsed = parse_constant(constant).unwrap(); |
|
|
|
|
println!( |
|
|
|
|
"Big Subtraction of '{}', decimal value is {}", |
|
|
|
@ -170,12 +155,12 @@ fn instruct(statement: Pair<Rule>, state: &mut State, out: &mut Builder) { |
|
|
|
|
out.append("subb\n"); |
|
|
|
|
} |
|
|
|
|
Rule::subv => { |
|
|
|
|
let variable_name = extract_operand(statement); |
|
|
|
|
let variable_name = operand; |
|
|
|
|
println!("Subtraction from variable '{}'", variable_name); |
|
|
|
|
out.append("subv\n"); |
|
|
|
|
} |
|
|
|
|
Rule::copy => { |
|
|
|
|
let variable_name = extract_operand(statement); |
|
|
|
|
let variable_name = operand; |
|
|
|
|
println!("Copy to variable '{}'", variable_name); |
|
|
|
|
out.append("copy\n"); |
|
|
|
|
} |
|
|
|
@ -191,11 +176,6 @@ fn instruct(statement: Pair<Rule>, state: &mut State, out: &mut Builder) { |
|
|
|
|
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("["); |
|
|
|
@ -212,6 +192,32 @@ fn instruct(statement: Pair<Rule>, state: &mut State, out: &mut Builder) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn instruct(statement: Pair<Rule>, state: &mut State, out: &mut Builder) { |
|
|
|
|
match statement.as_rule() { |
|
|
|
|
Rule::include => { |
|
|
|
|
let file_path_raw = extract_operand(statement); |
|
|
|
|
let file_path = &file_path_raw[1..file_path_raw.len() - 1]; |
|
|
|
|
println!("Including {} into this src file", file_path); |
|
|
|
|
let content = std::fs::read_to_string(&file_path) |
|
|
|
|
.with_context(|| format!("could not read source file {:?}", file_path)) |
|
|
|
|
.unwrap(); |
|
|
|
|
let parsed_file = MblfParser::parse(Rule::file, &content) |
|
|
|
|
.expect("Parse Error") |
|
|
|
|
.next() |
|
|
|
|
.unwrap(); |
|
|
|
|
for statement in parsed_file.into_inner() { |
|
|
|
|
instruct(statement, state, out); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
Rule::loopBlock => { |
|
|
|
|
for nested_statement in statement.into_inner() { |
|
|
|
|
instruct(nested_statement, state, out); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ => to_bf(statement.as_rule(), extract_operand(statement), state, out), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn main() -> Result<(), Box<dyn std::error::Error>> { |
|
|
|
|
let args = Cli::from_args(); |
|
|
|
|
|
|
|
|
@ -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(); |
|
|
|
|