finifini
This commit is contained in:
parent
2ddc195b73
commit
d8ea42b795
@ -59,3 +59,7 @@ exercises:
|
||||
- "compute_division_by_zero_push"
|
||||
- "compute_division_by_zero_operation"
|
||||
- "compute_all_ops"
|
||||
- "compute_add"
|
||||
- "compute_sub"
|
||||
- "compute_mul"
|
||||
- "compute_div"
|
||||
|
||||
@ -56,3 +56,23 @@ pub fn compute_all_ops() {
|
||||
Ok(3.0),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn compute_add() {
|
||||
assert_eq!(compute(&[Operation::Push(1.0), Operation::Push(2.0), Operation::Binary(Binary::Add)]), Ok(3.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn compute_sub() {
|
||||
assert_eq!(compute(&[Operation::Push(1.0), Operation::Push(2.0), Operation::Binary(Binary::Sub)]), Ok(-1.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn compute_mul() {
|
||||
assert_eq!(compute(&[Operation::Push(3.0), Operation::Push(2.0), Operation::Binary(Binary::Mul)]), Ok(6.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn compute_div() {
|
||||
assert_eq!(compute(&[Operation::Push(42.0), Operation::Push(7.0), Operation::Binary(Binary::Div)]), Ok(6.0));
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
│ └── result.rs
|
||||
├── errors.rs
|
||||
├── vec
|
||||
│ └── access.rs
|
||||
│ ├── access.rs
|
||||
│ └── compute.rs
|
||||
├── vec.rs
|
||||
└── lib.rs
|
||||
|
||||
64
subject_text/vec/compute.md
Normal file
64
subject_text/vec/compute.md
Normal file
@ -0,0 +1,64 @@
|
||||
---
|
||||
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));
|
||||
}
|
||||
```
|
||||
@ -1,7 +1,7 @@
|
||||
---
|
||||
name = "Vecs and slices"
|
||||
difficulty = 2
|
||||
exercises = ["access.md"]
|
||||
difficulty = 5
|
||||
exercises = ["access.md", "compute.md"]
|
||||
---
|
||||
|
||||
Let's now look at some functions on [`slice`](https://doc.rust-lang.org/std/primitive.slice.html)s and [`Vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html)s. Instead of manualy checking things we will follow the type system using `Option`s and `Result`s we saw earlier.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user