The DO command makes an entry in the GT.M invocation stack and transfers execution to the location specified by the entryref.

The format of the DO command is:

D[O][:tvexpr] [entryref[(expr|.lvn[,...])][:tvexpr][,...]]
  • The optional truth-valued expression immediately following the command is a command postconditional that controls whether or not GT.M executes the command.

  • The optional entryref specifies a location (with some combination of label, offset, and routinename) at which execution continues immediately following the DO.

  • A DO command without an argument (that is, a DO followed by two (2) spaces) transfers execution to the next line in the routine if that line contains an appropriate number of periods (.) after the optional label and before the required linestart. These periods indicate the current level of "immediate" nesting caused by argumentless DOs. If the line following the DO contains too many periods, GT.M reports an error; if the line following the DO contains too few periods, GT.M ignores the DO command.

  • A DO command without an argument stacks the current value of $TEST, in contrast to a DO with an argument, which does not protect the current value of $TEST.

  • The optional parameter list enclosed in parentheses ( ) contains parameters to pass to the routine entry point.

  • Label invocations using DO do not require parentheses for calls with no actuallist. If DO or a $$ that does not specify an actuallist invokes a label with a formallist, the missing parameters are undefined in the called routine.

    [Caution]Warning

    If DO or $$ specifies a routine but no label using an actuallist, then whether that routine's top label has a formallist or not, the actuallist applies to it directly, whereas before the actuallist would "fall through" to the first label with executable code.

  • If the DO specifies a parameter list, the entryref location must start with a label and an argument list (M prohibits entryrefs with offsets during parameter passing).

  • If an element in the parameter list starts with a period, it specifies an unsubscripted local variable name and the DO passes that variable by reference. Otherwise, the element specifies an expression that the DO evaluates and passes as a value.

  • The optional truth-valued expression following the parameter list, or the entryref if the argument contains no parameter list, specifies the argument postconditional and controls whether GT.M performs a DO using that argument.

  • An indirection operator and an expression atom evaluating to a list of one or more DO arguments form a legal argument for a DO.

An explicit or implicit QUIT within the scope of the DO, but not within the scope of any other DO, FOR, XECUTE, or extrinsic, returns execution to the instruction following the calling point. This point may be the next DO argument or another command. At the end of a routine, or the end of a nesting level created by an argumentless DO, GT.M performs an implicit QUIT. Any line that reduces the current level of nesting by changing the number of leading periods (.) causes an implicit QUIT, even if that line only contains a comment. Terminating the image and execution of ZGOTO commands are the only ways to avoid eventually returning execution to the calling point.

A DO command may optionally pass parameters to the invoked subroutine. For more information about entryrefs and parameter passing, refer to Chapter 5: “General Language Features of M.

Example:

GTM>DO ^%RD

This example invokes the routine directory utility program (%RD) from Direct Mode. The caret symbol (^) specifies that the DO command invokes %RD as an external routine.

Example:

GTM>DO A(3)

This example invokes the subroutine at label A and passes the value 3 as a parameter. The DO argument does not have a caret symbol (^), therefore, it identifies A as a label in the current routine.

Example:

ReportA ; Label for ReportA
        SET di="" OPEN outfile USE outfile 
        FOR  SET di=$ORDER(^div(di)) QUIT:di=""  DO PREP DO  DO POST
        .SET de="",(nr,gr)=0
        .WRITE "Division ",di,! F   S de=$ORDER(^de(di,de)) QUIT:de=""   DO
        ..WRITE "Department ",de," Gross Rev: ",^grev(di,de),!
        ..WRITE "Department ",de," Net Rev: ",^nrev(di,de),!
        ..SET gr=gr+^grev(di,de),nr=nr+^nrev(di,de)
        .W "Division Gross Rev: ",gr,!,"Division Net Rev: ",nr,!
         DO PRINT^OUTPUT(outfile)
         QUIT

This routine first uses a DO with a label argument (PREP) to do some pre-processing. Then, it uses an argumentless DO to loop through each division of a company to format a report. Within the first argumentless DO, a second argumentless DO (line 4) loops through and formats each department within a division. After the processing of all departments, control returns to the first argumentless DO, which prints a summary of the division. Following processing of all divisions, a DO with a label argument (POST) does some post-processing. Finally, at the next-to-last line, the routine uses a DO that invokes a subroutine at a label (PRINT) in an external routine (^OUTPUT), passing the name of the output file (outfile) as a parameter.

Example:

GTM>zprint ^SQR
SQR(z);
  set revert=0
  if $view("undef") set revert=1 view "noundef"
  if z="" write "Missing parameter.",!     view:revert "undef" quit
  else  write z*z,! view:revert "undef" quit  
GTM>do ^SQR(10)
100
GTM>do ^SQR
Missing parameter.

This examples demonstrates label invocations using DO with and without parentheses.

loading table of contents...