Macro (ciência da computação) - Macro (computer science)

editor de macro do jEdit

Uma macro (abreviação de "macro instrução", do grego combinando forma μακρο- "longo, grande") em ciência da computação é uma regra ou padrão que especifica como uma determinada entrada deve ser mapeada para uma saída de substituição. Aplicar uma macro a uma entrada é uma expansão de macro . A entrada e a saída podem ser uma sequência de tokens ou caracteres lexicais ou uma árvore de sintaxe . As macros de caracteres são suportadas em aplicativos de software para facilitar a invocação de sequências de comandos comuns. Macros de token e árvore são suportados em algumas linguagens de programação para permitir a reutilização de código ou para estender a linguagem, às vezes para linguagens de domínio específico .

As macros são usadas para disponibilizar uma sequência de instruções de computação ao programador como uma única instrução de programa, tornando a tarefa de programação menos entediante e menos sujeita a erros. (Assim, eles são chamados de "macros" porque um "grande" bloco de código pode ser expandido a partir de uma "pequena" sequência de caracteres.) As macros geralmente permitem parâmetros posicionais ou de palavra-chave que ditam o que o programa montador condicional gera e têm sido usados ​​para crie programas inteiros ou conjuntos de programas de acordo com variáveis ​​como sistema operacional , plataforma ou outros fatores. O termo deriva de "macro instrução" e tais expansões foram originalmente usadas na geração de código em linguagem assembly .

Macros de teclado e mouse

As macros do teclado e do mouse permitem que sequências curtas de pressionamentos de tecla e ações do mouse se transformem em outras, geralmente mais demoradas, sequências de pressionamentos de tecla e ações do mouse. Desta forma, as sequências frequentemente usadas ou repetitivas de pressionamentos de tecla e movimentos do mouse podem ser automatizadas . Programas separados para criar essas macros são chamados de gravadores de macro .

Durante a década de 1980, os programas de macro - originalmente SmartKey , depois SuperKey, KeyWorks, Prokey - eram muito populares, primeiro como um meio de formatar roteiros automaticamente , depois para uma variedade de tarefas de entrada do usuário. Esses programas eram baseados no modo de operação TSR ( encerrar e permanecer residente ) e aplicados a todas as entradas do teclado, independentemente do contexto em que ocorressem. Em certa medida, eles caíram em obsolescência após o advento de interfaces de usuário orientadas a mouse e a disponibilidade de macros de teclado e mouse em aplicativos como processadores de texto e planilhas , tornando possível criar macros de teclado sensíveis a aplicativos.

As macros de teclado podem ser usadas em jogos de RPG online para vários jogadores (MMORPGs) para realizar tarefas repetitivas, mas lucrativas, acumulando recursos. Como isso é feito sem esforço humano, pode prejudicar a economia do jogo. Por esse motivo, o uso de macros é uma violação dos TOS ou EULA da maioria dos MMORPGs, e seus administradores fazem um esforço considerável para suprimi-los.

Macros de aplicativos e scripts

As macros de teclado e mouse criadas com os recursos de macro integrados de um aplicativo são, às vezes, chamadas de macros de aplicativo . Eles são criados executando a sequência uma vez e permitindo que o aplicativo grave as ações. Também pode existir uma linguagem de programação de macro subjacente, mais comumente uma linguagem de script , com acesso direto aos recursos do aplicativo.

O editor de texto dos programadores, Emacs , (abreviação de "edição de macros") segue esta ideia a uma conclusão. Na verdade, a maior parte do editor é feita de macros. O Emacs foi originalmente desenvolvido como um conjunto de macros na linguagem de edição TECO ; mais tarde foi portado para dialetos do Lisp .

Outro editor de texto para programadores, o Vim (um descendente de vi ), também possui uma implementação de macros de teclado. Ele pode gravar em um registro (macro) o que uma pessoa digita no teclado e pode ser reproduzido ou editado da mesma forma que as macros VBA para o Microsoft Office. O Vim também possui uma linguagem de script chamada Vimscript para criar macros.

Visual Basic for Applications (VBA) é uma linguagem de programação incluída no Microsoft Office do Office 97 ao Office 2019 (embora estivesse disponível em alguns componentes do Office antes do Office 97). No entanto, sua função evoluiu e substituiu as macrolinguagens originalmente incluídas em alguns desses aplicativos.

