diff options
Diffstat (limited to '')
| -rw-r--r-- | crates/brainf_rs/src/parser.rs (renamed from src/parser.rs) | 39 |
1 files changed, 19 insertions, 20 deletions
diff --git a/src/parser.rs b/crates/brainf_rs/src/parser.rs index e639516..c9b3246 100644 --- a/src/parser.rs +++ b/crates/brainf_rs/src/parser.rs @@ -1,11 +1,10 @@ //! Parser implementation for Brainfuck. Parses operator codes into instruction //! sets. +use brainf_lexer::Token; use miette::{Diagnostic, SourceSpan}; use thiserror::Error; -use crate::lexer::OperatorCode; - /// Parsed instructions for Brainfuck. #[derive(Clone, Debug)] pub enum Instruction { @@ -102,49 +101,49 @@ pub enum Error { /// This function will return an error if a loop is encountered with no /// beginning, a loop is encountered with no ending, or if the parser attempts /// to slice out of bounds. -pub fn parse(src: &str, operator_codes: &[OperatorCode]) -> Result<Vec<Instruction>, Error> { +pub fn parse(src: &str, tokens: &[Token]) -> Result<Vec<Instruction>, Error> { let mut program: Vec<Instruction> = Vec::new(); let mut loop_stack: i32 = 0; let mut loop_start = 0; - let mut loop_source_offset: usize = 0; + let mut loop_span: (usize, usize) = (0, 0); - operator_codes + tokens .iter() .enumerate() .try_for_each(|(i, operator_code)| -> Result<(), Error> { match (loop_stack, *operator_code) { - (0i32, OperatorCode::StartLoop { offset }) => { + (0i32, Token::StartLoop(span)) => { loop_start = i; - loop_source_offset = offset; + loop_span = span; loop_stack += 1i32; } (0i32, _) => { if let Some(instruction) = match *operator_code { - OperatorCode::IncrementPointer => Some(Instruction::IncrementPointer), - OperatorCode::DecrementPointer => Some(Instruction::DecrementPointer), - OperatorCode::IncrementByte => Some(Instruction::IncrementByte), - OperatorCode::DecrementByte => Some(Instruction::DecrementByte), - OperatorCode::OutputByte => Some(Instruction::OutputByte), - OperatorCode::InputByte => Some(Instruction::InputByte), - OperatorCode::EndLoop { offset } => { + Token::IncrementPointer => Some(Instruction::IncrementPointer), + Token::DecrementPointer => Some(Instruction::DecrementPointer), + Token::IncrementByte => Some(Instruction::IncrementByte), + Token::DecrementByte => Some(Instruction::DecrementByte), + Token::OutputByte => Some(Instruction::OutputByte), + Token::InputByte => Some(Instruction::InputByte), + Token::EndLoop(span) => { return Err(Error::LoopWithNoBeginning { input: src.to_owned(), - loop_src: (offset, 1).into(), + loop_src: span.into(), }) } // We don't care about this variant as it is handled in a subsequent arm - OperatorCode::StartLoop { .. } => None, + Token::StartLoop { .. } => None, } { program.push(instruction); } } - (_, OperatorCode::StartLoop { .. }) => loop_stack += 1i32, - (_, OperatorCode::EndLoop { .. }) => { + (_, Token::StartLoop { .. }) => loop_stack += 1i32, + (_, Token::EndLoop { .. }) => { loop_stack -= 1i32; if loop_stack == 0i32 { let loop_program = parse( src, - match operator_codes.get(loop_start + 1..i) { + match tokens.get(loop_start + 1..i) { Some(value) => value, None => return Err(Error::SliceOutOfBounds(loop_start + 1..i)), }, @@ -164,7 +163,7 @@ pub fn parse(src: &str, operator_codes: &[OperatorCode]) -> Result<Vec<Instructi } else { Err(Error::LoopWithNoEnding { input: src.to_owned(), - loop_src: (loop_source_offset, 1).into(), + loop_src: loop_span.into(), }) } } |