&
 Operador macro -- unário                          (Especial)
------------------------------------------------------------------------------

 Sintaxe

     &<cMacroVar>[.]
     &(<cMacroExp>)

 Operandos

     <cMacroVar> pode ser qualquer variável caractere.  O ponto (.) é o
     terminador do macro e é utilizado para indicar o final da variável
     macro e para distinguir a variável macro do texto adjacente da
     declaraçao.

     <cMacroExp> é uma expressao caractere que deve ser englobada entre
     parênteses.  Neste caso, a expressao é avaliada primeiro, e a operaçao
     macro é executada no valor caractere resultante.  Isto permite que o
     conteúdo de campos e elementos de vetor sejam compilados e executados.

 Descriçao

     O operador macro em Clipper 5.0 é um operador especial que permite a
     compilaçao em tempo de execuçao de expressoes e substituiçao de textos
     dentro de strings.  Sempre que o operador macro (&) é encontrado, o
     operando é submetido a um compilador especial em tempo de execuçao
     chamado de compilador macro, que pode compilar expressoes, mas
     nao declaraçoes ou comandos.

     Substituiçao de Textos

     Sempre que é encontrada uma referência a uma variável macro privada ou
     pública dentro de uma cadeia de caracteres, desta forma:

     cMacro := "there"
     ? "Hello &cMacro"               // Resulta: Hello there

     o conteúdo da variável macro é substituido pela referência da
     variável.  Se for especificada uma expressao macro (por exemplo,
     &(cMacro1 + cMacro2), a variável macro é uma variável local, estática,
     de campo, ou um elemento de vetor, ela é tratada como texto literal e
     nao expandido.

     Compilaçao e Execuçao

     Quando é encontrada especificada uma expressao ou uma variável macro
     dentro de uma de uma expressao, ela é tratada como uma expressao sendo
     que o símbolo de macro comporta-se como o operador de compilaçao e
     execuçao.  Se o macro for especificado como uma variávle macro desta
     forma:

     cMacro := "DTOC(DATE())"
     ? &cMacro

     o conteúdo da variável macro é compilado pelo compilador macro e depois
     executado.  O código do compilador é entao dispensado.  Se uma
     expressao for especificada entre aprênteses e precedida do operador
     macro (&) desta forma:

     ? &(INDEXKEY(0))

     a expressao é avaliada e a cadeia de caracteres resultante é compilada
     e executada da mesma forma que uma variável macro.

     Um dos efeitos interessantes das expressoes macro é que você pode
     compilar uma cadeia de caracteres que contém uma definiçao de bloco de
     código, assim:

     bBlock := &("{ |exp| QOUT(exp) }")
     .
     .
     .
     EVAL(bBlock, DATE())

     Neste caso, a cadeia de caracteres que contém o bloco de código é
     compilada e a porçao executada retorna o bloco de código como um
     valor.  O bloco de código resultante pode ser gravado e avaliado mais
     tarde com a funçao EVAL().

 Notas

     ■  Palavras chave de comando: O operador macro (&) nao pode ser
        utilizado para substituir ou compilar palavras chave de comandos.
        No Clipper 5.0, isto nao faz muito sentido, pois os comandos sao em
        declaraçoes e expressoes em tempo de compilaçao.  A redefiniçao de
        palavras chave de comandos, porém, pode ser feita modificando a
        definiçao do comando em STD.CH, substituindo a definiçao de comando
        existente por uma nova definiçao através da diretiva #command, ou
        redefinindo uma palavra chave de comando através da diretiva
        #translate.  Em ambos os casos, a redefiniçao de uma palavra chave
        de comando pode ocorrer somente em tempo de compilaçao, e nao em
        tempo de execuçao.

     ■  Argumentos de comando: Nas versoes anteriores do Clipper, bem
        como em outros dialetos, as variáveis macro geralmente eram
        utilizadas para especificar os argumentos de comandos que exigiam
        valores de texto literal.  Isto incluia todos os argumentos de
        comando de arquivos, bem como comoandos SET com argumentos de
        comuta.  Nestes casos, agora você pode utilizar uma expressao
        estendida no lugar do argumento literal caso a expressao esteja
        entre parênteses.  Por exemplo, o seguinte:

        xcDatabase = "Invoices"
        USE &xcDatabase.

        pode ser substituido por:

        xcDatabase = "Invoices"
        USE (xcDatabase)

        É importante utilizar expressoes estendidas, em especial se você
        estiver usando variáveis locais e estáticas.  Os comandos sao
        pré-processados geralmente para chamadas de funçao sendo os
        argumentos de comando traduzidos para argumentos de funçao como
        valores legais do Clipper.  Com os comandos de arquivo, por exemplo,
        os nomes de arquivos sao transformados em cadeias de caracteres
        através da marca de resultado condicional, e passados como
        argumentos para as funçoes que efetivamente executam as operaçoes
        desejadas.  Caso um valor macro ou literal seja especificado como o
        argumento de comando, ele é transformado em cadeia de caracteres.
        Se, porém, o argumento for uma expressao estendida, ele é escrito no
        texto resultante exatamente como especificado.  Por exemplo, as
        seguintes especificaçoes do comando RENAME:

        #command RENAME <xcOld> TO <xcNew> => FRENAME( <(xcOld)>, <(xcNew)> )
        //
        RENAME &xcOld TO &xcNew
        RENAME (xcOld) TO (xcNew)

        sao escritas no texto resulttante da seguinte forma:

        FRENAME( "&xcOld", "&xcNew" )
        FRENAME( xcOld, xcNew )

        ao serem pré-processados.  Quando as variáveis macro sao
        transformadas em cadeias de caracteres, os nomes das variáveis macro
        ficam ocultos no string e nao sao compilados.  Mais tarde, em tempo
        de execuçao, sao substituidos no string e passados como argumentos
        paqra a funçao FRENAME().   Isto exclui as variáveis macro locais e
        estáticas, pois os nomes das variáveis nao estao presentes em tempo
        de execuçao para serem substituidas.  As variáveis públicas e
        privadas, porém, comportam-se da maneira como você espera.  Se isto
        parece um tanto confuso, consulte a seçao Variáveis.  Isto exclui as
        variáveis macro locais e estáticas, pois os nomes das variáveis nao
        estao presentes em tempo de execuçao para serem substituidas.  As
        variáveis públicas e privadas, porém, comportam-se como você deve
        esperar.  Caso isto pareça um tanto confuso, consulte a seçao
        Variáveis para obter mais informaçoes sobre a diferença entre
        variáveis locais e estáticas, e variáveis privadas e públicas.

     ■  Listas como argumentos de comandos: O operador macro (&) nao
        irao substituir ou compilar completamente uma lista como um
        argumento da maioria dos comandos.  Em especial, estes sao comandos
        onde uma lista de argumentos é processada em um vetor ou um bloco de
        código.  Exemplos disto sao argumentos da cláusula FIELDS e SET
        INDEX.  Uma exceçao é o comando SET COLOR, que pré-processa a lista
        de cores em uma cadeia de caracteres simples e a passa para a funçao
        SETCFOLOR().

        Em ambos os casos, argumentos de lista sempre devem ser
        especificados como expressoes estendidas sendo cada argumento de
        lista especificado:

        LOCAL xcIndex := { "Ntx1", "Ntx2" }
        SET INDEX TO (xcIndex[1]), (xcIndex[2])

     ■  Vetores: O operador macro (&) pode ser utilizado juntamente
        com vetores e elementos de vetor.  Porém, por causa da capacidade
        maior dos vetores do Clipper 5.0, você pode nao achar tao necessário
        usar o operador macro (&) a fim de fazer referências de variáveis a
        vetores.  Agora você pode atribuir referências de vetor a variáveis,
        retornar referências de vetor de funçoes definidas pelo usuário, e
        aninhar referências de vetor dentro de outros vetores.  Além disso,
        os vetores podem ser criados especificando-se vetores literais ou
        através da funçao ARRAY().  Para maiores informaçoes a respeito de
        vetores, consulte a seçao Vetores deste capítulo.

        Pode-se, portanto, fazer referências a vetores e elementos de vetor
        através de variáveis macro e expressoes macro com a restriçao que as
        referências subscritas nao podem ser feitas em uma declaraçao
        PRIVATE ou PUBLIC.  Esta tentativa gerará um erro fatal do
        compilador.  Por exemplo, a seguir esrtao demonstradas referências a
        elementos de vetor através de variáveis macro:

        cName := "aArray"
        nElements := 5
        cNameElement := "aArray[1]"
        //
        PRIVATE &cName.[nElements]   // Cria "array" com 5 elementos
        &cNameElement. := 100        // Atribui 100 ao elemento 1
        &cName.[3] := "abc"          // Atribui "abc" ao elemento 3

        Pode também ser aplicado um operador macro (&) a um elemento de
        vetor se a referência é feita através de uma expressao macro.  Uma
        referência a variável macro, porém, gerará um erro em tempo de
        execuçao.  Por exemplo, a seguir estao relacionados os valores de
        todos os campos do registro corrente:

        USE Customer NEW
        aStruc := DBSTRUCT()
        //
        FOR nField := 1 TO LEN(aStruc)
           ? &(aStruc[nField, 1])
        NEXT

     ■  Blocos de código: O operador macro (&) pode ser aplicado a
        uma expressao ou variável macro em um bloco de código na maioria dos
        casos.  Existe uma restriçao quando a variável ou expressao macro
        contém uma variável declarada.  A restriçao acontece quando uma
        expressao complexa (uma expressao que contém um operador e um ou
        mais operandos) inclui o operador macro (&) e é especificada dentro
        de um bloco de código.  Caso seja feita esta tentativa, ocorre um
        erro em tempo de execuçao

        Observe que esta restriçao tem implicaçoes importantes com relaçao à
        utilizaçao de variáveis estáticas e locais nas cláusulas
        condicionais de comandos, pois estas cláusulas sao transformadas de
        blocos quando sao escritas no texto resultante quando o comando é
        pré-processado.  Isto aplica-se a todas as cláusulas FOR e WHILE, ao
        ocmando SET FILTER, e à expressao SET RELATION.  A melhor maneira de
        se evitar este problema é juntar toda a expressao em uma única
        variável macro e depois aplicar o operador macro (&) à variável.

     ■  Condiçoes macro: Ao utilizar o operador macro (&) para
        especificar cláusulas condicionais de comandos de tratamento de
        bancos de dados tais como cláusulas FOR ou WHILE, existem algumas
        restriçoes com relaçao à complexidade e no tamanho da expressao, as
        seguir:

        .  O tamanho máximo de um string que o compilador macro pode
           processar é de 254 caracteres

        .  Existe um limte à complexidade de condiçoes (quanto mais
           complexa, menor a quantidade de condiçoes que pode ser
           especificada

     ■  Rotinas e funçoes: As chamadas de rotinas e funçoes podem ser
        referenciadas através de expressoes e variáveis macro.  Com DO, a
        referência da variável macro à rotina pode preencher todo ou parte
        do nome da rotina.  Com uma chamada a funçao (pertencente ao sistema
        ou definida pelo usuário), a referência a variável macro deve
        incluir o nome da funçao e todos os seus argumentos.

        Com o advento dos blocos de código no Clipper 5.0, esta nao é mais a
        prática mais apropriada.  Ao invés disso, todas as invocaçoes de
        rotinas funçoes que utilizam o operador macro devem ser convertidas
        para a avaliaçao dos blocos de código.  Por exemplo, o seguinte
        fragmento de código:

        cProc := "AcctsRpt"
        .
        .
        .
        DO &cProc

        pode ser substituido por:

        bProc := &( "{ || AcctsRpt() }" )
        .
        .
        .
        EVAL(bProc)

        A vantagem clara de um bloco de código em lugar de uma avalizaçao
        macro é que a compilaçao de um string que contém um bloco de código
        pode ser gravada e portanto deve ser compilada apenas uma vez.  As
        avaliaçoes macro compilam cada vez referenciada.

     ■  Referências para overlays: Rotinas e funçoes definidas pelo
        usuário utilizadas em expressoes macro mas nao referenciadas em
        nenhum outro lugar devem ser declaradas EXTERNAL, ou entao o linker
        nao as incluirá no arquivo executável (.EXE).  A única exceçao a
        esta regra é se uma rotina ou funçao definida pelo usuário tiver
        sido pré-linkada em uma biblitoeca (.PLL).

     ■  TEXT...ENDTEXT: Variáveis macro referenciadas em uma
        construçao TEXT...ENDTEXT sao expandidas.  Observe que um campo nao
        pode ser expandida, portanto você deve primeiramente atribuir o
        valor de campo a uma variável de memória dentro de TEXT...ENDTEXT.
        Por exemplo:

        USE Customer NEW
        myVar := Customer->CustName
        TEXT
        This is text with a macro &myVar..
        ENDTEXT

     ■  Macros aninhados: O processamento de variáveis e expressoes
        macro em Clipper é bastante dinâmico, permitindo definiçoes macro
        aninhadas.  Por exemplo, após atribuir uma variável macro a outra
        variável macro, a variável macro original pode ser expandida,
        resultando na expansao da segunda variável macro e a avaliaçao de
        seu conteúdo. Por exemplo:

        cOne = "&cTwo"
        cTwo = "cThree"
        cThree = "hello"
        //
        ? &cOne                   // Resulta: "hello"