XEDIT , em execução no componente Conversational Monitor System (CMS) da VM , suporta macros gravadas em EXEC , EXEC2 e REXX , e alguns comandos CMS eram, na verdade, wrappers em torno de macros XEDIT. O Hessling Editor (THE), um clone parcial do XEDIT, suporta macros Rexx usando Regina e Open Object REXX (oorexx). Muitos aplicativos comuns, e alguns em PCs, usam Rexx como uma linguagem de script.

Vírus de macro

O VBA tem acesso à maioria das chamadas de sistema do Microsoft Windows e é executado quando os documentos são abertos. Isso torna relativamente fácil escrever vírus de computador em VBA, comumente conhecidos como vírus de macro . Em meados da década de 1990, esse se tornou um dos tipos mais comuns de vírus de computador. No entanto, durante o final da década de 1990 e até hoje, a Microsoft vem corrigindo e atualizando seus programas. Além disso, os programas antivírus atuais neutralizam imediatamente esses ataques.

Macro parametrizada

Uma macro parametrizada é uma macro capaz de inserir determinados objetos em sua expansão. Isso dá à macro parte do poder de uma função .

Como um exemplo simples, na linguagem de programação C , esta é uma macro típica que não é uma macro parametrizada:

 #define PI   3.14159

Isso faz PIcom que seja sempre substituído por 3.14159onde quer que ocorra. Um exemplo de macro parametrizada, por outro lado, é este:

 #define pred(x)  ((x)-1)

A expansão dessa macro depende de qual argumento x é passado para ela. Aqui estão algumas expansões possíveis:

 pred(2)    →  ((2)   -1)
 pred(y+2)  →  ((y+2) -1)
 pred(f(5)) →  ((f(5))-1)

As macros parametrizadas são um mecanismo de nível de origem útil para realizar a expansão in-line , mas em linguagens como C, onde usam substituição textual simples, elas têm uma série de desvantagens graves sobre outros mecanismos para realizar a expansão in-line, como funções inline .

As macros parametrizadas usadas em linguagens como Lisp , PL / I e Scheme , por outro lado, são muito mais poderosas, capazes de tomar decisões sobre qual código produzir com base em seus argumentos; portanto, eles podem ser usados ​​com eficácia para executar a geração de código em tempo de execução .

Macros de substituição de texto

Linguagens como C e algumas linguagens assembly têm sistemas de macro rudimentares, implementados como pré - processadores para o compilador ou montador. As macros do pré-processador C funcionam por simples substituição textual no token , em vez de no nível do caractere. No entanto, os recursos de macro de montadores mais sofisticados, por exemplo, IBM High Level Assembler (HLASM) não podem ser implementados com um pré-processador; o código para montar instruções e dados é intercalado com o código para montar invocações de macro.

Um uso clássico de macros é no sistema de composição de computador TeX e seus derivados, onde a maior parte da funcionalidade é baseada em macros.

MacroML é um sistema experimental que busca conciliar tipagem estática e sistemas macro. Nemerle digitou macros de sintaxe e uma maneira produtiva de pensar nessas macros de sintaxe é como uma computação de vários estágios .

Outros exemplos:

Alguns aplicativos principais foram escritos como macro de texto invocados por outros aplicativos, por exemplo, por XEDIT em CMS.

Linguagens incorporáveis

Algumas linguagens, como PHP , podem ser incorporadas em texto de formato livre ou no código-fonte de outras linguagens. O mecanismo pelo qual os fragmentos de código são reconhecidos (por exemplo, sendo colocados entre colchetes <?phpe ?>) é semelhante a uma linguagem macro textual, mas são linguagens muito mais poderosas e completas.

Macros procedurais

As macros na linguagem PL / I são escritas em um subconjunto da própria PL / I: o compilador executa " instruções do pré-processador " no momento da compilação e a saída dessa execução faz parte do código que é compilado. A capacidade de usar uma linguagem procedural familiar como a linguagem macro fornece um poder muito maior do que o das macros de substituição de texto, às custas de um compilador maior e mais lento.

