mumu 0.9.1

Lava Mumu is a language for those in the now and that know
Documentation
// FILE: src/parser/statements.rs

/* ─────────────────────────────────────────────────────────────────────────────
   1) Helpers to strip comments
   ─────────────────────────────────────────────────────────────────────────── */
fn remove_block_comments(source: &str) -> String {
    let mut result = String::new();
    let bytes = source.as_bytes();
    let mut i = 0;
    while i < bytes.len() {
        if i + 1 < bytes.len() && bytes[i] == b'/' && bytes[i + 1] == b'*' {
            i += 2;
            while i + 1 < bytes.len() {
                if bytes[i] == b'*' && bytes[i + 1] == b'/' {
                    i += 2;
                    break;
                }
                i += 1;
            }
        } else {
            result.push(bytes[i] as char);
            i += 1;
        }
    }
    result
}

fn remove_line_comment(line: &str) -> String {
    let mut in_quotes = false;
    let mut quote_char = '\0';
    let mut escape = false;
    let mut index = None;
    let mut chars = line.char_indices().peekable();

    while let Some((i, c)) = chars.next() {
        if escape {
            escape = false;
            continue;
        }
        if c == '\\' {
            escape = true;
            continue;
        }
        if matches!(c, '"' | '\'' | '`') {
            if in_quotes && quote_char == c {
                in_quotes = false;
            } else if !in_quotes {
                in_quotes = true;
                quote_char = c;
            }
        }
        if !in_quotes && c == '/' {
            if let Some(&(_, nx)) = chars.peek() {
                if nx == '/' {
                    index = Some(i);
                    break;
                }
            }
        }
    }

    if let Some(pos) = index {
        line[..pos].to_string()
    } else {
        line.to_string()
    }
}

/* ─────────────────────────────────────────────────────────────────────────────
   2) unify_partial_usage_lines – unchanged
   ─────────────────────────────────────────────────────────────────────────── */
fn unify_partial_usage_lines(lines: &[String]) -> Vec<String> {
    let mut result = Vec::new();
    let mut i = 0;
    while i < lines.len() {
        let mut current_line = lines[i].clone();

        if i + 1 < lines.len() {
            let trimmed = current_line.trim_end();
            let next_trimmed = lines[i + 1].trim_start();
            let next_trimmed_strict = lines[i + 1].trim();

            if trimmed.ends_with('}') && next_trimmed_strict == ")" {
                current_line.push(' ');
                current_line.push_str(next_trimmed_strict);
                i += 1;
            } else {
                let ends_with_paren  = trimmed.ends_with(')');
                let ends_with_combo  = trimmed.ends_with(")(");
                let next_starts_pair = next_trimmed.starts_with('(') || next_trimmed.starts_with('[');

                if (ends_with_paren || ends_with_combo) && next_starts_pair {
                    current_line.push(' ');
                    current_line.push_str(next_trimmed);
                    i += 1;
                }
            }
        }

        result.push(current_line);
        i += 1;
    }
    result
}

/* ─────────────────────────────────────────────────────────────────────────────
   3) gather_statements – quote tracking extended for back-ticks
   ─────────────────────────────────────────────────────────────────────────── */
pub fn gather_statements(source: &str, verbose: bool) -> Vec<String> {
    let no_block = remove_block_comments(source);
    let mut raw_lines = Vec::new();

    for line in no_block.lines() {
        let stripped = remove_line_comment(line);
        let trimmed  = stripped.trim();
        if !trimmed.is_empty() { raw_lines.push(trimmed.to_string()); }
    }

    let merged_lines = unify_partial_usage_lines(&raw_lines);
    let merged_str  = merged_lines.join("\n");
    let chars: Vec<char> = merged_str.chars().collect();

    let mut statements = Vec::new();
    let mut current = String::new();

    let mut in_quotes        = false;
    let mut quote_char       = '\0';
    let mut bracket_depth    = 0;
    let mut paren_depth      = 0;
    let mut in_brace_lambda  = false;
    let mut brace_depth      = 0;

    let mut i = 0;
    while i < chars.len() {
        let c = chars[i];
        current.push(c);

        match c {
            '"' | '\'' | '`' => {
                if in_quotes && quote_char == c {
                    in_quotes = false;
                } else if !in_quotes {
                    in_quotes = true;
                    quote_char = c;
                }
            }
            '(' => { if !in_quotes { paren_depth   += 1; } }
            ')' => { if !in_quotes && paren_depth > 0 { paren_depth -= 1; } }
            '[' => { if !in_quotes { bracket_depth += 1; } }
            ']' => { if !in_quotes && bracket_depth > 0 { bracket_depth -= 1; } }
            '{' => {
                if !in_quotes {
                    if current.contains("=>") {
                        in_brace_lambda = true;
                        brace_depth = 1;
                    } else if in_brace_lambda {
                        brace_depth += 1;
                    }
                }
            }
            '}' => {
                if in_brace_lambda {
                    if brace_depth > 0 { brace_depth -= 1; }
                    if brace_depth == 0 {
                        in_brace_lambda = false;
                        let st = current.trim();
                        if !st.is_empty() { statements.push(st.to_string()); }
                        current.clear();
                        i += 1;
                        continue;
                    }
                }
            }
            '=' => {
                if i + 1 < chars.len() && chars[i + 1] == '>' {
                    current.push('>');
                    i += 1;
                    in_brace_lambda = true;
                    brace_depth = 0;
                } else if i + 1 < chars.len() && chars[i + 1] == '=' {
                    current.push('=');
                    i += 1;
                }
            }
            '>' | '<' => {
                if !in_quotes && i + 1 < chars.len() && chars[i + 1] == '=' {
                    current.push(chars[i + 1]);
                    i += 1;
                }
            }
            '\n' => {
                if !in_quotes && !in_brace_lambda && bracket_depth == 0 && paren_depth == 0 {
                    let st = current.trim();
                    if !st.is_empty() { statements.push(st.to_string()); }
                    current.clear();
                }
            }
            _ => {}
        }

        i += 1;
    }

    let leftover = current.trim();
    if !leftover.is_empty() { statements.push(leftover.to_string()); }

    if verbose { eprintln!("[gather_statements] final => {:#?}", statements); }
    statements
}