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/07/11 20:07:31 UTC

more help with an AST

Hello All,

Let me go to the well one more time for help with my AST....

First, let me ask ---
    is there any reason the AST browser would lie and show you what you want to
    see and not what the compiler really does??

Sorry, that's harsh.  But, I've been staring that the AST browser for hours trying
to spot the difference between two lines of code - one that runs and one the blows
up - and I can't see any thing other than lineNumber/columnNumber differences.


Some background.  I want to replace some binary methods (like multiply and plus)
so I can play around and do them the way I want.  So, my AST goes through and
replaces binary method calls like "le * re" with "myCtx.multiply( le, re)".

Looking at the massaged code through the AST browser, it looks like my xform is
doing what it should - but the code won't execute.

Trying to get to a simple example, if I have two lines of code before xforming:

     sum = myCtx.multiply( le, re)          <------- the xform leaves this alone
     sum = le * re                                   <------- the xform changes this

the browser shows a post-xform output of:

     sum = myCtx.multiply( le, re)          <------- this executes
     sum = myCtx.multiply( le, re)          <------- this doesn't

But, when run, the first line works while the second one results in a
MissingMethodException stating there is no "multiply" method for the type
Complex - which is the type of "le".

It's as if the compiler tried to execute "le * re" (which would give exactly this MME)
and not "myCtx.multiply( le, re)".

Drilling down in the AST itself, I'm not seeing any difference - other than line
numbers and column numbers - between the various *Expressions
(e.g. VariableExpression) making up the subtrees for the two lines.


Obviously I'm doing something wrong.  But I can't see what it is.


Any suggestions?

Regards,

Ed Clark







Re: more help with an AST

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

Did my info provide any clues?  Is there anything else I can provide to help
find where I'm going wrong?

Thanks,

Ed


