From b9866761450540bb1185e24f62d21e8adf07e921 Mon Sep 17 00:00:00 2001
From: Xavier L'Heureux <xavier.lheureux@icloud.com>
Date: Thu, 11 Apr 2019 07:16:36 -0400
Subject: [PATCH] Use Terminator before StatementSplitter to trim comments &
 whitespace

---
 src/lib/parser/statement/parse.rs | 35 ++++++++++++++-----------------
 src/lib/shell/flow.rs             | 35 ++++++++++++++++++-------------
 2 files changed, 36 insertions(+), 34 deletions(-)

diff --git a/src/lib/parser/statement/parse.rs b/src/lib/parser/statement/parse.rs
index e399820b..7d6b9dd8 100644
--- a/src/lib/parser/statement/parse.rs
+++ b/src/lib/parser/statement/parse.rs
@@ -1,5 +1,5 @@
 use super::{
-    super::pipelines::{self, Pipeline},
+    super::pipelines,
     case,
     functions::{collect_arguments, parse_function},
 };
@@ -13,19 +13,6 @@ use crate::{
 use small;
 use std::char;
 
-fn collect<F>(arguments: &str, statement: F) -> Statement
-where
-    F: Fn(Pipeline) -> Statement,
-{
-    match pipelines::Collector::run(arguments) {
-        Ok(pipeline) => statement(pipeline),
-        Err(err) => {
-            eprintln!("ion: syntax error: {}", err);
-            Statement::Default
-        }
-    }
-}
-
 pub fn is_valid_name(name: &str) -> bool {
     let mut chars = name.chars();
     chars.next().map_or(false, |b| b.is_alphabetic())
@@ -109,12 +96,16 @@ pub(crate) fn parse(code: &str) -> Statement {
                 Statement::Else
             }
         }
-        _ if cmd.starts_with("while ") => {
-            collect(cmd[6..].trim_start(), |pipeline| Statement::While {
+        _ if cmd.starts_with("while ") => match pipelines::Collector::run(cmd[6..].trim_start()) {
+            Ok(pipeline) => Statement::While {
                 expression: vec![Statement::Pipeline(pipeline)],
                 statements: Vec::new(),
-            })
-        }
+            },
+            Err(err) => {
+                eprintln!("ion: syntax error: {}", err);
+                Statement::Default
+            }
+        },
         _ if cmd.starts_with("for ") => {
             let mut cmd = cmd[4..].trim_start();
             let mut variables = None;
@@ -213,7 +204,13 @@ pub(crate) fn parse(code: &str) -> Statement {
         _ if cmd.starts_with("! ") => Statement::Not(Box::new(parse(cmd[1..].trim_start()))),
         _ if cmd.eq("not") | cmd.eq("!") => Statement::Not(Box::new(Statement::Default)),
         _ if cmd.is_empty() || cmd.starts_with('#') => Statement::Default,
-        _ => collect(cmd, Statement::Pipeline),
+        _ => match pipelines::Collector::run(cmd) {
+            Ok(pipeline) => Statement::Pipeline(pipeline),
+            Err(err) => {
+                eprintln!("ion: syntax error: {}", err);
+                Statement::Default
+            }
+        },
     }
 }
 
diff --git a/src/lib/shell/flow.rs b/src/lib/shell/flow.rs
index 4fff77e3..81d59fd8 100644
--- a/src/lib/shell/flow.rs
+++ b/src/lib/shell/flow.rs
@@ -11,7 +11,7 @@ use crate::{
         assignments::is_array,
         expand_string, parse_and_validate,
         pipelines::{PipeItem, Pipeline},
-        ForValueExpression, StatementSplitter,
+        ForValueExpression, StatementSplitter, Terminator,
     },
     shell::{assignments::VariableStore, variables::Value},
     types,
@@ -366,21 +366,26 @@ impl FlowLogic for Shell {
 
     fn on_command(&mut self, command_string: &str) {
         self.break_flow = false;
-        let iterator = StatementSplitter::new(command_string).map(parse_and_validate);
-
-        // Go through all of the statements and build up the block stack
-        // When block is done return statement for execution.
-        for statement in iterator {
-            match insert_statement(&mut self.flow_control, statement) {
-                Err(why) => {
-                    eprintln!("{}", why);
-                    self.flow_control.reset();
-                    return;
-                }
-                Ok(Some(stm)) => {
-                    let _ = self.execute_statement(&stm);
+        for stmt in command_string
+            .bytes()
+            .batching(|cmd| Terminator::new(cmd).terminate())
+            .filter_map(Result::ok)
+        {
+            // Go through all of the statements and build up the block stack
+            // When block is done return statement for execution.
+            for statement in StatementSplitter::new(&stmt).map(parse_and_validate) {
+                println!("A: {:?}", statement);
+                match insert_statement(&mut self.flow_control, statement) {
+                    Err(why) => {
+                        eprintln!("{}", why);
+                        self.flow_control.reset();
+                        return;
+                    }
+                    Ok(Some(stm)) => {
+                        let _ = self.execute_statement(stm);
+                    }
+                    Ok(None) => {}
                 }
-                Ok(None) => {}
             }
         }
     }
-- 
GitLab