3

Scala 言語のステートメントを「エミュレート」する Scala continuations に関する素敵なブログ投稿を見ました。(継続GOTOについて詳しくはこちら)

プログラミング言語Groovyでも同じことがしたいです。Groovy コンパイラーのフェーズ変換内で可能だと思います。

私はドメイン固有言語 (DSL) に取り組んでおり、Groovy に組み込むことをお勧めします。GOTODSL は構造化されていない言語 (そしてワークフロー図から生成される) であるため、ステートメントが必要です。行番号ではなく、「ラベル付き」の goto ステートメントが必要です。

DSL はワークフロー定義用の言語であり、ノード間の矢印に制限がないため、gotoが必要です。while(またはetcで読めないコード)

Groovy と Scala の初心者として、Scala ソリューションを Groovy に翻訳できるかどうかはわかりませんが、Groovy には継続があると思います。

Groovy でラベル付き goto をエミュレートするためのアルゴリズム/コードを探しています。私が念頭に置いていたアルゴリズムの 1 つは、eval繰り返し使用することです。evalあなたがいるときにやっていますgoto。DSL はevalalready で評価されます。

「while」ループなどを探しているのではなく、このコードが機能するように変換しています (他の構文は問題ありません)。

label1: 
a();
b();
goto label1; 

PS: 本当に GOTO ステートメントを使用する必要があるかどうかについての議論は好みません。DSL は仕様言語であり、おそらく変数や効率などに対応していません。

PS2: 他のキーワードをGOTO使用できます。

4

4 に答える 4

5

構築しようとしている言語についてもう少し詳しく説明する必要があるかもしれません。おそらく、変換を処理するのはオーバーエンジニアリングになるほど単純です。
AST をいじることは、グルーヴィーな人々が何年も前から行ってきたことであり、非常に強力です。
spock フレームワーク担当者は、作成したテストを書き直して、コードにラベルを付けます。 http://code.google.com/p/spock/

ハムレット・ダーシーは、この問題についていくつかのプレゼンテーションを行いました。彼のブログにもいくつかの投稿があります。 http://hamletdarcy.blogspot.com/
Cedric Champeau が、彼が構築した興味深い変革とその進化について説明しています http://www.jroller.com/melix/

おそらく他の多くの人を見逃していますが、私が覚えている人は.
おそらくすでに知っているが、実際に役立つ可能性のある出発点。 http://groovy.codehaus.org/Compile-time+Metaprogramming+-+AST+Transformations
http://groovy.codehaus.org/Building+AST+Guide

簡単に言えば、その可能性は十分にあると言えます

于 2011-02-08T19:31:36.937 に答える
1

これを投げるだけで、おそらくスコープ付きのスイッチケースができます

したがって、DSL に次のように記述されている場合:

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; 
}

あなたの「コンパイラ」はこれを次のように変えることができます:

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
}
于 2011-02-14T01:47:51.773 に答える
1

gotoGroovyの予約語(Java と同様) のように、これを試しても何も得られないため、DSL で使用すると問題が発生します。

これは Scala の予約語ではないため、これは問題ではありません

于 2011-02-08T15:17:12.133 に答える
1

ifおよびループgotoをエミュレートできます。whileきれいではありません。不要なコードブロックがたくさん導入されますが、どの関数でも機能するはずです。このようにコードを書き直すことは常に可能であるといういくつかの証拠がありますが、もちろん、可能であるということは、それが優れている、または簡単であるという意味ではありません。

基本的に、すべてのローカル変数を関数の先頭に移動し、ローカル変数を追加しbool takeJumpます。while(takeJump){次に、任意の goto+label ペアに+ペアを追加し、}while の前と while の終わりの前にフラグを必要な値に設定します。

しかし、正直なところ、私はそのアプローチをお勧めしません。ラベルと goto を使用して AST を作成し、それを直接バイトコードに変換できるライブラリを使用したいと考えています。

または、Java VM をサポートする他の言語を使用してgotoください。確かにそういう言語はあります。

于 2011-02-08T15:22:14.580 に答える