use crate::parser::interpreter::eval::eval_expression; use crate::parser::interpreter::Interpreter;
use crate::parser::types::Value;
use crate::parser::tokens::tokenize_bracket_contents;
use indexmap::IndexMap;
pub fn parse_bracketed_array(interp: &mut Interpreter, arr_str: &str) -> Result<Value, String> {
let inside = &arr_str[1..arr_str.len() - 1];
let tokens = tokenize_bracket_contents(inside, interp.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 key_part = tok[..idx].trim();
let val_part = tok[idx + 1..].trim();
if val_part.starts_with('[') && val_part.ends_with(']') {
let subval = parse_bracketed_array(interp, val_part)?;
map.insert(key_part.to_string(), subval);
} else {
let subval = eval_expression(interp, val_part)?;
map.insert(key_part.to_string(), subval);
}
} else {
return Err(format!("Expected ':' in '{}'", tok));
}
}
Ok(Value::KeyedArray(map))
} else {
let mut all_ints = true;
let mut int_vals = Vec::new();
let mut str_vals = Vec::new();
for t in tokens {
if let Ok(n) = t.parse::<i32>() {
if !str_vals.is_empty() {
return Err("Mixed int/string array not supported.".to_string());
}
int_vals.push(n);
} else {
all_ints = false;
let unquoted = t.trim_matches('"').to_string();
if !int_vals.is_empty() {
return Err("Mixed int/string array not supported.".to_string());
}
str_vals.push(unquoted);
}
}
if all_ints {
Ok(Value::IntArray(int_vals))
} else {
Ok(Value::StrArray(str_vals))
}
}
}
pub fn find_lambda_arrow(expr: &str) -> Option<usize> {
let mut in_quotes = false;
let mut depth_paren = 0;
let chars: Vec<char> = expr.chars().collect();
let mut i = 0;
while i + 1 < chars.len() {
let c = chars[i];
if c == '"' {
in_quotes = !in_quotes;
} else if !in_quotes {
if c == '(' {
depth_paren += 1;
} else if c == ')' && depth_paren > 0 {
depth_paren -= 1;
} else if depth_paren == 0 && c == '=' && chars[i + 1] == '>' {
return Some(i);
}
}
i += 1;
}
None
}
pub fn parse_param_list(param_str: &str) -> Result<Vec<String>, String> {
let trimmed = param_str.trim();
let without_parens = if trimmed.starts_with('(') && trimmed.ends_with(')') {
&trimmed[1..trimmed.len() - 1]
} else {
trimmed
};
if without_parens.is_empty() {
return Ok(vec![]);
}
Ok(without_parens
.split(',')
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
.collect())
}