From a4fc18f8fe9c39138f8ededadc28d51e9c940f31 Mon Sep 17 00:00:00 2001 From: Daniel Bulant Date: Fri, 10 Dec 2021 10:26:31 +0100 Subject: [PATCH] feat: and or expressions --- src/parser/exec.rs | 66 ++++++++++++++++++++++++++++++++++++++++---- src/parser/tokens.rs | 5 ++++ 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/src/parser/exec.rs b/src/parser/exec.rs index d0851ac..38632f2 100644 --- a/src/parser/exec.rs +++ b/src/parser/exec.rs @@ -3,7 +3,7 @@ use std::fs::File; use std::process::{Command, Stdio}; use std::io; use std::ops::Deref; -use crate::parser::ast::{CommandValue, Expression, FileSourceExpression, FileTargetExpression, LetExpression, RedirectTargetExpression, Value}; +use crate::parser::ast::{AndExpression, CommandValue, Expression, FileSourceExpression, FileTargetExpression, LetExpression, OrExpression, RedirectTargetExpression, Value}; use crate::parser::vars; use crate::parser::vars::{Context, Variable}; @@ -73,9 +73,9 @@ impl ExecExpression for Expression { Expression::RedirectTargetExpression(expr) => expr.exec(ctx), Expression::FileTargetExpression(expr) => expr.exec(ctx), Expression::FileSourceExpression(expr) => expr.exec(ctx), - Expression::Expressions(_) => todo!(), - Expression::OrExpression(_) => todo!(), - Expression::AndExpression(_) => todo!() + Expression::Expressions(expr) => expr.exec(ctx), + Expression::OrExpression(expr) => expr.exec(ctx), + Expression::AndExpression(expr) => expr.exec(ctx) } } } @@ -178,6 +178,62 @@ impl ExecExpression for FileSourceExpression { } } +impl ExecExpression for Vec { + fn exec(self, ctx: &mut Context) -> Option { + let mut last = None; + for expr in self { + last = expr.exec(ctx); + } + last + } +} + +impl ExecExpression for OrExpression { + fn exec(self, ctx: &mut Context) -> Option { + let mut first = match self.first.exec(ctx) { + None => panic!("Invalid OR expression"), + Some(cmd) => cmd + }; + let mut res = match first.spawn() { + Result::Err(e) => { + self.second.exec(ctx) + }, + Result::Ok(mut res) => { + if res.wait().unwrap().success() { + Some(first) + } else { + self.second.exec(ctx) + } + } + }; + + res + } +} + +impl ExecExpression for AndExpression { + fn exec(self, ctx: &mut Context) -> Option { + let mut first = match self.first.exec(ctx) { + None => panic!("Invalid AND expression"), + Some(cmd) => cmd + }; + let mut res = match first.spawn() { + Result::Err(e) => { + Some(first) + }, + Result::Ok(mut res) => { + if !res.wait().unwrap().success() { + Some(first) + } else { + self.second.exec(ctx) + } + } + }; + + res + } +} + pub fn exec_tree(tree: Vec, ctx: &mut vars::Context) { for mut expression in tree { let mut cmd = expression.exec(ctx); @@ -189,7 +245,7 @@ pub fn exec_tree(tree: Vec, ctx: &mut vars::Context) { }, Result::Ok(mut res) => { let out = res.wait().unwrap(); - ctx.set_var(String::from("!"), Variable::I32(out.code().unwrap_or(1))); + ctx.set_var(String::from("?"), Variable::I32(out.code().unwrap_or(1))); } } } diff --git a/src/parser/tokens.rs b/src/parser/tokens.rs index ed43a3c..7a2d65d 100644 --- a/src/parser/tokens.rs +++ b/src/parser/tokens.rs @@ -98,6 +98,11 @@ fn read_var_ahead(i: usize, text: &String) -> (usize, Tokens) { } break; } + '?' => { + buf.push(letter.clone()); + x += 1; + break; + } _ => { if !parens_mode { break } else { panic!("Invalid variable name") } } } }