Hi everyone,
I would like to modify the AST of a smalltalk expression compiled to automatically send a certain message when a node represents a Character (so the user does not have to write the message sending explicitly). I would of course add a special button in the menu you get when right clicking in a playground so the user knows it is a "special" do-it... For example: $a. would transform into an ast that the source code looks like $a aMessage How can I do this? :) Julien |
If you don't want to manually operate on AST, you can use Mark's Rewrite Tool ( http://screencast.com/t/LCEl0hFl , https://medium.com/@peteruhnak/using-rewrite-tool-for-fixing-deprecated-code-12a595b291d8 ) As for ASTs I would be also curious about the answer, as this seems like it should be a simple task. Peter On Sat, Sep 12, 2015 at 2:24 PM, Julien Delplanque <[hidden email]> wrote: Hi everyone, |
Hi everyone, The only problem I see is that you want to do this only with single symbol. Because, in my tool you can do: transform: `#literal into: `#literal aMessage. In this case `#literal means any literal, not only symbols. In other words it will transform $a into $a aMessage Also, this rule will transform, for instance 123 into 123 aMessage If I understand right, you would like to do this programatically, so you don't need RewriteTool in that case. Mark 2015-09-12 16:46 GMT+03:00 Peter Uhnák <[hidden email]>:
|
In reply to this post by Peter Uhnak
Le 12/09/2015 15:46, Peter Uhnák a écrit :
> If you don't want to manually operate on AST, you can use Mark's Rewrite > Tool ( http://screencast.com/t/LCEl0hFl , > https://medium.com/@peteruhnak/using-rewrite-tool-for-fixing-deprecated-code-12a595b291d8 > ) > > As for ASTs I would be also curious about the answer, as this seems like > it should be a simple task. It is fairly easy if you write a RB AST visitor subclass, with a single method / case to handle character literal. Now, I'm sure you can use RBParseTreeRewriter to do it with a single call... Thierry > Peter > > On Sat, Sep 12, 2015 at 2:24 PM, Julien Delplanque <[hidden email] > <mailto:[hidden email]>> wrote: > > Hi everyone, > > I would like to modify the AST of a smalltalk expression compiled to > automatically send a certain message > when a node represents a Character (so the user does not have to > write the message sending explicitly). > I would of course add a special button in the menu you get when > right clicking in a playground so the user > knows it is a "special" do-it... > > For example: > $a. > would transform into an ast that the source code looks like > $a aMessage > > How can I do this? :) > > Julien > > |
In reply to this post by Mark Rizun
Hi Julien, Mark and Peter,
here is a RB approach: | rewriter | rewriter := RBParseTreeRewriter new replace: ' `#aLiteral `{:node | node value isCharacter}' with: '`#aLiteral aMessage'; yourself. rewriter executeTree: (RBParser parseExpression: 'Array with: $a asciiValue with: $b with: #c with: d'). rewriter tree formattedCode And the result is: 'Array with: $a aMessage asciiValue with: $b aMessage with: #c with: d' Need to keep all those snipets somewhere. And I think the chapter in Pharo for the enterprise does not explain well the conditional stuff in { }. Thierry Le 12/09/2015 16:03, Mark Rizun a écrit : > Hi everyone, > > I believe you should be able to do this transformation with Rewrite Tool. > The only problem I see is that you want to do this only with single symbol. > Because, in my tool you can do: > > transform: *`#literal* into: *`#literal aMessage*. > In this case `#literal**means any literal, not only symbols. > In other words it will transform > > $a into $a aMessage > > Also, this rule will transform, for instance > 123 into 123 aMessage > > If I understand right, you would like to do this programatically, so you > don't need RewriteTool in that case. > > Mark > > 2015-09-12 16:46 GMT+03:00 Peter Uhnák <[hidden email] > <mailto:[hidden email]>>: > > If you don't want to manually operate on AST, you can use Mark's > Rewrite Tool ( http://screencast.com/t/LCEl0hFl , > https://medium.com/@peteruhnak/using-rewrite-tool-for-fixing-deprecated-code-12a595b291d8 > ) > > As for ASTs I would be also curious about the answer, as this seems > like it should be a simple task. > > Peter > > On Sat, Sep 12, 2015 at 2:24 PM, Julien Delplanque <[hidden email] > <mailto:[hidden email]>> wrote: > > Hi everyone, > > I would like to modify the AST of a smalltalk expression > compiled to automatically send a certain message > when a node represents a Character (so the user does not have to > write the message sending explicitly). > I would of course add a special button in the menu you get when > right clicking in a playground so the user > knows it is a "special" do-it... > > For example: > $a. > would transform into an ast that the source code looks like > $a aMessage > > How can I do this? :) > > Julien > > > |
Need to keep all those snipets somewhere. And I think the chapter in Pharo for the enterprise does not explain well the conditional stuff in { }. I always forget the syntax of writing condition on nodes :) |
In reply to this post by Thierry Goubier
Great! Thats what I was looking for.
On 12/09/15 18:12, Thierry Goubier wrote: > Hi Julien, Mark and Peter, > > here is a RB approach: > > | rewriter | > rewriter := RBParseTreeRewriter new > replace: ' `#aLiteral `{:node | node value isCharacter}' > with: '`#aLiteral aMessage'; yourself. > rewriter executeTree: (RBParser parseExpression: 'Array with: $a > asciiValue with: $b with: #c with: d'). > rewriter tree formattedCode > > And the result is: > > 'Array > with: $a aMessage asciiValue > with: $b aMessage > with: #c > with: d' > > Need to keep all those snipets somewhere. And I think the chapter in > Pharo for the enterprise does not explain well the conditional stuff > in { }. > > Thierry > > > Le 12/09/2015 16:03, Mark Rizun a écrit : >> Hi everyone, >> >> I believe you should be able to do this transformation with Rewrite >> Tool. >> The only problem I see is that you want to do this only with single >> symbol. >> Because, in my tool you can do: >> >> transform: *`#literal* into: *`#literal aMessage*. >> In this case `#literal**means any literal, not only symbols. >> In other words it will transform >> >> $a into $a aMessage >> >> Also, this rule will transform, for instance >> 123 into 123 aMessage >> >> If I understand right, you would like to do this programatically, so you >> don't need RewriteTool in that case. >> >> Mark >> >> 2015-09-12 16:46 GMT+03:00 Peter Uhnák <[hidden email] >> <mailto:[hidden email]>>: >> >> If you don't want to manually operate on AST, you can use Mark's >> Rewrite Tool ( http://screencast.com/t/LCEl0hFl , >> https://medium.com/@peteruhnak/using-rewrite-tool-for-fixing-deprecated-code-12a595b291d8 >> ) >> >> As for ASTs I would be also curious about the answer, as this seems >> like it should be a simple task. >> >> Peter >> >> On Sat, Sep 12, 2015 at 2:24 PM, Julien Delplanque <[hidden email] >> <mailto:[hidden email]>> wrote: >> >> Hi everyone, >> >> I would like to modify the AST of a smalltalk expression >> compiled to automatically send a certain message >> when a node represents a Character (so the user does not have to >> write the message sending explicitly). >> I would of course add a special button in the menu you get when >> right clicking in a playground so the user >> knows it is a "special" do-it... >> >> For example: >> $a. >> would transform into an ast that the source code looks like >> $a aMessage >> >> How can I do this? :) >> >> Julien >> >> >> > > |
In reply to this post by Mark Rizun
Le 12/09/2015 18:20, Mark Rizun a écrit :
> Need to keep all those snipets somewhere. And I think the chapter in > Pharo for the enterprise does not explain well the conditional stuff > in { }. > > > I always forget the syntax of writing condition on nodes :) I was missing the fact that the condition apply to the previous pattern variable? Conditions are very convenient, however, to execute code during the matching part of the rewrite. Especially code with side effects ;) Thierry |
| rewriter | This is cool! And so simple! Need to keep all those snipets somewhere. And I think the chapter in Pharo for the enterprise does not explain well the conditional stuff in { }. P4E is still work-in-progress, no? So it still can be added there. I think we need some better way to present the content of the books than just a "book"... like with side menu showing topics within a chapter, search, or whatever. Maybe it could be made available somewhere with Guille's Ecstatic generator. Peter |
This can be combined with the compiler transform plugins of Opal: -> make subclass of OCCompilerASTPlugin -> put your code in a method called #transform now when you override #compiler on the class side of a class like this: compiler ^super compiler addPlugin: ASTPluginMeaningOfLife. the plugin will be active for the hierarchy, which means that all code compiled will be transformed. There is a simple example ASTPluginMeaningOfLife in the image. Marcus |
Le 13/09/2015 08:56, Marcus Denker a écrit :
> >> On 12 Sep 2015, at 19:23, Peter Uhnák <[hidden email] >> <mailto:[hidden email]>> wrote: >> >> | rewriter | >> rewriter := RBParseTreeRewriter new >> replace: ' `#aLiteral `{:node | node value isCharacter}' >> with: '`#aLiteral aMessage'; yourself. >> rewriter executeTree: (RBParser parseExpression: 'Array with: $a >> asciiValue with: $b with: #c with: d'). >> rewriter tree formattedCode >> >> >> This is cool! And so simple! >> > > This can be combined with the compiler transform plugins of Opal: > > -> make subclass of OCCompilerASTPlugin > -> put your code in a method called #transform > > now when you override #compiler on the class side of a class like this: > > compiler > ^super compiler addPlugin: ASTPluginMeaningOfLife. > > the plugin will be active for the hierarchy, which means that all code > compiled will be transformed. > > There is a simple example ASTPluginMeaningOfLife in the image. Cool. Intriguing. I'm sure I can use it to: - patch problematic code on the fly without registering an override - change the semantics of some smalltalk statement (so that a := becomes self a: or anything else) Would it be possible to couple it with Clement work to have some ability to pre-compile some code in specific classes (strength reduction, once literals) where we know that this is valuable? It would also be nice to have a way not to write bytecode by hand, like, say, in the slots example of a few days back. Oh, ok, for the literal stuff, I think I know how to do it: In a method: - replace target expression with symbol literal. - evaluate target expression in isolation, store value. - compile method with symbol literal. - in compiled method, replace symbol literal with value stored above. Would that work? Thierry > > Marcus > |
> > Cool. Intriguing. > > I'm sure I can use it to: > - patch problematic code on the fly without registering an override > - change the semantics of some smalltalk statement (so that a := becomes self a: or anything else) > Yes, it is for “evil” experiments that can not be done else (short of changing the compiler itself). e.g. last week for an experiment, I wanted a form of “super” where it is not “self, but start lookup in superclass”, but instead “this object, do a send to it but start lookup in the superclass”. There are no messages called #super in the image, so you can so that by transforming all myObject super doSomething into myObject perform: #doSomething withArguments: #() inSuperclass: myObject class superclass. The needed Opal plugin has this #transform method: transform | superSends new | superSends := ast sendNodes select: [ :each | each selector = #super ]. superSends do: [ :spnode | new := RBMessageNode receiver: spnode receiver copy selector: #perform:withArguments:inSuperclass: arguments: {RBLiteralNode value: spnode parent selector copy . RBArrayNode statements: spnode parent arguments . RBMessageNode receiver: (RBMessageNode receiver: spnode receiver copy selector: #class) selector: #superclass}. spnode parent replaceWith: new ]. ^ast > Would it be possible to couple it with Clement work to have some ability to pre-compile some code in specific classes (strength reduction, once literals) where we know that this is valuable? > Good question…. > It would also be nice to have a way not to write bytecode by hand, like, say, in the slots example of a few days back. > Yes, the byte code writing for Slots is just a solution that works *today*. With a runtime optimizer you could instead always generate the reflective slow version and let Sista optimise it. > Oh, ok, for the literal stuff, I think I know how to do it: > > In a method: > - replace target expression with symbol literal. > - evaluate target expression in isolation, store value. > - compile method with symbol literal. > - in compiled method, replace symbol literal with value stored above. > > Would that work? > Hmm… messages to known objects without side effect could be evaluated by the compiler. What makes it hard ist mostly debugging: mapping the generated code back to the original source…. Marcus |
Free forum by Nabble | Edit this page |