start of test-driven development/macro done

This commit is contained in:
Rowan Torbitzky-Lane 2025-04-03 15:38:02 -05:00
parent ed70888a30
commit 64fad0dff8
6 changed files with 103 additions and 22 deletions

View File

@ -1 +1,55 @@
#[macro_use]
pub mod macros {
// A macro that makes a push instruction given: the name of the stack to use,
// an internal function to call, and the type of a function.
#[macro_export]
macro_rules! make_instruction {
($stack_name:ident, $fn_name:ident, $fn_type:ty) => {
paste::item! {
fn [< $stack_name $fn_name >] (state: &mut PushState, num_inputs: usize) {
if state.$stack_name.len() < num_inputs {
return;
}
let mut inputs: Vec<$fn_type> = Vec::with_capacity(num_inputs);
for n in 0..num_inputs {
inputs.push(state.$stack_name[n]);
}
if let Some(result) = $fn_name(inputs) {
for _ in 0..num_inputs {
state.$stack_name.pop();
}
state.$stack_name.push(result);
}
}
}
};
}
}
pub mod numeric; pub mod numeric;
pub mod utils;
// /// A macro that makes a push instruction given: the name of the stack to use,
// /// an internal function to call, and the type of a function.
// #[macro_export]
// macro_rules! make_instruction {
// ($stack_name:ident, $fn_name:ident, $fn_type:ty) => {
// paste::item! {
// fn [< $stack_name $fn_name >] (state: &mut PushState, num_inputs: usize) {
// if state.$stack_name.len() < num_inputs {
// return;
// }
// let mut inputs: Vec<$fn_type> = Vec::with_capacity(num_inputs);
// for n in 0..num_inputs {
// inputs.push(state.$stack_name[n]);
// }
// if let Some(result) = $fn_name(inputs) {
// for _ in 0..num_inputs {
// state.$stack_name.pop();
// }
// state.$stack_name.push(result);
// }
// }
// }
// };
// }

View File

@ -2,38 +2,61 @@
//! //!
//! This file contains numeric instructions for int and float. //! This file contains numeric instructions for int and float.
use crate::push::state::*; use crate::push::state::{EMPTY_STATE, PushState};
use paste::paste; use std::ops::{Add, Sub};
use std::ops::Add;
fn _add<T: Add<Output = T>>(val0: T, val1: T) -> T { /// Adds two addable values together.
val0 + val1 fn _add<T>(vals: Vec<T>) -> Option<T>
where
T: Add<Output = T>,
T: Copy,
{
Some(vals[1] + vals[0])
} }
#[macro_export] /// Subtracts two subtractable values from each other.
macro_rules! make_instruction { fn _sub<T>(vals: Vec<T>) -> Option<T>
($stack_name:ident, $fn_name:ident) => { where
paste::item! { T: Sub<Output = T>,
fn [< $stack_name $fn_name >] (state: &mut PushState) -> Option< { T: Copy,
let val0 = state.$stack_name[0]; {
let val1 = state.$stack_name[1]; Some(vals[1] - vals[0])
$fn_name(val0, val1);
println!("{val0} {val1}");
}
}
};
} }
/// Declares int_add
make_instruction!(int, _add, i64);
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
/// Tests the _add function.
#[test] #[test]
fn add_test() { fn add_test() {
let vals: Vec<i64> = vec![1, 2];
assert_eq!(Some(3), _add(vals));
let vals: Vec<f64> = vec![1.1, 2.2];
assert_eq!(Some(3.3), _add(vals));
}
/// Tests the _sub function.
#[test]
fn sub_test() {
let vals: Vec<i64> = vec![1, 2];
assert_eq!(Some(1), _sub(vals));
let vals: Vec<f64> = vec![1.1, 2.2];
assert_eq!(Some(1.1), _sub(vals));
}
// Tests that the various state_add functions work.
#[test]
fn state_add() {
let mut test_state = EMPTY_STATE; let mut test_state = EMPTY_STATE;
test_state.int = vec![1, 2]; test_state.int = vec![1, 2];
// assert_eq!(vec![1, 2, 3], _add(&mut test_state).int); test_state.float = vec![1.1, 2.2];
make_instruction!(int, _add); int_add(&mut test_state, 2);
int_add(&mut test_state); assert_eq!(test_state.int, vec![3]);
} }
} }

View File

@ -0,0 +1 @@

1
src/lib.rs Normal file
View File

@ -0,0 +1 @@

View File

@ -2,5 +2,7 @@ mod instructions;
mod push; mod push;
fn main() { fn main() {
println!("Hello, world!"); let arr: Vec<i32> = vec![];
let slice = &arr[..2];
println!("{:?}", slice);
} }

View File

@ -1,7 +1,7 @@
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct PushState { pub struct PushState {
pub int: Vec<i64>, pub int: Vec<i64>,
pub float: Vec<i64>, pub float: Vec<f64>,
pub string: Vec<Vec<u8>>, pub string: Vec<Vec<u8>>,
pub bool: Vec<bool>, pub bool: Vec<bool>,
pub char: Vec<u8>, pub char: Vec<u8>,