HPlogo System Debug Reference Manual > Chapter 6 System Debug Command Specifications M-X

MAC[RO]

MPE documents

Complete PDF
Table of Contents
Index

E0201 Edition 4 ♥
E0300 Edition 3
E0692 Edition 3

Defines a macro.

Syntax



   MAC[RO] name {body}
   MAC[RO] name [ (parameters) ] {body}
   MAC[RO] name [ (parameters) ] [options] {body}

Macros are a body of commands that are executed (invoked) by name. Macros can have optional parameters.

Macros can be executed as if they were commands.

Macros can also be invoked as functions within expressions to return a value.

Macro definitions can include three special options in order to specify a version number (MACVER), a help string (MACHELP), and a keyword string (MACKEY). See the MACLIST command.

Reference counts are maintained for macros. Each time a macro is invoked, the reference count for the macro is incremental. (Refer to the MACREF and MACLIST commands.)

Two special commands are provided to assist with the debugging and support of macros. See the MACECHO and MACTRACE commands.

The entire set of currently defined macros can be saved into a binary file for later restoration. (Refer to the STORE and RESTORE commands.)

Parameters


name

The name of the macro that is being defined. Names must begin with an alphabetic character and are restricted to thirty-two (32) characters, that must be alphanumeric, or "_", or " ' ", or "$". Longer names are truncated (with a warning). Names are case insensitive.

All macros are functions that can be used as operands within expressions to return a single value of a specified type.

A default macro return value can optionally be specified directly following the macro name. The return_type must be preceded by a colon. The default return_value must be preceded by an equal sign, and can be entered as an expression. Below is a syntax of a macro call, followed by examples:


   macro name [:return_type] [= return_value]

For example:

   macro getnextptr:s16 = -1            {body}
   macro tblname = "UNDEF"              {body}
   macro tblsize:u32 = max * entrylen   {body}
   macro fmtstring:str                  {body}

If the default macro return_value is not specified, one is assigned automatically, based on the type of the macro. The following table lists the default return_values that are based on the macro's return_type:

Macro Return Type

Default Return Value

BOOL

FALSE

U16, S16, U32, S32, SPTR

0

LPTR

0.0

CPTR class

0.0 (based on type)

STR

' ' (null string)

By default, a macro is assigned the return value of 0 as a signed 32-bit number.

( parameters )

Macros can optionally have a maximum of five declared parameters. Parameter definitions are declared within parentheses, separated by blanks or commas.


   ( parm1def parm2def, parm3def, parm4def parm5def )

