You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@groovy.apache.org by Ed Clark <ea...@ameritech.net> on 2017/02/14 11:41:38 UTC

Re: help with an AST

Hi Jochen,

Well, I've been slowly making progress on this; kind of feels like bashing my
head against a wall at times, but I have made a small hole in the wall through
which I can see my goal. ;-)

Unfortunately, I've reached a point where the hole isn't getting any bigger and
my google-fu isn't up to the task of finding what I need to make it bigger.

Specifically, I haven't figured out how to inject a variable into the scope of an outer
with's closure that can be used by code in an interior with's closure.  For example,
consider

   myCtx1.with {
       __outerCtx1 = null            // injected statement
       __currCtx1 = myCtx1       // injected statement
       .... some code ...
       myCtx2.with {
           __outerCtx2 = __currCtx1   // injected statement <---  doesn't work
           __currCtx2 = myCtx2          // injected statement

My problem is the compiler chokes on the reference to __currCtx1 in the inner
with closure, claiming that __currCtx1 isn't a property of myCtx1.

My google-fu only tells me I haven't set up the scoping correctly, but for the life of me
I haven't found the correct way to do this.  And further experimenting, groping in the
dark, and head banging hasn't helped either. :\

Any illuminating insight, or direction pointing, or example would be greatly appreciated!

Thanks

Ed

On 12/31/2016 06:36 PM, Jochen Theodorou wrote:
>
>
> On 31.12.2016 17:32, Ed Clark wrote:
> [...]
>>> Assuming you still want to do something like this with more... AST
>>> involvement...
>>>
>>>> My questions for you are,
>>>>
>>>>      - is an AST the way to go?
>>>
>>> first you have to decide what you want to compile to and then we can
>>> think about how the AST for that has to look like. So this is actually
>>> the last step. But assuming you have some kind of handler object you
>>> could compile a+b to handler.invoke("plus",a,b)... in other words you
>>> would replace almost any expression by a MethodCallExpression. Hint:
>>> ExpressonTransformer and helper classes.
>>
>> Hmmm, I will have a handler object - sort of - and that's the context
>> object itself.  Well, at
>> least in the case of instance based contexts.  For class based contexts,
>> there won't be
>> an instantiated handler, but I could still see having a static "invoke"
>> method.
>>
>> I hadn't considered the invoke approach; it is interesting.  I think it
>> would provide some
>> additional flexibility that the context developer could use to add
>> "operators" beyond the
>> ones built into the Groovy parser/AST.  I'll have to think about this
>> some more.
>
> the handler object does not have to be the context object itself. It can be a collection of 
> context objects, be it classes or instances. It could be also be a collection of methods and 
> instances from the context. Important for the compiler part is only the calling convention.
>
>>>>      - I'm guessing that I can do the context nesting and composing by building on
>>>>        methodMissing (with ctx2 chaining to ctx3 chaining to Ctx1 above), but is there
>>>>        a better way?
>>>
>>> I guess the code path for categories won�t help you here, since that
>>> is kind of special treated. You could create a special meta class and
>>> all the context methods to it, then use its mechanisms to select an
>>> appropriate method... hint getMetaMethod, init
>>
>> Just to be clear, I don't think there is anything special about the
>> contexts - they are
>> just POGOs.  Their methods just happen to be focused on manipulating
>> objects that
>> fall under their scope.  So, I'm not sure how creating a meta class
>> would help.
>
> you would not really create a meta class of a specific class, you would create a meta class in the 
> sense of an enumeration of methods and method selection mechanism. But well... now need for that 
> at this point I guess. You can of course simply work with methodMissing.
>
> [...]
>> Yeah, one of my problems is I think too far ahead ;).  I start worrying
>> about what
>> it might take to run a marathon when I haven't even learned to walk.  So
>> I don't
>> even get started.  Part of the this resolution is to just get off my
>> butt and write
>> some code.
>
> that's a good resolution for the new year ;)
>
> Let me help you: assuming you use "with"-blocks:
>
> Step 1) write an AST transformation that will recognize the with-block and store the context in a 
> variable
>
> Step 2) add an expression transformer, that will transform all the expressions of interest in the 
> with-block to method calls based on the context variable
>
> Step 3) implement a context
>
> Step 4) transform nested with method calls to calls that allow you the creation and nesting of a 
> context plus add code to delegate to outer contexts
>
> Even if it turns out not to be useful in the end (and I think it will be useful) you will still 
> get some practice about writing such things. Nothing to really loose here imho ;)
>
> bye Jochen



Re: help with an AST

Posted by Ed Clark <ea...@ameritech.net>.
Hi Paul,

Unfortunately that didn't help.  I still get the error:

     BUG! exception in phase 'class generation' in source unit 'CtxTest2.groovy' Operation: 
(<assignment operator>:  "=" ) not supported

I put those two lines right after my top level "visit" call. Thinking
about it, the class node being visited is that of the top level
script - the classes that are being transformed are not explicitly
being visited.  Perhaps the "visit" at the top level script will descend
into the inner classes?

On the off chance that it won't, I also tried something I found online:

VariableScopeVisitor scopeVisitor = new VariableScopeVisitor( sourceUnit)
sourceUnit.AST.classes.each {
      println '11111111111111111 visiting class ' + it
      scopeVisitor.visitClass( it)
}

