stringtranslate.com

Макро (компьютерные науки)

Редактор макросов jEdit

В компьютерном программировании макрос (сокращение от « макроинструкция »; от греч. μακρο  «длинный, большой» [1] ) — это правило или шаблон , который определяет, как определенный ввод должен быть сопоставлен с заменяющим выводом. Применение макроса к вводу известно как макрорасширение . Ввод и вывод могут быть последовательностью лексических токенов или символов , или синтаксическим деревом . Макросы символов поддерживаются в программных приложениях, чтобы упростить вызов общих последовательностей команд . Макросы токенов и деревьев поддерживаются в некоторых языках программирования, чтобы обеспечить повторное использование кода или расширить язык, иногда для доменно-специфических языков .

Макросы используются для того, чтобы сделать последовательность вычислительных инструкций доступной программисту в виде одного программного оператора , что делает задачу программирования менее утомительной и менее подверженной ошибкам. [2] [3] Таким образом, они называются «макросами», потому что «большой» блок кода может быть расширен из «маленькой» последовательности символов. Макросы часто допускают позиционные или ключевые параметры, которые диктуют, что генерирует условная ассемблерная программа, и использовались для создания целых программ или программных наборов в соответствии с такими переменными, как операционная система , платформа или другие факторы. Термин происходит от «макроинструкция», и такие расширения изначально использовались при генерации кода на языке ассемблера .

Макросы клавиатуры и мыши

Макросы клавиатуры и мыши позволяют преобразовывать короткие последовательности нажатий клавиш и действий мыши в другие, обычно более трудоемкие последовательности нажатий клавиш и действий мыши. Таким образом, часто используемые или повторяющиеся последовательности нажатий клавиш и движений мыши могут быть автоматизированы . Отдельные программы для создания таких макросов называются макрорекордерами .

В 1980-х годах макропрограммы — изначально SmartKey , затем SuperKey, KeyWorks, Prokey — были очень популярны, сначала как средство автоматического форматирования сценариев , затем для различных задач пользовательского ввода. Эти программы были основаны на режиме работы terminate-and-stay-resident и применялись ко всем вводам с клавиатуры, независимо от того, в каком контексте это происходило. Они в некоторой степени устарели после появления пользовательских интерфейсов, управляемых мышью, и доступности макросов клавиатуры и мыши в приложениях, таких как текстовые процессоры и электронные таблицы , что сделало возможным создание макросов клавиатуры, чувствительных к приложениям.

Макросы клавиатуры могут использоваться в многопользовательских ролевых онлайн-играх (MMORPG) для выполнения повторяющихся, но прибыльных задач, таким образом накапливая ресурсы. Поскольку это делается без человеческих усилий, это может исказить экономику игры. По этой причине использование макросов является нарушением TOS или EULA большинства MMORPG, и их администраторы прилагают значительные усилия для их подавления. [4]

Макросы и скрипты приложений

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

Программистский текстовый редактор Emacs (сокращение от «редактирование макросов») следует этой идее до конца. По сути, большая часть редактора состоит из макросов. Emacs изначально был разработан как набор макросов на языке редактирования TECO ; позже он был портирован на диалекты Lisp .

Другой программистский текстовый редактор, Vim (потомок vi ), также имеет реализацию клавиатурных макросов. Он может записывать в регистр (макрос) то, что человек печатает на клавиатуре, и это можно воспроизводить или редактировать так же, как макросы VBA для Microsoft Office. Vim также имеет скриптовый язык Vimscript [5] для создания макросов.

Visual Basic for Applications (VBA) — язык программирования, включенный в Microsoft Office с Office 97 по Office 2019 (хотя он был доступен в некоторых компонентах Office до Office 97). Однако его функция развилась из макроязыков, которые изначально были включены в некоторые из этих приложений, и заменила их.

XEDIT , работающий на компоненте Conversational Monitor System (CMS) VM , поддерживает макросы, написанные на EXEC , EXEC2 и REXX , а некоторые команды CMS на самом деле были оболочками вокруг макросов XEDIT. Hessling Editor (THE), частичный клон XEDIT, поддерживает макросы Rexx с использованием Regina и Open Object REXX (oorexx). Многие распространенные приложения, а также некоторые на ПК, используют Rexx в качестве языка сценариев.

