Browse Source

Add parser

master
garritfra 4 years ago
parent
commit
9ea02a56ee
  1. 6
      src/instructions.rs
  2. 30
      src/main.rs
  3. 32
      src/parser.rs

6
src/instructions.rs

@ -1,4 +1,4 @@
#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq)]
pub enum OpCode {
Increment,
Decrement,
@ -10,7 +10,7 @@ pub enum OpCode {
LoopEnd,
}
#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq)]
pub enum Instruction {
Increment,
Decrement,
@ -18,5 +18,5 @@ pub enum Instruction {
MoveLeft,
Print,
Read,
Loop(Vec<OpCode>),
Loop(Vec<Instruction>),
}

30
src/main.rs

@ -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);
}
}

32
src/parser.rs

@ -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…
Cancel
Save