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

bugzilla-daemon at libre-soc.org bugzilla-daemon at libre-soc.org
Fri Jun 9 23:45:57 BST 2023


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

--- Comment #76 from Luke Kenneth Casson Leighton <lkcl at lkcl.net> ---
(In reply to Dmitry Selyutin from comment #69)
> Option 4, which is, I think, the best one: have a full element path. That
> is, for example: db.record.ppc, or db.record.fields[0].
> db.record.mdwn.operands[0]... and so on.

mmmm.... this kind of thing is what the Visitor should do (itself),
by having all of the functions

class BiggerVisitor(BaseVisitor):
    def __init__(self):
        self.stack_of_stuff = []
    @contextlib.contextmanager
    def Record(self, node, depth):
        self.stack_of_stuff.append(node.name)
        print(".".join(self.stack_of_stuff))
        yield node
        self.stack_of_stuff.pop(-1) # i think
    def Opcode(self, node, depth):
        self.stack_of_stuff.append(node.name)
        print(".".join(self.stack_of_stuff))
        yield node
        self.stack_of_stuff.pop(-1) # i think

urrr... those are both the same.  urrr....      

ahhhh... i think i know why you replaced def Record (etc) with def __call__,
because the above is just this, because the two do the same thing

    def __call__(self, node):
        self.stack_of_stuff.append(node.name)
        print(".".join(self.stack_of_stuff))
        yield node
        self.stack_of_stuff.pop(-1) # i think

hmmmm hmmm hmmm....   this is solved in python 2.7 ast.py with
a getattr(), isn't it?

https://github.com/python/cpython/blob/2.7/Lib/ast.py#L237

    def visit(self, node):
        """Visit a node."""
        method = 'visit_' + node.__class__.__name__
        visitor = getattr(self, method, self.generic_visit)
        return visitor(node)

the equivalent here (for us) would be:

        visitor = getattr(self, method, self.__call__)

ahhhh that's it.  that's the solution.  demonstrating back in the original
(from yesterday?):

@_dataclasses.dataclass(eq=True, frozen=True)
class Dataclass:
    def subnodes(self, match=None):
        if match is None:
            match = lambda subnode: True

        def subnode(field):                  vvvvvvvvvvvvvvv
            return getattr(self, field.name, field.__call__)
                                             ^^^^^^^^^^^^^^^
        yield from filter(match, map(subnode, _dataclasses.fields()))

that will cope with both... is that right?


class Dataclass(metaclass=DataclassMeta):
    @walkmethod
    def walk(clsself, match=None):
        if match is None:
            match = lambda subnode: True

        def field_type(field):
            return field.type

        def field_value(field):                 vvvvvvvvvvvvvv
            return getattr(clsself, field.name, field.__call__)
                                                ^^^^^^^^^^^^^^
        field = (field_type if isinstance(clsself, type) else field_value)

        yield from filter(match, map(field, _dataclasses.fields(clsself)))

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


More information about the libre-soc-bugs mailing list