M Tutorial (part 4/6)
$TEXT(<progpos>) or $T(<progpos>)
This function allows the programmer to store data within a program. In some of the
programs we have discussed in this issue the only method of storing data within a program
is that of assigning the constant to a string within the program. This is an alternative
method as INTFN114 will demonstrate.
INTFN114Þ;Program demonstrates intrinsic functions - Chris Bonnici - Aug 1997
Þ;M Web Magazine @ http://geocities.datacellar.net/SiliconValley/7041/mwm.html
Þ;You are using this program at your own risk
Þ;
ÞN PRG
10ÞD HEAD("Main Menu")
ÞS PRG=$$SCRNTOP("Main Menu")
ÞI PRG="" W # Q
ÞD @PRG
ÞG 10
Þ;*** EOR ***
SCRNTOP(WHAT)ÞN MAX,TAB,TXT,PRG,ANS
ÞW !
ÞS MAX=0,TAB=30
P10ÞS MAX=MAX+1,TXT=$T(MENULN+MAX),TXT=$P(TXT,";",2)
ÞI TXT="" S MAX=MAX-1 G P20
ÞS:MAX=10 TAB=TAB-1
ÞW !,?TAB,MAX,". ",TXT
ÞG P10
P20ÞW /CUP(23,30),"Option"
ÞR /CUP(23,40),ANS
ÞQ:ANS="" ""
ÞG:ANS'?1N.N P20 ; Check for numeric input
ÞG:ANS<1!(ANS>MAX) P20 ; Out of Range
ÞS TXT=$T(MENULN+ANS),PRG=$P(TXT,";",3)
ÞQ PRG
Þ;*** EOR ***
MENULNÞ;
Þ;Run INTFN101;^INTFN101
Þ;Run INTFN102;^INTFN102
Þ;Run INTFN103;^INTFN103
Þ;Run INTFN104;^INTFN104
Þ;Run INTFN105;^INTFN105
Þ;Run INTFN106;^INTFN106
Þ;Run INTFN107;^INTFN107
Þ;;
Þ;*** EOR ***
Þ; Displays a 1 line Header at the very top of the screen
HEAD(WHAT)ÞN I
ÞW #
ÞW /CUP(1,33),"M Web Magazine"
ÞW /CUP(2,1) F I=1:1:79 W "-"
ÞW /CUP(2,(79-$L(WHAT))\2+1),WHAT
ÞQ
This program provides a menu through which other programs can
be called. Once the called program terminates, control is returned back to the menu which
is redisplayed.
Of interest to us here is MENULN. This contains what apparently seem to be commented
lines. Each has a format of ;<program
description>;<program>. Line P10 in our program uses
$TEXT to read from these lines and processes them. The actual retrieving in done by S
TXT=$T(MENULN+MAX) where MENULN is the line label we want to commence reading from and MAX
is the numeric offset for this label. (This should not be difficult to follow as in
MWM001, our first discussion on M we talked about line labels and how they are addressed.)
The effect of $T is to transfer the entire line to variable TXT from where it is then
processed.
The program knows there are no more entries to process because the last line of the
menu is empty. This is checked for in the program.
Another point worth noting is that of indirection. At 10+3 we have the line D @PRG. PRG
is a variable that will contain within it the program name, e.g. ^INTFN002. M has the
facility to process what is help in a variable rather than the variable itself. A bit of
clarification is merited here.
If we say DO PRG, M will interpret this to mean transfer control to line label PRG
within the loaded program and continue from there. When we want to tell M to process not
PRG but the value within PRG we must use indirection. This is done by preceding the
variable by an @ symbol.
While indirection is very useful, it can lead to quite complex programs, very difficult
to understand. When another approach is possible, it should be used.
$TRANSLATE(<string>,<fndstr>,<repstr>) or
$TR(<string>,<fndstr>,<repstr>)
$TRANSLATE is used to change characters in <string> by checking if they
are present in <fndstr> and replacing them with the corresponding character
in <repstr>.
What should be understood is that $TR works on a character level and not on a string
level as demonstrated by the program below.
INTFN115Þ;Program demonstrates intrinsic functions - Chris Bonnici - Aug 1997
Þ;M Web Magazine @ http://geocities.datacellar.net/SiliconValley/7041/mwm.html
Þ;You are using this program at your own risk
Þ;
ÞN PHRASE
ÞR /ED(2),/CUP(1,1),"Enter a phrase: ",PHRASE
ÞW
/CUP(3,1),$TR(PHRASE,"abcdefghijklmnopqrstuvwxyz","ABCDEFGHIJKLMNOPQRSTUWVXYZ")
ÞQ
INTFN115 converts all lower case characters in string to
upper case. The phrase is user inputted. Let us assume the user enters the phrase
"Test":
- T is looked for in <fndstr>. Since it is not present, nothing
happens.
- e is found as the 5th character in <fndstr>. This is
then replaced by the 5th character in <repstr>.
- s is the 19th character of <fndstr> and so it is
replaced by the 19th character of <repstr>.
INTFN116Þ;Program
demonstrates intrinsic functions - Chris Bonnici - Aug 1997
Þ;M Web Magazine @ http://geocities.datacellar.net/SiliconValley/7041/mwm.html
Þ;You are using this program at your own risk
Þ;
ÞN PHRASE
ÞR /ED(2),/CUP(1,1),"Enter a phrase: ",PHRASE
ÞW /CUP(3,1),$TR(PHRASE,"aaaaaaaaaaa","ABCDEFGHIJKLMNOPQRSTUWVXYZ")
ÞQ
The above code has two things worth looking at:
- If <repstr> is longer than <fndstr> the extra character in
<repstr> will never get utilised because a corresponding equivalent in <fndstr>
will never occur.
- <fndstr> is searched left to right and once a match is found no more searching is
performed for that character. Repeated characters in <fndstr> will never be
matched. (Try running the above program, entering aaaaaaaaaaaaaaaaa when
prompted).
What will
happen in <fndstr> is longer than <repstr>? Modify INTFN115 and
run the program entering characters that do not have a positional entry in <repstr>.
Write a library containing functions that perform the following: covert to lowercase,
COVERT TO UPPERCASE, tOGGLE cASE, Sentence case.
$ZBOOLEAN(<bool1>,<bool2>,<oper>) or $ZB(<bool1>,<bool2>,<oper>)
Some time back we had gone into Boolean operation. This function allows us to perform
such operations. When working at this level we look at characters in their binary format.
For example the letter A would be 65 using decimal (taken from the ASCII table we talked
about in a previous issue of MWM) notation, 1000001 in binary. In numbering systems, each
digits position is the result of its multiplication by the base of the number raised
to respective position. For example 12310 is
1 x 102 2 x 101
3 x 100 |
= 100 + = 20
= 3
---
123 |
10 is the base, i.e. the
number of digits in the numbering system, 0 9 (10 digits in all). The power is the
position, commencing at zero in the rightmost position and incrementing by 1 as we move to
the left. |
To convert from binary to decimal, the following may be useful:
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
This would work out to:
1 x 20
0 x 21
0 x 22
0 x 23
0 x 24
0 x 25
1 x 26
0 x 27 |
=
=
=
=
=
=
=
= |
1
0
0
0
0
0
64
0 |
Adding up, we get 65.
One method on how to convert a decimal number to its binary equivalent is to
progressively divide the number by 2 noting down the remainder of each division (which can
be either 0 or 1).
Equation |
|
Integer
Division |
Remainder |
69/2 |
= |
34 |
1 |
34/2 |
= |
17 |
0 |
17/2 |
= |
8 |
1 |
8/2 |
= |
4 |
0 |
4/2 |
= |
2 |
0 |
2/2 |
= |
1 |
0 |
½ |
= |
0 |
1 |
Reading the remainders bottom up, we can say that 6910
= 10001012.
Continued...
E&OE
|