Цикл по списку - foreach

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

Очень полезный макрос, выполняющий цикл по строковому списку (аналог цикла for in в QPILE, но в препроцессорном варианте)

divert(-1)
# foreach(x, (item_1, item_2, ..., item_n), stmt)
define(`foreach', `pushdef(`$1', `')_foreach(`$1', `$2', `$3')popdef(`$1')')
define(`_arg1', `$1')
define(`_foreach',
`ifelse(`$2', `()', ,
`define(`$1', _arg1$2)$3`'_foreach(`$1', (shift$2), `$3')')')
# traceon(`define', `foreach', `_foreach', `ifelse')
divert

Например, если использовать макрос foreach следующим образом:

foreach(`x', `(AAAA, BBBBB, CCCCC)', `Word was: x
')

Получим в результате:

Word was: AAAA
Word was: BBBBB
Word was: CCCCC


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

define(`foreach',`ifelse(eval($#>2),1,
`pushdef(`$1',`$3')$2`'popdef(`$1')dnl
`'ifelse(eval($#>3),1,`$0(`$1',`$2',shift(shift(shift($@))))')')')

Теперь для вызова


 foreach(`X',`Open the X. ',`door',`window',`bottle')

Получим результат:

Open the door. Open the window. Open the bottle.

Пример реального использования: Локальные переменные в QPILE

Добавить комментарий


Защитный код
Обновить

Библиотека