groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ed Clark <>
Subject Re: more help with an AST
Date Wed, 12 Jul 2017 11:30:24 GMT
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()
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
> 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 .__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))      <-----
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.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

   ------------ Constant - multiply : java.lang.String
   ------------ ArgumentList - (le,re)

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


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


View raw message