From 23f2dde37d4969493a31cf7dc2aa7ee81cd6ecea Mon Sep 17 00:00:00 2001 From: Peter Tseng Date: Tue, 6 Jun 2017 20:16:39 -0700 Subject: [PATCH] forth: return `Vec`, not `String`, from `stack` (#294) 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: https://github.com/exercism/exercism.io/pull/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: https://github.com/exercism/x-common/pull/394#discussion_r81705078 https://github.com/exercism/xhaskell/pull/412 This doesn't get this track all the way to forth 1.0.0, but is a useful step there. --- exercises/forth/example.rs | 8 ++------ exercises/forth/src/lib.rs | 2 +- exercises/forth/tests/forth.rs | 36 +++++++++++++++++----------------- 3 files changed, 21 insertions(+), 25 deletions(-) diff --git a/exercises/forth/example.rs b/exercises/forth/example.rs index 595767cd4..ab7eacaf7 100644 --- a/exercises/forth/example.rs +++ b/exercises/forth/example.rs @@ -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 { + self.stack.iter().cloned().collect() } pub fn eval(&mut self, input: &str) -> ForthResult { diff --git a/exercises/forth/src/lib.rs b/exercises/forth/src/lib.rs index 2b8e59647..97d9a73bb 100644 --- a/exercises/forth/src/lib.rs +++ b/exercises/forth/src/lib.rs @@ -15,7 +15,7 @@ impl Forth { pub fn new() -> Forth { } - pub fn format_stack(&self) -> String { + pub fn stack(&self) -> Vec { } pub fn eval(&mut self, input: &str) -> ForthResult { diff --git a/exercises/forth/tests/forth.rs b/exercises/forth/tests/forth.rs index 95dc91acf..6a16dfa9d 100644 --- a/exercises/forth/tests/forth.rs +++ b/exercises/forth/tests/forth.rs @@ -1,10 +1,10 @@ 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::::new(), Forth::new().stack()); } #[test] @@ -12,7 +12,7 @@ fn no_input_no_stack() { 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] @@ -21,7 +21,7 @@ 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] @@ -29,7 +29,7 @@ fn non_word_characters_are_separators() { 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] @@ -37,7 +37,7 @@ fn basic_arithmetic_1() { 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] @@ -95,7 +95,7 @@ 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] @@ -103,7 +103,7 @@ fn dup() { 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] @@ -121,7 +121,7 @@ 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::::new(), f.stack()); } #[test] @@ -129,7 +129,7 @@ fn drop() { 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] @@ -147,7 +147,7 @@ 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] @@ -155,7 +155,7 @@ fn swap() { 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] @@ -177,7 +177,7 @@ 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] @@ -185,7 +185,7 @@ fn over() { 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] @@ -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] @@ -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] @@ -227,7 +227,7 @@ 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] @@ -235,7 +235,7 @@ fn redefining_an_existing_built_in_word() { 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]