[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