How GOTO statement in Groovy?

主宰稳场 提交于 2019-12-04 13:06:15
jpertino

You might want to tell a little bit more about the language you are trying to build, perhaps it's simple enough that dealing with transformations would be overengineering.
Playing with the AST is something groovy people have been doing for years and it's really powerful.
The spock framework guys rewrite the tests you create annotating the code with labels. http://code.google.com/p/spock/

Hamlet D'Arcy has given several presentations on the matter. Several posts can also be found on his blog. http://hamletdarcy.blogspot.com/
Cedric Champeau describes an interesting transformation he built and its evolution http://www.jroller.com/melix/

Probably missing lots of other guys but those I remember.
A possible starting points that you probably already know but are really useful. http://groovy.codehaus.org/Compile-time+Metaprogramming+-+AST+Transformations
http://groovy.codehaus.org/Building+AST+Guide

Long story short, I'd say its quite possible

You won't get anywhere trying this, as goto is a reserved word in Groovy (as it is in Java), so using it in your DSL will be problematic.

It's not a reserved word in Scala, so this isn't an issue

You can emulate if and goto with while loops. It won't be pretty, it will introduce lots of unnecessary code-blocks, but it should work for any function. There is some proof that this is always possible to rewrite code like that, but of course being possible does not mean it's nice or easy.

Basically you move all local variables to the beginning of the function and add a bool takeJump local variable. Then add a while(takeJump){+} pair for any goto+label pair and set the flag before the while and before the end of the while to the value you want.

But to be honest I don't recommend that approach. I'd rather use a library that allows me to build an AST with labels and gotos and then translates that directly to byte-code.

Or use some other language built on the java vm that does support goto. I'm sure there is such a language.

Just throwing this out there, perhaps you could have a scoped switch case

So if your DSL says this:

def foo() {
   def x = x()
   def y
   def z
   label a:
     y = y(x)
   if(y < someConst) goto a
   label b: 
    z = y(z)
    if(z > someConst) goto c
    x = y(y(z+x))
    z = y(x)
   label c:
    return z; 
}

Your "compiler" can turn it into this:

def foo() {
    String currentLABEL = "NO_LABEL"
    while(SCOPED_INTO_BLOCK_0143) {
       def x
       def y
       def z
       def retval
       switch(currentLABEL) {
       case "NO_LABEL":
          x = x()
       case "LABEL_A"
          y = y(x)

          if(y < someConst) {
            currentLABEL = "LABEL_A"
           break
          }
       case "LABEL_B"
          z = y(z)

          if(z > someConst) {
            currentLabel = "LABEL_C"
            break
          }
          x = y(y(z+x))
          z = y(x)
       case "LABEL_C"
          SCOPED_INTO_BLOCK_0143 = false
          retval = z
       }
    }
    return retval
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!