From 5ac2fd749600f2071020a67ea4d79337b1ff4af5 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy <mmstickman@gmail.com> Date: Sun, 15 Jul 2018 00:17:19 +0000 Subject: [PATCH] Conditional Improvements --- examples/if_with_builtins.ion | 9 +++++++++ examples/if_with_builtins.out | 2 ++ examples/not.ion | 8 ++++++-- examples/not.out | 4 ++++ src/lib/parser/statement/parse.rs | 23 ++++++++++++----------- src/lib/shell/flow.rs | 12 ++++++++---- src/lib/shell/flow_control.rs | 4 ++-- 7 files changed, 43 insertions(+), 19 deletions(-) create mode 100644 examples/if_with_builtins.ion create mode 100644 examples/if_with_builtins.out diff --git a/examples/if_with_builtins.ion b/examples/if_with_builtins.ion new file mode 100644 index 00000000..3c1ec3e8 --- /dev/null +++ b/examples/if_with_builtins.ion @@ -0,0 +1,9 @@ +if not false + echo a +end + +if not true + echo b +else if not false + echo c +end diff --git a/examples/if_with_builtins.out b/examples/if_with_builtins.out new file mode 100644 index 00000000..0f7bc766 --- /dev/null +++ b/examples/if_with_builtins.out @@ -0,0 +1,2 @@ +a +c diff --git a/examples/not.ion b/examples/not.ion index ef5f4b36..8c2444c5 100644 --- a/examples/not.ion +++ b/examples/not.ion @@ -1,6 +1,10 @@ not true || echo not true +! true || echo not true not false && echo not false -true && not false && echo true and not false +! false && echo not false +true && not false && echo true and not false +true && ! false && echo true and not false not test -z "a" && echo not test +! test -z "a" && echo not test not echo hello -echo $? \ No newline at end of file +echo $? diff --git a/examples/not.out b/examples/not.out index 471a3051..bbc2a417 100644 --- a/examples/not.out +++ b/examples/not.out @@ -1,6 +1,10 @@ not true +not true +not false not false true and not false +true and not false +not test not test hello 1 diff --git a/src/lib/parser/statement/parse.rs b/src/lib/parser/statement/parse.rs index 33b31535..cae756f2 100644 --- a/src/lib/parser/statement/parse.rs +++ b/src/lib/parser/statement/parse.rs @@ -81,12 +81,12 @@ pub(crate) fn parse(code: &str) -> Statement { return Statement::Export(ExportAction::Assign(keys, op, values)); } _ if cmd.starts_with("if ") => { - return collect(cmd[3..].trim_left(), |pipeline| Statement::If { - expression: pipeline, + return Statement::If { + expression: Box::new(parse(cmd[3..].trim_left())), success: Vec::new(), else_if: Vec::new(), failure: Vec::new(), - }) + } } "else" => return Statement::Else, _ if cmd.starts_with("else") => { @@ -94,11 +94,9 @@ pub(crate) fn parse(code: &str) -> Statement { if cmd.is_empty() { return Statement::Else; } else if cmd.starts_with("if ") { - return collect(cmd[3..].trim_left(), |pipeline| { - Statement::ElseIf(ElseIf { - expression: pipeline, - success: Vec::new(), - }) + return Statement::ElseIf(ElseIf { + expression: Box::new(parse(cmd[3..].trim_left())), + success: Vec::new() }); } } @@ -209,7 +207,10 @@ pub(crate) fn parse(code: &str) -> Statement { _ if cmd.starts_with("not ") => { return Statement::Not(Box::new(parse(cmd[3..].trim_left()))) } - _ if cmd.eq("not") => return Statement::Not(Box::new(Statement::Default)), + _ if cmd.starts_with("! ") => { + return Statement::Not(Box::new(parse(cmd[1..].trim_left()))) + } + _ if cmd.eq("not") | cmd.eq("!") => return Statement::Not(Box::new(Statement::Default)), _ => (), } @@ -232,7 +233,7 @@ mod tests { // Default case where spaced normally let parsed_if = parse("if test 1 -eq 2"); let correct_parse = Statement::If { - expression: Pipeline { + expression: Box::new(Statement::Pipeline(Pipeline { items: vec![PipeItem { job: Job::new( vec![ @@ -247,7 +248,7 @@ mod tests { outputs: Vec::new(), inputs: Vec::new(), }], - }, + })), success: vec![], else_if: vec![], failure: vec![], diff --git a/src/lib/shell/flow.rs b/src/lib/shell/flow.rs index 7da5dd09..a0cfe827 100644 --- a/src/lib/shell/flow.rs +++ b/src/lib/shell/flow.rs @@ -56,7 +56,7 @@ pub(crate) trait FlowLogic { /// expressions fn execute_if( &mut self, - expression: Pipeline, + expression: Box<Statement>, success: Vec<Statement>, else_if: Vec<ElseIf>, failure: Vec<Statement>, @@ -335,7 +335,7 @@ impl FlowLogic for Shell { fn execute_if( &mut self, - expression: Pipeline, + expression: Box<Statement>, success: Vec<Statement>, else_if: Vec<ElseIf>, failure: Vec<Statement>, @@ -345,8 +345,12 @@ impl FlowLogic for Shell { .into_iter() .map(|cond| (cond.expression, cond.success)); - for (mut condition, statements) in first_condition.chain(else_conditions) { - if self.run_pipeline(&mut condition) == Some(SUCCESS) { + for (condition, statements) in first_condition.chain(else_conditions) { + if let Condition::SigInt = self.execute_statements(vec![*condition]) { + return Condition::SigInt; + } + + if self.previous_status == 0 { return self.execute_statements(statements); } } diff --git a/src/lib/shell/flow_control.rs b/src/lib/shell/flow_control.rs index f6831ba4..40226401 100644 --- a/src/lib/shell/flow_control.rs +++ b/src/lib/shell/flow_control.rs @@ -8,7 +8,7 @@ use lexers::assignments::{KeyBuf, Operator, Primitive}; #[derive(Debug, PartialEq, Clone)] pub(crate) struct ElseIf { - pub expression: Pipeline, + pub expression: Box<Statement>, pub success: Vec<Statement>, } @@ -63,7 +63,7 @@ pub(crate) enum Statement { Case(Case), Export(ExportAction), If { - expression: Pipeline, + expression: Box<Statement>, success: Vec<Statement>, else_if: Vec<ElseIf>, failure: Vec<Statement>, -- GitLab