On 07/12/2017 07:30 AM, Ed Clark wrote:
> Hi Jochen,
>
> Thanks for getting back to me.  Responses inline.
>
> On 07/12/2017 02:02 AM, Jochen Theodorou wrote:
>> On 11.07.2017 22:07, Ed Clark wrote:
>> [...]
>>> the browser shows a post-xform output of:
>>>
>>>      sum = myCtx.multiply( le, re)          <------- this executes
>>>      sum = myCtx.multiply( le, re)          <------- this doesn't
>>>
>>> But, when run, the first line works while the second one results in a
>>> MissingMethodException stating there is no "multiply" method for the type
>>> Complex - which is the type of "le".
>>
>> can you give me the full exception text? I need to know the number and types of arguments
>
> ------------------------
> Caught: groovy.lang.MissingMethodException: No signature of method: 
> withctx.math.Complex.multiply() is applicable for argument types: (withctx.math.Complex) values: [0]
> groovy.lang.MissingMethodException: No signature of method: withctx.math.Complex.multiply() is 
> applicable for argument types: (withctx.math.Complex) values: [0]
>         at withctx.matrix.BraKet$_multiply_closure13$_closure28.doCall(BraKet.groovy:176)
> ------------------------
>
> The two interesting points to me here are 1)  there's only one value ("0") for the
> missing method "multiply" and 2) the missing method is for the class Complex.
>
> This makes me think that the method involved is "le.multiply( re)".
>
> ("le" and "re" are both instances of Complex, and at this point in the execution
> they both have a value which prints as "0".)
>
>
>>
>> [...]
>>> Drilling down in the AST itself, I'm not seeing any difference - other than line
>>> numbers and column numbers - between the various *Expressions
>>> (e.g. VariableExpression) making up the subtrees for the two lines.
>>
>> Can you write down how the AST looks like? For VariableExpressions I would be also interested in 
>> the accessedVariable and in generalabout what phase we are actually talking about.
>>
>
> The phase used by the AST browser is "Instruction Selection"; the phase
> specified for the xform is "SEMANTIC_ANALYSIS".  (I wanted to make sure
> that the browser was past the action of the xform.)
>
> The pre-xform code is
>
>   // inner product
>     T multiply( Bra<T> left, Ket<T> right) {
>         T sum
>         compCtx.withContext {
>             (0..size - 1).each { idx ->
>                 // use some local variables to get the generic type because I
>                 // haven't done the code to extract the type through a "getAt" method call
>                 T le = left[idx]
>                 T re = right[idx]
>                 println 'compCtx.multiply gives ' + compCtx.multiply( le, re)
>                 println 'compCtx.* gives ' + ( le * re)
>                 if (idx == 0) sum = le * re
>                 else sum = sum + le * re
>             }
>         }
>         return sum
>     }
>
> (The two println's are in there for debugging purposes so the failure happens
> on something simpler than an if statement.)
>
> The post-xform code shown in the browser is
>
>     public java.lang.Object<T> multiply(withctx.matrix.Bra<T> left, withctx.matrix.Ket<T> right) {
>         java.lang.Object<T> sum =
>         compCtx.withContext({
>             compCtx .__contextPtr = 0
>             java.lang.Object __rtContexts = [ compCtx ]
>             compCtx .__contextStack = __rtContexts
>             (0.. size - 1).each({ java.lang.Object idx ->
>                 java.lang.Object<T> le = left [ idx ]
>                 java.lang.Object<T> re = right [ idx ]
>                 this.println('compCtx.multiply gives ' + compCtx.multiply(le, re))      <----- 
> this runs fine
>                 this.println('compCtx.* gives ' + compCtx.multiply(le, re))                 <---- 
> this is line 176
>                 if ( idx == 0) {
>                     sum = compCtx.multiply(le, re)
>                 } else {
>                     sum = compCtx.plus(sum, compCtx.multiply(le, re))
>                 }
>             })
>             __rtContexts = __rtContexts.dropRight(1)
>         })
>         return sum
>     }
>
> (To my untrained eye, the xform did exactly what I want.... the "le * re"
> method calls have been replaced by "compCtx.multiply(le,re)".)
>
>
> For the line 176 (with fails), the AST in the browser looks like:
>
>   -- ExpressionStatement - MethodCallExpression
>   ---- MethodCall - this.println((compCtx.* gives + compCtx.multiply(le,re)))
>   ------ Variable - this : java.lang.Object
>   ------ Constant - println : java.lang.String
>   ------ ArgumentList - ((compCtx.* gives + compCtx.multiply(le,re)))
>   -------- Binary - (compCtx.* gives + compCtx.multiply(le,re))
>   ---------- Constant - compCtx.* gives : java.lang.String
>   ---------- MethodCall - compCtx.multiply(le,re)
>   ------------ Variable - compCtx : withctx.math.Field -> withctx.math.Field <E extends 
> java.lang.Object>
>   ------------ Constant - multiply : java.lang.String
>   ------------ ArgumentList - (le,re)
>
> for both lines 175 and 176, the accessedVariable for the
> Variable "compCtx" is
>
>     org.codehaus.groovy.ast.FieldNode@1d84267f
>
>
> At a high level, the way my xform works is it scans the AST looking
> for a specifically annotated method call, after which it begins its work
> on the closure passed to that method.
>
> In this case, the line 169 "compCtx.withContext" is such a method call.
>
> The xform then walks the closure looking for binary MethodCallExpressions
> that matching signatures of methods defined by the "compCtx" class.
> In this case, the MethodCallExpression for "le * re" matches the
> "multiply" method.
>
> The xform then replaces that MCE with a new MCE that uses the
> VariableExpression (that points at "compCtx") from the triggering
> "compCtx.withContext" method call.
>
> (There seems to be a potential scoping issue for my xform in that the
> triggering "compCtx" is from a scope outside the closure's scope. I
> am going to address that once I get past this stumbling block - unless
> it's the same block...)
>
> Please let me know if you need more details.
>
>>
>> bye Jochen
> Thanks,
>
> Ed
>
>


Re: more help with an AST

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

Thanks for getting back to me.  Responses inline.

On 07/12/2017 02:02 AM, Jochen Theodorou wrote:
> On 11.07.2017 22:07, Ed Clark wrote:
> [...]
>> the browser shows a post-xform output of:
>>
>>      sum = myCtx.multiply( le, re)          <------- this executes
>>      sum = myCtx.multiply( le, re)          <------- this doesn't
>>
>> But, when run, the first line works while the second one results in a
>> MissingMethodException stating there is no "multiply" method for the type
>> Complex - which is the type of "le".
>
> can you give me the full exception text? I need to know the number and types of arguments

------------------------
Caught: groovy.lang.MissingMethodException: No signature of method: withctx.math.Complex.multiply() 
is applicable for argument types: (withctx.math.Complex) values: [0]
groovy.lang.MissingMethodException: No signature of method: withctx.math.Complex.multiply() is 
applicable for argument types: (withctx.math.Complex) values: [0]
         at withctx.matrix.BraKet$_multiply_closure13$_closure28.doCall(BraKet.groovy:176)
------------------------

The two interesting points to me here are 1)  there's only one value ("0") for the
missing method "multiply" and 2) the missing method is for the class Complex.

This makes me think that the method involved is "le.multiply( re)".

("le" and "re" are both instances of Complex, and at this point in the execution
they both have a value which prints as "0".)


>
> [...]
>> Drilling down in the AST itself, I'm not seeing any difference - other than line
>> numbers and column numbers - between the various *Expressions
>> (e.g. VariableExpression) making up the subtrees for the two lines.
>
> Can you write down how the AST looks like? For VariableExpressions I would be also interested in 
> the accessedVariable and in generalabout what phase we are actually talking about.
>