Макровирус

VBA имеет доступ к большинству системных вызовов Microsoft Windows и выполняется при открытии документов. Это делает сравнительно простым написание компьютерных вирусов на VBA, обычно известных как макровирусы . В середине-конце 1990-х годов это стало одним из самых распространенных типов компьютерных вирусов. Однако в конце 1990-х годов и по сей день Microsoft исправляет и обновляет свои программы. [ необходима цитата ] Кроме того, современные антивирусные программы немедленно противодействуют таким атакам.

Параметризованные и непараметризованные макросы

Параметризованный макрос — это макрос, который может вставлять заданные объекты в свое расширение. Это дает макросу некоторую силу функции .

В качестве простого примера, в языке программирования C , это типичный макрос, который не является параметризованным макросом, т.е. макросом без параметров :

 #определить ПИ 3.14159

Это приводит PIк тому, что всегда заменяется на 3.14159везде, где встречается. Пример параметризованного макроса, с другой стороны, такой:

 #определить пред(x) ((x)-1)

То, во что расширяется этот макрос, зависит от того, какой аргумент x ему передается. Вот некоторые возможные расширения:

пред(2) → ((2) -1) пред(y+2) → ((y+2) -1) пред(ф(5)) → ((ф(5))-1)

Параметризованные макросы являются полезным механизмом исходного уровня для выполнения встроенного расширения , но в таких языках, как C , где они используют простую текстовую замену, они имеют ряд серьезных недостатков по сравнению с другими механизмами выполнения встроенного расширения, такими как встроенные функции .

С другой стороны, параметризованные макросы, используемые в таких языках, как Lisp , PL/I и Scheme , гораздо более мощны и способны принимать решения о том, какой код создавать, на основе своих аргументов; таким образом, их можно эффективно использовать для генерации кода во время выполнения .

Макросы подстановки текста

Такие языки, как C и некоторые языки ассемблера, имеют элементарные макросистемы, реализованные как препроцессоры для компилятора или ассемблера. Макросы препроцессора C работают путем простой текстовой подстановки на уровне токена , а не на уровне символов. Однако возможности макросов более сложных ассемблеров, например, IBM High Level Assembler (HLASM), не могут быть реализованы с помощью препроцессора; код для сборки инструкций и данных перемежается с кодом для сборки вызовов макросов.

Классическим примером использования макросов является система компьютерного набора TeX и ее производные, где большая часть функциональности основана на макросах.

MacroML — это экспериментальная система, которая стремится примирить статическую типизацию и макросистемы. Nemerle имеет типизированные синтаксические макросы, и один из продуктивных способов думать об этих синтаксических макросах — это многоэтапное вычисление .

Другие примеры:

Некоторые основные приложения были написаны как текстовые макросы, вызываемые другими приложениями, например, XEDIT в CMS.

Встраиваемые языки

Некоторые языки, такие как PHP , могут быть встроены в текст свободного формата или исходный код других языков. Механизм, с помощью которого распознаются фрагменты кода (например, заключаются в скобки <?phpи ?>), похож на текстовый макроязык, но они являются гораздо более мощными, полнофункциональными языками.

Процедурные макросы

Макросы в языке PL/I написаны на подмножестве самого PL/I: компилятор выполняет " предварительные операторы" во время компиляции, и вывод этого выполнения формирует часть кода, который компилируется. Возможность использовать знакомый процедурный язык в качестве макроязыка дает мощность, намного большую, чем у макросов подстановки текста, за счет более крупного и медленного компилятора. Макросы в PL/I, а также во многих ассемблерах, могут иметь побочные эффекты , например, установку переменных, к которым могут обращаться другие макросы.

