Introduced in the 1977 ANSI M[UMPS] language standard.
DO LABEL
DO LABEL+OFFSET
Note that use of the LABEL+OFFSET syntax may have
unintended ramifications when lines of code are inserted between
the line with the LABEL and the line that was indicated
by LINE+OFFSET before the insertion.
DO ^PROGRAM
DO LABEL^PROGRAM
DO LABEL+OFFSET^PROGRAM
DO @ARGUMENT
DO @INDLABEL^PROGRAM
DO @INDLABEL^@INDPROG
Note: a reference like +OFFSET^ROUTINE is acceptable as a parameter for $TEXT, but not as an argument for the commands DO and GOTO.
The 1990 M[UMPS] language standard added:
DO LABEL(actuallist)
DO @INDLABEL(actuallist)
DO @X(A)
Does not do parameter passing. Uses indirect array element.
DO @X(.A)
Does parameter passing.
DO @X(B)(A)
Does routine indirect X(B) passing the value of
A.
DO @X^@Y
Does label @X in routine @Y.
DO @X^@Y(A)
Does label @X in routine @Y(A).
DO @X^@Y(.A)
Does label @X in routine @Y passing A
by reference.
DO @X^@Y(B)(A)
Does label @X in routine @Y(B) passing the
value of A.
An offset is an integer expression. This means that the following
three invocations all address the same entry point:
DO A+1^B
DO A+1.5^B
DO A+1.9999999999^B
Assume that the following label exists
SUB(A,B) ;
The subroutine call DO SUB(12) will have the result that, within the subroutine, the formal parameter B will initially be undefined (i.e. $DATA(B) = 0).
The subroutine call DO SUB(1,2,43) will cause an error, because there is no matching formal parameter for the actual parameter 43.
Assume that a M[UMPS] routine contains the command
Assume that a M[UMPS] routine contains the command
SET VA=1 DO
. DO SUB
. QUIT
WRITE VA
QUIT
;
SUB SET VA=2
QUIT
The value 2 will be written. While the command DO
SUB occurs at a line with level 2, the DO
command invokes a new block of code, which happens to start at
level 1; there is no implicit QUIT command because
the line at label SUB is of a lower level than
the line containing the DO command. Within an 'indented
block', subroutines may be called, even if they reside in other
routines.
SET EXP2=0
IF EXP1 DO
. WRITE !,"First: ",$TEST
. IF EXP2
. WRITE !,"Second: ",$TEST
. WRITE !,"Today is ",$$DAY,"."
. QUIT
WRITE !,"Third: ",$TEST
QUIT
;
DAY() NEW DAYS
SET DAYS="Thurs Fri Satur Sun Mon Tues Wednes"
QUIT $PIECE(DAYS," ",$HOROLOG#7+1)_"day"
If local variable EXP1 is false, this example
will write:
Third: 0
If local variable EXP1 is true, this example will
write:
First: 1
Second: 0
Today is xxxxxday.
Third: 1
The value of $TEST is stacked within the argumentless
DO command, and reset to its original value when control
returns back from the indented block to the next higher
level.
SET A="President"
DO SUB1(.A)
WRITE !,A
QUIT
;
SUB1(B) KILL B
SET B="Prime minister"
QUIT
Local variable A is passed by reference to
subroutine SUB1. Even though the value of the variable
is removed by means of the KILL command, the 'by
reference' link remains in effect. Thus, when the value
"Prime minister" is assigned to parameter variable
B, it is actually assigned to local variable A,
which means that the value "Prime minister" will be
written.
SET SUM=$$ADD(A,A)
SET WHICH=$$WHICH(12,34)
QUIT
ADD(P,Q) QUIT P+Q
WHICH(Z,Z) WRITE Z
 SET RESULT=Z
QUIT RESULT
While it makes perfect sense to pass the same value multiple
times as an actual parameter, it is considered to be erroneous to
have multiple formal parameters with the same name.
While the 1990 ANSI M[UMPS] language standard does not specify any behavior in such a case, the 1995 ANSI M[UMPS] language standard specifies that multiple occurrences of the same name in a formal parameter list is an error.
If an implementation does not return an error (pre-1995
implementation), it is to be expected that the value 34
(because the parameterlist is scanned left-to-right, the
rightmost occurrence of the name wins) will be written.
SET Y="President"
DO WHICH(.Y,"Court Jester")
WRITE !,Y
QUIT
;
WHICH(Z,Z) WRITE !,Z
QUIT
In this example, the above mentioned phenomenon is taken one step
further. Although this usage is considered to be erroneous (and
post-1995 implementations will produce an error), pre-1995
implementations may allow such usage.
Within the subroutine 'the rightmost occurrence of the name
wins', and the value "Court Jester" will be displayed.
However, this is only because of the link between the parameter
variable and the values passed.
The original local variable Y is not changed in any way,
and the main routine will display the value
"President".
ELECTION SET X="Mr. Sun"
DO VOTE(.X)
WRITE X
QUIT
VOTE(Y) SET Y="Mr. Moon"
QUIT
The value "Mr. Moon" will be written. Local variable
X is passed by reference to the subroutine
VOTE, and all changes that are made to parameter
variable Y will be visible in the local variable to
which it is bound 'by reference'.
Upon return from a subroutine or function, the "NEWed" variables are reset to their original state. If such a state was "undefined", then the variable in question will no longer have any value that was assigned within a subroutine or procedure.
KILL
SET A=1,B=2 DO SUB(B,.C,D)
WRITE $DATA(A),", ",$DATA(B),", ",$DATA(C),", "
WRITE $DATA(D),", ",$DATA(E),", ",$DATA(F)
WRITE !,"B=",B,", D=",D
QUIT
SUB(A,C,F) SET A=3,B=5,C=7,D=9,F=11
QUIT
will produce:
1, 1, 1, 1, 0, 0
B=5, D=9
Note that local variable C is passed by reference, so the assignment within the subroutine is still visible after the QUIT from the subroutine, and local variable D is passed by reference, so the assignment F=11 is to a local copy within the subroutine, which disappears when the QUIT command is executed, and the assignment D=9 is to the original variable, so that this assignment will be persistent after the subroutine has completed.
Assume that a routine contains the command:
DO A+$$B^C
One might wonder how to interpret this address. Seemingly, there
are two possible interpretations:
The behavior of $TEST is different when the DO command does not have an argument:
IF A=B DO ONE
ELSE DO TWO
In this example, the code following the ELSE command will be executed:
IF A=B DO
. DO ONE
. QUIT
ELSE DO
. DO TWO
. QUIT
In this example, the code following the ELSE command will only be executed when A happens to be unequal to B. Any changes to the value of $TEST that may happen inside subroutine ONE are "undone" when control reverts to the level where the argument-less DO command was executed.
Addition in the 1995 ANSI M[UMPS] language standard:
Parameters may be omitted:
Assume that the following label occurs:
LABEL(P,Q,R,S,T,U) ; Entry in ROUTINE
Most commonly, the subroutine would be invoked using a reference like: DO LABEL^ROUTINE(A,B,C,D,E,F)
According to the 1990 ANSI M[UMPS] language standard, trailing
parameters may be omitted:
DO LABEL^ROUTINE(A,B)
causes that within the subroutine: $DATA(R)=0,
$DATA(S)=0, $DATA(T)=0 and $DATA(U)=0
The addition is that any parameter may be omitted:
DO LABEL^ROUTINE(A,B,,D,E,.F)
causes that within the subroutine: $DATA(R)=0,
$DATA(S)=1, $DATA(T)=1 and
$DATA(U)=$DATA(F)
The special variable $TEST may occur as an argument of the
NEW command.
SET T="$TEST should be "
IF REASON DO SUB1 WRITE !,T,"1:
",$TEST,"."
ELSE DO SUB2 WRITE !,T,"1:
",$TEST,"."
QUIT
SUB1 WRITE !,T,"1: ",$TEST,"."
NEW $TEST
IF 0 ; Force $TEST to a new value
QUIT
SUB2 WRITE !,T,"0: ",$TEST,"."
IF 1 ; Force $TEST to a new value
QUIT
Examples with naked references:
DO ROUTINE
SET ^ABC(1,2)="reset naked indicator"
; Naked indicator is now ^ABC(1,
DO @^(3,4)
; Naked indicator is now: ^ABC(1,3,
; Actual reference is: ^ABC(1,3,4)
DO ROUTINE(PARAMETERS)
SET ^ABC(1,2)="reset naked indicator"
; Naked indicator is now ^ABC(1,
DO ^routine(^(3,4),^(5,6))
; 1. fetch ^(3,4) = ^ABC(1,3,4)
; 2. fetch ^(5,6) = ^ABC(1,3,5,6)
; Naked indicator is now: ^ABC(1,3,5,
This document is © Ed de Moel, 1995-2005.
It is part of a book by Ed de Moel that is published under
the title "M[UMPS] by Example" (ISBN 0-918118-42-5).
Printed copies of the book are no longer available.
This document describes the various commands that are defined in the M[UMPS] language standard (ANSI X11.1, ISO 11756).
The information in this document is NOT authoritative
and subject to be modified at any moment.
Please consult the appropriate (draft) language standard for an
authoritative definition.
In this document, information is included that will
appear in
future standards.
The MDC cannot guarantee that these 'next'
standards will indeed appear.