Как GOTO постановка в Groovy? - PullRequest
       8

Как GOTO постановка в Groovy?

3 голосов
/ 05 января 2011

Я видел этот хороший пост в блоге о продолжениях Scala , который «эмулирует» оператор GOTO на языке Scala.(подробнее о Продолжения здесь )

Я бы хотел, чтобы то же самое было в языке программирования Groovy.Я думаю, что это возможно в рамках Groovy фазового преобразования компилятора .

Я работаю над предметно-ориентированным языком (DSL), и предпочитаю встроенный в Groovy.Я хотел бы иметь оператор GOTO, потому что DSL является неструктурированным языком (и генерируется из диаграмм рабочих процессов).Мне нужен «помеченный» оператор goto, а не номера строк.

DSL - это язык для определения рабочих процессов, и поскольку для стрелок между узлами нет ограничений, необходим goto.(или нечитаемый код с while и т. д.)

Как новичок в Groovy и Scala, я не знаю, смогу ли я перевести решение Scala на Groovy, но я не думаю, что в Groovy есть продолжения.

Я ищу алгоритм / код для эмуляции помеченных goto в Groovy.Один алгоритм, который я имел в виду, использует eval несколько раз;делать eval, когда вы находитесь на goto.DSL оценивается уже с eval.

Я не ищу цикл while или что-то в этом роде, а скорее перевод этого кода, чтобы он работал (какой-то другой синтаксис не проблема)*

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

PS: Я не предпочитаю обсуждение, если мне действительно нужно использовать / хотеть выражение GOTO.DSL является языком спецификаций и, вероятно, не справляется с переменными, эффективностью и т. Д.

PS2: можно использовать другое ключевое слово, кроме GOTO.

Ответы [ 4 ]

5 голосов
/ 08 февраля 2011

Возможно, вы захотите рассказать немного больше о языке, который вы пытаетесь создать, возможно, это достаточно просто, чтобы иметь дело с трансформациями, это будет слишком трудоемким.
Игра с AST - это то, что отличные люди делают годами иэто действительно мощно.
Ребята из спок-фреймворка переписывают созданные вами тесты, аннотируя код метками.http://code.google.com/p/spock/

Гамлет Д'Арси сделал несколько презентаций по этому вопросу.Несколько постов также можно найти в его блоге.http://hamletdarcy.blogspot.com/
Седрик Шампо описывает интересное преобразование, которое он построил, и его эволюцию http://www.jroller.com/melix/

Вероятно, пропущено множество других парней, но тех, кого я помню.
Возможные отправные точки, которые вы, вероятно,уже знаю, но действительно полезно.http://groovy.codehaus.org/Compile-time+Metaprogramming+-+AST+Transformations
http://groovy.codehaus.org/Building+AST+Guide

Короче говоря, я бы сказал, что это вполне возможно

1 голос
/ 14 февраля 2011

Просто добавив это, возможно, у вас может быть случай переключателя с ограничением

Так что, если ваш 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; 
}

Ваш "компилятор" может превратить это в это1006 *

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
}
1 голос
/ 08 февраля 2011

Вы можете эмулировать if и goto с помощью while петель. Он не будет красивым, он будет содержать много ненужных блоков кода, но он должен работать для любой функции. Есть некоторые доказательства того, что всегда можно переписать подобный код, но, конечно, возможность не означает, что это хорошо или просто.

По сути, вы перемещаете все локальные переменные в начало функции и добавляете bool takeJump локальную переменную. Затем добавьте пару while(takeJump){ + } для любой пары goto + label и установите флаг до времени и до конца времени на желаемое значение.

Но, если честно, я не рекомендую такой подход. Я бы предпочел использовать библиотеку, которая позволяет мне создавать AST с метками и gotos, а затем переводить это непосредственно в байт-код.

Или используйте другой язык, построенный на Java VM, который поддерживает goto. Я уверен, что есть такой язык.

1 голос
/ 08 февраля 2011

Вы нигде не попробуете это, поскольку goto является зарезервированным словом в Groovy (как в Java), поэтому его использование в DSL будет проблематичным.

Это не зарезервированное слово в Scala , так что это не проблема

...