☜ | DOM[UMPS] by Example | ☞ |
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
Do ^EXAMPLE(1)
and that routine EXAMPLE looks like
FIRST ; author ; date/time ; function
EXAMPLE(X) ;
Write !,X
Quit
The Do command will cause an error
(M20) when the (sub)routine is called
and control is transferred to the first line. Because an actual
parameter is specified, that first line (regardless of what the
actual label is on that line) should have a formal parameter
list. The absence of a parameter list on the line to which
control is transferred will cause the error condition.
Assume that a M[UMPS] routine contains the command
Do ^EXAMPLE(1)
and that routine EXAMPLE looks like
FIRST(X) ; author ; date/time ; function
;
Write !,X
Quit
The Do command will cause the value 1 to be displayed.
Regardless of the actual label on the first line, the parameter is passed
through the parameter list on the first line of the routine.
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:
Because of the way that the "offset" is defined, the "longest" sequence of characters that fits the syntax of an integer expression is used to calculate the offset, i.e. the second interpretation is the one supported by the language standard.
The behavior of $Test is different when the Do command does not have an argument:
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)
Suppose you have a routine that contains the following label:
FUN(A,B,C) ; ...
If you call this subroutine with a reference like Do FUN(1,2), then,
within that subroutine, the value of A will be 1,
the value of B will be 2, and the value of C will be undefined.
So far so good.
But now, if you call the subroutine with a reference like Do FUN. Is that legal?
Indeed, it is legal. Of course the values of all three A, B and C will
be undefined within the subroutine, but you are allowed to do that.
Having said that, it seems like a good practice to me to not do that,
but call the subroutine with a reference like Do FUN(),
just to indicate that "I know there are parameters, and I want them to be undefined".
Approved for addition in a future M[UMPS] language standard:
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,
Copyright © Standard Documents; 1977-2024 MUMPS Development Committee;
Copyright © Examples: 1995-2024 Ed de Moel;
Copyright © Annotations: 2003-2008 Jacquard Systems Research
Copyright © Annotations: 2008-2024 Ed de Moel.
The information in this page is
NOT authoritative and subject to be modified
at any moment.
Please consult the
appropriate (draft) language standard for an
authoritative definition.
Some specifications are "approved for inclusion in a future standard". Note that the MUMPS Development Committee cannot guarantee that such future standards will indeed be published.
This page most recently updated on 15-Nov-2023, 14:41:58.
For comments, contact Ed de Moel (demoel@jacquardsystems.com)