M Web Magazine 006 (March 5, 1998 - June 4, 1998)

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 digit’s 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

1