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())
}