mirror of https://git.sr.ht/~garritfra/rustfuck
garritfra
4 years ago
3 changed files with 62 additions and 6 deletions
@ -1,10 +1,34 @@
|
||||
mod instructions; |
||||
mod lexer; |
||||
mod parser; |
||||
use instructions::Instruction; |
||||
use instructions::OpCode; |
||||
|
||||
fn main() { |
||||
let tokens: Vec<OpCode> = lexer::lex("++++++ [ > ++++++++++ < - ] > +++++ ."); |
||||
for token in tokens { |
||||
println!("{:?}", token); |
||||
let tokens: Vec<OpCode> = lexer::lex("+[--]."); |
||||
|
||||
let instructions: Vec<Instruction> = parser::parse(tokens); |
||||
|
||||
for instruction in &instructions { |
||||
println!("{:?}", instruction); |
||||
} |
||||
} |
||||
|
||||
#[cfg(test)] |
||||
mod tests { |
||||
use crate::instructions::Instruction; |
||||
#[test] |
||||
fn when_input_contains_loop_then_loop_gets_parsed() { |
||||
let input = "+[-]."; |
||||
let tokens = super::lexer::lex(input); |
||||
let instructions: Vec<Instruction> = super::parser::parse(tokens); |
||||
println!("{:?}", instructions); |
||||
assert_eq!(instructions.len(), 3); |
||||
assert_eq!(*instructions.get(0).unwrap(), Instruction::Increment); |
||||
assert_eq!( |
||||
*instructions.get(1).unwrap(), |
||||
Instruction::Loop(vec![Instruction::Decrement]) |
||||
); |
||||
assert_eq!(*instructions.get(2).unwrap(), Instruction::Print); |
||||
} |
||||
} |
||||
|
@ -0,0 +1,32 @@
|
||||
use crate::instructions::*; |
||||
|
||||
pub fn parse(op_codes: Vec<OpCode>) -> Vec<Instruction> { |
||||
let mut instructions: Vec<Instruction> = Vec::new(); |
||||
|
||||
let mut codes = op_codes.iter(); |
||||
loop { |
||||
if let Some(code) = codes.next() { |
||||
match code { |
||||
OpCode::Increment => instructions.push(Instruction::Increment), |
||||
OpCode::Decrement => instructions.push(Instruction::Decrement), |
||||
OpCode::MoveRight => instructions.push(Instruction::MoveRight), |
||||
OpCode::MoveLeft => instructions.push(Instruction::MoveLeft), |
||||
OpCode::Print => instructions.push(Instruction::Print), |
||||
OpCode::Read => instructions.push(Instruction::Read), |
||||
OpCode::LoopStart => { |
||||
let codes_ref = &mut codes; |
||||
let loop_opcodes: Vec<OpCode> = codes_ref |
||||
.take_while(|x| **x != OpCode::LoopEnd) |
||||
.cloned() |
||||
.collect(); |
||||
instructions.push(Instruction::Loop(parse(loop_opcodes))); |
||||
} |
||||
OpCode::LoopEnd => panic!("Extra ] found"), |
||||
} |
||||
} else { |
||||
break; |
||||
} |
||||
} |
||||
|
||||
instructions |
||||
} |
Loading…
Reference in new issue