Parameter names have the same restrictions as macro names. Names must begin with an alphabetic character and are restricted to thirty-two (32) characters, that must be alphanumeric, or an underscore (_), a single quotation (`or'), or a dollar sign ($). Longer names are truncated (with a warning). Names are case insensitive.

Each parameter definition can include an optional parmtype declaration that must follow after a colon. In addition, a default initial value for the parameter can optionally be specified, preceded by an equal sign. The initial value can be an expression. Below is a syntax of a parameter description, followed by examples:


   ( parmname1 [:parmtype1] [=parm_default_value1], ..

   ( addr:sptr=c000104c, len=0, count=20 )
   ( p1:u32=$100, p2=40-!count  p3:str="totals")

When a macro is invoked, a local variable is declared for each parameter, just as if the following command(s) had been entered:

   LOC parmname1 :type1= default1
   LOC parmname2 :type2= default2  ... etc.

Parameters are referenced within the macro body in the same manner that local variables are referenced. The parameter name can be preceded by an optional exclamation mark (!) to avoid ambiguity.

When execution of the macro body is completed, the local variables declared for the parameters are automatically deleted.

{body}

The macro body is a single command, or a list of commands, entered between curly braces. Multiple commands must be separated by semicolons. The commands in this body are executed whenever the macro is invoked. For example:


                   { CMD }
   { CMD1; CMD2; CMD3; .. CMDn }

Unterminated command lists, introduced by the left curly brace, can span multiple lines without the use of the continuation character (&) between lines. Additional command lines are automatically digested as part of the cmdlist until the closing right brace is detected.

   { CMD1;
     CMD2;
     CMD3;
         ...
     CMDn }

The RETURN command is used within the macro body to return a specified value and to exit the macro immediately. If a RETURN command is not supplied within the macro body, the macro exits when all commands have been executed, and the default return value is used.

options

Special macro options can be specified following the parameter declarations that precede the macro body. Any number of these options can be specified in any order. Each option is specified as a keyword, followed by a (case sensitive) string value:

  • MACVER = version_string

  • MACKEY = keyword_string

  • MACHELP = help_string

The following are typical valid declarations for macro options:
  • MACVER = 'A.00.01'

  • MACKEY = "PROCESS PIN PARENT"

  • MACHELP = "Returns the pin number of the parent process"

By default, the null string (' ') is assigned for unspecified options.

Examples



   $nmdat > macro showtime {wl 'The current time is: ' time}
   $nmdat > showtime
   The current time is:  2:14 PM

This example demonstrates a simple macro that executes a single command. The new macro, named showtime, is defined and then executed as if it were a command. The macro body, in this case a simple write command, is executed, and the current time is displayed. This macro has no parameters.

   $nmdat > macro starline (num:u16=#20) {
   {$1} multi > while num > 0 do {
   {$2} multi >   w '*';
   {$2} multi >   loc num num -1 };
   {$1} multi > wl }

   $nmdat > starline (5)
   *****

   $nmdat > starline (#60)|
   ************************************************************

   $nmdat > starline
   ********************

   $nmdat > starline (-3)
   Parameter type incompatibility.  (error #4235)
     expected the parameter "num:U16"  for "starline"
     starline (-3)
                 ^
    Error during macro evaluation.  (error #2115)

This example defines a macro named starline that prints a line of stars. The number of stars is based on the macro parameter num that is typed (unsigned 16-bit), and has a default value of decimal twenty.

The macro is entered interactively across several lines. The unterminated left curly brace causes the interpreter to enter multi-line mode. The prompt changes to indicate that the interpreter is waiting for additional input. The nesting level, or depth of unterminated curly braces, is displayed as part of the prompt.

The macro starline is called with the parameter 5, and a line of five stars is printed. The macro is called again to print a line with sixty stars. In the third invocation no parameter value is specified, so the default value of twenty stars is used.

The fourth and final call displays the parameter type checking, which is performed for typed macro parameters. In this example a negative number of stars are requested, and the interpreter indicates that the parameter is invalid.

   $nmdat > mac fancytime {starline(#30); showtime; starline(#30)}
   $nmdat > fancytime
   ******************************
   The current time is:  2:17 PM
   ******************************

In this example a new macro named fancytime is defined. This new macro calls the two previously defined macros in order to produce a fancy display of the time.

Macros can include calls to other macros. The contents of macro bodies are not inspected when macros are defined. Therefore one macro can include a call to another macro before it is defined.

   %nmdebug > mac printsum (p1,p2=0) {wl "the sum is " p1+p2}
   %nmdebug > printsum (1 2)
   the sum is $3
   %nmdebug > printsum 3 4
   the sum is $7
   %nmdebug > printsum 5
   the sum is $5

Defines macro printsum that prints the sum of the two parameters p1 and p2. Note how the parameters are referenced as simple local variables within the macro body. When a macro is used as a command, parentheses around parameters are optional. Also note how the default value (0) is used for the omitted optional parameter p2.

   %cmdebug > mac is (p1="DEBUG",p2:str="GNARLY") {wl p1 "is very" p2.}
   %cmdebug > is ("MPE" 'mysterious')
   MPE is very mysterious.
   %cmdebug > is ("mpe")
   mpe is very GNARLY.
   %cmdebug > is
   DEBUG is very GNARLY.

These examples demonstrate simple typed parameters with default values. The default values are used whenever optional parameters are omitted.

   %nmdat > mac double (p1) { return p1*2 }
   %nmdat > wl double(2)
   $4
   %nmdat > wl double(1+2)+1
   $7

Defines macro double as a function with one parameter p1. The RETURN command is used to return the functional result of twice the input parameter. Note how the macro is used as a function, as an operand in an expression.

   %nmdat > mac triple (p1:INT) { return p1*3 }
   %nmdat > wl triple(2)
   $6
   %nmdat > wl triple (double (1+2))
   $12

Macro function triple is similar to macro function double defined above. Note that macros (used as functions) can be nested within expressions.

   $nmdebug > { macro factorial=1 (n)
   {$1} multi >  machelp = 'Returns the factorial for parameter "n"'
   {$1} multi >  mackey  = 'FACTORIAL UTILITY ARITH TEST'
   {$1} multi >  macver = 'A.01.00'
   {$1} multi >  { if n <= 0
   {$2} multi >    then return
   {$2} multi >    else if n > 10
   {$2} multi >         then { wl "TOO BIG"; return}
   {$2} multi >         else return n * factorial(n-1)
   {$2} multi >  }
   {$1} multi > }

   $nmdebug > wl factorial(0)
   $1
   $nmdebug > wl factorial(1)
   $1
   $nmdebug > wl factorial(2)
   $2
   $nmdebug > wl factorial(3)
   $6
   $nmdebug > wl factorial(123)
   TOO BIG
   $1

This example defines a macro function named factorial that has a default return value of 1. A help string, keyword string, and version string are included in the macro definition.

Note that the macro definition was preceded by a left curly brace in order to enter multi-line mode. This allowed the options to be specified on separate lines, before the left curly brace for the macro body.

This macro calls itself recursively, but protects against runaway recursion by testing the input parameter against an upper limit of ten.

Discussion - Macro Parameters


Assume that the following macro is defined.

   $nmdat > { macro double( num=$123, loud=TRUE)
   {$1} multi > { if loud
   {$2} multi >   then wl 'the double of ', num, ' = ', num*2;
   {$2} multi >   return num*2}
   {$1} multi > }
   $nmdat >

This macro has two optional parameters: num that defaults to the value 123, and loud that defaults to TRUE.

The macro is written in a manner that allows it to be invoked as a function to return a value that is the double of the input parameter. The second parameter controls the display of an output line, and therefore this macro might also be used as a command to calculate a value and display the result. When invoked as a command, the returned value is simply ignored.

The following examples illustrate the rules governing the specification of macro parameters for macros invoked as functions and for macros invoked as commands.

Macro Functions


For macros invoked as a function, parameters must be specified within parentheses as a parameter list. The same convention applies to parameters passed to any of the System Debug standard functions. Optional parameters can be implicitly omitted if a comma is used as a parameter place holder. When all parameters are optional and are to be omitted, the parentheses around the empty parameter list can be omitted.

   $nmdat > wl double(1,false)
   $2

   $nmdat > wl double(,false)
   $246

   $nmdat > wl double ()
   the double of $123 = $246
   $246

   $nmdat > wl double
   the double of $123 = $246
   $246

Macro Commands


For macros invoked as commands, parameter(s) can be specified without parentheses, in the same manner that System Debug commands are normally used.

Unlike normal System Debug commands, however, parentheses can be used to surround a parameter list for a macro command. If the first parameter to a macro command requires a parenthesized expression, an ambiguity arises. In this case, parentheses should be used around the entire parameter list.

Just as with macro functions, optional parameters can be implicitly omitted if a comma is used as a parameter place holder.

   $nmdat > double 1
   the double of $1 = $2

   $nmdat > double (2)
   the double of $2 = $4

   $nmdat > double 3 true
   the double of $3 = $6

   $nmdat > double ( (1+2)*3 )
   the double of $9 = $12

   $nmdat > double
   the double of $123 = $246

   $nmdat > double 6,false
   $nmdat >

Limitations, Restrictions


Refer to ENV MACROS and ENV MACROS_LIMIT. These environment variables determine the number of macros that can be created.

Current limit of 32 characters in a macro name or macro parameter name.

Current limit of five parameters per macro.

Macro parameters are passed by value. Parameter values are not changed.

The total length of an entire macro definition is limited by the maximum supported string length, that is currently 2048 characters. See the STRMAX function.

The System Debug interpreter maintains an internal command stack for general command execution, including the execution of macros. The command stack is large enough to support the useful nesting of macros, including simple recursive macros. Command stack overflow is possible, however, and when detected, results in an error message and the immediate termination of the current command line execution. Following command stack overflow, the stack is reset, the prompt is displayed, and normal command line interpretation resumes.




M (modify)


MACD[EL]