(Obviously, the println is there to check that the xformed classes are visited
explicitly; which they are.)

The error is still there.

I also saw warnings online that you don't want to visit the same scope twice.
If a visit to the top level script implicitly visits the classes defined within,
then this would be a double visit to the xformed classes - I'm guessing.

(Perhaps I need to look at the VariableScopeVisitor implementation to better
understand what's going on.)

Other thoughts/suggestions?

Regards,

Ed


On 02/16/2017 04:41 PM, Paul King wrote:
> Do you have something like:
>
> VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(source)
> scopeVisitor.visitClass(cNode)
>
> for each of your closure(s)? Where cNode is a closure's classNode?
>
> Cheers, Paul.
>
>
> On Thu, Feb 16, 2017 at 9:35 PM, Ed Clark <ea...@ameritech.net> wrote:
>> Ok, a little more headbanging and I seem to have gotten farther (maybe?).
>> At least the error message has changed.  Now I'm getting:
>>
>> BUG! exception in phase 'class generation' in source unit 'CtxTest2.groovy'
>> Operation: (<assignment operator>:  "=" ) not supported
>>
>> Searching hasn't helped with this one.
>>
>> The xform-ed code looks good -- in fact, if I type the code into a separate
>> groovyConsole, it will run.  (The console AST generation works up thru
>> the Instruction Selection phase, obviously.)
>>
>> I'm guessing it's still with how I'm setting up the scoping (or how I'm not
>> setting up the scoping).
>>
>> Ideas, please?
>>
>> Thanks,
>>
>> Ed
>>
>>
>> On 02/14/2017 12:58 PM, Ed Clark wrote:
>>> On 02/14/2017 12:16 PM, Jochen Theodorou wrote:
>>>>
>>>>
>>>> On 14.02.2017 12:41, Ed Clark wrote:
>>>>> Hi Jochen,
>>>>>
>>>>> Well, I've been slowly making progress on this; kind of feels like
>>>>> bashing my
>>>>> head against a wall at times, but I have made a small hole in the wall
>>>>> through
>>>>> which I can see my goal. ;-)
>>>>
>>>> making holes my lead to brain damage.. then things get really hard to
>>>> solve ;)
>>> Maybe I'm too late, and that's why things aren't coming together ;)
>>>
>>>> [...]
>>>>> Specifically, I haven't figured out how to inject a variable into the
>>>>> scope of an outer
>>>>> with's closure that can be used by code in an interior with's closure.
>>>>> For example,
>>>>> consider
>>>>>
>>>>>    myCtx1.with {
>>>>>        __outerCtx1 = null            // injected statement
>>>>>        __currCtx1 = myCtx1       // injected statement
>>>>>        .... some code ...
>>>>>        myCtx2.with {
>>>>>            __outerCtx2 = __currCtx1   // injected statement <---  doesn't
>>>>> work
>>>>>            __currCtx2 = myCtx2          // injected statement
>>>>
>>>> where is __currCtx1 and __outerCtx1 coming from? Are they supposed to be
>>>> new local variables? in that case you will have to add a
>>>> DeclarationStatement, not just an assignment to a VariableExpression.
>>>> Otherwise the compiler will thnk they are dynamic properties and tries to
>>>> resolve them against the context.
>>>>
>>>> as for the logic behind __outerCtxN... with number wouldn't have to be
>>>> null I would have said you should think of using getOwner on Closure
>>>>
>>> Hmmm, I'm close to that, but not quite the same.  I was trying
>>>
>>>     ExpressionStatement currCtx = new ExpressionStatement(
>>>         new DeclarationExpression (
>>>             new VariableExpression( "__currCtx$levelcnt"),
>>>             new Token( Types.ASSIGNMENT_OPERATOR, "=", -1, -1),
>>>             new MethodCallExpression( new VariableExpression( 'this'),
>>> 'getDelegate', new ArgumentListExpression())
>>>         )
>>>     )
>>>
>>> Would a DeclarationStatment act differently from an ExpressionStatement
>>> with an embedded
>>> DeclarationExpression?  If my foggy memory is correct, I wrote my code
>>> after looking at the
>>> AST displayed for a short test script in groovyConsole.
>>>
>>> Plus, if foggy memory serves, I tried using getOwner and it came back with
>>> the closure being
>>> owned by the test script, not the object doing the with.  Calling
>>> getDelegate gave me the object.
>>> If foggy memory serves.
>>>
>>> I also tried playing around with setClosureSharedVariable( true) and
>>> putReferencedLocalVariable()
>>> without success.  But, those were somewhat blind stabs in the dark, so I
>>> might not have been
>>> using them correctly.
>>>
>>> Looking at the AST generated by groovyConsole, my transform looks like it
>>> is working, but
>>> the compiler complains about things not being in scope (in the inner
>>> closure).  So, I'm doing
>>> something wrong with setting up the scoping.
>>>
>>>>   bye Jochen
>>>
>>> Thanks,
>>>
>>> Ed
>>>


Re: help with an AST

Posted by Ed Clark <ea...@ameritech.net>.
Just in case someone searches this topic in the future (probably me in
a year or two ;) ), using ASSIGN rather than ASSIGNMENT_OPERATOR
does work.  Thanks Paul.

On 02/22/2017 06:07 PM, Paul King wrote:
> You can probably use ASSIGN rather than ASSIGNMENT_OPERATOR which is
> meant to be a type class though I am not sure we really use it.
>
> On Thu, Feb 23, 2017 at 2:08 AM, Ed Clark <ea...@ameritech.net> wrote:
>> I can report progress.  Turns out there were two problems.
>>
>> The error message that I was getting concerning <assignment operator>: "="
>> not being supported had to do with how I built the token for the
>> BinaryExpression.
>>
>> I was using:
>>
>>      new BinaryExpression(
>>          sV,    // a VariableExpression
>>          new Token( Types.ASSIGNMENT_OPERATOR, '=', -1, -1),
>>          rtV    // another VariableExpression
>>
>> When I examined the AST that was generated after the transform, I noticed
>> that
>> the corresponding token mentioned:  <assignment operator>.  But, if I looked
>> at
>> a separate AST from hand written code that matched the output of the
>> transform,
>> that token mentioned:  symbol "=".  Not the same
>>
>> After a quick Google search I hit upon:
>>
>>      new BinaryExpression(
>>          sV,    // a VariableExpression
>>          Token.newSymbol(  '=', -1, -1),
>>          rtV    // another VariableExpression
>>
>> This gets rid of the error!  I'm not sure why the first way to build a Token
>> doesn't
>> work.  I'll also note that there are a number code examples using the first
>> approach that turn up in a web search.  In any case, I'm happy to have one
>> that
>> does work.
>>
>> At this point, applying the VariableScopeVisitor that Paul suggested seems
>> to
>> clean up my remaining problem with scoping issues.
>>
>> Yeah!
>>
>> On to the next wall, how to generate a table of method signatures (at
>> transform time)
>> for all the methods defined in the user written classes (marked with my
>> annotation)...
>>
>> Many thanks,
>>
>> Ed
>>
>>
>>
>> On 02/20/2017 12:06 PM, Ed Clark wrote:
>>
>> Ok, poking around the source for VariableScopeVisitor didn't provide me
>> with any insights.  It did lead me to try
>>      VariableScopeVisitor scopeVisitor = new VariableScopeVisitor( source,
>> true)
>> but I still get the error:
>>      BUG! exception in phase 'class generation' in source unit
>> 'CtxTest2.groovy' Operation: (<assignment operator>:  "=" ) not supported
>>
>> One possible twist that I noticed, is if I run my test script under
>> groovyConsole
>> I get one error message.  But, if I run the equivalent code (with a 'main')
>> as a
>> standalone groovy file, the error message is printed twice.  Not sure what
>> that
>> indicates.
>>
>> But, it is tied to my inserted statements.  If I comment out the statement
>> insertions, the compiler is happy.  So I'm guessing I'm building bad
>> statements.
>>
>> What is the proper way to build a statement that set a property that is
>> defined in a base class (i.e., extended by a class that gets instantiated)?
>>
>> I'm currently doing:
>>
>>      VariableExpression cV = new VariableExpression( '__currentContext')
>> //    PropertyExpression cP = new PropertyExpression( cnStack[ -1],
>> '__currentContext')
>>      ExpressionStatement currStmt = new ExpressionStatement(
>>          new BinaryExpression(
>>                  cV,                           // also tried assigning to cP
>> instead of cV
>>                  new Token(Types.ASSIGNMENT_OPERATOR, "=", -1, -1),
>>                  cnStack[ -1]
>> //                 new MethodCallExpression(
>> VariableExpression.THIS_EXPRESSION,
>> //                                                             new
>> ConstantExpression( 'getDelegate'),
>> //                                                             new
>> ArgumentListExpress())
>>          )
>>      )
>>      blockStatement.statements.add( 0, currStmt)
>>
>> (I've tried with and without the VariableScopeVisitor call, and with and
>> without
>> a call to "blockStatement.variableScope.putReferencedClassVariable( cv)".)
>>
>> So, does this look like the correct way to set the value of a property that
>> is
>> inherited from a base class?
>>
>> (The somewhat frustrating thing is the resultant AST with the inserted
>> statements
>> looks correct after the transform (up through the Instruction Selection
>> phase).
>> In fact, if I type that code into a separate groovyConsole, it runs.)
>>
>>
>> Thanks for your time,
>>
>> Ed
>>
>>
>>
>> On 02/16/2017 04:41 PM, Paul King wrote:
>>
>> Do you have something like:
>>
>> VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(source)
>> scopeVisitor.visitClass(cNode)
>>
>> for each of your closure(s)? Where cNode is a closure's classNode?
>>
>> Cheers, Paul.
>>
>>


Re: help with an AST

Posted by Paul King <pa...@asert.com.au>.
You can probably use ASSIGN rather than ASSIGNMENT_OPERATOR which is
meant to be a type class though I am not sure we really use it.

On Thu, Feb 23, 2017 at 2:08 AM, Ed Clark <ea...@ameritech.net> wrote:
> I can report progress.  Turns out there were two problems.
>
> The error message that I was getting concerning <assignment operator>: "="
> not being supported had to do with how I built the token for the
> BinaryExpression.
>
> I was using:
>
>     new BinaryExpression(
>         sV,    // a VariableExpression
>         new Token( Types.ASSIGNMENT_OPERATOR, '=', -1, -1),
>         rtV    // another VariableExpression
>
> When I examined the AST that was generated after the transform, I noticed
> that
> the corresponding token mentioned:  <assignment operator>.  But, if I looked
> at
> a separate AST from hand written code that matched the output of the
> transform,
> that token mentioned:  symbol "=".  Not the same
>
> After a quick Google search I hit upon:
>
>     new BinaryExpression(
>         sV,    // a VariableExpression
>         Token.newSymbol(  '=', -1, -1),
>         rtV    // another VariableExpression
>
> This gets rid of the error!  I'm not sure why the first way to build a Token
> doesn't
> work.  I'll also note that there are a number code examples using the first
> approach that turn up in a web search.  In any case, I'm happy to have one
> that
> does work.
>
> At this point, applying the VariableScopeVisitor that Paul suggested seems
> to
> clean up my remaining problem with scoping issues.
>
> Yeah!
>
> On to the next wall, how to generate a table of method signatures (at
> transform time)
> for all the methods defined in the user written classes (marked with my
> annotation)...
>
> Many thanks,
>
> Ed
>
>
>
> On 02/20/2017 12:06 PM, Ed Clark wrote:
>
> Ok, poking around the source for VariableScopeVisitor didn't provide me
> with any insights.  It did lead me to try
>     VariableScopeVisitor scopeVisitor = new VariableScopeVisitor( source,
> true)
> but I still get the error:
>     BUG! exception in phase 'class generation' in source unit
> 'CtxTest2.groovy' Operation: (<assignment operator>:  "=" ) not supported
>
> One possible twist that I noticed, is if I run my test script under
> groovyConsole
> I get one error message.  But, if I run the equivalent code (with a 'main')
> as a
> standalone groovy file, the error message is printed twice.  Not sure what
> that
> indicates.
>
> But, it is tied to my inserted statements.  If I comment out the statement
> insertions, the compiler is happy.  So I'm guessing I'm building bad
> statements.
>
> What is the proper way to build a statement that set a property that is
> defined in a base class (i.e., extended by a class that gets instantiated)?
>
> I'm currently doing:
>
>     VariableExpression cV = new VariableExpression( '__currentContext')
> //    PropertyExpression cP = new PropertyExpression( cnStack[ -1],
> '__currentContext')
>     ExpressionStatement currStmt = new ExpressionStatement(
>         new BinaryExpression(
>                 cV,                           // also tried assigning to cP
> instead of cV
>                 new Token(Types.ASSIGNMENT_OPERATOR, "=", -1, -1),
>                 cnStack[ -1]
> //                 new MethodCallExpression(
> VariableExpression.THIS_EXPRESSION,
> //                                                             new
> ConstantExpression( 'getDelegate'),
> //                                                             new
> ArgumentListExpress())
>         )
>     )
>     blockStatement.statements.add( 0, currStmt)
>
> (I've tried with and without the VariableScopeVisitor call, and with and
> without
> a call to "blockStatement.variableScope.putReferencedClassVariable( cv)".)
>
> So, does this look like the correct way to set the value of a property that
> is
> inherited from a base class?
>
> (The somewhat frustrating thing is the resultant AST with the inserted
> statements
> looks correct after the transform (up through the Instruction Selection
> phase).
> In fact, if I type that code into a separate groovyConsole, it runs.)
>
>
> Thanks for your time,
>
> Ed
>
>
>
> On 02/16/2017 04:41 PM, Paul King wrote:
>
> Do you have something like:
>
> VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(source)
> scopeVisitor.visitClass(cNode)
>
> for each of your closure(s)? Where cNode is a closure's classNode?
>
> Cheers, Paul.
>
>

Re: help with an AST

Posted by Ed Clark <ea...@ameritech.net>.
I can report progress.  Turns out there were two problems.

The error message that I was getting concerning <assignment operator>: "="
not being supported had to do with how I built the token for the BinaryExpression.

I was using:

     new BinaryExpression(
         sV,    // a VariableExpression
         new Token( Types.ASSIGNMENT_OPERATOR, '=', -1, -1),
         rtV    // another VariableExpression

When I examined the AST that was generated after the transform, I noticed that
the corresponding token mentioned:  <assignment operator>. But, if I looked at
a separate AST from hand written code that matched the output of the transform,
that token mentioned:  symbol "=".  Not the same

After a quick Google search I hit upon:

     new BinaryExpression(
         sV,    // a VariableExpression
         Token.newSymbol(  '=', -1, -1),
         rtV    // another VariableExpression

This gets rid of the error!  I'm not sure why the first way to build a Token doesn't
work.  I'll also note that there are a number code examples using the first
approach that turn up in a web search.  In any case, I'm happy to have one that
does work.

At this point, applying the VariableScopeVisitor that Paul suggested seems to
clean up my remaining problem with scoping issues.

Yeah!

On to the next wall, how to generate a table of method signatures (at transform time)
for all the methods defined in the user written classes (marked with my annotation)...

Many thanks,

Ed


On 02/20/2017 12:06 PM, Ed Clark wrote:
> Ok, poking around the source for VariableScopeVisitor didn't provide me
> with any insights.  It did lead me to try
>     VariableScopeVisitor scopeVisitor = new VariableScopeVisitor( source, true)
> but I still get the error:
>     BUG! exception in phase 'class generation' in source unit 'CtxTest2.groovy' Operation: 
> (<assignment operator>:  "=" ) not supported
>
> One possible twist that I noticed, is if I run my test script under groovyConsole
> I get one error message.  But, if I run the equivalent code (with a 'main') as a
> standalone groovy file, the error message is printed twice.  Not sure what that
> indicates.
>
> But, it is tied to my inserted statements.  If I comment out the statement
> insertions, the compiler is happy.  So I'm guessing I'm building bad
> statements.
>
> What is the proper way to build a statement that set a property that is
> defined in a base class (i.e., extended by a class that gets instantiated)?
>
> I'm currently doing:
>
>     VariableExpression cV = newVariableExpression( '__currentContext')
> //    PropertyExpression cP = newPropertyExpression( cnStack[ -1], '__currentContext')
>     ExpressionStatement currStmt = newExpressionStatement(
>         new BinaryExpression(
>                 cV,                           // also tried assigning to cP instead of cV
>                 new Token(Types.ASSIGNMENT_OPERATOR, "=", -1, -1),
>                 cnStack[ -1]
> //                 new MethodCallExpression( VariableExpression.THIS_EXPRESSION,
> // new ConstantExpression( 'getDelegate'),
> // new ArgumentListExpress())
>     )
>     )
>     blockStatement.statements.add( 0, currStmt)
>
> (I've tried with and without the VariableScopeVisitor call, and with and without
> a call to "blockStatement.variableScope.putReferencedClassVariable( cv)".)
>
> So, does this look like the correct way to set the value of a property that is
> inherited from a base class?
>
> (The somewhat frustrating thing is the resultant AST with the inserted statements
> looks correct after the transform (up through the Instruction Selection phase).
> In fact, if I type that code into a separate groovyConsole, it runs.)
>
>
> Thanks for your time,
>
> Ed
>
>
>
> On 02/16/2017 04:41 PM, Paul King wrote:
>> Do you have something like:
>>
>> VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(source)
>> scopeVisitor.visitClass(cNode)
>>
>> for each of your closure(s)? Where cNode is a closure's classNode?
>>
>> Cheers, Paul.
>>


Re: help with an AST

Posted by Ed Clark <ea...@ameritech.net>.
Ok, poking around the source for VariableScopeVisitor didn't provide me
with any insights.  It did lead me to try
     VariableScopeVisitor scopeVisitor = new VariableScopeVisitor( source, true)
but I still get the error:
     BUG! exception in phase 'class generation' in source unit 'CtxTest2.groovy' Operation: 
(<assignment operator>:  "=" ) not supported

One possible twist that I noticed, is if I run my test script under groovyConsole
I get one error message.  But, if I run the equivalent code (with a 'main') as a
standalone groovy file, the error message is printed twice.  Not sure what that
indicates.

But, it is tied to my inserted statements.  If I comment out the statement
insertions, the compiler is happy.  So I'm guessing I'm building bad
statements.

What is the proper way to build a statement that set a property that is
defined in a base class (i.e., extended by a class that gets instantiated)?

I'm currently doing:

     VariableExpression cV = newVariableExpression( '__currentContext')
//    PropertyExpression cP = newPropertyExpression( cnStack[ -1], '__currentContext')
     ExpressionStatement currStmt = newExpressionStatement(
         new BinaryExpression(
                 cV,                           // also tried assigning to cP instead of cV
                 new Token(Types.ASSIGNMENT_OPERATOR, "=", -1, -1),
                 cnStack[ -1]
//                 new MethodCallExpression( VariableExpression.THIS_EXPRESSION,
//                                                             new ConstantExpression( 'getDelegate'),
//                                                             new ArgumentListExpress())
     )
     )
     blockStatement.statements.add( 0, currStmt)

(I've tried with and without the VariableScopeVisitor call, and with and without
a call to "blockStatement.variableScope.putReferencedClassVariable( cv)".)

So, does this look like the correct way to set the value of a property that is
inherited from a base class?

(The somewhat frustrating thing is the resultant AST with the inserted statements
looks correct after the transform (up through the Instruction Selection phase).
In fact, if I type that code into a separate groovyConsole, it runs.)


Thanks for your time,

Ed



On 02/16/2017 04:41 PM, Paul King wrote:
> Do you have something like:
>
> VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(source)
> scopeVisitor.visitClass(cNode)
>
> for each of your closure(s)? Where cNode is a closure's classNode?
>
> Cheers, Paul.
>

Re: help with an AST

Posted by Ed Clark <ea...@ameritech.net>.
Hi Paul,

No I don't have that.  Let me play around with it.
Thanks for the pointer.

Ed

On 02/16/2017 04:41 PM, Paul King wrote:
> Do you have something like:
>
> VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(source)
> scopeVisitor.visitClass(cNode)
>
> for each of your closure(s)? Where cNode is a closure's classNode?
>
> Cheers, Paul.
>
>
> On Thu, Feb 16, 2017 at 9:35 PM, Ed Clark <ea...@ameritech.net> wrote:
>> Ok, a little more headbanging and I seem to have gotten farther (maybe?).
>> At least the error message has changed.  Now I'm getting:
>>
>> BUG! exception in phase 'class generation' in source unit 'CtxTest2.groovy'
>> Operation: (<assignment operator>:  "=" ) not supported
>>
>> Searching hasn't helped with this one.
>>
>> The xform-ed code looks good -- in fact, if I type the code into a separate
>> groovyConsole, it will run.  (The console AST generation works up thru
>> the Instruction Selection phase, obviously.)
>>
>> I'm guessing it's still with how I'm setting up the scoping (or how I'm not
>> setting up the scoping).
>>
>> Ideas, please?
>>
>> Thanks,
>>
>> Ed
>>
>>
>> On 02/14/2017 12:58 PM, Ed Clark wrote:
>>> On 02/14/2017 12:16 PM, Jochen Theodorou wrote:
>>>>
>>>>
>>>> On 14.02.2017 12:41, Ed Clark wrote:
>>>>> Hi Jochen,
>>>>>
>>>>> Well, I've been slowly making progress on this; kind of feels like
>>>>> bashing my
>>>>> head against a wall at times, but I have made a small hole in the wall
>>>>> through
>>>>> which I can see my goal. ;-)
>>>>
>>>> making holes my lead to brain damage.. then things get really hard to
>>>> solve ;)
>>> Maybe I'm too late, and that's why things aren't coming together ;)
>>>
>>>> [...]
>>>>> Specifically, I haven't figured out how to inject a variable into the
>>>>> scope of an outer
>>>>> with's closure that can be used by code in an interior with's closure.
>>>>> For example,
>>>>> consider
>>>>>
>>>>>    myCtx1.with {
>>>>>        __outerCtx1 = null            // injected statement
>>>>>        __currCtx1 = myCtx1       // injected statement
>>>>>        .... some code ...
>>>>>        myCtx2.with {
>>>>>            __outerCtx2 = __currCtx1   // injected statement <---  doesn't
>>>>> work
>>>>>            __currCtx2 = myCtx2          // injected statement
>>>>
>>>> where is __currCtx1 and __outerCtx1 coming from? Are they supposed to be
>>>> new local variables? in that case you will have to add a
>>>> DeclarationStatement, not just an assignment to a VariableExpression.
>>>> Otherwise the compiler will thnk they are dynamic properties and tries to
>>>> resolve them against the context.
>>>>
>>>> as for the logic behind __outerCtxN... with number wouldn't have to be
>>>> null I would have said you should think of using getOwner on Closure
>>>>
>>> Hmmm, I'm close to that, but not quite the same.  I was trying
>>>
>>>     ExpressionStatement currCtx = new ExpressionStatement(
>>>         new DeclarationExpression (
>>>             new VariableExpression( "__currCtx$levelcnt"),
>>>             new Token( Types.ASSIGNMENT_OPERATOR, "=", -1, -1),
>>>             new MethodCallExpression( new VariableExpression( 'this'),
>>> 'getDelegate', new ArgumentListExpression())
>>>         )
>>>     )
>>>
>>> Would a DeclarationStatment act differently from an ExpressionStatement
>>> with an embedded
>>> DeclarationExpression?  If my foggy memory is correct, I wrote my code
>>> after looking at the
>>> AST displayed for a short test script in groovyConsole.
>>>
>>> Plus, if foggy memory serves, I tried using getOwner and it came back with
>>> the closure being
>>> owned by the test script, not the object doing the with.  Calling
>>> getDelegate gave me the object.
>>> If foggy memory serves.
>>>
>>> I also tried playing around with setClosureSharedVariable( true) and
>>> putReferencedLocalVariable()
>>> without success.  But, those were somewhat blind stabs in the dark, so I
>>> might not have been
>>> using them correctly.
>>>
>>> Looking at the AST generated by groovyConsole, my transform looks like it
>>> is working, but
>>> the compiler complains about things not being in scope (in the inner
>>> closure).  So, I'm doing
>>> something wrong with setting up the scoping.
>>>
>>>>   bye Jochen
>>>
>>> Thanks,
>>>
>>> Ed
>>>


Re: help with an AST

Posted by Paul King <pa...@asert.com.au>.
Do you have something like:

VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(source)
scopeVisitor.visitClass(cNode)

for each of your closure(s)? Where cNode is a closure's classNode?

Cheers, Paul.


On Thu, Feb 16, 2017 at 9:35 PM, Ed Clark <ea...@ameritech.net> wrote:
> Ok, a little more headbanging and I seem to have gotten farther (maybe?).
> At least the error message has changed.  Now I'm getting:
>
> BUG! exception in phase 'class generation' in source unit 'CtxTest2.groovy'
> Operation: (<assignment operator>:  "=" ) not supported
>
> Searching hasn't helped with this one.
>
> The xform-ed code looks good -- in fact, if I type the code into a separate
> groovyConsole, it will run.  (The console AST generation works up thru
> the Instruction Selection phase, obviously.)
>
> I'm guessing it's still with how I'm setting up the scoping (or how I'm not
> setting up the scoping).
>
> Ideas, please?
>
> Thanks,
>
> Ed
>
>
> On 02/14/2017 12:58 PM, Ed Clark wrote:
>>
>> On 02/14/2017 12:16 PM, Jochen Theodorou wrote:
>>>
>>>
>>>
>>> On 14.02.2017 12:41, Ed Clark wrote:
>>>>
>>>> Hi Jochen,
>>>>
>>>> Well, I've been slowly making progress on this; kind of feels like
>>>> bashing my
>>>> head against a wall at times, but I have made a small hole in the wall
>>>> through
>>>> which I can see my goal. ;-)
>>>
>>>
>>> making holes my lead to brain damage.. then things get really hard to
>>> solve ;)
>>
>> Maybe I'm too late, and that's why things aren't coming together ;)
>>
>>>
>>> [...]
>>>>
>>>> Specifically, I haven't figured out how to inject a variable into the
>>>> scope of an outer
>>>> with's closure that can be used by code in an interior with's closure.
>>>> For example,
>>>> consider
>>>>
>>>>   myCtx1.with {
>>>>       __outerCtx1 = null            // injected statement
>>>>       __currCtx1 = myCtx1       // injected statement
>>>>       .... some code ...
>>>>       myCtx2.with {
>>>>           __outerCtx2 = __currCtx1   // injected statement <---  doesn't
>>>> work
>>>>           __currCtx2 = myCtx2          // injected statement
>>>
>>>
>>> where is __currCtx1 and __outerCtx1 coming from? Are they supposed to be
>>> new local variables? in that case you will have to add a
>>> DeclarationStatement, not just an assignment to a VariableExpression.
>>> Otherwise the compiler will thnk they are dynamic properties and tries to
>>> resolve them against the context.
>>>
>>> as for the logic behind __outerCtxN... with number wouldn't have to be
>>> null I would have said you should think of using getOwner on Closure
>>>
>> Hmmm, I'm close to that, but not quite the same.  I was trying
>>
>>    ExpressionStatement currCtx = new ExpressionStatement(
>>        new DeclarationExpression (
>>            new VariableExpression( "__currCtx$levelcnt"),
>>            new Token( Types.ASSIGNMENT_OPERATOR, "=", -1, -1),
>>            new MethodCallExpression( new VariableExpression( 'this'),
>> 'getDelegate', new ArgumentListExpression())
>>        )
>>    )
>>
>> Would a DeclarationStatment act differently from an ExpressionStatement
>> with an embedded
>> DeclarationExpression?  If my foggy memory is correct, I wrote my code
>> after looking at the
>> AST displayed for a short test script in groovyConsole.
>>
>> Plus, if foggy memory serves, I tried using getOwner and it came back with
>> the closure being
>> owned by the test script, not the object doing the with.  Calling
>> getDelegate gave me the object.
>> If foggy memory serves.
>>
>> I also tried playing around with setClosureSharedVariable( true) and
>> putReferencedLocalVariable()
>> without success.  But, those were somewhat blind stabs in the dark, so I
>> might not have been
>> using them correctly.
>>
>> Looking at the AST generated by groovyConsole, my transform looks like it
>> is working, but
>> the compiler complains about things not being in scope (in the inner
>> closure).  So, I'm doing
>> something wrong with setting up the scoping.
>>
>>>  bye Jochen
>>
>>
>> Thanks,
>>
>> Ed
>>
>

Re: help with an AST

Posted by Ed Clark <ea...@ameritech.net>.
Ok, a little more headbanging and I seem to have gotten farther (maybe?).
At least the error message has changed.  Now I'm getting:

BUG! exception in phase 'class generation' in source unit 'CtxTest2.groovy' Operation: (<assignment 
operator>:  "=" ) not supported

Searching hasn't helped with this one.

The xform-ed code looks good -- in fact, if I type the code into a separate
groovyConsole, it will run.  (The console AST generation works up thru
the Instruction Selection phase, obviously.)

I'm guessing it's still with how I'm setting up the scoping (or how I'm not
setting up the scoping).

Ideas, please?

Thanks,

Ed

On 02/14/2017 12:58 PM, Ed Clark wrote:
> On 02/14/2017 12:16 PM, Jochen Theodorou wrote:
>>
>>
>> On 14.02.2017 12:41, Ed Clark wrote:
>>> Hi Jochen,
>>>
>>> Well, I've been slowly making progress on this; kind of feels like
>>> bashing my
>>> head against a wall at times, but I have made a small hole in the wall
>>> through
>>> which I can see my goal. ;-)
>>
>> making holes my lead to brain damage.. then things get really hard to solve ;)
> Maybe I'm too late, and that's why things aren't coming together ;)
>
>>
>> [...]
>>> Specifically, I haven't figured out how to inject a variable into the
>>> scope of an outer
>>> with's closure that can be used by code in an interior with's closure.
>>> For example,
>>> consider
>>>
>>>   myCtx1.with {
>>>       __outerCtx1 = null            // injected statement
>>>       __currCtx1 = myCtx1       // injected statement
>>>       .... some code ...
>>>       myCtx2.with {
>>>           __outerCtx2 = __currCtx1   // injected statement <---  doesn't
>>> work
>>>           __currCtx2 = myCtx2          // injected statement
>>
>> where is __currCtx1 and __outerCtx1 coming from? Are they supposed to be new local variables? in 
>> that case you will have to add a DeclarationStatement, not just an assignment to a 
>> VariableExpression. Otherwise the compiler will thnk they are dynamic properties and tries to 
>> resolve them against the context.
>>
>> as for the logic behind __outerCtxN... with number wouldn't have to be null I would have said you 
>> should think of using getOwner on Closure
>>
> Hmmm, I'm close to that, but not quite the same.  I was trying
>
>    ExpressionStatement currCtx = new ExpressionStatement(
>        new DeclarationExpression (
>            new VariableExpression( "__currCtx$levelcnt"),
>            new Token( Types.ASSIGNMENT_OPERATOR, "=", -1, -1),
>            new MethodCallExpression( new VariableExpression( 'this'), 'getDelegate', new 
> ArgumentListExpression())
>        )
>    )
>
> Would a DeclarationStatment act differently from an ExpressionStatement with an embedded
> DeclarationExpression?  If my foggy memory is correct, I wrote my code after looking at the
> AST displayed for a short test script in groovyConsole.
>
> Plus, if foggy memory serves, I tried using getOwner and it came back with the closure being
> owned by the test script, not the object doing the with.  Calling getDelegate gave me the object.
> If foggy memory serves.
>
> I also tried playing around with setClosureSharedVariable( true) and putReferencedLocalVariable()
> without success.  But, those were somewhat blind stabs in the dark, so I might not have been
> using them correctly.
>
> Looking at the AST generated by groovyConsole, my transform looks like it is working, but
> the compiler complains about things not being in scope (in the inner closure).  So, I'm doing
> something wrong with setting up the scoping.
>
>>  bye Jochen
>
> Thanks,
>
> Ed
>


Re: help with an AST

Posted by Ed Clark <ea...@ameritech.net>.
On 02/14/2017 12:16 PM, Jochen Theodorou wrote:
>
>
> On 14.02.2017 12:41, Ed Clark wrote:
>> Hi Jochen,
>>
>> Well, I've been slowly making progress on this; kind of feels like
>> bashing my
>> head against a wall at times, but I have made a small hole in the wall
>> through
>> which I can see my goal. ;-)
>
> making holes my lead to brain damage.. then things get really hard to solve ;)
Maybe I'm too late, and that's why things aren't coming together ;)

