VMS Help  —  MACRO  /ALPHA  Lexical Operators

1  –  Processing with Lexical Operators

    Lexical operator processing is performed on all source lines
    and macro expansion lines before any other assembler processing.
    Thus, macro invocations, assembler directives, and instructions
    are subject to lexical operator processing before normal
    assembler processing.

    Lexical operators are recognized and processed within string
    literals. Lexical operator processing is suppressed during macro
    registration in order that lexical operator evaluation may occur
    during macro expansion. Lexical operator evaluation is also
    suppressed for a range of text that is conditionally excluded
    with one of the .IF directives. In addition, lexical operator
    processing is not performed within a comment.

2  –  Syntax

    You invoke a lexical string operator with a percent sign followed
    by the lexical operator name, a left parentheses, a list of
    arguments separated by commas, and a right parentheses. The
    following example shows the lexical operator syntax:

       .print "%EDIT(<Fred>,<upcase>)"

    Spaces are allowed between syntax elements in the general lexical
    operator syntax. For example, the following syntax, including
    spaces, is allowed:

    .print "%EDIT ( <Fred> , <upcase> )"

    Spaces are also allowed between the opening and closing percent
    signs in a lexical substitution operator.

    .print "% lexical_symbol_name %"

    Spaces are not allowed between the pair of percent signs
    indicating a lexical escape operator.

    You can specify lexical operator arguments in the same way as
    macro arguments:

    o  A numeric symbol name preceded by a backslash (\). This
       construct results in the decimal value of the numeric symbol,
       as shown in the following example:

          \N

    o  Any string of characters surrounded by left- and right-angle
       brackets, as shown in the following example:

       <Foo bar thud>

       You can nest angle brackets (<>).  For example:

       <<X+7>*17>

    o  Any string of characters surrounded by a delimiter specified
       after a caret character (^). You cannot nest delimiters. For
       example:

       ^%Foo bar thud%

    o  Any undelimited string of characters not separated by a space,
       tab, form feed, comma, equal sign, semicolon, or end of line.
       For example:

       A+B+C

    In addition to the formats allowed for a macro argument, you can
    also specify lexical operator arguments as follows:

    o  An undelimited string of characters may also contain a string
       of characters enclosed within left and right parentheses. The
       characters between the left and right parentheses may contain
       space, tab, or comma delimiters. For example:

       16( R27 )

    o  You can use a lexical operator as an argument to another
       lexical operator. For example:

       %EXTRACT( %LOCATE($,X), %LENGTH(X) - %LOCATE($,X) ,X)

    Except for the %TYPE lexical operator, a string symbol name
    supplied as a lexical operator argument is replaced with the
    value of the string symbol.

    Each lexical operator accepts a given number of arguments and
    each argument has a specific type. There are three different
    types of arguments-string, integer, and name:

    o  A string argument can be any arbitrary sequence of characters.

    o  An integer argument must be an absolute or relocatable
       expression that can be resolved at that point in the assembly.
       A relocatable expression represents a psect and an offset
       within that psect. If you specify a relocatable expression for
       an integer argument, the assembler uses only the value of the
       offset within the psect. The offset value is determined before
       optimization and code alignment, but after data alignment.

    o  The name argument type is used only by the %TYPE lexical
       operator. The %TYPE lexical operator accepts the name of a
       numeric symbol, string symbol, label, psect, or a permanent
       symbol as its argument. Unlike the other lexical operators, if
       a string symbol name is specified as an argument to %TYPE, the
       value of the string symbol is not substituted for its name.
       Instead, information about the name is returned.

    If you omit a string argument, the default is the empty string.
    An empty string is a string with no characters. If you omit an
    integer argument or specify an illegal expression, the default
    value is 0. The assembler does not issue diagnostic messages
    for illegal expressions used as arguments to lexical operators.
    If you omit the name argument or specify an illegal name to the
    %TYPE lexical operator, %TYPE returns a 0 value.

