From d9fc75b1ff82cf55f89be6a0b32381d0e1c0c616 Mon Sep 17 00:00:00 2001 From: Amir Sabbaghi Date: Mon, 9 Oct 2017 21:44:38 +0330 Subject: [PATCH] adding and operator --- jmespath.lua | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/jmespath.lua b/jmespath.lua index 0f26c9d..85eb82e 100644 --- a/jmespath.lua +++ b/jmespath.lua @@ -55,7 +55,6 @@ local Lexer = (function() ['('] = 'lparen', [')'] = 'rparen', ['@'] = 'current', - ['&'] = 'expref' }, -- Tokens that can be numbers numbers = { @@ -178,6 +177,16 @@ local Lexer = (function() return {type = 'or', value = '||', pos = lexer.pos - 2}; end + --- Consumes an and, '&&', and expref, '&' token + local function consume_amp(lexer) + consume(lexer) + if lexer.c ~= '&' then + return {type = 'expref', value = '&', pos = lexer.pos - 1}; + end + consume(lexer) + return {type = 'and', value = '&&', pos = lexer.pos - 2}; + end + --- Parse a string of tokens inside of a delimiter. -- @param lexer Lexer instance -- @param wrapper Wrapping character @@ -265,6 +274,8 @@ local Lexer = (function() tokens[#tokens + 1] = consume_operator(self) elseif self.c == '|' then tokens[#tokens + 1] = consume_pipe(self) + elseif self.c == '&' then + tokens[#tokens + 1] = consume_amp(self) elseif self.c == '"' then tokens[#tokens + 1] = consume_quoted_identifier(self) elseif self.c == '`' then @@ -341,7 +352,8 @@ local Parser = (function() pipe = 1, comparator = 2, ['or'] = 5, - flatten = 6, + ['and'] = 6, + flatten = 7, star = 20, dot = 40, lbrace = 50, @@ -559,6 +571,11 @@ local Parser = (function() return {type = 'or', children = {left, expr(parser, bp['or'])}} end + parselets.led_and = function(parser, left) + parser:advance() + return {type = 'and', children = {left, expr(parser, bp['and'])}} + end + parselets.led_pipe = function(parser, left) parser:advance() return {type = 'pipe', children = {left, expr(parser, bp.pipe)}} @@ -1170,6 +1187,16 @@ local Interpreter = (function() return result end, + ["and"] = function(interpreter, node, data) + local result = interpreter:visit(node.children[1], data) + local t = type(result) + if not result or result == '' or (t == 'table' and next(result) == nil) + then + return result + end + return interpreter:visit(node.children[2], data) + end, + pipe = function(interpreter, node, data) return interpreter:visit( node.children[2],