regast-core 0.1.0

Parse-tree matching backends for regast
Documentation
use std::collections::HashMap;

use crate::{
    Disambiguation, IrId, IrPool, Value,
    value_parser::ValueTable,
    value_set::{Span, ValueSet},
};

#[allow(clippy::too_many_arguments)]
pub(crate) fn alt_values(
    pool: &IrPool,
    root: IrId,
    table: &ValueTable,
    left: IrId,
    right: IrId,
    disambiguation: Disambiguation,
    limit: usize,
) -> Result<HashMap<Span, Value>, usize> {
    let mut result = ValueSet::new(limit);
    for (&span, value) in &table[left.0 as usize] {
        result.select(
            pool,
            root,
            span,
            Value::Left(Box::new(value.clone())),
            disambiguation,
        )?;
    }
    for (&span, value) in &table[right.0 as usize] {
        result.select(
            pool,
            root,
            span,
            Value::Right(Box::new(value.clone())),
            disambiguation,
        )?;
    }
    Ok(result.into_inner())
}

#[allow(clippy::too_many_arguments)]
pub(crate) fn seq_values(
    pool: &IrPool,
    root: IrId,
    table: &ValueTable,
    left: IrId,
    right: IrId,
    boundary_count: usize,
    disambiguation: Disambiguation,
    limit: usize,
) -> Result<HashMap<Span, Value>, usize> {
    let mut result = ValueSet::new(limit);
    for start in 0..boundary_count {
        for end in start..boundary_count {
            for split in start..=end {
                let Some(left_value) = table[left.0 as usize].get(&(start, split)) else {
                    continue;
                };
                let Some(right_value) = table[right.0 as usize].get(&(split, end)) else {
                    continue;
                };
                let value = Value::Seq(Box::new(left_value.clone()), Box::new(right_value.clone()));
                result.select(pool, root, (start, end), value, disambiguation)?;
            }
        }
    }
    Ok(result.into_inner())
}

#[allow(clippy::too_many_arguments)]
pub(crate) fn star_values(
    pool: &IrPool,
    root: IrId,
    table: &ValueTable,
    inner: IrId,
    boundary_count: usize,
    disambiguation: Disambiguation,
    limit: usize,
) -> Result<HashMap<Span, Value>, usize> {
    let mut result = ValueSet::new(limit);
    for position in 0..boundary_count {
        result.insert((position, position), Value::Stars(Vec::new()))?;
    }
    for width in 1..boundary_count {
        for start in 0..boundary_count - width {
            let end = start + width;
            for split in start + 1..=end {
                let Some(first) = table[inner.0 as usize].get(&(start, split)) else {
                    continue;
                };
                let Some(Value::Stars(rest)) = result.get(&(split, end)) else {
                    continue;
                };
                let mut values = Vec::with_capacity(rest.len() + 1);
                values.push(first.clone());
                values.extend(rest.iter().cloned());
                result.select(
                    pool,
                    root,
                    (start, end),
                    Value::Stars(values),
                    disambiguation,
                )?;
            }
        }
    }
    Ok(result.into_inner())
}