2011-01-05 15 views
2

このnice blog post about a Scala continuationsは、Scala言語のGOTOステートメントを 'エミュレート'しています。GroovyのGOTO文はどうですか?

を(Continuations hereについての詳細を読む)私はプログラミング言語Groovyで同じを持っていると思います。私はGroovy compiler phase transformationの中でそれが可能だと思います。

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

DSLは、ワークフロー定義するための言語である、とノード間の矢のための制限はありませんので、gotoが必要とされています。 (whileなどのコードを読むことができません)

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

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

私は「しばらく」ループか何かを探しているのではなく、それが動作するようにこのコードを翻訳していないよ(他のいくつかの構文は問題ありません)

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

PS: 私は好みませんもし私がGOTOステートメントを本当に使用したい/希望したいのであれば議論。 DSLは仕様言語であり、おそらくなど

PS2変数、効率的に対処されていません。他のいくつかのキーワードが、その後GOTOを使用することができます。

+0

gotoとラベル付けされた脇役は、連続よりも簡単にシミュレートすることができます。 –

+0

@Gabriel:あなたは私に糊を与えることができますか? – Julian

+0

いいえ、私は接着剤がありません:)...あなたのDSLが実際にどのような制約を持っているのか分かりませんし、Groovyについてよく分かりませんが、gotoを扱う方法の1つは配列/リスト/現在のインデックス/キーを実行する1つのメソッドがあります。これはgotoで変更される可能性があります。 –

答えて

1

gotoreserved word in Groovy(Javaのように)ですので、DSLで使用すると問題があります。

それはreserved word in Scalaではありませんので、これはあなたがwhileループでifgotoをエミュレートすることができ、問題

+0

それでは、キーワードgooを使用しますか?それは実際のキーワードではなく、行動に関するものです。 – Julian

1

ではありません。これはきれいではありません。多くの不要なコードブロックが導入されますが、どの機能でも機能するはずです。このようなコードを書き換えることが常に可能であるという証拠がいくつかありますが、もちろん可能であっても、それがいいか簡単かはわかりません。

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

しかし、私はそのアプローチをお勧めしません。私はむしろ、ラベルとヒッポスを使ってASTを構築し、それを直接バイトコードに変換するライブラリを使用したいと思います。

やサポートgotoを行うのJava VM上に構築されたいくつかの他の言語を使用します。私はそのような言語があると確信しています。

+0

私は知っているので、開始ポストで私は言った: "私は 'whileループや何か"を探していない;) – Julian

+0

それは少しでも簡単に取得しますが、それはかなりではないとそれは3 /最悪の場合には符号長が2増加する。 –

5

ビルドしようとしている言語について少し詳しく説明したいと思うかもしれません。おそらく、変換を扱うことが重要です。
ASTで遊ぶことは、人々が何年もやってきたことです。本当に強力です。
スポークフレームワークの人は、あなたが作成したテストをラベルを使ってコードに書き換えます。 http://code.google.com/p/spock/

ハムレットダルシーは、この問題についていくつかのプレゼンテーションを行っています。彼のブログにもいくつかの投稿があります。 http://hamletdarcy.blogspot.com/
セドリックChampeauは興味深い彼が建て転換とその進化http://www.jroller.com/melix/

おそらく不足している他の人たちの多くが、私は覚えていたものを説明しています。
おそらく既に知っているかもしれないが、本当に便利な出発点です。 http://groovy.codehaus.org/Compile-time+Metaprogramming+-+AST+Transformations
http://groovy.codehaus.org/Building+AST+Guide

かいつまんで、私はそのかなり可能

+0

私はAST変換が良い方向だと思います。私は、DSLに関するより多くの情報で開始ポストを更新する。 – Julian

+0

AST変換を書くための接着剤はありますか? – Julian

+0

@Julian申し訳ありませんが、私はこれのトラックを失った。 私はあなたに変身のヒントを与えることができますが、今あなたの投稿を読んだので、あなたが構築したい言語はかなり考えが必要になると思います。 基本的に、完全に構造化されていない言語が必要な場合は、それを構造化言語で書くのに2つ以上のトリックが必要です。注入されたループは入れ子に関して非常に制限的なものになるので、誰かが提案したように、シーケンス全体を再設計しなければならないかもしれません。いずれにしても さんと一緒に遊びたい場合、これは非常に単純な例です http://groovyconsole.appspot.com/script/418002 – jpertino

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 
} 
関連する問題