>
> [...]
>> Specifically, I haven't figured out how to inject a variable into the
>> scope of an outer
>> with's closure that can be used by code in an interior with's closure.
>> For example,
>> consider
>>
>>   myCtx1.with {
>>       __outerCtx1 = null            // injected statement
>>       __currCtx1 = myCtx1       // injected statement
>>       .... some code ...
>>       myCtx2.with {
>>           __outerCtx2 = __currCtx1   // injected statement <---  doesn't
>> work
>>           __currCtx2 = myCtx2          // injected statement
>
> where is __currCtx1 and __outerCtx1 coming from? Are they supposed to be new local variables? in 
> that case you will have to add a DeclarationStatement, not just an assignment to a 
> VariableExpression. Otherwise the compiler will thnk they are dynamic properties and tries to 
> resolve them against the context.
>
> as for the logic behind __outerCtxN... with number wouldn't have to be null I would have said you 
> should think of using getOwner on Closure
>
Hmmm, I'm close to that, but not quite the same.  I was trying

    ExpressionStatement currCtx = new ExpressionStatement(
        new DeclarationExpression (
            new VariableExpression( "__currCtx$levelcnt"),
            new Token( Types.ASSIGNMENT_OPERATOR, "=", -1, -1),
            new MethodCallExpression( new VariableExpression( 'this'), 'getDelegate', new 
ArgumentListExpression())
        )
    )

Would a DeclarationStatment act differently from an ExpressionStatement with an embedded
DeclarationExpression?  If my foggy memory is correct, I wrote my code after looking at the
AST displayed for a short test script in groovyConsole.

Plus, if foggy memory serves, I tried using getOwner and it came back with the closure being
owned by the test script, not the object doing the with.  Calling getDelegate gave me the object.
If foggy memory serves.

I also tried playing around with setClosureSharedVariable( true) and putReferencedLocalVariable()
without success.  But, those were somewhat blind stabs in the dark, so I might not have been
using them correctly.

Looking at the AST generated by groovyConsole, my transform looks like it is working, but
the compiler complains about things not being in scope (in the inner closure).  So, I'm doing
something wrong with setting up the scoping.

>  bye Jochen

Thanks,

Ed


Re: help with an AST

Posted by Jochen Theodorou <bl...@gmx.org>.

On 14.02.2017 12:41, Ed Clark wrote:
> Hi Jochen,
>
> Well, I've been slowly making progress on this; kind of feels like
> bashing my
> head against a wall at times, but I have made a small hole in the wall
> through
> which I can see my goal. ;-)

making holes my lead to brain damage.. then things get really hard to 
solve ;)

[...]
> Specifically, I haven't figured out how to inject a variable into the
> scope of an outer
> with's closure that can be used by code in an interior with's closure.
> For example,
> consider
>
>   myCtx1.with {
>       __outerCtx1 = null            // injected statement
>       __currCtx1 = myCtx1       // injected statement
>       .... some code ...
>       myCtx2.with {
>           __outerCtx2 = __currCtx1   // injected statement <---  doesn't
> work
>           __currCtx2 = myCtx2          // injected statement

where is __currCtx1 and __outerCtx1 coming from? Are they supposed to be 
new local variables? in that case you will have to add a 
DeclarationStatement, not just an assignment to a VariableExpression. 
Otherwise the compiler will thnk they are dynamic properties and tries 
to resolve them against the context.

as for the logic behind __outerCtxN... with number wouldn't have to be 
null I would have said you should think of using getOwner on Closure

  bye Jochen