2011-01-05 92 views
2

我看到這個nice blog post about a Scala continuations,它模仿Scala語言中的GOTO語句。 (閱讀更多關於Continuations hereGroovy中的GOTO語句如何?

我想在編程語言Groovy中具有相同的功能。我認爲這可能在Groovy compiler phase transformation之內。

我正在研究域特定語言(DSL),並且首選嵌入到Groovy中。我希望得到GOTO聲明,因爲DSL是非結構化語言(並且從工作流程圖生成)。我需要一個'標籤'goto聲明,而不是行號。

DSL是用於工作流定義的語言,並且由於節點之間的箭頭沒有限制,因此需要goto。 (或無法讀取的代碼while等)

作爲Groovy和Scala的初學者,我不知道我是否可以將Scala解決方案轉換爲Groovy,但我不認爲Groovy中存在延續。

我正在尋找用於在Groovy中模擬標記的goto的算法/代碼。我想到的一種算法是反覆使用eval;當您在goto時,請執行eval。 已使用eval評估DSL。

我不是在尋找一個「而」循環或東西,而是要將這種代碼,以便它的工作原理(一些其他的語法是沒有問題的)

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

PS: 我不喜歡討論如果我真的應該使用/想要GOTO語句。 DSL是一種規範語言,可能不會應對變量,效率等。

PS2:可以使用其他一些關鍵字GOTO

+0

只是一個旁註,標記爲goto可以比連續模擬更容易... – 2011-01-10 10:27:49

+0

@Gabriel:那麼你可以給我任何膠水? – Julian 2011-02-09 13:37:23

+0

不,我沒有膠水:)...我不知道你的DSL真的有什麼限制,我不太瞭解Groovy,但是處理goto的一種方法可能是讓array/list/map關閉常量和一個執行當前索引/鍵的方法,可能會隨着goto而改變。 – 2011-02-09 14:47:32

回答

1

因爲gotoreserved word in Groovy(因爲它在Java中),所以在你的DSL中使用它將會產生問題。

這不是一個reserved word in Scala,所以這不是一個問題

+0

那麼我們使用關鍵字'gooto'?這是關於行爲,而不是關於實際的關鍵字。 – Julian 2011-02-09 13:29:09

1

可以效仿ifgotowhile循環。它不會很漂亮,它會引入大量不必要的代碼塊,但它應該適用於任何函數。有一些證據表明,總是可以重寫這樣的代碼,但當然可能並不意味着它很好或很容易。

基本上你將所有局部變量移動到該函數的開頭,並添加一個局部變量bool takeJump。然後爲任何goto +標籤對添加while(takeJump){ + }對,並在該時段之前和結束之前將標誌設置爲所需的值。

但說實話,我不建議這樣做。我寧願使用一個庫,允許我用標籤和gotos來構建AST,然後直接將其轉換爲字節碼。

或者使用支持goto的java vm上構建的某種其他語言。我確定有這樣的語言。

+0

我知道了,因此在開始的帖子中我說:「我不是在尋找一個'while'循環或者什麼東西」;) – Julian 2011-02-09 13:28:39

+0

if和while會變得更容易,但它不太好看,它可能需要3/2最壞情況下碼長的增加。 – 2011-02-09 14:49:39

5

您可能想要更多地瞭解您正在嘗試構建的語言,可能很簡單,處理轉換就是過度工程。
與AST一起玩是Groovy人多年來一直在做的事情,它非常強大。
spock框架傢伙重寫您創建的標籤代碼註釋的測試。 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 2011-02-09 13:33:33

+0

你可以提供任何粘合劑來編寫AST轉換嗎? – Julian 2011-02-10 21:02:53

+0

@Julian抱歉,我失去了這一點。 我可以給你一個關於ast轉換的提示,但現在我重讀了你的文章,我相信你想要構建的語言需要相當多的思考。基本上,如果你想要一種完全沒有結構的語言,你將需要不止一個技巧來用結構化語言編寫它。注入循環在嵌套方面的限制性很強,您可能需要重新設計整個測序,正如有人所建議的那樣。無論如何,如果你想玩ast,這是一個極其簡單的例子 http://groovyconsole.appspot.com/script/418002 – jpertino 2011-02-14 22:35:55

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 
}