As macros de quadro da tecnologia de quadros têm sua própria sintaxe de comando, mas também podem conter texto em qualquer idioma. Cada quadro é um componente genérico em uma hierarquia de submontagens aninhadas e um procedimento de integração com seus quadros de submontagem (um processo recursivo que resolve conflitos de integração em favor de submontagens de nível superior). As saídas são documentos personalizados, normalmente módulos de origem compiláveis. A tecnologia de quadros pode evitar a proliferação de componentes semelhantes, mas sutilmente diferentes, um problema que tem atormentado o desenvolvimento de software desde a invenção de macros e sub - rotinas .

A maioria das linguagens assembly tem recursos de macro procedurais menos poderosos, por exemplo, permitindo que um bloco de código seja repetido N vezes para o desenrolamento do loop ; mas eles têm uma sintaxe completamente diferente da linguagem assembly real.

Macros sintáticas

Os macrossistemas - como o pré-processador C descrito anteriormente - que funcionam no nível dos tokens lexicais não podem preservar a estrutura lexical de maneira confiável. Os macrossistemas sintáticos funcionam, em vez disso, no nível das árvores sintáticas abstratas e preservam a estrutura lexical do programa original. As implementações mais amplamente utilizadas de macrossistemas sintáticos são encontradas em linguagens do tipo Lisp . Essas linguagens são especialmente adequadas para esse estilo de macro devido à sua sintaxe uniforme entre parênteses (conhecida como expressões S ). Em particular, a sintaxe uniforme torna mais fácil determinar as invocações de macros. As macros Lisp transformam a própria estrutura do programa, com a linguagem completa disponível para expressar tais transformações. Embora as macros sintáticas sejam frequentemente encontradas em linguagens semelhantes a Lisp, elas também estão disponíveis em outras linguagens, como Prolog , Erlang , Dylan , Scala , Nemerle , Rust , Elixir , Nim , Haxe e Julia . Eles também estão disponíveis como extensões de terceiros para JavaScript , C # e Python .

Macros de Lisp iniciais

Antes de Lisp ter macros, ele tinha os chamados FEXPRs , operadores semelhantes a funções cujas entradas não eram os valores calculados pelos argumentos, mas sim as formas sintáticas dos argumentos, e cuja saída eram valores a serem usados ​​no cálculo. Em outras palavras, FEXPRs foram implementados no mesmo nível que EVAL e forneceram uma janela para a camada de meta-avaliação. Em geral, descobriu-se que esse modelo era difícil de raciocinar com eficácia.

Em 1963, Timothy Hart propôs adicionar macros ao Lisp 1.5 no AI Memo 57: MACRO Definitions for LISP.

Macros anafóricas

Uma macro anafórica é um tipo de macro de programação que captura deliberadamente alguma forma fornecida à macro que pode ser referida por uma anáfora (uma expressão que se refere a outra). Macros anafóricas apareceram pela primeira vez em On Lisp, de Paul Graham, e seu nome é uma referência à anáfora linguística - o uso de palavras como substituto de palavras precedentes.

Macros higiênicas

Em meados dos anos oitenta, uma série de artigos introduziram a noção de macroexpansão higiênica ( syntax-rules), um sistema baseado em padrões onde os ambientes sintáticos da macro definição e do uso macro são distintos, permitindo que os macro definidores e usuários não se preocupem com inadvertência captura de variáveis ​​(cf. transparência referencial ). Macros higiênicas foram padronizadas para Scheme nos padrões R5RS , R6RS e R7RS . Um número de implementações de macros de higiene competindo existem, como syntax-rules, syntax-case, renomeação explícita e fechamentos sintáticos. Ambos syntax-rulese syntax-caseforam padronizados nos padrões do Esquema.

Recentemente, Racket combinou as noções de macros higiênicas com uma " torre de avaliadores ", de modo que o tempo de expansão sintática de um sistema macro é o tempo de execução normal de outro bloco de código, e mostrou como aplicar expansão intercalada e análise em um não -linguagem entre parênteses.

Vários idiomas diferentes do Scheme implementam macros higiênicas ou implementam sistemas parcialmente higiênicos. Os exemplos incluem Scala , Rust , Elixir , Julia , Dylan , Nim e Nemerle .

Formulários

