blazefuck/
lib.rs

1mod tokens;
2pub mod interpreter;
3pub mod interact;
4
5use crate::tokens::*;
6use anyhow::{Context, Result};
7
8fn lex(string: &str) -> Vec<Instruction> {
9    let mut tokens = string
10        .bytes()
11        .filter_map(|x| match x {
12            b'>' => Some(Instruction::POINTER_RIGHT),
13            b'<' => Some(Instruction::POINTER_LEFT),
14            b'+' => Some(Instruction::DATA_INCREMENT),
15            b'-' => Some(Instruction::DATA_DECREMENT),
16            b'.' => Some(Instruction::DATA_OUTPUT),
17            b',' => Some(Instruction::DATA_INPUT),
18            b'[' => Some(Instruction::CONDITIONAL_BEGIN),
19            b']' => Some(Instruction::CONDITIONAL_END),
20            _ => None,
21        })
22        .collect::<Vec<Instruction>>();
23
24    tokens.shrink_to_fit();
25    tokens
26}
27
28fn parse(instructions: &Vec<Instruction>, wait: bool) -> Result<Vec<(usize, usize)>> {
29    let mut stack: Vec<(usize, usize)> = Vec::with_capacity(instructions.len() / 2);
30    let mut bracket_pairs = Vec::with_capacity(instructions.len() / 2);
31
32    for (position, command) in instructions.iter().enumerate().filter(|&(_, &command)| {
33        command == Instruction::CONDITIONAL_BEGIN || command == Instruction::CONDITIONAL_END
34    }) {
35        match command {
36            Instruction::CONDITIONAL_BEGIN => stack.push((position, 0)),
37            Instruction::CONDITIONAL_END => {
38                match stack.pop() {
39                    Some((begin, _)) => bracket_pairs.push((begin, position)),
40                    None => return Err(Error::UNMATCHED_CONDITIONAL(position)).context("Syntax error encountered")
41                };
42            }
43            _ => (),
44        }
45    }
46
47    if !stack.is_empty() {
48        if !wait {
49            return Err(Error::UNMATCHED_CONDITIONAL(stack[0].1 + 1)).context("Syntax error encountered");
50        }
51
52        bracket_pairs.push((stack[0].1, 0));
53    }
54
55    bracket_pairs.sort();
56    bracket_pairs.shrink_to_fit();
57    Ok(bracket_pairs)
58}