3  –  Numeric Symbols and Lexical String Symbols

    Lexical string symbols are similar in concept and syntax to
    numeric symbols. MACRO-64 supports numeric symbols using the
    following syntax:

    numeric_symbol_name = numeric_expression

    MACRO-64 supports lexical string symbols using the following
    syntax:

    string_symbol_name = "any string of characters"

    The assembler differentiates between numeric symbol assignment
    and lexical string symbol assignment as follows:

    o  In a lexical string symbol assignment, a quoted string literal
       must appear after the equal sign.

    o  A lexical string symbol value is specified by the quoted
       string literal.

    The quotes are not included in the value of the lexical string
    symbol. You cannot use the same name for a lexical string symbol,
    numeric symbol, or label.

    Like numeric symbols, lexical string symbols are assembly time
    variables. After you assign a string value to a lexical string
    symbol, you can reassign a different value to that symbol later
    in the assembly.

    You can use lexical string symbols as arguments to lexical
    operators. In particular, you can use a lexical string symbol
    as an argument to the lexical substitution operator (%)  or the
    %STRING lexical operator to substitute the value of the lexical
    string symbol at any point in the text of your program.

4  –  Lexical Substitution Operator

    You can use the lexical substitution operator at any point in
    your program to cause the assembler to substitute the value of
    a lexical string symbol for the name of the symbol. The lexical
    substitution operator is the percent sign (%). Place the lexical
    substitution operator to the left and right of the name of the
    lexical string symbol that you wish to subsitute, as follows:

    %lexsym_name%

    For example:

         HORSES    = "All the king's horses"
         MEN       = "all the king's men"
         .print "%HORSES% and %MEN%"

    This example defines two lexical string symbols: HORSES and MEN.
    The third statement displays a message at assembly time. The text
    of the message specifies that the value of the HORSES and MEN
    lexical string symbols be substituted as indicated. After lexical
    processing, the third statement appears as:

         .print "All the king's horses and all the king's men"

5  –  Lexical Escape Operator

    It is possible to defer the processing of a lexical string
    operator by using the lexical escape operator, which is the
    percent sign (%).  Since all lexical string operators begin with
    a percent sign, the effect of placing two percent signs before
    the name of the lexical string operator defers the evaluation of
    the lexical string operator. If you want to defer processing of
    a lexical substitution operator, place two percent signs to the
    left and two percent signs to the right of the lexical string
    symbol name.

    This can be useful when you want the evaluation of a lexical
    string operator that you have used in a default macro argument
    to occur during macro expansion, rather than during macro
    definition. Lexical operator processing is suppressed during
    macro registration. Therefore, lexical operator processing is
    automatically deferred within the body of a macro. However, the
    .MACRO directive line that begins the macro definition is subject
    to normal lexical operator processing. Sometimes you may need
    to use the value of a lexical string symbol as the default for
    a macro argument, but you need to use the value of the lexical
    string symbol that is current when the macro expands, not when
    the macro is defined. Lexical Processing Without the Escape
    Operator shows an example of this, but it does not use an escape
    operator.

    Example 1  Lexical Processing Without the Escape Operator

        CODE_PSECT_NAME = "CODE1"
        .MACRO CODE_PSECT PSECT_NAME=%string(CODE_PSECT_NAME)
         .PSECT PSECT_NAME
        .ENDM CODE_PSECT
        CODE_PSECT
        CODE_PSECT_NAME = "CODE2"
        CODE_PSECT

    Lexical Processing Without the Escape Operator does not process
    correctly for the following reasons:

    o  The lexical operator in the .MACRO directive line is processed
       when the macro is defined, not when the macro expands.

    o  The CODE_PSECT macro always defaults to setting the psect
       to the CODE1 psect because the default for the PSECT_NAME
       argument will be set to CODE1, not %string(CODE_PSECT_NAME).
       This is because %string(CODE_PSECT_NAME) is evaluated when the
       CODE_PSECT macro is defined, not when it expands.

    Lexical Processing with Escape Operator is similar to Lexical
    Processing Without the Escape Operator except it uses the lexical
    escape operator.

    Example 2  Lexical Processing with Escape Operator

        CODE_PSECT_NAME = "CODE1"
        .macro CODE_PSECT PSECT_NAME=%%string(CODE_PSECT_NAME)
       .psect PSECT_NAME
        .endm CODE_PSECT
        CODE_PSECT
        CODE_PSECT_NAME = "CODE2"
        CODE_PSECT

    Lexical Processing with Escape Operator processes correctly for
    the following reasons:

    o  Lexical operator processing of %%string(CODE_PSECT_NAME)
       is deferred when the CODE_PSECT macro is defined. The
       default value for the PSECT_NAME argument is stored as
       %string(CODE_PSECT_NAME).

    o  During macro expansion, %string(CODE_PSECT_NAME) is evaluated,
       which results in the current value of the CODE_PSECT_NAME
       lexical string symbol as desired.