Ordem de avaliação
Os sistemas macro têm uma variedade de usos. Ser capaz de escolher a ordem de avaliação (ver avaliação preguiçosa e funções não estritas ) permite a criação de novas construções sintáticas (por exemplo, estruturas de controle ) indistinguíveis daquelas construídas na linguagem. Por exemplo, em um dialeto Lisp que tem condmas falta if, é possível definir o último em termos do primeiro usando macros. Por exemplo, Scheme tem continuações e macros higiênicas, o que permite que um programador projete suas próprias abstrações de controle, como loops e construções de saída antecipada, sem a necessidade de construí-las na linguagem.
Sub-idiomas de dados e idiomas específicos de domínio
Em seguida, as macros tornam possível definir linguagens de dados que são imediatamente compiladas em código, o que significa que construções como máquinas de estado podem ser implementadas de uma forma natural e eficiente.
Construções de ligação
As macros também podem ser usadas para introduzir novas construções de ligação. O exemplo mais conhecido é a transformação de letna aplicação de uma função a um conjunto de argumentos.

Felleisen conjectura que essas três categorias constituem os principais usos legítimos de macros em tal sistema. Outros propuseram usos alternativos de macros, como macros anafóricas em macrossistemas que são anti-higiênicos ou permitem uma transformação anti-higiênica seletiva.

A interação de macros e outros recursos de linguagem tem sido uma área produtiva de pesquisa. Por exemplo, componentes e módulos são úteis para programação em grande escala, mas a interação de macros e essas outras construções devem ser definidas para seu uso em conjunto. Módulos e sistemas de componentes que podem interagir com macros foram propostos para Scheme e outras linguagens com macros. Por exemplo, a linguagem Racket estende a noção de um sistema macro para uma torre sintática, onde macros podem ser escritas em linguagens incluindo macros, usando higiene para garantir que as camadas sintáticas sejam distintas e permitindo que os módulos exportem macros para outros módulos.

Macros para software independente de máquina

Normalmente, as macros são usadas para mapear uma string curta (chamada de macro) para uma seqüência mais longa de instruções. Outro uso menos comum de macros é fazer o inverso: mapear uma sequência de instruções para uma string de macro. Essa foi a abordagem adotada pelo STAGE2 Mobile Programming System, que usou um compilador de macro rudimentar (chamado SIMCMP) para mapear o conjunto de instruções específico de um determinado computador para contraparte macros independentes de máquina . Os aplicativos (notavelmente compiladores) escritos nessas macros independentes de máquina podem ser executados sem alterações em qualquer computador equipado com o compilador de macro rudimentar. O primeiro aplicativo executado em tal contexto é um compilador de macro mais sofisticado e poderoso, escrito na linguagem de macro independente da máquina. Este macro compilador é aplicado a si mesmo, de forma bootstrap , para produzir uma versão compilada e muito mais eficiente de si mesmo. A vantagem dessa abordagem é que aplicativos complexos podem ser transferidos de um computador para um computador muito diferente com muito pouco esforço (para cada arquitetura de máquina-alvo, apenas a escrita do compilador de macro rudimentar). O advento de linguagens de programação modernas, notadamente C , para as quais os compiladores estão disponíveis em praticamente todos os computadores, tornou essa abordagem supérflua. Esta foi, no entanto, uma das primeiras instâncias (se não a primeira) de inicialização do compilador .

Linguagem de montagem

Embora as instruções de macro possam ser definidas por um programador para qualquer conjunto de instruções do programa assembler nativo, normalmente as macros são associadas a bibliotecas de macro fornecidas com o sistema operacional, permitindo o acesso às funções do sistema operacional, como

  • acesso periférico por métodos de acesso (incluindo macros como OPEN, CLOSE, READ e WRITE)
  • funções do sistema operacional como ATTACH, WAIT e POST para criação e sincronização de subtarefas. Normalmente, essas macros se expandem em código executável, por exemplo, para a macroinstrução EXIT,
  • uma lista de instruções de constante de definição , por exemplo, para a macro DCB - DTF (Define The File) para DOS - ou uma combinação de código e constantes, com os detalhes da expansão dependendo dos parâmetros da instrução macro (como uma referência para um arquivo e uma área de dados para uma instrução READ);
  • o código executável frequentemente termina em uma instrução de registro de ramificação e link para chamar uma rotina ou em uma instrução de chamada de supervisor para chamar uma função do sistema operacional diretamente.
  • Gerando um fluxo de trabalho do Estágio 2 para geração do sistema , por exemplo, OS / 360 . Ao contrário das macros típicas, as macros sysgen estágio 1 não geram dados ou código a serem carregados no armazenamento, mas usam a instrução PUNCH para gerar JCL e dados associados.