Макросы фреймов технологии Frame имеют собственный синтаксис команд, но также могут содержать текст на любом языке. Каждый фрейм является как общим компонентом в иерархии вложенных подсборок, так и процедурой для интеграции себя с фреймами своих подсборок (рекурсивный процесс, который разрешает конфликты интеграции в пользу подсборок более высокого уровня). Выходные данные представляют собой пользовательские документы, как правило, компилируемые исходные модули. Технология Frame позволяет избежать распространения похожих, но слегка отличающихся компонентов, проблемы, которая преследовала разработку программного обеспечения с момента изобретения макросов и подпрограмм .

Большинство языков ассемблера имеют менее мощные возможности процедурных макросов, например, позволяющие повторять блок кода N раз для развертывания цикла ; но они имеют совершенно другой синтаксис по сравнению с фактическим языком ассемблера.

Синтаксические макросы

Макросистемы, такие как описанный ранее препроцессор C, которые работают на уровне лексических токенов, не могут надежно сохранять лексическую структуру. Синтаксические макросистемы работают вместо этого на уровне абстрактных синтаксических деревьев и сохраняют лексическую структуру исходной программы. Наиболее широко используемые реализации синтаксических макросистем находятся в языках, подобных Lisp . Эти языки особенно подходят для этого стиля макросов из-за их единообразного, заключенного в скобки синтаксиса (известного как S-выражения ). В частности, единообразный синтаксис упрощает определение вызовов макросов. Макросы Lisp преобразуют саму структуру программы, при этом для выражения таких преобразований доступен полный язык. Хотя синтаксические макросы часто встречаются в языках типа Lisp, они также доступны в других языках, таких как Prolog , [6] Erlang , [7] Dylan , [8] Scala , [9] Nemerle , [10] Rust , [11] Elixir , [12] Nim , [13] Haxe , [14] и Julia . [15] Они также доступны как сторонние расширения для JavaScript [16] и C# . [17]

Ранние макросы Lisp

До того, как в Lisp появились макросы, в нем были так называемые FEXPR , операторы, подобные функциям, чьи входные данные были не значениями, вычисляемыми аргументами, а скорее синтаксическими формами аргументов, и чьи выходные данные были значениями, которые должны были использоваться в вычислениях. Другими словами, FEXPR были реализованы на том же уровне, что и EVAL, и предоставляли окно в слой метаоценки. В целом это оказалось сложной моделью для эффективного рассуждения. [18]

В 1963 году Тимоти Харт предложил добавить макросы в Lisp 1.5 в AI Memo 57: MACRO Definitions for LISP. [19]

Анафорические макросы

Анафорический макрос — это тип макроса программирования, который намеренно фиксирует некоторую форму, предоставленную макросу, на которую можно ссылаться с помощью анафоры (выражения, ссылающегося на другое). Анафорические макросы впервые появились в книге Пола Грэма On Lisp, и их название является отсылкой к лингвистической анафоре — использованию слов в качестве замены предшествующих слов.

Гигиенические макросы

В середине восьмидесятых годов в ряде статей [20] [21] было введено понятие гигиенического макрорасширения ( syntax-rules), основанной на шаблонах системы, в которой синтаксические среды определения макроса и использования макроса различны, что позволяет разработчикам макросов и пользователям не беспокоиться о непреднамеренном захвате переменных (ср. ссылочную прозрачность ). Гигиенические макросы были стандартизированы для Scheme в стандартах R5RS , R6RS и R7RS . Существует ряд конкурирующих реализаций гигиенических макросов, таких как syntax-rules, syntax-case, явное переименование и синтаксические замыкания. Оба syntax-rulesи syntax-caseбыли стандартизированы в стандартах Scheme.

Недавно Ракет объединил понятия гигиенических макросов с «башней оценщиков», так что время синтаксического расширения одной макросистемы равно обычному времени выполнения другого блока кода [22] , и показал, как применять чередующееся расширение и синтаксический анализ в языке без скобок. [23]

Ряд языков, отличных от Scheme, либо реализуют гигиенические макросы, либо реализуют частично гигиенические системы. Примерами являются Scala , Rust , Elixir , Julia , Dylan , Nim и Nemerle .

