mumu 0.10.0

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

/// parse_bracketed_array => for expressions like `[1,2,3]` or `[x:1,y:2]`.
pub fn parse_bracketed_array(interp: &mut Interpreter, arr_str: &str) -> Result<Value, String> {
    let inside = &arr_str[1..arr_str.len()-1];
    // Use is_verbose() if you want:
    let tokens = tokenize_bracket_contents(inside, interp.is_verbose())?;

    let has_colon = tokens.iter().any(|t| t.contains(':'));
    if has_colon {
        let mut map = IndexMap::new();
        for tok in tokens {
            if let Some(idx) = tok.find(':') {
                let k = tok[..idx].trim().to_string();
                let v_str = tok[idx+1..].trim();
                // If v_str is another bracketed array, parse recursively
                if v_str.starts_with('[') && v_str.ends_with(']') {
                    let subval = parse_bracketed_array(interp, v_str)?;
                    map.insert(k, subval);
                } else {
                    // minimal
                    map.insert(k, Value::StrArray(vec![v_str.to_string()]));
                }
            }
        }
        Ok(Value::KeyedArray(map))
    } else {
        let mut ints = Vec::new();
        let mut all_ints = true;
        let mut strs = Vec::new();
        for t in tokens {
            if let Ok(x) = t.parse::<i32>() {
                ints.push(x);
            } else {
                all_ints = false;
                strs.push(t.trim_matches('"').to_string());
            }
        }
        if all_ints {
            Ok(Value::IntArray(ints))
        } else {
            Ok(Value::StrArray(strs))
        }
    }
}

/// find_lambda_arrow => find top-level "=>" in an expression
pub fn find_lambda_arrow(expr: &str) -> Option<usize> {
    let mut depth = 0;
    let mut in_quotes = false;
    let chars: Vec<char> = expr.chars().collect();
    let mut i = 0;
    while i < chars.len()-1 {
        let c = chars[i];
        if c == '"' {
            in_quotes = !in_quotes;
        } else if !in_quotes {
            if c == '(' {
                depth += 1;
            } else if c == ')' && depth > 0 {
                depth -= 1;
            } else if depth == 0 && c == '=' && chars[i+1] == '>' {
                return Some(i);
            }
        }
        i+=1;
    }
    None
}

/// parse_param_list => parse something like `(x,y)`.
pub fn parse_param_list(s: &str) -> Result<Vec<String>, String> {
    let trimmed = s.trim();
    let content = if trimmed.starts_with('(') && trimmed.ends_with(')') {
        &trimmed[1..trimmed.len()-1]
    } else {
        trimmed
    };
    if content.is_empty() {
        return Ok(vec![]);
    }
    Ok(content.split(',').map(|x| x.trim().to_string()).collect())
}