mumu 0.11.1

Lava Mumu is a language for those in the now and that know
Documentation
use crate::parser::types::Value;
use crate::parser::interpreter::Interpreter;

pub fn eval_index_expr(
    _interp: &mut Interpreter,
    base_val: Value,
    idx_val: Value,
) -> Result<Value, String> {
    let actual_base = match base_val {
        Value::Ref(arc_mutex) => arc_mutex.lock().unwrap().clone(),
        v => v,
    };
    match (actual_base, idx_val) {
        (Value::IntArray(xs), Value::Int(i)) => {
            let len = xs.len() as i32;
            let idx = if i < 0 { len + i } else { i };
            if idx < 0 || idx >= len {
                return Ok(Value::Placeholder);
            }
            Ok(Value::Int(xs[idx as usize]))
        }
        (Value::FloatArray(ffs), Value::Int(i)) => {
            let len = ffs.len() as i32;
            let idx = if i < 0 { len + i } else { i };
            if idx < 0 || idx >= len {
                return Ok(Value::Placeholder);
            }
            Ok(Value::Float(ffs[idx as usize]))
        }
        (Value::StrArray(ss), Value::Int(i)) => {
            let len = ss.len() as i32;
            let idx = if i < 0 { len + i } else { i };
            if idx < 0 || idx >= len {
                return Ok(Value::Placeholder);
            }
            Ok(Value::SingleString(ss[idx as usize].clone()))
        }
        (Value::Int2DArray(rows), Value::Int(r)) => {
            let len = rows.len() as i32;
            let idx = if r < 0 { len + r } else { r };
            if idx < 0 || idx >= len {
                return Ok(Value::Placeholder);
            }
            Ok(Value::IntArray(rows[idx as usize].clone()))
        }
        (Value::Float2DArray(rows), Value::Int(r)) => {
            let len = rows.len() as i32;
            let idx = if r < 0 { len + r } else { r };
            if idx < 0 || idx >= len {
                return Ok(Value::Placeholder);
            }
            Ok(Value::FloatArray(rows[idx as usize].clone()))
        }
        (Value::MixedArray(items), Value::Int(i)) => {
            let len = items.len() as i32;
            let idx = if i < 0 { len + i } else { i };
            if idx < 0 || idx >= len {
                return Ok(Value::Placeholder);
            }
            Ok(items[idx as usize].clone())
        }
        (Value::KeyedArray(map), Value::SingleString(key)) => {
            if let Some(v) = map.get(&key) {
                Ok(v.clone())
            } else {
                Ok(Value::Placeholder)
            }
        }
        (Value::KeyedArray(map), Value::StrArray(arr)) if arr.len() == 1 => {
            if let Some(v) = map.get(&arr[0]) {
                Ok(v.clone())
            } else {
                Ok(Value::Placeholder)
            }
        }
        (Value::KeyedArray(_), Value::Int(_)) => {
            Err("Cannot index into a KeyedArray with an integer".to_string())
        }
        other => Err(format!("Cannot index into {:?}", other)),
    }
}