Приложения

Порядок оценки
Системы макросов имеют ряд применений. Возможность выбора порядка оценки (см. ленивые оценки и нестрогие функции ) позволяет создавать новые синтаксические конструкции (например, управляющие структуры ), неотличимые от встроенных в язык. Например, в диалекте Lisp, в котором есть, condно отсутствует if, можно определить последний в терминах первого с помощью макросов. Например, в Scheme есть как продолжения , так и гигиенические макросы, что позволяет программисту разрабатывать собственные абстракции управления, такие как циклы и конструкции раннего выхода, без необходимости встраивать их в язык.
Подъязыки данных и предметно-ориентированные языки
Далее, макросы позволяют определять языки данных, которые немедленно компилируются в код, что означает, что такие конструкции, как конечные автоматы, могут быть реализованы таким образом, который является как естественным, так и эффективным. [24]
Связывающие конструкции
Макросы также могут использоваться для введения новых конструкций связывания. Наиболее известным примером является преобразование letв применение функции к набору аргументов.

Феллейзен предполагает [25] , что эти три категории составляют основные законные применения макросов в такой системе. Другие предложили альтернативные применения макросов, такие как анафорические макросы в макросистемах, которые негигиеничны или допускают выборочную негигиеничную трансформацию.

Взаимодействие макросов и других языковых функций стало продуктивной областью исследований. Например, компоненты и модули полезны для крупномасштабного программирования, но взаимодействие макросов и этих других конструкций должно быть определено для их совместного использования. Для Scheme и других языков с макросами были предложены модульные и компонентные системы, которые могут взаимодействовать с макросами. Например, язык Racket расширяет понятие макросистемы до синтаксической башни, где макросы могут быть написаны на языках, включающих макросы, используя гигиену для обеспечения того, чтобы синтаксические слои были различимы, и позволяя модулям экспортировать макросы в другие модули.

Макросы для машинно-независимого программного обеспечения

Макросы обычно используются для отображения короткой строки (вызова макроса) в более длинную последовательность инструкций. Другое, менее распространенное использование макросов — сделать обратное: отобразить последовательность инструкций в макростроку. Такой подход был принят в системе мобильного программирования STAGE2 , которая использовала элементарный макрокомпилятор (называемый SIMCMP) для отображения определенного набора инструкций данного компьютера в машинно-независимые макросы. Приложения (в частности, компиляторы), написанные на этих машинно-независимых макросах, затем могут быть запущены без изменений на любом компьютере, оснащенном элементарным макрокомпилятором. Первое приложение, запущенное в таком контексте, — это более сложный и мощный макрокомпилятор, написанный на машинно-независимом макроязыке. Этот макрокомпилятор применяется к самому себе в режиме самозагрузки для создания скомпилированной и гораздо более эффективной версии самого себя. Преимущество этого подхода в том, что сложные приложения можно переносить с одного компьютера на совершенно другой с минимальными усилиями (для каждой целевой архитектуры машины достаточно написать элементарный макрокомпилятор). [26] [27] Появление современных языков программирования, в частности C , для которого компиляторы доступны практически на всех компьютерах, сделало такой подход излишним. Однако это был один из первых случаев (если не первый) самонастройки компилятора .

язык ассемблера

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

В старых операционных системах, таких как те, что использовались на мэйнфреймах IBM, полная функциональность операционной системы была доступна только программам на языке ассемблера, а не программам на языке высокого уровня (конечно, если не использовались подпрограммы языка ассемблера), поскольку стандартные макрокоманды не всегда имели аналоги в подпрограммах, доступных для языков высокого уровня.

История

