use crate::prelude::*;
impl Runtime {
pub fn parse_by_enumerate_stmt(
&mut self,
tb: &mut TokenBlock,
) -> Result<Stmt, RuntimeError> {
tb.skip_token(ENUMERATE)?;
let mut params: Vec<String> = vec![];
let mut param_sets: Vec<ListSet> = vec![];
if tb.current_token_is_equal_to(COLON) {
return Err(RuntimeError::new_parse_error_with_msg_position_previous_error(
"by enumerate: expects at least one (param, set) pair".to_string(),
tb.line_file.clone(),
None,
));
}
while tb.current()? != COLON {
params.push(tb.advance()?);
param_sets.push(self.parse_list_set_obj(tb)?);
if tb.current_token_is_equal_to(COMMA) {
tb.skip_token(COMMA)?;
}
}
tb.skip_token(COLON)?;
if !tb.exceed_end_of_head() {
return Err(RuntimeError::new_parse_error_with_msg_position_previous_error(
"by enumerate: expected end of head after params".to_string(),
tb.line_file.clone(),
None,
));
}
if tb.body.is_empty() {
return Err(RuntimeError::new_parse_error_with_msg_position_previous_error(
"by enumerate: expects prove: block and at least one fact to prove".to_string(),
tb.line_file.clone(),
None,
));
}
if tb.body.is_empty() {
return Err(RuntimeError::new_parse_error_with_msg_position_previous_error(
"by enumerate: expects at least one body block".to_string(),
tb.line_file.clone(),
None,
));
}
tb.body[0].skip_token_and_colon_and_exceed_end_of_head(PROVE)?;
let mut to_prove: Vec<ExistOrAndChainAtomicFact> = Vec::new();
for block in tb.body[0].body.iter_mut() {
to_prove.push(self.parse_exist_or_and_chain_atomic_fact(block)?);
}
let mut proof: Vec<Stmt> = vec![];
for block in tb.body[1..].iter_mut() {
proof.push(self.parse_stmt(block)?);
}
Ok(ByEnumerateStmt::new(
params,
param_sets,
to_prove,
proof,
tb.line_file.clone(),
)
.into())
}
}