The phase used by the AST browser is "Instruction Selection"; the phase
specified for the xform is "SEMANTIC_ANALYSIS".  (I wanted to make sure
that the browser was past the action of the xform.)

The pre-xform code is

   // inner product
     T multiply( Bra<T> left, Ket<T> right) {
         T sum
         compCtx.withContext {
             (0..size - 1).each { idx ->
                 // use some local variables to get the generic type because I
                 // haven't done the code to extract the type through a "getAt" method call
                 T le = left[idx]
                 T re = right[idx]
                 println 'compCtx.multiply gives ' + compCtx.multiply( le, re)
                 println 'compCtx.* gives ' + ( le * re)
                 if (idx == 0) sum = le * re
                 else sum = sum + le * re
             }
         }
         return sum
     }

(The two println's are in there for debugging purposes so the failure happens
on something simpler than an if statement.)

The post-xform code shown in the browser is

     public java.lang.Object<T> multiply(withctx.matrix.Bra<T> left, withctx.matrix.Ket<T> right) {
         java.lang.Object<T> sum =
         compCtx.withContext({
             compCtx .__contextPtr = 0
             java.lang.Object __rtContexts = [ compCtx ]
             compCtx .__contextStack = __rtContexts
             (0.. size - 1).each({ java.lang.Object idx ->
                 java.lang.Object<T> le = left [ idx ]
                 java.lang.Object<T> re = right [ idx ]
                 this.println('compCtx.multiply gives ' + compCtx.multiply(le, re))      <----- this 
runs fine
                 this.println('compCtx.* gives ' + compCtx.multiply(le, re))                 <---- 
this is line 176
                 if ( idx == 0) {
                     sum = compCtx.multiply(le, re)
                 } else {
                     sum = compCtx.plus(sum, compCtx.multiply(le, re))
                 }
             })
             __rtContexts = __rtContexts.dropRight(1)
         })
         return sum
     }

(To my untrained eye, the xform did exactly what I want.... the "le * re"
method calls have been replaced by "compCtx.multiply(le,re)".)


For the line 176 (with fails), the AST in the browser looks like:

   -- ExpressionStatement - MethodCallExpression
   ---- MethodCall - this.println((compCtx.* gives + compCtx.multiply(le,re)))
   ------ Variable - this : java.lang.Object
   ------ Constant - println : java.lang.String
   ------ ArgumentList - ((compCtx.* gives + compCtx.multiply(le,re)))
   -------- Binary - (compCtx.* gives + compCtx.multiply(le,re))
   ---------- Constant - compCtx.* gives : java.lang.String
   ---------- MethodCall - compCtx.multiply(le,re)
   ------------ Variable - compCtx : withctx.math.Field -> withctx.math.Field <E extends 
java.lang.Object>
   ------------ Constant - multiply : java.lang.String
   ------------ ArgumentList - (le,re)

for both lines 175 and 176, the accessedVariable for the
Variable "compCtx" is

     org.codehaus.groovy.ast.FieldNode@1d84267f


At a high level, the way my xform works is it scans the AST looking
for a specifically annotated method call, after which it begins its work
on the closure passed to that method.

In this case, the line 169 "compCtx.withContext" is such a method call.

The xform then walks the closure looking for binary MethodCallExpressions
that matching signatures of methods defined by the "compCtx" class.
In this case, the MethodCallExpression for "le * re" matches the
"multiply" method.

The xform then replaces that MCE with a new MCE that uses the
VariableExpression (that points at "compCtx") from the triggering
"compCtx.withContext" method call.

(There seems to be a potential scoping issue for my xform in that the
triggering "compCtx" is from a scope outside the closure's scope.  I
am going to address that once I get past this stumbling block - unless
it's the same block...)

Please let me know if you need more details.

>
> bye Jochen
Thanks,

Ed



Re: more help with an AST

Posted by Jochen Theodorou <bl...@gmx.org>.
On 11.07.2017 22:07, Ed Clark wrote:
[...]
> the browser shows a post-xform output of:
> 
>      sum = myCtx.multiply( le, re)          <------- this executes
>      sum = myCtx.multiply( le, re)          <------- this doesn't
> 
> But, when run, the first line works while the second one results in a
> MissingMethodException stating there is no "multiply" method for the type
> Complex - which is the type of "le".

can you give me the full exception text? I need to know the number and 
types of arguments

[...]
> Drilling down in the AST itself, I'm not seeing any difference - other 
> than line
> numbers and column numbers - between the various *Expressions
> (e.g. VariableExpression) making up the subtrees for the two lines.

Can you write down how the AST looks like? For VariableExpressions I 
would be also interested in the accessedVariable and in generalabout 
what phase we are actually talking about.


bye Jochen