From 2bfb1ee6fe07a8f6d5521cfe3bca58cb0b75303c Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Wed, 31 Jul 2019 18:12:35 -0500 Subject: [PATCH] DEV: Regex binary expressions work. --- src/build/opcode/mod.rs | 1 + src/build/opcode/runtime.rs | 34 +++++++++++++++++++++++++++++++++- src/build/opcode/test.rs | 1 + src/build/opcode/translate.rs | 13 +++++++++---- src/build/opcode/vm.rs | 2 +- 5 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/build/opcode/mod.rs b/src/build/opcode/mod.rs index d37d051..7737c0c 100644 --- a/src/build/opcode/mod.rs +++ b/src/build/opcode/mod.rs @@ -90,6 +90,7 @@ pub enum Hook { Out, Assert, Convert, + Regex, } #[derive(Debug, PartialEq, Clone)] diff --git a/src/build/opcode/runtime.rs b/src/build/opcode/runtime.rs index e190ae7..e55cc16 100644 --- a/src/build/opcode/runtime.rs +++ b/src/build/opcode/runtime.rs @@ -18,8 +18,10 @@ use std::io::Read; use std::path::{Path, PathBuf}; use std::rc::Rc; +use regex::Regex; + use super::cache; -use super::Value::{P, C, F}; +use super::Value::{C, F, P}; use super::VM; use super::{Composite, Error, Hook, Primitive, Value}; use crate::build::AssertCollector; @@ -72,6 +74,7 @@ impl Builtins { Hook::Map => self.map(path, stack), Hook::Filter => self.filter(path, stack), Hook::Reduce => self.reduce(path, stack), + Hook::Regex => self.regex(stack), } } @@ -351,6 +354,35 @@ impl Builtins { Ok(()) } + fn regex(&self, stack: &mut Vec>) -> Result<(), Error> { + // 1. get left side (string) + let left_str = if let Some(val) = stack.pop() { + if let &P(Str(ref s)) = val.as_ref() { + s.clone() + } else { + return dbg!(Err(Error {})); + } + } else { + return dbg!(Err(Error {})); + }; + + // 2. get right side (string) + let right_str = if let Some(val) = stack.pop() { + if let &P(Str(ref s)) = val.as_ref() { + s.clone() + } else { + return dbg!(Err(Error {})); + } + } else { + return dbg!(Err(Error {})); + }; + + // 3. compare via regex + let rex = Regex::new(&right_str)?; + stack.push(Rc::new(P(Bool(rex.find(&left_str).is_some())))); + Ok(()) + } + fn reduce>(&self, path: P, stack: &mut Vec>) -> Result<(), Error> { // get the list from the stack let list = if let Some(list) = stack.pop() { diff --git a/src/build/opcode/test.rs b/src/build/opcode/test.rs index c16e360..88942fb 100644 --- a/src/build/opcode/test.rs +++ b/src/build/opcode/test.rs @@ -556,6 +556,7 @@ fn simple_binary_expr() { "2>1;" => P(Bool(true)), "2<1;" => P(Bool(false)), "1!=1;" => P(Bool(false)), + "\"foo\" ~ \"bar\";" => P(Bool(false)), //"true && false;" => P(Bool(false)), ) } diff --git a/src/build/opcode/translate.rs b/src/build/opcode/translate.rs index bc9b206..64a7912 100644 --- a/src/build/opcode/translate.rs +++ b/src/build/opcode/translate.rs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. use crate::ast::{BinaryExprType, Expression, Statement, Value}; -use crate::build::opcode::Op; use crate::build::opcode::Primitive; use crate::build::opcode::Value::{C, F, M, P, T}; +use crate::build::opcode::{Hook, Op}; pub struct AST(); @@ -82,9 +82,14 @@ impl AST { ops.push(Op::Equal); ops.push(Op::Not); } - BinaryExprType::REMatch - | BinaryExprType::NotREMatch - | BinaryExprType::IN + BinaryExprType::REMatch => { + ops.push(Op::Runtime(Hook::Regex)); + } + BinaryExprType::NotREMatch => { + ops.push(Op::Runtime(Hook::Regex)); + ops.push(Op::Not); + } + BinaryExprType::IN | BinaryExprType::IS | BinaryExprType::Mod | BinaryExprType::OR diff --git a/src/build/opcode/vm.rs b/src/build/opcode/vm.rs index 0e0cc82..2753734 100644 --- a/src/build/opcode/vm.rs +++ b/src/build/opcode/vm.rs @@ -278,7 +278,7 @@ impl<'a> VM { } return Err(dbg!(Error {})); } - + fn op_equal(&mut self) -> Result<(), Error> { let left = self.pop()?; let right = self.pop()?;