Le 22/11/2015 19:56, Mariano Martinez Peck a écrit :


On Sat, Nov 21, 2015 at 7:07 AM, Thierry Goubier
<[email protected] <mailto:[email protected]>> wrote:

    Hi Mariano,

    Le 20/11/2015 20:58, Mariano Martinez Peck a écrit :

        Thierry,

        Sorry to bother again. Unfortunately, RB does not work out of
        the box in
        GemStone .... only the formatter part. grrr.


    There is maybe a message to send to the maintainer of RB in Gemstone :)


Thanks Thierry. Yes, I talked with Dale and the only "official"
usage/port of RB is actually the formatter ;)

:(

        Anyway, I am trying to make it work, and it's failing in this
        easy example:

        /| tree rewriter |/
        /tree := RBParser parseMethod: 'DoIt ^ [:proxy | proxy at:
        #oldSelector.
        ]'./
        /rewriter := RBParseTreeRewriter new./
        /rewriter /
        /replace: ('`#oldSelector `{:node | node value isSymbol and:
        [node value
        matchesRegex: ''.*oldSelector.*''] }')/
        /with: ('`{RBLiteralNode value: (`#oldSelector value copyReplaceAll:
        ''oldSelector'' with: ''newSelector'') asSymbol }')./
        /rewriter executeTree: tree./
        /rewriter tree newSource/
        And the problem is the line:

        /with: ('`{RBLiteralNode value: (`#oldSelector value copyReplaceAll:
        ''oldSelector'' with: ''newSelector'') asSymbol }')./

        which gets translated to:

        [ :aDictionary |
        RBLiteralNode
            value:
              ((*self* lookupMatchFor: '`#oldSelector' in: aDictionary)
        value
                copyReplaceAll: 'oldSelector'
                with: 'newSelector') asSymbol ]

        The problem in GemStone is that that "self" is binded to nil and
        not to
        the receiver instance (RBPatternBlockNode). And so I get a Nil dnu..
        *And I don't know how that closure is finally generated.*

        The message node:

        /(*self* lookupMatchFor: '`#oldSelector' in: aDictionary) /

        Its generated in:

        RBPatternBlockNode >> constructLookupNodeFor: aString in:
        aRBBlockNode
        | argumentNode |
        argumentNode := RBLiteralNode value: aString.

        ^RBMessageNode
        receiver:* (RBVariableNode named: 'self')*
        selector: #lookupMatchFor:in:
        arguments: (Array with: argumentNode with: aRBBlockNode
        arguments last)

        Any ideas?


    Yes. I think it is possible to work around it by using the
    dictionary itself, storing the node selector in it in the replace:
    pattern and retrieving it in the with: pattern.

    rewriter
                     replace: ('`#oldSelector `{:node :dic | (node value
    isSymbol and: [node value matchesRegex: ''.*oldSelector.*''])
    ifTrue: [dic at: #selector put: node value. true] ifFalse: [false] }')
                     with: ('`{:dic | RBLiteralNode value: ((dic at:
    #selector) copyReplaceAll: ''oldSelector'' with: ''newSelector'')
    asSymbol }').


Wow, that's very cool. I wasn't aware that I could pass arguments (like
the dict in this case). This is powerful.

Yes, quite significant. Also the fact the dictionary is cleared for each match (so that it can be reused for the next match in the same ast).

Thank you RB Jedi.

I've had the guidance of John Brant (and spent some time over the SmaCC code where he uses it)...

    Now, maybe correcting RB in Gemstone is something to do, as well.


Yes. So with the dict workaround you said, it DID work, but when I
continue a little more and I found out where was the closure being
generated, and that is RBPatternBlockNode >> #createBlockFor:
And yeah, the way it was being generated the closure ("source
evalauted") was binding "self" to nil.  I found a way to make it bind
the real self and that worked too. So...time to fork RB for GemStone and
commit the fix :)

You're now the maintainer of RB for GemStone! Congratulations :)

BTW, do you image other cases like this?

You mean storing those RB rules? I try to collect them if I see some (or participate to), or remember where I see them.

I used to know where the RBRewriteTree chapter was in the Pharo books, but it seems to have disappeared, so I have recreated a copy that I'll try to update.

Thanks!

You're welcome. You are giving opportunities to improve which is what I need (need to practice, need to practice, need to practice...).

I have ideas for Mark Rizun's tool, but I don't have the time to work on them.

Thierry

Reply via email to