6  –  %EDIT

    Lexical operator for editing text strings.

    Format

      %EDIT  (string1,string2)

6.1  –  Arguments

 string1

    The first argument, of type string, specifies the string to be
    edited.

 string2

    The second argument, of type string, specifies a list of edits to
    perform, which are separated by commas.

6.2  –  Description

    %EDIT is modeled after the OpenVMS DCL lexical function F$EDIT.
    It is used to perform one or more edits on a specified string.
    %EDIT processes the string of arguments from left to right. %EDIT
    gives precedence to the last argument. %EDIT gives precedence to
    uppercase over lowercase.

    The list of edits may contain any combination of the following
    elements:

    Element    Function

    COLLAPSE   Removes all tabs and spaces.
    COMPRESS   Replaces multiple, consecutive tabs or spaces with a
               single space.
    LOWERCASE  Changes uppercase characters to lowercase.
    TRIM       Removes leading and trailing spaces and tabs.
    UPCASE     Changes lowercase characters to uppercase.

6.3  –  Examples

      Example 1
             .PRINT "%EDIT(< Fred Smith >, <TRIM,COLLAPSE,UPCASE>)"

      After lexical processing, the statement apears as the
      following:

             .PRINT "FREDSMITH"
      Example 2
             .PRINT "%EDIT(<AbCdEfG>,<upcase,lowercase>)
             .PRINT "%EDIT(<AbCdEfG>,<lowercase,upcase>)

      The first source statement produces the string "abcdefg" and
      the second source statement produces the string "ABCDEFG". Each
      of the edits in the edit list is performed in sequence, from
      left to right.

7  –  %ELEMENT

    Lexical operator for extracting elements from a list of elements.

    Format

      %ELEMENT  (integer,string1,string2)

7.1  –  Arguments

 integer

    The first argument, of type integer, is the element number to
    extract. The first element is number 0.

 string1

    The second argument, of type string, is the delimiter or
    delimiters that separate elements.

 string2

    The third argument, of type string, is the list of elements.

7.2  –  Description

    %ELEMENT is modeled after the OpenVMS DCL lexical function
    F$ELEMENT. It is used to extract one element from a string of
    elements. Note that unlike F$ELEMENT, you may specify multiple
    delimiters. The result is the specified string element. If the
    specified element number is greater than the number of elements
    in the list, the delimiter argument is returned.

7.3  –  Example

             .PRINT "%ELEMENT (2, <+-*/>, JOE+FRED-TOM*BILL/ERIC)"

      After lexical processing, the statement appears as:

             .PRINT "TOM"

8  –  %EXTRACT

    Lexical operator for extracting a range of characters from a
    string of characters.

    Format

      %EXTRACT  (integer1,integer2,string)

8.1  –  Arguments

 integer1

    The first argument, of type integer, is the offset at which to
    begin the extraction. The first character is at offset 0.

 integer2

    The second argument, of type integer, is the number of characters
    to extract.

 string

    The third argument, of type string, is the string from which to
    extract the characters.

8.2  –  Description

    %EXTRACT is modeled after VAX MACRO's %EXTRACT macro string
    operator and the OpenVMS DCL lexical function F$EXTRACT. %EXTRACT
    is used to extract a specified range of characters from a string.

8.3  –  Example

             .PRINT "%EXTRACT(3,4,ABCDEFGHIJKLMNOP)"

      After lexical processing, the statement appears as:

             .PRINT "DEFG"

