code: def evaluate(self):
          ops = []
          rpn = []
          for token in self.expr:
              if isinstance(token, int):
                  while len(ops) and token <= ops[-1]:
                      rpn.append(ops.pop())
                  ops.append(token)
              else:
                  rpn.append(token)
          while len(ops):
              rpn.append(ops.pop())
          stack = []
          for token in rpn:
              if isinstance(token, int):
                  if token == OPERATOR.NOT:
                      stack[-1] = IsNot(stack[-1])
                      continue
                  if len(stack) < 2:
                      raise RuntimeError('Unable to build a valid expression. Not enough operands available.')
                  if token == OPERATOR.OR:
                      matcher = hc.any_of(*stack[-2:])
                  else:
                      matcher = hc.all_of(*stack[-2:])
                  stack[-2:] = [matcher]
              else:
                  stack.append(token)
          if len(stack) != 1:
              raise RuntimeError('Unable to build a valid expression. The RPN stack should have just one item.')
          matcher = stack.pop()
          if self.description:
              matcher = hc.described_as(self.description, matcher)
          return matcher