Re: more help with an AST

2017-07-12 Thread Ed Clark

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 left, Ket 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 multiply(withctx.matrix.Bra left, 
withctx.matrix.Ket right) {
java.lang.Object 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 le = left [ idx ]
java.lang.Object 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 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.gro

more help with an AST

2017-07-11 Thread Ed Clark

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: help with an AST

2017-02-23 Thread Ed Clark

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 <eacl...@ameritech.net> wrote:

I can report progress.  Turns out there were two problems.

The error message that I was getting concerning : "="
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:  .  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: (:  "=" ) 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

2017-02-22 Thread Ed Clark

I can report progress.  Turns out there were two problems.

The error message that I was getting concerning : "="
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:  . 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: 
(:  "=" ) 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

2017-02-20 Thread Ed Clark

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: 
(:  "=" ) 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

2017-02-18 Thread Ed Clark

Hi Paul,

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

BUG! exception in phase 'class generation' in source unit 'CtxTest2.groovy' Operation: 
(:  "=" ) 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 '1 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 <eacl...@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: (:  "=" ) 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

2017-02-16 Thread Ed Clark

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 <eacl...@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: (:  "=" ) 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

2017-02-14 Thread Ed Clark

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

2017-02-14 Thread Ed Clark

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: problem with GroovyLab startup at some platforms?

2017-01-19 Thread Ed Clark

On 01/19/2017 08:44 AM, sterg wrote:



On 01/19/2017 03:39 PM, Jochen Theodorou wrote:

On 19.01.2017 12:57, sterg wrote:

Hi all,


a user reported me, that GroovyLab

(https://github.com/sterglee/GroovyLab)

fails silently at startup, at his platform.


no error at all?




yes, with no error message, or e.g. a stack trace of a possible exception fault.
However, up to now I couldn't reproducible the fault.



bye Jochen




Thanks
Stergios

Since I am the reader in question, let me add some info.  The snapshot that I 
grabbed
in November works fine.  When I grabbed a new snapshot a couple of days ago I
noticed that the startup script just returned without anything happening.

And, if I just use the command "java -jar GroovyLab.jar", the November one 
starts but
the January one dies silently.  (Eyeballing it, the January command returns 
after roughly
the same length of time that the first window takes to appear on the November 
one,
about 1 sec on my machine.)

More info - the January snapshot dies on both my Fedora 24 main machine and a
Centos 7 machine I've got on the side.  But, it runs fine on a RaspberryPi3 
that I've
got.  So, score one hit for Raspbian, and 2 misses for Redhat.

On the F24 machine java -version gives:
java version "1.8.0_72"
Java(TM) SE Runtime Environment (build 1.8.0_72-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.72-b15, mixed mode)
On the Centos7 machine java -version gives:
openjdk version "1.8.0_111"
OpenJDK Runtime Environment (build 1.8.0_111-b15)
OpenJDK 64-Bit Server VM (build 25.111-b15, mixed mode)
On the Raspbian machine java -version gives:
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) Client VM (build 25.65-b01, mixed mode)


Ed




help with an AST

2016-12-30 Thread Ed Clark

Happy New Year All!

As one of my New Year's resolutions, I'm going to try and implement a 
programming
construct that I've been want to play with for a while - and I think a Groovy 
AST just
might let me do it.

While the syntax part of this is straightforward (I think), I'm not as clear on 
the
how of the method resolution logic that will be at the core.

The basic idea is that I'll be able to designate a section of code where binary
operators would be resolved not against the neighbouring object's class, but 
against
the surrounding context.  Perhaps some code will make my goal clearer

My understanding of Groovy (and OO in general) is that an expression like
obj1 + obj2
is interpreted as if it were written
obj1.plus( obj2)

What I'd like to do is have something like
withCtx( ctx1) {
obj1 + obj2
}
get interpreted as
ctx1.plus( obj1, obj2)


If I squint at this, it kind of sort of looks to me a bit like how the "with" 
construct
in Groovy works.  But, the with construct is an enhancement to the existing OO
method resolution; this construct would go in a different direction.

(Actually, to be useful, the interior expression would probably be something
like -- var1 = obj1 + obj2 -- but I want to focus on one step/method at a time.)

With this idea, methods between objects (e.g. binary methods) don't belong to 
the
class of (one of the) objects involved, but to the context within which the 
objects
are being used.

And, just to make things more challenging, I'd like to be able to nest and 
compose
contexts.

Consider
withCtx( Ctx1) {
withCtx( ctx2, ctx3) {
obj1 + obj2
}
}

Here, the methods of ctx2 would be checked to see if there's a "plus" that can 
take
arguments obj1 and obj2.  If not, then ctx3's methods will be check.  If 
there's no
appropriate "plus" in ctx3, then Ctx1's methods will be checked.

Finally, if there are no appropriate context methods for "plus-ing" these two
objects, then method resolution would fall back to the normal Groovy approach.

To add yet another wrinkle, I'd like to be able to use either a Context class 
or a context
instance when doing this.  So, in the above, if "Ctx1" is a class name (note 
the cap C),
its static methods would be used.  But, assuming ctx2 and ctx3 are context 
instances
(note the lower case c's), the appropriate instance methods would be used.

Hopefully this description makes my goal clearer.

My questions for you are,

- is an AST the way to go?

- 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?

- what might I be breaking in Groovy by doing this?

- what help/hints can I get from the compiler vs. doing this all at runtime?


Thanks for your time,

Ed Clark