#m4
#м4
Вопрос:
Я пытаюсь написать макрос M4 для создания точечной записи, но я борюсь с рекурсией.
Я хотел бы иметь макрос, который принимает первый параметр и добавляет отношение точечной диаграммы для всех остальных параметров. Например
coachExisting(a, b, c, d)
будет производить
a -gt; b; a -gt; c; a -gt; d;
Это была моя попытка сделать это:
define(coachExisting, `ifelse(eval($#==2), 1, `ifdef(first, first, $1) -gt; $2;', ifelse(eval($#gt;2), 1, `ifdef(first, ,define(first, $1)) first -gt; $2; $0(shift($*))') )')
Однако это, похоже, работает только в том случае, если я использую числа
coachExisting(1, 2, 3, 4) 1 -gt; 2; 1 -gt; 3; 1 -gt; 4;
Когда я пытаюсь использовать буквы, кажется, что они теряют first
определение.
coachExisting(a, b, c, d) b -gt; b; b -gt; c; c -gt; d;
Ответ №1:
Вы играете быстро и свободно с цитированием. Пожалуйста, внимательно прочитайте руководство m4 для получения инструкций по цитированию и рекурсивной оценке макросов. При первом расширении вы получаете define(first, $1)
=gt; gt; define(first, a)
. Но при втором выполнении он расширяется как define(first, $1)
=gt; gt; define(first, b)
=gt; gt; define(a, b)
(потому first
что расширяется как макрос). Вам нужно цитировать first
везде, где вы можете, так define(`first', `$1')'
что для начала.
Гораздо более чистый способ реализации вашего макроса-это с самого начала избегать временного макроса. Я бы рекомендовал что-то вроде:
define(`coachExisting', `ifelse(eval($#==2), 1, `$1 -gt; $2', `$1 -gt; $2; $0(`$1', shift(shift($@)))')')
(однако будьте осторожны-я не разработал этот макрос для обработки случаев с аргументом 0 или 1).