From 7d8986ccb5d528035ba6aa103f810a1a80b95fbb Mon Sep 17 00:00:00 2001
From: Michael Aaron Murphy <mmstickman@gmail.com>
Date: Thu, 6 Apr 2017 17:23:22 -0400
Subject: [PATCH] Mark String/Array Methods As Complete

---
 README.md                        | 26 ++++++++++++++++++++++----
 examples/methods.ion             |  7 +++++++
 examples/methods.out             |  4 ++++
 src/parser/shell_expand/mod.rs   |  2 ++
 src/parser/shell_expand/words.rs | 10 ++++++++++
 src/parser/statements.rs         |  4 +++-
 6 files changed, 48 insertions(+), 5 deletions(-)
 create mode 100644 examples/methods.ion
 create mode 100644 examples/methods.out

diff --git a/README.md b/README.md
index 009d3f16..3bde3e3d 100644
--- a/README.md
+++ b/README.md
@@ -17,8 +17,8 @@ core functionality is complete. Features below:
 - [x] Array Expressions (**[]**)
 - [x] Array-based Command Substitution (**@[]**)
 - [x] String-based Command Substitution (**$()**)
-- [ ] Array Methods (**@split(var, ' ')**)
-- [ ] String Methods (**$join(array, ', ')**)
+- [x] Array Methods (**@split(var, ' ')**)
+- [x] String Methods (**$join(array, ', ')**)
 - [x] Array Splicing
 - [ ] Maps
 - [x] For Loops
@@ -57,8 +57,8 @@ If the command is executed without any arguments, it will simply list all availa
 
 ### Using Variables
 
-Variables may be called with ith **$** sigil, where the value that follows may be a local or global value.
-They may also be optionally be defined using a braced syntax, which is useful in the event that you need the value
+Variables may be called with the **$** sigil, where the value that follows may be a local or global value.
+They may also be optionally defined using a braced syntax, which is useful in the event that you need the value
 integrated alongside other characters that do not terminate the variable parsing.
 
 ```ion
@@ -225,6 +225,24 @@ echo @array[3..]
 echo @array[..]
 ```
 
+### Methods
+
+There are two types of methods -- string-based and array-based methods. The type that a method returns is denoted
+by the sigil that is used to invoke the method. Currently, there are only two supported methods: **$join()** and
+**@split**.
+
+```ion
+let results = [ 1 2 3 4 5]
+echo $join(results) @join # Both of these effectively do the same thing
+echo $join(results, ', ') # You may provide a custom pattern instead
+
+let line = "one  two  three  four  five"
+echo @split(line) # Splits a line by whitespace
+
+let row = "one,two,three,four,five"
+echo @split(row, ',') # Splits by commas
+```
+
 ### Commands
 
 Commands may be written line by line or altogether on the same line with semicolons separating them.
diff --git a/examples/methods.ion b/examples/methods.ion
new file mode 100644
index 00000000..8db26733
--- /dev/null
+++ b/examples/methods.ion
@@ -0,0 +1,7 @@
+let array = [ one two three four ]
+let space_string = $join(array)
+let comma_string = $join(array, ', ')
+echo $space_string
+echo $comma_string
+echo @split(space_string)
+echo @split(comma_string, ', ')
diff --git a/examples/methods.out b/examples/methods.out
new file mode 100644
index 00000000..128c4c4c
--- /dev/null
+++ b/examples/methods.out
@@ -0,0 +1,4 @@
+one two three four
+one, two, three, four
+one two three four
+one two three four
diff --git a/src/parser/shell_expand/mod.rs b/src/parser/shell_expand/mod.rs
index dc5bf174..c764e01e 100644
--- a/src/parser/shell_expand/mod.rs
+++ b/src/parser/shell_expand/mod.rs
@@ -1,3 +1,5 @@
+// TODO: Handle Runtime Errors
+
 extern crate permutate;
 
 mod braces;
diff --git a/src/parser/shell_expand/words.rs b/src/parser/shell_expand/words.rs
index f97033c4..e27cf661 100644
--- a/src/parser/shell_expand/words.rs
+++ b/src/parser/shell_expand/words.rs
@@ -158,6 +158,11 @@ impl<'a> WordIterator<'a> {
                                 }
                                 self.read += 1;
                             }
+                        } else if character == b')' {
+                            // If no pattern is supplied, the default is a space.
+                            let variable = &self.data[start..self.read];
+                            self.read += 1;
+                            return WordToken::StringMethod(method, variable, " ");
                         }
                         self.read += 1;
                     }
@@ -221,6 +226,11 @@ impl<'a> WordIterator<'a> {
                                 }
                                 self.read += 1;
                             }
+                        } else if character == b')' {
+                            // If no pattern is supplied, the default is a space.
+                            let variable = &self.data[start..self.read];
+                            self.read += 1;
+                            return WordToken::ArrayMethod(method, variable, " ");
                         }
                         self.read += 1;
                     }
diff --git a/src/parser/statements.rs b/src/parser/statements.rs
index 3079031a..56cce713 100644
--- a/src/parser/statements.rs
+++ b/src/parser/statements.rs
@@ -1,4 +1,6 @@
-// TODO: Rewrite this in the same style as shell_expand::words.
+// TODO: 
+// - Rewrite this in the same style as shell_expand::words.
+// - Validate syntax in methods
 
 use std::u16;
 use std::io::{self, Write};
-- 
GitLab