Skip to content

Commit

Permalink
forth: return Vec<Value>, not String, from stack (#294)
Browse files Browse the repository at this point in the history
Questioning the assumptions: Why must the output be a string?

Reasons I thought of:

* It was this way in the original version of the exercise:
  exercism/exercism#1188
    * But, we have no obligation to follow that.
* It matches the fact that we have strings as inputs.
    * But, it is probably more work for the student to create a string.
    * It can be argued that it's easier to check the vector.

Previous discussions:
exercism/problem-specifications#394 (comment)
exercism/haskell#412

This doesn't get this track all the way to forth 1.0.0, but is a useful
step there.
  • Loading branch information
petertseng authored Jun 7, 2017
1 parent d10471d commit 23f2dde
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 25 deletions.
8 changes: 2 additions & 6 deletions exercises/forth/example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,8 @@ impl Forth {
}
}

pub fn format_stack(&self) -> String {
let mut s = self.stack.iter().fold(String::new(), |s, v| {
s + &v.to_string() + " "
});
s.pop();
s
pub fn stack(&self) -> Vec<Value> {
self.stack.iter().cloned().collect()
}

pub fn eval(&mut self, input: &str) -> ForthResult {
Expand Down
2 changes: 1 addition & 1 deletion exercises/forth/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl Forth {
pub fn new() -> Forth {
}

pub fn format_stack(&self) -> String {
pub fn stack(&self) -> Vec<Value> {
}

pub fn eval(&mut self, input: &str) -> ForthResult {
Expand Down
36 changes: 18 additions & 18 deletions exercises/forth/tests/forth.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
extern crate forth;

use forth::{Forth, Error};
use forth::{Forth, Error, Value};

#[test]
fn no_input_no_stack() {
assert_eq!("", Forth::new().format_stack());
assert_eq!(Vec::<Value>::new(), Forth::new().stack());
}

#[test]
#[ignore]
fn numbers_just_get_pushed_onto_the_stack() {
let mut f = Forth::new();
assert!(f.eval("1 2 3 4 5 -1").is_ok());
assert_eq!("1 2 3 4 5 -1", f.format_stack());
assert_eq!(vec![1, 2, 3, 4, 5, -1], f.stack());
}

#[test]
Expand All @@ -21,23 +21,23 @@ fn non_word_characters_are_separators() {
let mut f = Forth::new();
// Note the Ogham Space Mark ( ), this is a spacing character.
assert!(f.eval("1\u{0000}2\u{0001}3\n4\r5 6\t7").is_ok());
assert_eq!("1 2 3 4 5 6 7", f.format_stack());
assert_eq!(vec![1, 2, 3, 4, 5, 6, 7], f.stack());
}

#[test]
#[ignore]
fn basic_arithmetic_1() {
let mut f = Forth::new();
assert!(f.eval("1 2 + 4 -").is_ok());
assert_eq!("-1", f.format_stack());
assert_eq!(vec![-1], f.stack());
}

#[test]
#[ignore]
fn basic_arithmetic_2() {
let mut f = Forth::new();
assert!(f.eval("2 4 * 3 /").is_ok());
assert_eq!("2", f.format_stack());
assert_eq!(vec![2], f.stack());
}

#[test]
Expand Down Expand Up @@ -95,15 +95,15 @@ fn division_by_zero() {
fn dup() {
let mut f = Forth::new();
assert!(f.eval("1 DUP").is_ok());
assert_eq!("1 1", f.format_stack());
assert_eq!(vec![1, 1], f.stack());
}

#[test]
#[ignore]
fn dup_case_insensitive() {
let mut f = Forth::new();
assert!(f.eval("1 Dup").is_ok());
assert_eq!("1 1", f.format_stack());
assert_eq!(vec![1, 1], f.stack());
}

#[test]
Expand All @@ -121,15 +121,15 @@ fn dup_error() {
fn drop() {
let mut f = Forth::new();
assert!(f.eval("1 drop").is_ok());
assert_eq!("", f.format_stack());
assert_eq!(Vec::<Value>::new(), f.stack());
}

#[test]
#[ignore]
fn drop_with_two() {
let mut f = Forth::new();
assert!(f.eval("1 2 drop").is_ok());
assert_eq!("1", f.format_stack());
assert_eq!(vec![1], f.stack());
}

#[test]
Expand All @@ -147,15 +147,15 @@ fn drop_error() {
fn swap() {
let mut f = Forth::new();
assert!(f.eval("1 2 swap").is_ok());
assert_eq!("2 1", f.format_stack());
assert_eq!(vec![2, 1], f.stack());
}

#[test]
#[ignore]
fn swap_with_three() {
let mut f = Forth::new();
assert!(f.eval("1 2 3 swap").is_ok());
assert_eq!("1 3 2", f.format_stack());
assert_eq!(vec![1, 3, 2], f.stack());
}

#[test]
Expand All @@ -177,15 +177,15 @@ fn swap_error() {
fn over() {
let mut f = Forth::new();
assert!(f.eval("1 2 over").is_ok());
assert_eq!("1 2 1", f.format_stack());
assert_eq!(vec![1, 2, 1], f.stack());
}

#[test]
#[ignore]
fn over_with_three() {
let mut f = Forth::new();
assert!(f.eval("1 2 3 over").is_ok());
assert_eq!("1 2 3 2", f.format_stack());
assert_eq!(vec![1, 2, 3, 2], f.stack());
}

#[test]
Expand All @@ -208,7 +208,7 @@ fn defining_a_new_word() {
let mut f = Forth::new();
assert!(f.eval(": CoUnT 1 2 3 ;").is_ok());
assert!(f.eval("count COUNT").is_ok());
assert_eq!("1 2 3 1 2 3", f.format_stack());
assert_eq!(vec![1, 2, 3, 1, 2, 3], f.stack());
}

#[test]
Expand All @@ -218,7 +218,7 @@ fn redefining_an_existing_word() {
assert!(f.eval(": foo dup ;").is_ok());
assert!(f.eval(": foo dup dup ;").is_ok());
assert!(f.eval("1 foo").is_ok());
assert_eq!("1 1 1", f.format_stack());
assert_eq!(vec![1, 1, 1], f.stack());
}

#[test]
Expand All @@ -227,15 +227,15 @@ fn redefining_an_existing_built_in_word() {
let mut f = Forth::new();
assert!(f.eval(": swap dup ;").is_ok());
assert!(f.eval("1 swap").is_ok());
assert_eq!("1 1", f.format_stack());
assert_eq!(vec![1, 1], f.stack());
}

#[test]
#[ignore]
fn defining_words_with_odd_characters() {
let mut f = Forth::new();
assert!(f.eval(": € 220371 ; €").is_ok());
assert_eq!("220371", f.format_stack());
assert_eq!(vec![220371], f.stack());
}

#[test]
Expand Down

0 comments on commit 23f2dde

Please sign in to comment.