pub struct Engine {
pub stack: Vec<Bucket>,
pub variables: HashMap<String, Bucket>,
pub undo_history: VecDeque<Vec<Bucket>>,
pub undo_variable_history: VecDeque<HashMap<String, Bucket>>,
pub undo_state_pointer: u8,
pub previous_answer: Bucket,
}Expand description
The core evaluation engine responsible for processing Reverse Polish Notation (RPN) operations.
The Engine maintains a stack, variable storage, and undo history to facilitate command execution
and state management.
Fields§
§stack: Vec<Bucket>The stack of bucket items
variables: HashMap<String, Bucket>Hashmap of set variables
undo_history: VecDeque<Vec<Bucket>>History vecdeque for undo support
undo_variable_history: VecDeque<HashMap<String, Bucket>>Variables vecdeque for undo support
undo_state_pointer: u8Offset pointer to the current index of the undo history.
Index will be calculated by history.len() - pointer - 1
previous_answer: BucketPrevious answer
Implementations§
Source§impl Engine
impl Engine
Sourcepub fn new() -> Engine
pub fn new() -> Engine
Initializes an empty stack, variable storage, and undo history, with the previous answer set to zero.
Sourcepub fn add_item_to_stack(
&mut self,
item: Bucket,
) -> Result<EngineSignal, String>
pub fn add_item_to_stack( &mut self, item: Bucket, ) -> Result<EngineSignal, String>
Adds an item to the stack, resolving variables and constants if necessary.
§Arguments
item- ABucketcontaining the value to be added to the stack.
§Behavior
- If
itemis"@", it is replaced with the value ofself.previous_answer. - If
itemis a variable (its string representation starts with$), it is resolved usingself.variables.- If the variable is undefined, an error is returned.
- If
itemis a recognized constant, it is converted accordingly. - If
itemis a numeric string, it is parsed into aFloatbucket. - Otherwise,
itemis stored as aStringbucket.
§Returns
Ok(EngineSignal::StackUpdated)if the item is successfully added to the stack.Err(String)if an undefined variable is referenced.
§Errors
Returns an error if the function encounters a reference to an undefined variable.
§Side Effects
- Modifies
self.stackby pushing the resolvedBucket.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.variables.insert("x".to_string(), Bucket::from(42.0));
assert!(engine.add_item_to_stack(Bucket::from("$x")).is_ok()); // Pushes 42.0 to the stack.
assert!(engine.add_item_to_stack(Bucket::from("$y")).is_err()); // Error: Undefined variable.Sourcepub fn get_operands_as_f(&mut self, number: i32) -> Result<Vec<f64>, String>
pub fn get_operands_as_f(&mut self, number: i32) -> Result<Vec<f64>, String>
Retrieves a specified number of operands from the stack as f64 values.
§Arguments
number- The number of operands to retrieve from the stack.
§Behavior
- Ensures that the stack contains at least
numberelements. - Checks that all requested operands are valid types (
BucketTypes::FloatorBucketTypes::Constant). - Extracts the operands from the stack, converting them to
f64. - Returns the operands in the correct order.
§Returns
Ok(Vec<f64>)containing the extracted operands.Err(String)if:- The stack does not contain enough items.
- Any of the operands are of an invalid type (
BucketTypes::StringorBucketTypes::Undefined). - An operand is missing a value.
- An operand cannot be parsed as
f64.
§Errors
Returns an error if:
- The stack has fewer items than
number. - An operand is of an incompatible type.
- Parsing an operand as
f64fails.
§Side Effects
- Modifies
self.stackby removing the retrieved operands.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(3.5));
engine.stack.push(Bucket::from(2.0));
let result = engine.get_operands_as_f(2);
assert_eq!(result, Ok(vec![3.5, 2.0])); // Successfully retrieved operands.Sourcepub fn get_operands_as_dec(
&mut self,
number: i32,
) -> Result<Vec<Decimal>, String>
pub fn get_operands_as_dec( &mut self, number: i32, ) -> Result<Vec<Decimal>, String>
Retrieves a specified number of operands from the stack as Decimal values.
§Arguments
number- The number of operands to retrieve from the stack.
§Behavior
- Ensures that the stack contains at least
numberelements. - Checks that all requested operands are valid types (
BucketTypes::FloatorBucketTypes::Constant). - Converts recognized mathematical constants (
π,e, etc.) into their correspondingDecimalvalues. - Parses other valid numeric values into
Decimal. - Returns the operands in the correct order.
§Returns
Ok(Vec<Decimal>)containing the extracted operands.Err(String)if:- The stack does not contain enough items.
- Any of the operands are of an invalid type (
BucketTypes::StringorBucketTypes::Undefined). - An operand is missing a value.
- Parsing an operand as
Decimalfails.
§Errors
Returns an error if:
- The stack has fewer items than
number. - An operand is of an incompatible type.
- Parsing an operand as
Decimalfails.
§Side Effects
- Modifies
self.stackby removing the retrieved operands.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(3.1415926535));
engine.stack.push(Bucket::from(2.0));
let result = engine.get_operands_as_dec(2);
assert!(result.is_ok()); // Successfully retrieved operands as Decimals.Sourcepub fn get_operands_as_string(
&mut self,
number: i32,
) -> Result<Vec<String>, String>
pub fn get_operands_as_string( &mut self, number: i32, ) -> Result<Vec<String>, String>
Retrieves a specified number of operands from the stack as String values.
§Arguments
number- The number of operands to retrieve from the stack.
§Behavior
- Ensures that the stack contains at least
numberelements. - Converts each operand to a
String. - Maintains the correct order of retrieved operands.
§Returns
Ok(Vec<String>)containing the extracted operands as strings.Err(String)if there are not enough items on the stack.
§Errors
Returns an error if the stack has fewer items than number.
§Side Effects
- Modifies
self.stackby removing the retrieved operands.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from("hello"));
engine.stack.push(Bucket::from("world"));
let result = engine.get_operands_as_string(2);
assert_eq!(result.unwrap(), vec!["hello", "world"]);Sourcepub fn get_operands_raw(&mut self, number: i32) -> Result<Vec<Bucket>, String>
pub fn get_operands_raw(&mut self, number: i32) -> Result<Vec<Bucket>, String>
Retrieves a specified number of operands from the stack as raw Bucket values.
§Arguments
number- The number of operands to retrieve from the stack.
§Behavior
- Ensures that the stack contains at least
numberelements. - Extracts the top
numberelements from the stack without modifying their types. - Maintains the original order of retrieved operands.
§Returns
Ok(Vec<Bucket>)containing the extracted operands in their raw form.Err(String)if there are not enough items on the stack.
§Errors
Returns an error if the stack has fewer items than number.
§Side Effects
- Modifies
self.stackby removing the retrieved operands.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(3.14));
engine.stack.push(Bucket::from("test"));
let result = engine.get_operands_raw(2);
assert!(result.is_ok());
assert_eq!(result.unwrap(), vec![Bucket::from(3.14), Bucket::from("test")]);Sourcepub fn update_previous_answer(&mut self) -> Result<EngineSignal, String>
pub fn update_previous_answer(&mut self) -> Result<EngineSignal, String>
Updates the previous_answer variable to the last item on the stack.
§Behavior
- If the stack is not empty, the last item is cloned and stored as
previous_answer. - If the stack is empty, returns an error.
§Algebraic Mode Consideration
- If you’re application has an algebraic mode, this function must be called after a full
algebraic expression has been executed. This ensures that
previous_answeris updated at the end of the statement, rather than in the middle of execution.
§Returns
Ok(EngineSignal::NOP)ifprevious_answeris successfully updated.Err(String)if the stack is empty.
§Errors
Returns an error if the stack is empty, as there is no value to store as previous_answer.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(42));
assert!(engine.update_previous_answer().is_ok());
assert_eq!(engine.previous_answer, Bucket::from(42));Sourcepub fn add(&mut self) -> Result<EngineSignal, String>
pub fn add(&mut self) -> Result<EngineSignal, String>
Performs addition on the top two operands of the stack.
§Behavior
- Retrieves the top two values from the stack as
Decimalnumbers. - Computes the sum of these values.
- Pushes the result back onto the stack.
- Returns
EngineSignal::StackUpdatedto indicate a successful operation.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if there are not enough operands on the stack or if the operands are invalid.
§Errors
This function will return an error if:
- The stack contains fewer than two operands.
- The operands are of an invalid type that cannot be converted to
Decimal.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(5));
engine.stack.push(Bucket::from(10));
assert!(engine.add().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(15));Sourcepub fn subtract(&mut self) -> Result<EngineSignal, String>
pub fn subtract(&mut self) -> Result<EngineSignal, String>
Performs subtraction on the top two operands of the stack.
§Behavior
- Retrieves the top two values from the stack as
Decimalnumbers. - Computes the difference of these values.
- Pushes the result back onto the stack.
- Returns
EngineSignal::StackUpdatedto indicate a successful operation.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if there are not enough operands on the stack or if the operands are invalid.
§Errors
This function will return an error if:
- The stack contains fewer than two operands.
- The operands are of an invalid type that cannot be converted to
Decimal.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(5));
engine.stack.push(Bucket::from(10));
assert!(engine.subtract().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(-5));Sourcepub fn multiply(&mut self) -> Result<EngineSignal, String>
pub fn multiply(&mut self) -> Result<EngineSignal, String>
Performs multiplication on the top two operands of the stack.
§Behavior
- Retrieves the top two values from the stack as
Decimalnumbers. - Computes the product of these values.
- Pushes the result back onto the stack.
- Returns
EngineSignal::StackUpdatedto indicate a successful operation.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if there are not enough operands on the stack or if the operands are invalid.
§Errors
This function will return an error if:
- The stack contains fewer than two operands.
- The operands are of an invalid type that cannot be converted to
Decimal.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(5));
engine.stack.push(Bucket::from(10));
assert!(engine.multiply().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(50));Sourcepub fn divide(&mut self) -> Result<EngineSignal, String>
pub fn divide(&mut self) -> Result<EngineSignal, String>
Performs division on the top two operands of the stack.
§Behavior
- Retrieves the top two values from the stack as
Decimalnumbers. - Computes the quotient of these values.
- Pushes the result back onto the stack.
- Returns
EngineSignal::StackUpdatedto indicate a successful operation.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if there are not enough operands on the stack or if the operands are invalid.
§Errors
This function will return an error if:
- The stack contains fewer than two operands.
- The operands are of an invalid type that cannot be converted to
Decimal. - The denominator is zero
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(10));
engine.stack.push(Bucket::from(5));
assert!(engine.divide().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(2));Sourcepub fn power(&mut self) -> Result<EngineSignal, String>
pub fn power(&mut self) -> Result<EngineSignal, String>
Performs exponentiation on the top two operands of the stack.
§Behavior
- Retrieves the top two values from the stack as
Decimalnumbers. - Treats the item on the
top-1of the stack as the base and the item on the top of the stack as the exponent. - If the exponent is an integer, uses
checked_powdfromrust_decimal. - If the exponent is a decimal, converts both values to
f64and usespowf. - Pushes the result back onto the stack.
- Returns
EngineSignal::StackUpdatedto indicate a successful operation.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if there are not enough operands on the stack or if the operands are invalid.
§Errors
This function will return an error if:
- The stack contains fewer than two operands.
- Either operand is of an invalid type that cannot be converted to
Decimal. - Converting a value to
f64fails. - Overflow occurs during exponentiation.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(2));
engine.stack.push(Bucket::from(3));
assert!(engine.power().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(8)); // 2^3 = 8Sourcepub fn sqrt(&mut self) -> Result<EngineSignal, String>
pub fn sqrt(&mut self) -> Result<EngineSignal, String>
Calculates the square root of the top operand on the stack.
§Behavior
- Retrieves the top value from the stack as a
Decimalnumber. - Computes the square root of this value.
- Pushes the result back onto the stack.
- Returns
EngineSignal::StackUpdatedto indicate a successful operation.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if there are not enough operands on the stack or if the operands are invalid.
§Errors
This function will return an error if:
- The stack is empty
- The operand is of an invalid type that cannot be converted to
Decimal.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(16));
assert!(engine.sqrt().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(4));Sourcepub fn modulo(&mut self) -> Result<EngineSignal, String>
pub fn modulo(&mut self) -> Result<EngineSignal, String>
Performs modulo on the top two operands of the stack.
§Behavior
- Retrieves the top two values from the stack as
Decimalnumbers. - Computes the euclidean modulo of these values.
- Pushes the result back onto the stack.
- Returns
EngineSignal::StackUpdatedto indicate a successful operation.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if there are not enough operands on the stack or if the operands are invalid.
§Errors
This function will return an error if:
- The stack contains fewer than two operands.
- The operands are of an invalid type that cannot be converted to
Decimal. - The denominator is zero
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(11));
engine.stack.push(Bucket::from(2));
assert!(engine.modulo().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(1));Sourcepub fn sin(&mut self) -> Result<EngineSignal, String>
pub fn sin(&mut self) -> Result<EngineSignal, String>
Computes the sine of the top operand on the stack.
§Behavior
- Retrieves the top value from the stack.
- Computes the sine of the value.
- Pushes the result back onto the stack.
- Returns
EngineSignal::StackUpdatedupon success.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if the stack is empty or the operand cannot be processed.
§Errors
This function will return an error if:
- The stack contains no operands.
- The operand does not support the
sinoperation.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(0.0));
assert!(engine.sin().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(0.0)); // sin(0) = 0Sourcepub fn cos(&mut self) -> Result<EngineSignal, String>
pub fn cos(&mut self) -> Result<EngineSignal, String>
Computes the cosine of the top operand on the stack.
§Behavior
- Retrieves the top value from the stack.
- Computes the cosine of the value.
- Pushes the result back onto the stack.
- Returns
EngineSignal::StackUpdatedupon success.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if the stack is empty or the operand cannot be processed.
§Errors
This function will return an error if:
- The stack contains no operands.
- The operand does not support the
cosoperation.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(0.0));
assert!(engine.cos().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(1.0)); // cos(0) = 1Sourcepub fn tan(&mut self) -> Result<EngineSignal, String>
pub fn tan(&mut self) -> Result<EngineSignal, String>
Computes the tangent of the top operand on the stack.
§Behavior
- Retrieves the top value from the stack.
- Computes the tangent of the value.
- Pushes the result back onto the stack.
- Returns
EngineSignal::StackUpdatedupon success.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if the stack is empty or the operand cannot be processed.
§Errors
This function will return an error if:
- The stack contains no operands.
- The operand does not support the
tanoperation.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(0.0));
assert!(engine.tan().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(0.0)); // tan(0) = 0Sourcepub fn sec(&mut self) -> Result<EngineSignal, String>
pub fn sec(&mut self) -> Result<EngineSignal, String>
Computes the secant of the top operand on the stack.
§Behavior
- Retrieves the top value from the stack.
- Computes the secant of the value.
- Pushes the result back onto the stack.
- Returns
EngineSignal::StackUpdatedupon success.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if the stack is empty or the operand cannot be processed.
§Errors
This function will return an error if:
- The stack contains no operands.
- The operand does not support the
secoperation.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(0.0));
assert!(engine.sec().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(1.0)); // sec(0) = 1Sourcepub fn csc(&mut self) -> Result<EngineSignal, String>
pub fn csc(&mut self) -> Result<EngineSignal, String>
Computes the cosecant of the top operand on the stack.
§Behavior
- Retrieves the top value from the stack.
- Computes the cosecant of the value.
- Pushes the result back onto the stack.
- Returns
EngineSignal::StackUpdatedupon success.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if the stack is empty or the operand cannot be processed.
§Errors
This function will return an error if:
- The stack contains no operands.
- The operand does not support the
cscoperation.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(0.0));
assert!(engine.csc().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::new_undefined()); // csc(0) = undefinedSourcepub fn cot(&mut self) -> Result<EngineSignal, String>
pub fn cot(&mut self) -> Result<EngineSignal, String>
Computes the cotangent of the top operand on the stack.
§Behavior
- Retrieves the top value from the stack.
- Computes the cotangent of the value.
- Pushes the result back onto the stack.
- Returns
EngineSignal::StackUpdatedupon success.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if the stack is empty or the operand cannot be processed.
§Errors
This function will return an error if:
- The stack contains no operands.
- The operand does not support the
cotoperation.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(0.0));
assert!(engine.csc().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::new_undefined()); // cot(0) = undefinedSourcepub fn asin(&mut self) -> Result<EngineSignal, String>
pub fn asin(&mut self) -> Result<EngineSignal, String>
Computes the arcsine (inverse sine) of the top operand on the stack.
§Behavior
- Retrieves the top value from the stack.
- Computes the arcsine of the value (in radians).
- Pushes the result back onto the stack.
- Returns
EngineSignal::StackUpdatedupon success.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if the stack is empty or the operand cannot be processed.
§Errors
This function will return an error if:
- The stack contains no operands.
- The operand is not a valid input for the arcsine function (e.g., out of the range [-1, 1]).
§Example
use squiid_engine::bucket::{Bucket, ConstantTypes};
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(1.0));
assert!(engine.asin().is_ok());
// asin(1) = HalfPi
assert_eq!(engine.stack.last().unwrap().value, Bucket::from_constant(ConstantTypes::HalfPi).value);Sourcepub fn acos(&mut self) -> Result<EngineSignal, String>
pub fn acos(&mut self) -> Result<EngineSignal, String>
Computes the arccosine (inverse cosine) of the top operand on the stack.
§Behavior
- Retrieves the top value from the stack.
- Computes the arccosine of the value (in radians).
- Pushes the result back onto the stack.
- Returns
EngineSignal::StackUpdatedupon success.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if the stack is empty or the operand cannot be processed.
§Errors
This function will return an error if:
- The stack contains no operands.
- The operand is not a valid input for the arcsine function (e.g., out of the range [-1, 1]).
§Example
use squiid_engine::bucket::{Bucket, ConstantTypes};
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(-1.0));
assert!(engine.acos().is_ok());
// acos(-1) = Pi
assert_eq!(engine.stack.last().unwrap().value, Bucket::from_constant(ConstantTypes::Pi).value);Sourcepub fn atan(&mut self) -> Result<EngineSignal, String>
pub fn atan(&mut self) -> Result<EngineSignal, String>
Computes the arctangent (inverse tangent) of the top operand on the stack.
§Behavior
- Retrieves the top value from the stack.
- Computes the arctangent of the value (in radians).
- Pushes the result back onto the stack.
- Returns
EngineSignal::StackUpdatedupon success.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if the stack is empty or the operand cannot be processed.
§Errors
This function will return an error if:
- The stack contains no operands.
- The operand is not a valid input for the arcsine function (e.g., out of the range [-sqrt(3), sqrt(3)]).
§Example
use squiid_engine::bucket::{Bucket, ConstantTypes};
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(1.0));
assert!(engine.atan().is_ok());
// atan(1) = pi/4
assert_eq!(engine.stack.last().unwrap().value, Bucket::from_constant(ConstantTypes::QuarterPi).value);Sourcepub fn chs(&mut self) -> Result<EngineSignal, String>
pub fn chs(&mut self) -> Result<EngineSignal, String>
Changes the sign (negates) of the top operand on the stack.
§Behavior
- Retrieves the top value from the stack.
- Negates the value (multiplies by -1).
- Pushes the negated result back onto the stack.
- Returns
EngineSignal::StackUpdatedupon success.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if the stack is empty or the operand cannot be processed.
§Errors
This function will return an error if:
- The stack contains no operands.
- The operand cannot be processed (e.g., invalid type).
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(10.0));
assert!(engine.chs().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(-10.0));Sourcepub fn log(&mut self) -> Result<EngineSignal, String>
pub fn log(&mut self) -> Result<EngineSignal, String>
Computes the base-10 logarithm of the top operand on the stack.
§Behavior
- Retrieves the top value from the stack.
- Computes the base-10 logarithm (log10) of the value.
- If the value is 0 or negative, it returns an error.
- Pushes the result of the logarithm back onto the stack.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if the operand is less than or equal to 0, or if the stack is empty.
§Errors
This function will return an error if:
- The stack contains no operands.
- The operand is less than or equal to zero (logarithm of 0 or negative number is undefined).
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(100.0));
assert!(engine.log().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(2.0)); // log10(100) = 2Sourcepub fn blog(&mut self) -> Result<EngineSignal, String>
pub fn blog(&mut self) -> Result<EngineSignal, String>
Computes the logarithm of a number with a specified base using the change of base formula.
The change of base formula is:
log_b(a) = (log_d(a)) / (log_d(b))where:
ais the number whose logarithm is to be calculated.bis the base of the logarithm.
§Behavior
- Retrieves two operands from the stack: the number
aand the baseb. - Uses the change of base formula to compute the logarithm of
awith baseb. - If either operand is 0 or negative, or if division by zero occurs, it returns an error.
- Pushes the result back onto the stack.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if any of the following errors occur:- Either operand is 0 or negative.
- Division by zero occurs.
§Errors
This function will return an error if:
- Either operand is less than or equal to 0.
- Division by zero occurs during the calculation.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(100.0)); // 'a' value
engine.stack.push(Bucket::from(10.0)); // 'b' value (base)
assert!(engine.blog().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(2.0)); // log_10(100) = 2Sourcepub fn ln(&mut self) -> Result<EngineSignal, String>
pub fn ln(&mut self) -> Result<EngineSignal, String>
Computes the natural logarithm (ln) of a number.
The natural logarithm is the logarithm to the base of Euler’s number (e). It is defined for positive real numbers.
§Behavior
- Retrieves one operand from the stack (the number
a). - Computes the natural logarithm (ln) of the operand.
- If the operand is 0 or negative, returns an error.
- Pushes the result back onto the stack.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if the operand is 0 or negative.
§Errors
This function will return an error if:
- The operand is less than or equal to 0, as the natural logarithm is only defined for positive real numbers.
§Example
use squiid_engine::bucket::{Bucket, ConstantTypes};
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from_constant(ConstantTypes::E)); // Euler's number
assert!(engine.ln().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(1.0)); // ln(e) = 1Sourcepub fn abs(&mut self) -> Result<EngineSignal, String>
pub fn abs(&mut self) -> Result<EngineSignal, String>
Computes the absolute value of the top operand on the stack.
§Behavior
- Retrieves the top value from the stack.
- Takes the absolute value
- Pushes the negated result back onto the stack.
- Returns
EngineSignal::StackUpdatedupon success.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.Err(String)if the stack is empty or the operand cannot be processed.
§Errors
This function will return an error if:
- The stack contains no operands.
- The operand cannot be processed (e.g., invalid type).
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(-10.0));
assert!(engine.abs().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(10.0));Sourcepub fn equal(&mut self) -> Result<EngineSignal, String>
pub fn equal(&mut self) -> Result<EngineSignal, String>
Compares two operands for equality.
This function compares the top two operands on the stack to check if they are equal.
§Behavior
- Retrieves two operands from the stack (operands
aandb). - Compares the operands for equality (
a == b). - If the operands are equal, pushes
1(as au32) onto the stack; otherwise, pushes0.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.- The result is
1if the operands are equal, otherwise0.
§Errors
This function does not explicitly handle errors related to operand types.
It assumes that the operands are of compatible types (in this case, f64).
If incompatible types are used, an error will be returned by the get_operands_as_f function.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(5.0));
engine.stack.push(Bucket::from(5.0));
assert!(engine.equal().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(1)); // 5.0 == 5.0, so result is 1Sourcepub fn gt(&mut self) -> Result<EngineSignal, String>
pub fn gt(&mut self) -> Result<EngineSignal, String>
Compares two operands to check if the first is greater than the second.
This function compares the top two operands on the stack to check if the first operand is greater than the second operand.
§Behavior
- Retrieves two operands from the stack (operands
aandb). - Compares the operands to check if
a > b. - If the first operand is greater, pushes
1(as au32) onto the stack; otherwise, pushes0.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.- The result is
1if the first operand is greater than the second, otherwise0.
§Errors
This function does not explicitly handle errors related to operand types.
It assumes that the operands are of compatible types (in this case, f64).
If incompatible types are used, an error will be returned by the get_operands_as_f function.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(10.0));
engine.stack.push(Bucket::from(5.0));
assert!(engine.gt().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(1)); // 10.0 > 5.0, so result is 1Sourcepub fn lt(&mut self) -> Result<EngineSignal, String>
pub fn lt(&mut self) -> Result<EngineSignal, String>
Compares two operands to check if the first is less than the second.
This function compares the top two operands on the stack to check if the first operand is less than the second operand.
§Behavior
- Retrieves two operands from the stack (operands
aandb). - Compares the operands to check if
a < b. - If the first operand is less, pushes
1(as au32) onto the stack; otherwise, pushes0.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.- The result is
1if the first operand is greater than the second, otherwise0.
§Errors
This function does not explicitly handle errors related to operand types.
It assumes that the operands are of compatible types (in this case, f64).
If incompatible types are used, an error will be returned by the get_operands_as_f function.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(5.0));
engine.stack.push(Bucket::from(10.0));
assert!(engine.lt().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(1)); // 5.0 < 10.0, so result is 1Sourcepub fn geq(&mut self) -> Result<EngineSignal, String>
pub fn geq(&mut self) -> Result<EngineSignal, String>
Compares two operands to check if the first is greater than or equal to the second.
This function compares the top two operands on the stack to check if the first operand is greater than or equal to the second operand.
§Behavior
- Retrieves two operands from the stack (operands
aandb). - Compares the operands to check if
a >= b. - If the first operand is greater or equal, pushes
1(as au32) onto the stack; otherwise, pushes0.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.- The result is
1if the first operand is greater than or equal to the second, otherwise0.
§Errors
This function does not explicitly handle errors related to operand types.
It assumes that the operands are of compatible types (in this case, f64).
If incompatible types are used, an error will be returned by the get_operands_as_f function.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(10.0));
engine.stack.push(Bucket::from(9.0));
assert!(engine.geq().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(1)); // 10.0 >= 9.0, so result is 1Sourcepub fn leq(&mut self) -> Result<EngineSignal, String>
pub fn leq(&mut self) -> Result<EngineSignal, String>
Compares two operands to check if the first is less than or equal to the second.
This function compares the top two operands on the stack to check if the first operand is less than or equal to the second operand.
§Behavior
- Retrieves two operands from the stack (operands
aandb). - Compares the operands to check if
a <= b. - If the first operand is less or equal, pushes
1(as au32) onto the stack; otherwise, pushes0.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.- The result is
1if the first operand is less than or equal to the second, otherwise0.
§Errors
This function does not explicitly handle errors related to operand types.
It assumes that the operands are of compatible types (in this case, f64).
If incompatible types are used, an error will be returned by the get_operands_as_f function.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(9.0));
engine.stack.push(Bucket::from(10.0));
assert!(engine.leq().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(1)); // 9.0 <= 10.0, so result is 1Sourcepub fn round(&mut self) -> Result<EngineSignal, String>
pub fn round(&mut self) -> Result<EngineSignal, String>
Rounds a number to the nearest integer.
This function takes the top operand from the stack and rounds it to the nearest integer. The result is then pushed back onto the stack.
§Behavior
- Retrieves one operand from the stack.
- Rounds the operand to the nearest integer using Rust’s
f64::roundmethod. - Pushes the rounded result back onto the stack.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful.- The result is the rounded value of the operand.
§Errors
This function does not explicitly handle errors related to operand types. It assumes that
the operand is of type f64. If the operand is of an incompatible type, an error will be
returned by the get_operands_as_f function.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(3.7));
assert!(engine.round().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(4.0)); // Rounded from 3.7 to 4.0Sourcepub fn invert(&mut self) -> Result<EngineSignal, String>
pub fn invert(&mut self) -> Result<EngineSignal, String>
Inverts the top operand on the stack.
This function takes the top operand from the stack and computes its multiplicative inverse (1 / operand). If the operand is zero, an error is returned since division by zero is undefined. The result is then pushed back onto the stack.
§Behavior
- Retrieves one operand from the stack.
- Checks if the operand is zero. If it is, returns an error (division by zero).
- Computes the inverse of the operand (1 / operand) if it is non-zero.
- Pushes the result back onto the stack.
§Returns
Ok(EngineSignal::StackUpdated)if the operation is successful and the result is pushed onto the stack.Err(String)if the operand is zero, indicating division by zero.
§Errors
- Returns an error if the operand is zero, as division by zero is not allowed.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(5.0));
assert!(engine.invert().is_ok());
assert_eq!(engine.stack.last().unwrap(), &Bucket::from(0.2)); // Inverted from 5.0 to 0.2
engine.stack.push(Bucket::from(0.0));
assert!(engine.invert().is_err()); // Division by zero errorSourcepub fn drop(&mut self) -> Result<EngineSignal, String>
pub fn drop(&mut self) -> Result<EngineSignal, String>
Removes the top item from the stack.
This function pops the last item from the stack. If the stack is not empty, the item is removed.
If the stack is empty, the function does nothing but still returns EngineSignal::StackUpdated.
§Behavior
- Removes the top item from the stack.
§Returns
Ok(EngineSignal::StackUpdated)when the operation is successfully completed and the stack is updated.
§Errors
This function doesn’t return an error variant, and is only written this way to be compatible with the other engine functions.
§Notes
- If the stack is empty, the function will simply return without making changes, but still indicate that the stack has been updated.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(10.0));
assert!(engine.drop().is_ok());
assert!(engine.stack.is_empty()); // Stack is empty after dropping the itemSourcepub fn swap(&mut self) -> Result<EngineSignal, String>
pub fn swap(&mut self) -> Result<EngineSignal, String>
Swaps the top two items on the stack.
This function takes the last two values from the stack, removes them, and then places them back in reverse order.
§Behavior
- Retrieves the top two items from the stack.
- Swaps their positions on the stack.
§Returns
Ok(EngineSignal::StackUpdated)when the operation is successfully completed and the stack is updated.
§Errors
This function doesn’t return an error variant, and is only written this way to be compatible with the other engine functions.
§Notes
- If the stack has fewer than two items, the function will return an error indicating that not enough operands are present.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(5.0));
engine.stack.push(Bucket::from(10.0));
assert!(engine.swap().is_ok());
assert_eq!(engine.stack[0], Bucket::from(10.0)); // Top item after swap
assert_eq!(engine.stack[1], Bucket::from(5.0)); // Second item after swapSourcepub fn dup(&mut self) -> Result<EngineSignal, String>
pub fn dup(&mut self) -> Result<EngineSignal, String>
Duplicates the last item on the stack.
This function takes the top item from the stack and pushes it onto the stack twice, duplicating the top value.
§Returns
Ok(EngineSignal::StackUpdated)when the operation is successfully completed and the stack is updated.
§Errors
This function doesn’t return an error variant, and is only written this way to be compatible with the other engine functions.
§Notes
- If the stack is empty, the function will return an error indicating that no operand is available for duplication.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(5.0));
assert!(engine.dup().is_ok());
assert_eq!(engine.stack[0], Bucket::from(5.0)); // Top item after duplication
assert_eq!(engine.stack[1], Bucket::from(5.0)); // Duplicate itemSourcepub fn roll_down(&mut self) -> Result<EngineSignal, String>
pub fn roll_down(&mut self) -> Result<EngineSignal, String>
Rolls the stack down, rotating the elements to the right.
This function moves the topmost item to the bottom of the stack by rotating the stack right by one position.
§Returns
Ok(EngineSignal::StackUpdated)when the operation is successfully completed and the stack is updated.
§Errors
This function will return an error if:
- The stack is empty.
§Notes
- If the stack is empty, the function will return an error indicating that the operation cannot be performed.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(1.0));
engine.stack.push(Bucket::from(2.0));
engine.stack.push(Bucket::from(3.0));
assert!(engine.roll_down().is_ok());
assert_eq!(engine.stack[0], Bucket::from(3.0)); // Top item after roll
assert_eq!(engine.stack[2], Bucket::from(2.0)); // Last item moved to the bottomSourcepub fn roll_up(&mut self) -> Result<EngineSignal, String>
pub fn roll_up(&mut self) -> Result<EngineSignal, String>
Rolls the stack up, rotating the elements to the left.
This function moves the bottommost item to the top of the stack by rotating the stack left by one position.
§Returns
Ok(EngineSignal::StackUpdated)when the operation is successfully completed and the stack is updated.
§Errors
This function will return an error if:
- The stack is empty.
§Notes
- If the stack is empty, the function will return an error indicating that the operation cannot be performed.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(1.0));
engine.stack.push(Bucket::from(2.0));
engine.stack.push(Bucket::from(3.0));
assert!(engine.roll_up().is_ok());
assert_eq!(engine.stack[2], Bucket::from(1.0)); // Bottom item moved to the top
assert_eq!(engine.stack[0], Bucket::from(2.0));Sourcepub fn store(&mut self) -> Result<EngineSignal, String>
pub fn store(&mut self) -> Result<EngineSignal, String>
Stores a value in a variable.
This function stores the topmost value from the stack into a variable, validating that the variable name follows a valid identifier pattern.
§Returns
Ok(EngineSignal::StackUpdated)when the operation is successfully completed and the stack is updated.
§Errors
This function will return an error if:
- The variable name is not a valid ID
§Notes
- If the second operand is not a valid variable name, an error is returned.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(5.0));
engine.stack.push(Bucket::from("var1"));
assert!(engine.store().is_ok());
// Variable "var1" should now store the value 5.0
assert!(engine.variables.get("var1").is_some());Sourcepub fn purge(&mut self) -> Result<EngineSignal, String>
pub fn purge(&mut self) -> Result<EngineSignal, String>
Deletes a variable from memory.
This function removes a variable from the internal variable store if it exists. It only works if the variable is a valid identifier.
§Returns
Ok(EngineSignal::StackUpdated)when the operation is successfully completed and the stack is updated.
§Errors
This function will return an error if:
- The variable name is not a valid ID
- The variable is not set
§Notes
- If the variable does not exist or is not a valid identifier, an error is returned.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(5.0));
engine.stack.push(Bucket::from("var1"));
engine.store(); // Store a value in a variable
assert!(engine.variables.get("var1").is_some());
engine.stack.push(Bucket::from("var1"));
assert!(engine.purge().is_ok());
// Variable should now be removed
assert!(engine.variables.get("var1").is_none());Sourcepub fn invstore(&mut self) -> Result<EngineSignal, String>
pub fn invstore(&mut self) -> Result<EngineSignal, String>
Stores a value in a variable, with inverted argument order. Useful for how variable assignments are parsed in algebraic mode.
This function swaps the top two values on the stack and then calls the store function to store the value in the variable.
§Returns
Ok(EngineSignal::StackUpdated)when the operation is successfully completed and the stack is updated.
§Errors
This function will return an error if:
- The variable name is not a valid ID
§Notes
- This function uses
swap()and will return an error if swapping fails.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from("var1"));
engine.stack.push(Bucket::from(5.0));
assert!(engine.invstore().is_ok());
// Variable "var1" should now store the value 5.0
assert!(engine.variables.get("var1").is_some());Sourcepub fn clear(&mut self) -> Result<EngineSignal, String>
pub fn clear(&mut self) -> Result<EngineSignal, String>
Clears the entire stack.
This function empties the stack, removing all items stored in it.
§Returns
Ok(EngineSignal::StackUpdated)when the stack has been successfully cleared.
§Errors
This function doesn’t return an error variant, and is only written this way to be compatible with the other engine functions.
§Notes
- This function does not return an error; the stack is simply cleared.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
engine.stack.push(Bucket::from(5.0));
engine.stack.push(Bucket::from(10.0));
assert!(engine.clear().is_ok());
assert!(engine.stack.is_empty()); // Stack is now emptySourcepub fn undo(&mut self) -> Result<EngineSignal, String>
pub fn undo(&mut self) -> Result<EngineSignal, String>
Undoes the last operation by reverting the stack and variables to their previous state.
This function reverts the stack and variables to the state they were in at the time of the last operation. If no operations have been performed or the undo history has been exhausted, an error is returned.
§Returns
Ok(EngineSignal::StackUpdated)when the undo is successfully performed and the stack and variables are updated.Err(String)if there is no operation to undo.
§Errors
This function will return an error if:
- You try to undo further than the history allows
§Notes
- The undo history is stored, and each undo operation increments a pointer to track the state.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
use squiid_engine;
let mut engine = Engine::new();
// after each command, we must push a copy of the stack to the engine history
let _ = squiid_engine::handle_data(&mut engine, "1");
let _ = squiid_engine::handle_data(&mut engine, "2");
let _ = squiid_engine::handle_data(&mut engine, "test");
// test undo of adding something to the stack
let _ = engine.undo();
assert_eq!(engine.stack, vec![Bucket::from(1), Bucket::from(2),]);Sourcepub fn redo(&mut self) -> Result<EngineSignal, String>
pub fn redo(&mut self) -> Result<EngineSignal, String>
Redoes the last undone operation by restoring the stack and variables.
This function restores the stack and variables to the state they were in at the time of the last undone operation. If no operations have been undone or the redo history is exhausted, an error is returned.
§Returns
Ok(EngineSignal::StackUpdated)when the redo is successfully performed and the stack and variables are updated.Err(String)if there are no operations to redo.
§Errors
This function will return an error if:
- You try to redo further than the number of undone operations
§Notes
- The redo history is tracked using the undo state pointer to determine the next state to restore.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
use squiid_engine;
let mut engine = Engine::new();
// after each command, we must push a copy of the stack to the engine history
let _ = squiid_engine::handle_data(&mut engine, "1");
let _ = squiid_engine::handle_data(&mut engine, "2");
let _ = squiid_engine::handle_data(&mut engine, "test");
// test undo of adding something to the stack
let _ = engine.undo();
assert_eq!(engine.stack, vec![Bucket::from(1), Bucket::from(2),]);
// test redo
let _ = engine.redo();
assert_eq!(engine.stack, vec![Bucket::from(1), Bucket::from(2), Bucket::from("test")]);Sourcepub fn quit(&mut self) -> Result<EngineSignal, String>
pub fn quit(&mut self) -> Result<EngineSignal, String>
Terminates the engine and signals the system to quit.
This function sends a quit signal to the engine, indicating that it should stop processing and exit.
§Returns
Ok(EngineSignal::Quit)when the quit signal is sent.
§Errors
This function doesn’t return an error variant, and is only written this way to be compatible with the other engine functions.
§Notes
- This function does not affect the state of the stack or variables but instead signals the engine to stop execution.
§Example
use squiid_engine::bucket::Bucket;
use squiid_engine::engine::Engine;
let mut engine = Engine::new();
assert!(engine.quit().is_ok()); // The engine is now quitting