use crate::{
rvm::instructions::{ComprehensionMode, LoopMode},
value::Value,
Rc,
};
use alloc::{
collections::{BTreeMap, BTreeSet},
vec::Vec,
};
#[derive(Debug, Clone)]
pub struct LoopContext {
pub mode: LoopMode,
pub iteration_state: IterationState,
pub key_reg: u8,
pub value_reg: u8,
pub result_reg: u8,
pub body_start: u16,
pub loop_end: u16,
pub loop_next_pc: u16, pub body_resume_pc: usize,
pub success_count: usize,
pub total_iterations: usize,
pub current_iteration_failed: bool, }
#[derive(Debug, Clone)]
pub enum IterationState {
Array {
items: Rc<Vec<Value>>,
index: usize,
},
Object {
obj: Rc<BTreeMap<Value, Value>>,
current_key: Option<Value>,
first_iteration: bool,
},
Set {
items: Rc<BTreeSet<Value>>,
current_item: Option<Value>,
first_iteration: bool,
},
}
impl IterationState {
pub(super) const fn advance(&mut self) {
match *self {
Self::Array { ref mut index, .. } => {
*index = index.saturating_add(1);
}
Self::Object {
ref mut first_iteration,
..
}
| Self::Set {
ref mut first_iteration,
..
} => {
*first_iteration = false;
}
}
}
}
#[allow(unused)]
#[derive(Debug, Clone)]
pub struct CallRuleContext {
pub return_pc: usize,
pub dest_reg: u8,
pub result_reg: u8,
pub rule_index: u16,
pub rule_type: crate::rvm::program::RuleType,
pub current_definition_index: usize,
pub current_body_index: usize,
}
#[derive(Debug, Clone)]
pub(super) struct ComprehensionContext {
pub(super) mode: ComprehensionMode,
pub(super) result_reg: u8,
pub(super) key_reg: u8,
pub(super) value_reg: u8,
pub(super) body_start: u16,
pub(super) comprehension_end: u16,
pub(super) iteration_state: Option<IterationState>,
pub(super) resume_pc: usize,
}