[Libre-soc-bugs] [Bug 1094] insndb instruction database visitor-walker is needed

bugzilla-daemon at libre-soc.org bugzilla-daemon at libre-soc.org
Wed Jun 7 11:39:34 BST 2023


--- Comment #53 from Luke Kenneth Casson Leighton <lkcl at lkcl.net> ---
(In reply to Dmitry Selyutin from comment #52)
> Note that __getattr__ is kinda redundant: we always feed default self.Node
> in getattr calls. This, however, is more explicit. Just pointing that it can
> be reduced even more.

it looks really neat.  the amount of code really should be this short:
anything beyond 80 lines, there's something off.

i'd really like to see "Visitor" separate from "Visiting",  let me drop
a copy of the medium.com/sbcode.net code here

the design that you have, the "Visitor" and "Visiting" are still merged
into one: in the current code it is the *Visitor* that is performing
(explicitly) the walking, which it should not be doing.

  def Database(self, node, depth):
    yield node
      for subnode in node.subnodes: <- this is merging "Visitor" with

  def Record(self, node, depth):
    for opcode in node.opcodes:  <- again, "Visitor" is merged with "Visiting"

that will get complex *real* fast, approximately... 5 to 6 nested-depths of

here, they have the concept "accept()" which instead we want the ability
to yield from a contextmanager (i like that - "accept" sounds kinda dumb)

# pylint: disable=too-few-public-methods
# pylint: disable=arguments-differ
"The Visitor Pattern Concept"
from abc import ABCMeta, abstractmethod

class IVisitor(metaclass=ABCMeta):
    "An interface that custom Visitors should implement"
    def visit(element):
        "Visitors visit Elements/Objects within the application"

class IVisitable(metaclass=ABCMeta):
    An interface the concrete objects should implement that allows
    the visitor to traverse a hierarchical structure of objects
    def accept(visitor):
        The Visitor traverses and accesses each object through this

class Element(IVisitable):
    "An Object that can be part of any hierarchy"

    def __init__(self, name, value, parent=None):
        self.name = name
        self.value = value
        self.elements = set()
        if parent:

    def accept(self, visitor):
        "required by the Visitor that will traverse"
        for element in self.elements:

# The Client
# Creating an example object hierarchy.
Element_A = Element("A", 101)
Element_B = Element("B", 305, Element_A)
Element_C = Element("C", 185, Element_A)
Element_D = Element("D", -30, Element_B)

# Now Rather than changing the Element class to support custom
# operations, we can utilise the accept method that was
# implemented in the Element class because of the addition of
# the IVisitable interface

class PrintElementNamesVisitor(IVisitor):
    "Create a visitor that prints the Element names"
    def visit(element):

# Using the PrintElementNamesVisitor to traverse the object hierarchy

class CalculateElementTotalsVisitor(IVisitor):
    "Create a visitor that totals the Element values"
    total_value = 0

    def visit(cls, element):
        cls.total_value += element.value
        return cls.total_value

# Using the CalculateElementTotalsVisitor to traverse the
# object hierarchy
TOTAL = CalculateElementTotalsVisitor()

You are receiving this mail because:
You are on the CC list for the bug.

More information about the libre-soc-bugs mailing list