В середине 1950-х годов, когда программирование на языке ассемблера широко использовалось для написания программ для цифровых компьютеров , использование макроинструкций было инициировано для двух основных целей: сократить объем программного кода, который должен был быть написан, путем генерации нескольких операторов языка ассемблера из одной макроинструкции, и обеспечить соблюдение стандартов написания программ, например, указание команд ввода/вывода стандартными способами. [30] Макроинструкции были фактически промежуточным шагом между программированием на языке ассемблера и последующими языками программирования высокого уровня , такими как FORTRAN и COBOL . Две из самых ранних программных установок для разработки «макроязыков» для компьютера IBM 705 находились в Dow Chemical Corp. в Делавэре и Air Material Command, Ballistics Missile Logistics Office в Калифорнии. Макроинструкция, написанная в формате целевого языка ассемблера, обрабатывалась макрокомпилятором, который был препроцессором ассемблера, для генерации одной или нескольких инструкций языка ассемблера, которые затем обрабатывались программой ассемблера, которая переводила инструкции языка ассемблера в инструкции машинного языка . [31]

К концу 1950-х годов за макроязыком последовали макроассемблеры . Это была комбинация того и другого, где одна программа выполняла обе функции — макропрепроцессора и ассемблера в одном пакете. [31] [ проверка не удалась ]

В 1959 году Дуглас Э. Иствуд и Дуглас Макилрой из Bell Labs ввели условные и рекурсивные макросы в популярный ассемблер SAP , [32] создав то, что известно как Macro SAP. [33] Статья Макилроя 1960 года была основополагающей в области расширения любых (включая высокоуровневые ) языков программирования с помощью макропроцессоров . [34] [32]

Макроассемблеры позволяли программистам на языке ассемблера реализовывать собственный макроязык и допускали ограниченную переносимость кода между двумя машинами, работающими на одном и том же процессоре, но с разными операционными системами, например, ранними версиями MS-DOS и CP/M-86 . Библиотеку макросов нужно было писать для каждой целевой машины, но не для всей программы на языке ассемблера. Обратите внимание, что более мощные макроассемблеры позволяли использовать условные конструкции сборки в макроинструкциях, которые могли генерировать разный код на разных машинах или разных операционных системах, что снижало необходимость в нескольких библиотеках. [ необходима цитата ]

В 1980-х и начале 1990-х годов настольные ПК работали всего на нескольких МГц, и процедуры на языке ассемблера обычно использовались для ускорения программ, написанных на C, Fortran, Pascal и других. В то время эти языки использовали разные соглашения о вызовах. Макросы могли использоваться для сопряжения процедур, написанных на языке ассемблера, с интерфейсом приложений, написанных практически на любом языке. Опять же, базовый код на языке ассемблера оставался прежним, для каждого целевого языка требовалось написать только библиотеки макросов. [ необходима цитата ]

В современных операционных системах, таких как Unix и ее производные, доступ к операционной системе осуществляется через подпрограммы, обычно предоставляемые динамическими библиотеками. Высокоуровневые языки, такие как C, предлагают полный доступ к функциям операционной системы, устраняя необходимость в программах на языке ассемблера для такой функциональности. [ необходима цитата ]

Более того, стандартные библиотеки нескольких новых языков программирования, таких как Go , активно препятствуют использованию системных вызовов в пользу платформенно-независимых библиотек, если в этом нет необходимости, для улучшения переносимости и безопасности. [35]

Смотрите также