Em sistemas operacionais mais antigos, como aqueles usados ​​em mainframes IBM, a funcionalidade completa do sistema operacional estava disponível apenas para programas de linguagem assembler, não para programas de linguagem de alto nível (a menos que sub-rotinas de linguagem assembly foram usadas, é claro), pois as instruções macro padrão nem sempre têm contrapartes em rotinas disponíveis para linguagens de alto nível.

História

Em meados da década de 1950, quando a programação em linguagem assembly era comumente usada para escrever programas para computadores digitais , o uso de macroinstruções foi iniciado para dois propósitos principais: reduzir a quantidade de codificação de programa que precisava ser escrita, gerando várias instruções em linguagem assembly. de uma macro instrução e para reforçar os padrões de escrita do programa, por exemplo, especificando comandos de entrada / saída de maneiras padrão. As instruções macro foram efetivamente uma etapa intermediária entre a programação em linguagem assembly e as linguagens de programação de alto nível que se seguiram, como FORTRAN e COBOL . Duas das primeiras instalações de programação para desenvolver "macro linguagens" para o computador IBM 705 foram na Dow Chemical Corp. em Delaware e no Air Material Command, Ballistics Missile Logistics Office na Califórnia. Uma macro instrução escrita no formato da linguagem assembly alvo seria processada por um compilador de macro, que era um pré-processador para o montador, para gerar uma ou mais instruções em linguagem assembly a serem processadas em seguida pelo programa montador que traduziria o instruções em linguagem assembly em instruções em linguagem de máquina .

No final da década de 1950, a linguagem macro foi seguida pelos Macro Assemblers. Essa foi uma combinação de ambos, em que um programa atendia às duas funções, o de um pré-processador de macro e um montador no mesmo pacote.

Em 1959, Douglas E. Eastwood e Douglas McIlroy, da Bell Labs, introduziram macros condicionais e recursivas no popular assembler SAP , criando o que é conhecido como Macro SAP. O artigo de 1960 de McIlroy foi seminal na área de estender qualquer linguagem de programação (incluindo de alto nível ) por meio de macroprocessadores .

Os Macro Assemblers permitiram que os programadores da linguagem assembly implementassem sua própria macro-linguagem e permitiram a portabilidade limitada do código entre duas máquinas executando a mesma CPU, mas com sistemas operacionais diferentes, por exemplo, versões anteriores do MSDOS e CPM-86. A macro-biblioteca precisaria ser escrita para cada máquina de destino, mas não para o programa de linguagem assembly como um todo. Observe que os montadores de macro mais poderosos permitiam o uso de construções de montagem condicional em instruções de macro que poderiam gerar códigos diferentes em máquinas ou sistemas operacionais diferentes, reduzindo a necessidade de várias bibliotecas.

Na década de 1980 e no início da década de 1990, os desktops funcionavam apenas em alguns MHz e as rotinas de linguagem assembly eram comumente usadas para acelerar programas escritos em C, Fortran, Pascal e outros. Esses idiomas, na época, usavam convenções de chamada diferentes. As macros podem ser usadas para fazer a interface de rotinas escritas em linguagem assembly com o front-end de aplicativos escritos em quase qualquer linguagem. Novamente, o código básico da linguagem assembly permaneceu o mesmo, apenas as bibliotecas de macro precisaram ser escritas para cada linguagem de destino.

Em sistemas operacionais modernos, como Unix e seus derivados, o acesso ao sistema operacional é fornecido por meio de sub-rotinas, geralmente fornecidas por bibliotecas dinâmicas. Linguagens de alto nível, como C, oferecem acesso abrangente às funções do sistema operacional, eliminando a necessidade de programas em linguagem assembler para essa funcionalidade.

Veja também

Referências

links externos