diff --git a/src/instructions/code.rs b/src/instructions/code.rs index 4131b83..ebc97c7 100644 --- a/src/instructions/code.rs +++ b/src/instructions/code.rs @@ -2,7 +2,7 @@ use std::ops::Not; use crate::push::state::{Gene, PushState}; -use super::common::code_pop; +use super::common::{code_from_exec, code_pop}; /// Checks to see if a single gene is a block. fn _is_block(vals: Vec) -> Option { @@ -132,6 +132,36 @@ fn code_do_then_pop(state: &mut PushState) { state.exec.push(c); } +/// Evaluates the top item on the code stack based off +/// the range of two ints from the int stack. +fn code_do_range(state: &mut PushState) { + if state.code.is_empty() || state.int.len() < 2 { + return; + } + let to_do = state.code.pop().unwrap(); + let dest_idx = state.int.pop().unwrap(); + let current_idx = state.int.pop().unwrap(); + + let mut increment = 0; + if current_idx < dest_idx { + increment = 1 + } else if current_idx > dest_idx { + increment = -1 + } + + if increment != 0 { + state.exec.push(Gene::Block(Box::new(vec![ + Gene::GeneInt(current_idx + increment), + Gene::GeneInt(dest_idx), + Gene::StateFunc(code_from_exec), + to_do.clone(), + Gene::StateFunc(code_do_range), + ]))); + state.int.push(current_idx); + state.exec.push(to_do); + } +} + #[cfg(test)] mod tests { use super::*;