From 93a474942502f4917dc4bd1e4f5d511a0a73ab9b Mon Sep 17 00:00:00 2001 From: Rowan Torbitzky-Lane Date: Sat, 5 Apr 2025 23:58:30 -0500 Subject: [PATCH] part of interpreter, gene enum, tests --- src/instructions/mod.rs | 2 +- src/instructions/numeric.rs | 75 ++++++++++++++++++++++++++++++++++++- src/push/interpreter.rs | 58 +++++++++++++++++++++++++++- src/push/state.rs | 26 ++++++++++++- 4 files changed, 155 insertions(+), 6 deletions(-) diff --git a/src/instructions/mod.rs b/src/instructions/mod.rs index 3ff98c7..f3360f8 100644 --- a/src/instructions/mod.rs +++ b/src/instructions/mod.rs @@ -24,7 +24,7 @@ pub mod macros { paste::item! { /// Runs the $fn_name function on the top $fn_arity items from /// the $in_stack and places the calculated value on the $out_stack. - fn [< $in_stack $fn_name >] (state: &mut PushState) { + pub fn [< $in_stack $fn_name >] (state: &mut PushState) { let in_stack_len = state.$in_stack.len(); if in_stack_len < $fn_arity { return; diff --git a/src/instructions/numeric.rs b/src/instructions/numeric.rs index 4ba4fe8..df6897b 100644 --- a/src/instructions/numeric.rs +++ b/src/instructions/numeric.rs @@ -5,9 +5,9 @@ // There has to be a better way to declare these functions. // Just don't know enough Rust yet ig. -use crate::push::state::{EMPTY_STATE, PushState}; +use crate::push::state::PushState; +use rust_decimal::Decimal; use rust_decimal::prelude::{FromPrimitive, ToPrimitive}; -use rust_decimal::{Decimal, MathematicalOps, dec}; use std::cmp::{max, min}; use std::ops::{Add, Div, Mul, Sub}; @@ -298,9 +298,80 @@ where make_instruction!(int, int, _square, i128, 1); make_instruction!(float, float, _square, Decimal, 1); +/// A list of all of the defined int functions in this file. +/// Must manually register functions in this list if added. +pub fn int_instructions() -> Vec { + vec![ + int_add, + int_sub, + int_mult, + int_div, + int_rem, + int_max, + int_min, + int_inc, + int_dec, + int_lt, + int_gt, + int_lte, + int_gte, + int_sin, + int_arcsin, + int_cos, + int_arccos, + int_tan, + int_arctan, + int_to_float, + int_to_bool, + int_log, + int_exp, + int_sqrt, + int_inv, + int_abs, + int_sign_reverse, + int_square, + ] +} + +/// All of the float instructions declared in this file. +pub fn float_instructions() -> Vec { + vec![ + float_add, + float_sub, + float_mult, + float_div, + float_rem, + float_max, + float_min, + float_inc, + float_dec, + float_lt, + float_gt, + float_lte, + float_gte, + float_sin, + float_arcsin, + float_cos, + float_arccos, + float_tan, + float_arctan, + float_to_int, + float_to_bool, + float_log, + float_exp, + float_sqrt, + float_inv, + float_abs, + float_sign_reverse, + float_square, + ] +} + #[cfg(test)] mod tests { use super::*; + use crate::push::state::EMPTY_STATE; + use rust_decimal::dec; /// Tests the _add function. #[test] diff --git a/src/push/interpreter.rs b/src/push/interpreter.rs index c4f65ae..21b450d 100644 --- a/src/push/interpreter.rs +++ b/src/push/interpreter.rs @@ -1,3 +1,57 @@ -use crate::push::state; +use crate::push::state::*; -pub fn interpret_program() {} +pub fn gene_to_stack(state: &mut PushState, gene: Gene) { + match gene { + Gene::GeneInt(x) => state.int.push(x), + Gene::GeneFloat(x) => state.float.push(x), + Gene::GeneBoolean(x) => state.boolean.push(x), + Gene::GeneString(x) => state.string.push(x), + Gene::GeneChar(x) => state.char.push(x), + Gene::GeneVectorInt(x) => state.vector_int.push(x), + Gene::GeneVectorFloat(x) => state.vector_float.push(x), + Gene::GeneVectorBoolean(x) => state.vector_boolean.push(x), + Gene::GeneVectorString(x) => state.vector_string.push(x), + Gene::GeneVectorChar(x) => state.vector_char.push(x), + Gene::StateFunc(func) => func(state), + Gene::Block(x) => state.exec.extend(x.into_iter()), + Gene::Close => panic!("Close found in the exec stack, this should not happen!"), + Gene::Open(_) => panic!("Open found in the exec stack, this should not happen!"), + Gene::Skip => panic!("Skip found in the exec stack, this should not happen!"), + Gene::CrossoverPadding => { + panic!("CrossoverPadding found in the exec stack, this should not happen!") + } + } +} + +pub fn interpret_program(state: &mut PushState, step_limit: usize, max_stack_size: isize) { + let mut steps: usize = 0; + while state.exec.len() > 0 && steps < step_limit { + if let Some(val) = state.exec.pop() {} + } +} + +#[cfg(test)] +mod tests { + use super::*; + use rust_decimal::dec; + + #[test] + fn gene_to_stack_test() { + let mut test_state = EMPTY_STATE; + + gene_to_stack(&mut test_state, Gene::GeneInt(1)); + assert_eq!(vec![1], test_state.int); + test_state.int.clear(); + + gene_to_stack(&mut test_state, Gene::GeneFloat(dec!(1.2))); + gene_to_stack(&mut test_state, Gene::GeneFloat(dec!(2.4))); + assert_eq!(vec![dec!(1.2), dec!(2.4)], test_state.float); + test_state.float.clear(); + + gene_to_stack(&mut test_state, Gene::GeneBoolean(true)); + assert_eq!(vec![true], test_state.boolean); + test_state.boolean.clear(); + + // Need to finish these tests later. + } +} diff --git a/src/push/state.rs b/src/push/state.rs index 5c75d91..6e0c226 100644 --- a/src/push/state.rs +++ b/src/push/state.rs @@ -15,7 +15,9 @@ pub struct PushState { pub vector_float: Vec>, pub vector_string: Vec>>, pub vector_boolean: Vec>, - pub vector_char: Vec, + pub vector_char: Vec>, + pub exec: Vec, + pub code: Vec, } pub const EMPTY_STATE: PushState = PushState { @@ -29,4 +31,26 @@ pub const EMPTY_STATE: PushState = PushState { vector_string: vec![], vector_boolean: vec![], vector_char: vec![], + exec: vec![], + code: vec![], }; + +#[derive(PartialEq, Eq, Debug, Clone)] +pub enum Gene { + GeneInt(i128), + GeneFloat(Decimal), + GeneBoolean(bool), + GeneString(Vec), + GeneChar(u8), + GeneVectorInt(Vec), + GeneVectorFloat(Vec), + GeneVectorBoolean(Vec), + GeneVectorString(Vec>), + GeneVectorChar(Vec), + StateFunc(fn(&mut PushState)), + Close, + Open(u8), + Skip, + Block(Box>), + CrossoverPadding, +}