diff options
author | Irene Knapp <ireneista@irenes.space> | 2025-05-04 00:59:43 -0700 |
---|---|---|
committer | Irene Knapp <ireneista@irenes.space> | 2025-05-04 00:59:43 -0700 |
commit | 44c3362bcb565aa81f6e3fe0ab7a106dc89f4ba9 (patch) | |
tree | 5eb26c109d988c8cf345ac747b8e37cc560b5cb2 | |
parent | 381f71833ebfb99a7dde16b6f3ceeb4c0fd5a8bd (diff) |
okay now swap and roll exist. some mnemonics changed, too
Force-Push: yes Change-Id: Ie496dfdfda969a3b6c9b3f9daadc22bd779b1f14
-rw-r--r-- | src/main.rs | 83 |
1 files changed, 70 insertions, 13 deletions
diff --git a/src/main.rs b/src/main.rs index a94feaa..5c183b4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,14 +28,16 @@ const HELP_TEXT: &str = v take the square root of the top item on the stack\n\ \n\ STACK OPERATIONS\n\ - d duplicate the top item on the stack\n\ + s swap the top two items on the stack\n\ + d drop the top item from the stack\n\ + r roll the stack, rotating downwards by 1, top item as size\n\ + p duplicate the top item on the stack\n\ c clear the stack\n\ - , drop the top item from the stack\n\ ! assert the stack height, with the top item as desired height\n\ \n\ REGISTER OPERATIONS\n\ l load from register (register name as next character)\n\ - s store to register (register name as next character)\n\ + v save to register (register name as next character)\n\ \n\ CONTROL FLOW\n\ x evaluate string\n\ @@ -383,30 +385,85 @@ fn make_command_character_readtable() -> ReadTable { //////////////////////////////////////////////////////////// // Stack operation actions // + result.set_action('s', move |_, state| { + if state.stack.len() < 2 { + return Err(err_msg("Data underflow!".into())); + } + + let a = state.stack.pop().ok_or_else(|| err_msg( + "Data underflow!".into()))?; + let b = state.stack.pop().ok_or_else(|| err_msg( + "Data underflow!".into()))?; + + state.stack.push(a); + state.stack.push(b); + + Ok(()) + }); + result.set_action('d', move |_, state| { if state.stack.is_empty() { return Err(err_msg("Data underflow!".into())); } - let val = state.stack.pop().unwrap(); - state.stack.push(val.clone()); - state.stack.push(val.clone()); + state.stack.pop(); Ok(()) }); - result.set_action('c', move |_, state| { - state.stack.clear(); + result.set_action('r', move |_, state| { + if state.stack.is_empty() { + return Err(err_msg("Data underflow!".into())); + } - Ok(()) + if let Value::Num(size) = state.stack.pop().ok_or_else(|| err_msg( + "Data underflow!".into()))? + { + if !size.is_integer() { + return Err(err_msg("Size to roll must be an integer.".into())); + } + if !size.is_sign_positive() { + return Err(err_msg("Size to roll must be zero or more.".into())); + } + + let mut top_item = state.stack.pop().ok_or_else(|| err_msg( + "Data underflow!".into()))?; + + let mut other_items = Vec::new(); + let mut i = Decimal::ONE; + while i < size { + i += Decimal::ONE; + + other_items.push(state.stack.pop().ok_or_else(|| err_msg( + "Data underflow!".into()))?); + } + + state.stack.push(top_item); + + while !other_items.is_empty() { + state.stack.push(other_items.pop().unwrap()); + } + + Ok(()) + } else { + Err(err_msg("Size must be a number.".into())) + } }); - result.set_action(',', move |_, state| { + result.set_action('p', move |_, state| { if state.stack.is_empty() { return Err(err_msg("Data underflow!".into())); } - state.stack.pop(); + let val = state.stack.pop().unwrap(); + state.stack.push(val.clone()); + state.stack.push(val.clone()); + + Ok(()) + }); + + result.set_action('c', move |_, state| { + state.stack.clear(); Ok(()) }); @@ -439,7 +496,7 @@ fn make_command_character_readtable() -> ReadTable { }; result.set_action('l', register_command_action.clone()); - result.set_action('s', register_command_action.clone()); + result.set_action('v', register_command_action.clone()); //////////////////////////////////////////////////////////// // Control flow actions @@ -608,7 +665,7 @@ fn dispatch_register_command(name: &str, state: &mut RPState) { match state.reg_command.as_str() { "l" => load_from_register(name, state), - "s" => store_to_register(name, state), + "v" => store_to_register(name, state), _ => { Err(err_msg(format!( |