65 lines
1.7 KiB
Markdown
65 lines
1.7 KiB
Markdown
---
|
|
name = "Compute simple Forth expressions"
|
|
file = "src/vec/compute.rs"
|
|
---
|
|
|
|
[Forth](https://en.wikipedia.org/wiki/Forth_(programming_language)) is a stack based programming language based on the [Reverse Polish Notation](https://en.wikipedia.org/wiki/Reverse_Polish_notation). In this language, a program is expressed as a stream of words, each word representing an instruction. For example, this expression:
|
|
|
|
```
|
|
1.0 2.0 +
|
|
```
|
|
|
|
represent a program made of 3 words: `1.0` meaning "push the number 1.0" on the stack, `2.0` meaning push 2.0 on the stack, and `+` meaning "pop the two highest numbers off the stack, and push their sum". We will first define some types to represent such program, and then implement the `compute` function, taking a `slice` of operations and giving the result of computing these operations.
|
|
|
|
```rust
|
|
/// Possible operations
|
|
pub enum Operation {
|
|
Push(f32),
|
|
Binary(Binary),
|
|
}
|
|
|
|
/// Different binary operators
|
|
pub enum Binary {
|
|
/// +
|
|
Add,
|
|
/// -
|
|
Sub,
|
|
/// *
|
|
Mul,
|
|
/// /
|
|
Div,
|
|
}
|
|
|
|
/// What could go wrong when computing a Forth expression
|
|
#[derive(PartialEq, Debug)]
|
|
pub enum ComputeError {
|
|
NotEnoughData,
|
|
DivisionByZero,
|
|
}
|
|
```
|
|
|
|
```prototype
|
|
pub fn compute(operations: &[Operation]) -> Result<f32, ComputeError> {
|
|
unimplemented!()
|
|
}
|
|
```
|
|
|
|
```example
|
|
fn main() {
|
|
// 1 2 3 * +
|
|
// gives the result 7 because it's computed as 1 + 2 * 3
|
|
assert_eq!(
|
|
compute(&[
|
|
Operation::Push(1.0),
|
|
Operation::Push(2.0),
|
|
Operation::Push(3.0),
|
|
Operation::Binary(Binary::Mul),
|
|
Operation::Binary(Binary::Add),
|
|
]),
|
|
Ok(7.0)
|
|
);
|
|
|
|
assert_eq!(compute(&[Operation::Binary(Binary::Add)), Err(ComputeError::NotEnoughData));
|
|
}
|
|
```
|