Ссылки

  1. ^ Оксфордский словарь английского языка , макрос , макроинструкция и макро-
  2. ^ Гринвальд, Ирвин Д.; Кейн, Морин (апрель 1959 г.). «Система Share 709: программирование и модификация». Журнал ACM . 6 (2). Нью-Йорк, штат Нью-Йорк, США: ACM: 128–133. doi : 10.1145/320964.320967 . S2CID  27424222. Одним из важных применений макросов программиста является экономия времени и устранение ошибок канцелярского типа при написании последовательности инструкций, которые часто повторяются в ходе программы.
  3. ^ Стрейчи, Кристофер (октябрь 1965 г.). «Макрогенератор общего назначения». Computer Journal . 8 (3): 225–241. doi : 10.1093/comjnl/8.3.225 .
  4. ^ "Runescape: The Massive Online Adventure Game by Jagex Ltd" . Получено 2008-04-03 .
  5. ^ "скрипты: vim онлайн". www.vim.org .
  6. ^ "Prolog Macros". www.metalevel.at . Получено 2021-04-05 .
  7. ^ "Erlang -- Препроцессор". erlang.org . Получено 2021-05-24 .
  8. ^ "Система макросов Дилана — Open Dylan". opendylan.org . Получено 05.04.2021 .
  9. ^ "Def Macros". Документация Scala . Получено 2021-04-05 .
  10. ^ "О нас - Официальный сайт языка программирования Nemerle". nemerle.org . Получено 2021-04-05 .
  11. ^ "Макросы - язык программирования Rust". doc.rust-lang.org . Получено 2021-04-05 .
  12. ^ "Макросы". elixir-lang.github.com . Получено 2021-04-05 .
  13. ^ "макросы". nim-lang.org . Получено 2021-04-05 .
  14. ^ "Макросы". Haxe - кроссплатформенный инструментарий .
  15. ^ "Метапрограммирование · Язык Julia". docs.julialang.org . Получено 2021-04-05 .
  16. ^ «Sweet.js — гигиеничные макросы для JavaScript». www.sweetjs.org .
  17. ^ "Домашняя страница LeMP · Улучшенный C#". ecsharp.net .
  18. ^ Маршалл, Джо. "untitled email" . Получено 3 мая 2012 г. .
  19. ^ Харт, Тимоти П. (октябрь 1963 г.). «Определения МАКРОСОВ для LISP». AI Memos . hdl : 1721.1/6111 . AIM-057.
  20. ^ Kohlbecker, Eugene; Friedman, Daniel; Felleisen, Matthias; Duba, Bruce (1986). "Hygienic Macro Expansion". LFP '86: Труды конференции ACM 1986 года по LISP и функциональному программированию . стр. 151–161. doi :10.1145/319838.319859. ISBN 0897912004.
  21. ^ [1] Клингер, Риз. «Макросы, которые работают»
  22. ^ Флэтт, Мэтью. «Компонуемые и компилируемые макросы: когда они вам нужны?» (PDF) .
  23. ^ Рафкинд, Джон; Флэтт, Мэтью. «Хону: синтаксическое расширение алгебраической нотации посредством залесения» (PDF) .
  24. ^ «Автоматы через макросы». cs.brown.edu .
  25. ^ [2], Маттиас Феллейзен, размещение в списке рассылки LL1
  26. ^ Оргасс, Ричард Дж.; Уэйт, Уильям М. (сентябрь 1969 г.). «База для мобильной системы программирования». Сообщения ACM . 12 (9). Нью-Йорк, Нью-Йорк, США: ACM: 507–510. doi : 10.1145/363219.363226 . S2CID  8164996.
  27. ^ Уэйт, Уильям М. (июль 1970 г.). «Система мобильного программирования: STAGE2». Сообщения ACM . 13 (7). Нью-Йорк, Нью-Йорк, США: ACM: 415–421. doi :10.1145/362686.362691. S2CID  11733598.
  28. ^ "Университет Северной Флориды" (PDF) .
  29. ^ "DTF (DOS/VSE)". IBM .
  30. ^ "Центр знаний IBM". Центр знаний IBM . 16 августа 2013 г.
  31. ^ ab "Макроинструкции языка ассемблера". Cisco .
  32. ^ ab Холбрук, Бернард Д.; Браун, У. Стэнли. «Технический отчет по вычислительной науке № 99 – История исследований в области вычислительной техники в лабораториях Белла (1937–1975)». Bell Labs . Архивировано из оригинала 2 сентября 2014 г. Получено 2 февраля 2020 г.
  33. ^ "Macro SAP – Макро компиляторная модификация SAP". HOPL: Онлайновая историческая энциклопедия языков программирования . Архивировано из оригинала 13 августа 2008 г.
  34. ^ Layzell, P. (1985). «История макропроцессоров в расширяемости языков программирования». The Computer Journal . 28 (1): 29–33. doi : 10.1093/comjnl/28.1.29 .
  35. ^ "syscall package - syscall - Go Packages". pkg.go.dev . Получено 2024-06-06 .

Внешние ссылки