9  –  %FREG

    Lexical operator for obtaining the floating-point register number
    associated with a symbol.

    Format

      %FREG  (symbol)

9.1  –  Argument

 symbol

    The single argument, of type string, specifies a symbol that
    may or may not be currently defined as a floating-point register
    symbol.

9.2  –  Description

    %FREG returns the decimal number of the floating-point register
    when the specified symbol is defined as a floating-point register
    symbol. Otherwise, %FREG returns 32.

9.3  –  Example

            ; Is TARG_REG the same as F31?
            .IF EQ, <%FREG(TARG_REG)>, <%FREG(31)>

      If TARG_REG has been defined as floating-point register F5, the
      statements appear as follows after lexical processing:

            ; Is TARG_REG the same as F31?
            .IF EQ, <5>, <31>

10  –  %INTEGER

    Lexical operator for converting the value of an expression to a
    decimal value.

    Format

      %INTEGER  (integer)

10.1  –  Argument

 integer

    The single argument, of type integer, is the expression to be
    converted.

10.2  –  Description

    %INTEGER is modeled after the OpenVMS DCL lexical function
    F$INTEGER. It is used to convert the value of an expression to
    a decimal value. The result is its decimal value. You can also
    use %INTEGER to convert a relocatable expression to an absolute
    value.

10.3  –  Example

             .PRINT "%INTEGER (<<X+7>*17>)"

      After lexical processing, if X has the value 3, the statement
      will appear as:

             .PRINT "170"

11  –  %IREG

    Lexical operator for obtaining the integer register number
    associated with a symbol.

    Format

      %IREG  (symbol)

11.1  –  Argument

 symbol

    The single argument, of type string, specifies a symbol that may
    or may not be currently defined as an integer register symbol.

11.2  –  Description

    %IREG returns the decimal number of the integer register when
    the specified symbol is defined as an integer register symbol.
    Otherwise, %IREG returns 32.

11.3  –  Example

            ; Is SRC_REG the same as SP?
            .IF EQ, <%IREG(SRC_REG)>, <%IREG(SP)>

      If SRC_REG has been defined as integer register R16, the
      statements appear as follows after lexical processing:

            ; Is SRC_REG the same as SP?
            .IF EQ, <16>, <30>

12  –  %LENGTH

    Lexical operator for determining the length of a string.

    Format

      %LENGTH  (string)

12.1  –  Argument

 string

    The single argument, of type string, is the string from which the
    length is to be computed.

12.2  –  Description

    %LENGTH is modeled after VAX MACRO's %LENGTH macro string
    operator and the OpenVMS DCL lexical function F$LENGTH. %LENGTH
    is used to determine the length of a string. The result is the
    length of the string expressed as a decimal number.

12.3  –  Example

             .PRINT "%LENGTH(<The quick brown fox>)"

      After lexical processing, the statement appears as:

             .PRINT "19"

13  –  %LOCATE

    Lexical operator for locating a string of text within another
    string of text.

    Format

      %LOCATE  (string1,string2)

13.1  –  Arguments

 string1

    The first argument, of type string, is the string for which
    %LOCATE searches.

 string2

    The second argument, of type string, is the string in which the
    search is performed.

13.2  –  Description

    %LOCATE is modeled after VAX MACRO's %LOCATE macro string
    operator and the OpenVMS DCL lexical function F$LOCATE. %LOCATE
    is used to locate one string within another. The value returned
    is the decimal offset to the first occurrence of the first string
    within the second string. The offset to the first character is 0.
    If the first string cannot be found within the second string, the
    length of the second string is returned.

13.3  –  Example

             .PRINT "%LOCATE (DEF,ABCDEFGHIJKLMNOP)"

      After lexical processing, the statement appears as:

             .PRINT "3"

14  –  %REPEAT

    Lexical operator for repeating a specified string a specified
    number of times.

    Format

      %REPEAT  (integer,string)

14.1  –  Arguments

 integer

    The first argument, of type integer, is the number of times to
    repeat the string. If you specify a negative value, the string is
    repeated 0 times.

 string

    The second argument, of type string, is the string to be
    repeated.

