Структура и реализация макроязыковРефераты >> Программирование и компьютеры >> Структура и реализация макроязыков
-----------------
-----------------
END;
где <paramlist> это перечисление через запятую всех операндов макроса.
Предыдущая программа в таком случае может быть переписана следующим образом:
Исходный текст |
Расширение исходного текста |
MACRO MacGoto(labelno) SetPrevPos; MoveToMark(labelno); CenterFixScreenPos; END; . . . MacGoto(1) . . . MacGoto(2) . . . |
. . . SetPrevPos; MoveToMark(1); CenterFixScreenPos; . . . SetPrevPos; MoveToMark(2); CenterFixScreenPos; . . . |
Следует заметить, что макрокоманда может иметь и более одного операнда. Каждый операнд должен при этом соответствовать формальному параметру в строке определения имени макроса.
Рассмотрим следующий пример:
Пример 3:
.
.
.
ScrollScreenDown;
ScrollScreenLeft(0);
FixCursorPos;
.
.
.
ScrollScreenUp;
ScrollScreenLeft(1);
FixCursorPos;
.
.
.
В данном случае операнды в исходных последовательностях команд различны, как и команды. Эта программа может быть переписана так:
Исходный текст |
Расширение исходного текста |
MACRO MacMove(cmd,left) cmd; ScrollScreenLeft(left); FixCursorPos; END; . . . MacMove(ScrollScreenDown,0) . . . MacMove(ScrollScreenUp,1) |
. . ScrollScreenDown; ScrollScreenLeft(0); FixCursorPos; . . . ScrollScreenUp; ScrollScreenLeft(1); FixCursorPos; . . . |
Следует отметить, что существует два основных способа задания операндов. Первый способ - позиционный показан в вышестоящем примере. Существует также способ указания с применением ключевых операндов, который позволяет обращаться к формальным операторам, как по именам так и по позиции. Ссылаясь на формальные операторы в определении MacMove можно также использовать следующий вызов:
MacMove(cmd=ScrollScreenUp,left=1)
УСЛОВНОЕ МАКРОРАСШИРЕНИЕ
Иногда возникают потребности изменять порядок команд макрорасширения внутри макроса.
Рассмотрим следующую программу:
Пример 4:
.
.
.
ScrollScreenLeft(1);
LiteralChar('-');
.
.
.
ScrollScreenDown;
ScrollScreenLeft(2);
LiteralChar('*');
.
.
.
В этом примере не только параметры, но и количество команд - переменная величина. Эта программа может быть записана следующим образом:
.
.
.
MACRO Mac1(p1,left,chr)
IF p1==1 THEN
ScrollScreenDown;
ENDIF
ScrollScreenLeft(2);
LiteralChar('*');
END
. . . Mac1(1,2,’-’) . . . Mac1(0,1,’*’) . . . |
. . . ScrollScreenLeft(1); LiteralChar('-'); . . . ScrollScreenDown; ScrollScreenLeft(2); LiteralChar('*'); . . . |
Комбинация IF .THEN .ELSE является макрометками или символами следования и не появляются в выходном тексте макропроцессора. В макроязыке также могут быть предусмотрены псевдокоманды условного и безусловного перехода на псевдо-метку, с которой макропроцессор продолжит обработку текста программы. Точно так же, как и в случае выполнения программы, операторы переходов служат для указания выполнения операторов программы, операторы макро-переходов служат для указания порядка компиляции текста программы. Это дает возможность в процессе расширения получать конкретные варианты последовательностей команд, соответствующие данному случаю применения макрокоманды. Выполнение переходов и проверок внутри выполняемого кода увеличивает его размер и время выполнения, в то время, как проверка и переходы в макросах происходят на стадии компиляции и поэтому не требуют затрат времени при выполнении кода. Эта возможность избирательной выборки нужных частей текста является одним из самых мощных средств в системном программировании.
МАКРОВЫЗОВЫ ВНУТРИ МАКРООПРЕДЕЛЕНИЯ
Поскольку макроопределения являются, по сути, “сокращениями” для последовательности команд, то полезным свойством была бы возможность производить такие “сокращения” внутри самих макроопределений.
Пример 5:
.
.
.
MACRO Mac1
SetPrevPos;
CursorCharRight;
END
.
.
.
MACRO Mac2
Mac1
Mac1
END
.
.
.
Внутри макроопределения Mac2 дважды происходит ссылка на макроопределение Mac1. Это помогло нам уменьшить длину макроопределения Mac2 и сделало его более легким для понимания. Такое использование макросредств приводит к макрорасширениям на нескольких уровнях вложенности, например:
Исходный текст |
Расширение исходного текста (уровень 1) |
Расширение исходного текста (уровень 2) |
. . . MACRO Mac1 SetPrevPos; CursorCharRight; END MACRO Mac2 Mac1 Mac1 END . . . Mac2 . . . |
MACRO Mac2 SetPrevPos; CursorCharRight; SetPrevPos; CursorCharRight; END Mac2 . . . |
SetPrevPos; CursorCharRight; SetPrevPos; CursorCharRight; . . . |
Макровызовы, внутри макроопределений могут включать несколько уровней. Например, команда Mac2 могла бы быть выполнена внутри другого макроопределения. Фактически, такие средства, как макро-переходы дают возможность любое число раз обращаться к любому макроопределению, и даже к самому себе. Такие вызовы называются рекурсивными.