def _TwoArgs(w_parser): # type: (_StringWordEmitter) -> bool_expr_t """Returns an expression tree to be evaluated.""" w0 = w_parser.Read() w1 = w_parser.Read() s0 = w0.s if s0 == '!': return bool_expr.LogicalNot(bool_expr.WordTest(w1)) unary_id = Id.Undefined_Tok # Oil's preferred long flags if w0.s.startswith('--'): if s0 == '--dir': unary_id = Id.BoolUnary_d elif s0 == '--exists': unary_id = Id.BoolUnary_e elif s0 == '--file': unary_id = Id.BoolUnary_f elif s0 == '--symlink': unary_id = Id.BoolUnary_L if unary_id == Id.Undefined_Tok: unary_id = match.BracketUnary(w0.s) if unary_id == Id.Undefined_Tok: p_die('Expected unary operator, got %r (2 args)', w0.s, word=w0) return bool_expr.Unary(unary_id, w1)
def _TwoArgs(w_parser): """Returns an expression tree to be evaluated.""" w0 = w_parser.Read() w1 = w_parser.Read() if w0.s == '!': return bool_expr.LogicalNot(bool_expr.WordTest(w1)) unary_id = TEST_UNARY_LOOKUP.get(w0.s) if unary_id is None: # TODO: # - separate lookup by unary p_die('Expected unary operator, got %r (2 args)', w0.s, word=w0) return bool_expr.Unary(unary_id, w1)
def _TwoArgs(w_parser): # type: (_StringWordEmitter) -> bool_expr_t """Returns an expression tree to be evaluated.""" w0 = w_parser.Read() w1 = w_parser.Read() if w0.s == '!': return bool_expr.LogicalNot(bool_expr.WordTest(w1)) unary_id = match.BracketUnary(w0.s) if unary_id == -1: # TODO: # - separate lookup by unary p_die('Expected unary operator, got %r (2 args)', w0.s, word=w0) return bool_expr.Unary(unary_id, w1)
def _TwoArgs(w_parser): # type: (_StringWordEmitter) -> bool_expr_t """Returns an expression tree to be evaluated.""" w0 = w_parser.Read() # TODO: Implement --dir, --file, --exists here # --symlink, maybe --executable w1 = w_parser.Read() if w0.s == '!': return bool_expr.LogicalNot(bool_expr.WordTest(w1)) unary_id = match.BracketUnary(w0.s) if unary_id == Id.Undefined_Tok: # TODO: # - separate lookup by unary p_die('Expected unary operator, got %r (2 args)', w0.s, word=w0) return bool_expr.Unary(unary_id, w1)
def ParseFactor(self): # type: () -> bool_expr_t """ Factor : WORD | UNARY_OP WORD | WORD BINARY_OP WORD | '(' Expr ')' """ if self.b_kind == Kind.BoolUnary: # Just save the type and not the token itself? op = self.op_id self._Next() w = self.cur_word # e.g. [[ -f < ]]. But [[ -f '<' ]] is OK tag = w.tag_() if tag != word_e.Compound and tag != word_e.String: p_die('Invalid argument to unary operator', word=w) self._Next() node = bool_expr.Unary(op, w) # type: bool_expr_t return node if self.b_kind == Kind.Word: # Peek ahead another token. t2 = self._LookAhead() t2_op_id = word_.BoolId(t2) t2_b_kind = consts.GetKind(t2_op_id) #log('t2 %s / t2_op_id %s / t2_b_kind %s', t2, t2_op_id, t2_b_kind) # Op for < and >, -a and -o pun if t2_b_kind == Kind.BoolBinary or t2_op_id in (Id.Op_Less, Id.Op_Great): left = self.cur_word self._Next() op = self.op_id # TODO: Need to change to lex_mode_e.BashRegex. # _Next(lex_mode) then? is_regex = t2_op_id == Id.BoolBinary_EqualTilde if is_regex: self._Next(lex_mode=lex_mode_e.BashRegex) else: self._Next() right = self.cur_word if is_regex: # NOTE: StaticEval for checking regex syntax isn't enough. We could # need to pass do_ere so that the quoted parts get escaped. #ok, s, unused_quoted = word_.StaticEval(right) pass self._Next() return bool_expr.Binary(op, left, right) else: # [[ foo ]] w = self.cur_word self._Next() return bool_expr.WordTest(w) if self.op_id == Id.Op_LParen: self._Next() node = self.ParseExpr() if self.op_id != Id.Op_RParen: p_die('Expected ), got %s', word_.Pretty(self.cur_word), word=self.cur_word) self._Next() return node # It's not WORD, UNARY_OP, or '(' p_die('Unexpected token in boolean expression', word=self.cur_word)