bitr 0.1.1

Minimal BitScript interpreter.
Documentation
use std::{collections::HashMap, io};

use crate::*;

pub fn input(name: &[char], status: &mut Status, radix: u32) -> Result<(), String> {
    let input = status.inputs.pop().unwrap_or_else(|| {
        let mut input = String::new();
        io::stdin().read_line(&mut input).expect("cannot read line");
        input
    });

    if *name.last().unwrap_or(&' ') == ']' {
        let opening_index = match name.iter().enumerate().find(|(_index, c)| **c == '[') {
            Some((i, _c)) => i,
            None => return Err(String::from("mismatch brackets")),
        };

        input_single(
            BracketInfo {
                begin: opening_index,
                end: name.len() - 1,
                name: name[0..opening_index].iter().collect(),
                content: name[opening_index + 1..name.len() - 1].iter().collect(),
            },
            status,
            radix,
            input,
        )?;

        return Ok(());
    }
    input_multiple(
        name.iter().collect::<String>(),
        &mut status.variables,
        radix,
        input,
    )
}

fn input_single(
    info: BracketInfo,
    status: &mut Status,
    radix: u32,
    input: String,
) -> Result<(), String> {
    if let [begin, end] = info.content.split("..").collect::<Vec<_>>().as_slice() {
        let mut begin = begin.chars().collect();
        let mut end = end.chars().collect();
        eval(&mut begin, status)?;
        eval(&mut end, status)?;
        let arr = match status.variables.get_mut(&info.name) {
            Some(arr) => arr,
            None => {
                return Err(format!(
                    "cannot input to undeclared variable `{}`",
                    info.name
                ))
            }
        };

        let range = get_range_mut(
            &info.name,
            &begin.iter().collect::<String>(),
            &end.iter().collect::<String>(),
            arr,
        )?;

        assign_arr(range, input.trim(), radix)?;

        return Ok(());
    }
    let arr = match status.variables.get_mut(&info.name) {
        Some(arr) => arr,
        None => {
            return Err(format!(
                "cannot input to undeclared variable `{}`",
                info.name
            ))
        }
    };

    let index = match info.content.parse::<usize>() {
        Ok(n) => n,
        Err(_e) => return Err(format!("cannot parse `{}` into usize", info.content)),
    };

    let cell = match arr.get_mut(index) {
        Some(cell) => cell,
        None => {
            return Err(format!(
                "index out of bounds, length is {}, but index is {index}",
                arr.len()
            ))
        }
    };

    *cell = str_to_bool(input.trim())?;

    Ok(())
}

fn input_multiple(
    name: String,
    variables: &mut HashMap<String, Vec<bool>>,
    radix: u32,
    input: String,
) -> Result<(), String> {
    let arr = match variables.get_mut(&name) {
        Some(arr) => arr,
        None => return Err(format!("cannot input to undeclared variable `{name}`")),
    };

    assign_arr(arr.iter_mut().collect(), input.trim(), radix)?;

    Ok(())
}