[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


https://bugs.libre-soc.org/show_bug.cgi?id=1094

--- 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
https://sbcode.net/python/visitor/#visitorvisitor_conceptpy

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
"Visiting"

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

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


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"
    @staticmethod
    @abstractmethod
    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
    """
    @staticmethod
    @abstractmethod
    def accept(visitor):
        """
        The Visitor traverses and accesses each object through this
        method
        """

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:
            parent.elements.add(self)

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

# 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"
    @staticmethod
    def visit(element):
        print(element.name)

# Using the PrintElementNamesVisitor to traverse the object hierarchy
Element_A.accept(PrintElementNamesVisitor)

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

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

# Using the CalculateElementTotalsVisitor to traverse the
# object hierarchy
TOTAL = CalculateElementTotalsVisitor()
Element_A.accept(CalculateElementTotalsVisitor)
print(TOTAL.total_value)

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


More information about the libre-soc-bugs mailing list