Расширение синтаксиса QPILE: Return и Loop

Опубликовано в M4

Препроцессор M4 позволяет легко расширять синтаксис языка QPILE. Проиллюстрирую это на примере оператора RETURN

В стандартном варианте этот оператор применяется без параметров. Однако, в большинстве языков программирования этот оператор может иметь возвращаемое значение. Привычка - вторая натура и я частенько по привычке пробую вернуть что-то в этом операторе. Гадость состоит в том, что интерпретатор QPILE спокойно прожевывает конструкцию типа RETURN <VALUE>, но выполняет неправильно (подробнее в статье Оператор RETURN).

Препроцессор легко позволяет как облегчить мне жизнь, чтобы я писал так, как мне привычно, так и обойти ошибку QPILE.

Макрос выглядит тривиально:

define(Return,`ifelse($1,,return,translit($1,`a-z',`A-Z'),RESULT,return,
result = $1
return)')

При нахождении в тексте конструкции Return макрос обращает внимание на его аргумент.

  • если аргументов нет, все остается как есть
  • если аргумент имеется и совпадает с "result" - он игнорируется
  • во всех остальных случаях перед return происходит передача аргумента в переменную result
Исходный текст

После препроцессора

Return(5*frame)  

result = 5*frame
return

Return return
Return() return
Return(result) return

Таким образом, препроцессор позволяет довольно легко расширять синтаксис языка QPILE.

 


Чуть более сложный пример. В QPILE имеется только один вариант оператора цикла, базовый. Временами нужны иные типы циклов. Их можно создать из базового, причем очень гибко и различные типы. Определяем 4 макроса:

define(Loop,`for m4_loop from 0 to m4_loop')
define(While,`
if $1
else
break
end if
')
define(Until,`
if $1
break
end if
')
define(EndLoop,`end for')

Теперь у нас есть полная свобода в выборе типа цикла:

  • Бесконечный цикл:
Loop
   ... тело цикла ...
EndLoop
  • Цикл While с проверкой в начале:
Loop while(price<100)
   ... тело цикла ...
EndLoop
  • Цикл Until с проверкой в начале:
Loop Until(price <100)
    ... тело цикла ...
EndLoop
  • Цикл While с проверкой в конце:
Loop
       ... тело цикла ...
while(price < 100) EndLoop
  • Цикл Until с проверкой в конце:
Loop
     ... тело цикла ...
Until(price < 100) EndLoop
  • Комбинированный вариант
Loop Until(price1 == 100) While(price2 == 200)
      ... тело цикла ...
EndLoop
  • или даже такой:
Loop Until(a>5) Until(b<3) While(c==4)
     ... тело цикла ...
While(d != 8) while(e < 7) Until(c==6) EndLoop 

Все эти конструкции препроцессор развернет в допустимые в синтаксисе языка qpile и они будут исправно выполняться интерпретатором. Конечно, все циклы могут быть вложенными друг в друга.

Продолжение в статье Оператор Switch для QPILE.

Недостаточно прав для комментирования

Библиотека