14.2  –  Description

    %REPEAT is used to repeat the specified string a specified number
    of times.

14.3  –  Example

             .PRINT "Never, %REPEAT (3, <ever, >)touch that button!"

      After lexical processing, the statement appears as:

             .PRINT "Never, ever, ever, ever, touch that button!"

15  –  %STRING

    Lexical operator for obtaining the value of a lexical string
    symbol.

    Format

      %STRING  (string)

15.1  –  Argument

 string

    The single argument is of type string. If the argument is the
    name of the lexical string symbol, the value of the lexical
    string symbol is returned. Otherwise, the argument is returned
    unchanged.

15.2  –  Description

    %STRING is modeled after the OpenVMS DCL lexical function
    F$STRING. %STRING is generally used to obtain the value of
    a lexical string symbol, but you can use it with any string
    argument.

15.3  –  Example

             FOO = "All the king's horses"
             .PRINT "%STRING(FOO)"

      After lexical processing, the statement appears as:

             .PRINT "All the king's horses"

16  –  %TIME

    Lexical operator for obtaining the date and time of the assembly
    unit.

    Format

      %TIME  ()

16.1  –  Description

    %TIME is modeled after the OpenVMS DCL lexical function F$TIME.
    %TIME is used to obtain the time and date of the assembly unit.
    There are no arguments. The result is a string specifying the
    date and time of the assembly unit.

16.2  –  Example

             .PRINT "%TIME()"

      After lexical processing, the statement appears as:

             .PRINT " 8-OCT-1991 13:17:57"

17  –  %TYPE

    Lexical operator for obtaining information about a name.

    Format

      %TYPE  (name)

17.1  –  Argument

 name

    The single argument is of type name. Information is returned
    about the name specified in the argument.

17.2  –  Description

    %TYPE is modeled after the OpenVMS DCL lexical function
    F$TYPE. %TYPE is used to obtain information about a name. The
    value returned is a numeric value with certain bit positions,
    either 0 or 1, depending on whether the specified name has the
    corresponding attribute. As described elsewhere, the decimal
    digits of the numeric value are substituted for the %TYPE lexical
    operator. %TYPE Attributes shows the symbolic names that are
    predefined for each attribute.

    Table 5 %TYPE Attributes

    Symbolic Name          Attribute

    MACRO64$TYPE_SYMBOL    Name is a numeric symbol name.
    MACRO64$TYPE_PROC_     Name is a procedure descriptor name.
    DESC
    MACRO64$TYPE_LABEL     Name is a label.
    MACRO64$TYPE_EXTERN    Name is an external name.
    MACRO64$TYPE_WEAK      Name is a weak name.
    MACRO64$TYPE_PSECT     Name is a psect.
    MACRO64$TYPE_MACRO     Name is a macro name.
    MACRO64$TYPE_STRING    Name is a lexical string symbol name.
    MACRO64$TYPE_OPCODE    Name is an opcode.
    MACRO64$TYPE_DIR       Name is a directive.
    MACRO64$TYPE_GENREG    Name is a general register.
    MACRO64$TYPE_FLTREG    Name is a floating register.

    A given name may have zero, one, or several attributes.

17.3  –  Example

             .macro IS_GR ARG
               .IF equal, %TYPE(ARG) & <MACRO64$TYPE_GENREG>
                .PRINT "ARG is not a general register"
               .ENDC
             .endm IS_GR
             IS_GR F11

      Initially, the first line of the IS_GR macro expands as the
      following:

             .IF equal, <%TYPE(F11) & MACRO64$TYPE_GENREG>

      After lexical processing, the statement appears as:

             .IF equal, <8192 & MACRO64$TYPE_GENREG>

      In this example, 8192 is the attribute value for a floating-
      point register. This value could change in subsequent releases.
      Use only the predefined attribute masks described in %TYPE
      Attributes. Since the attribute for a general register
      MACRO64$TYPE_GENREG is 4096, the expression evaluates as 0.

             <8192 & MACRO64$TYPE_GENREG>
Close Help