docs: def run(self, node, expr=None, lineno=None, with_raise=True):
          """Execute parsed Ast representation for an expression."""
          # Note: keep the 'node is None' test: internal code here may run
          #    run(None) and expect a None in return.
          if time.time() - self.start_time > self.max_time:
              raise RuntimeError(ERR_MAX_TIME.format(self.max_time))
          out = None
          if len(self.error) > 0:
              return out
          if node is None:
              return out
          if isinstance(node, str):
              node = self.parse(node)
          if lineno is not None:
              self.lineno = lineno
          if expr is not None:
              self.expr = expr
  
          # get handler for this node:
          #   on_xxx with handle nodes of type 'xxx', etc
          try:
              handler = self.node_handlers[node.__class__.__name__.lower()]
          except KeyError:
              return self.unimplemented(node)
  
          # run the handler:  this will likely generate
          # recursive calls into this run method.
          try:
              ret = handler(node)
              if isinstance(ret, enumerate):
                  ret = list(ret)
              return ret
          except:
              if with_raise:
                  self.raise_exception(node, expr=expr)