• Keine Ergebnisse gefunden

The last one or more parameters in a parameter list may be qualified with "REPEAT ABLE"

6.3. System Procedures

A number of identifiers, including the procedures "read" and "write" and the files "logFile" and

"cmdFile", are "predeclared" by MAINSAIL; i.e., they may be used in a module that does not itself declare them. A "system procedure" is any predeclared procedure.

Unlike some languages for which partial or non-standard implementations exist, every implementation of MAINSAIL is guaranteed to have every system procedure listed in the

"MAINSAIL Language Manual". You may use them all without fear of compromising the portability of your programs.

This section introduces some of the more common system procedures used for string processing. MAINSAIL is richly endowed with facilities for character and character string manipulation. Table 6.3-1 lists the headers of some of these system procedures. The headers shown are not necessarily the "real" headers, since some of the procedures are generic (meaning they have several forms); at this point, however, just treat the procedures as if they were declared as in Table 6.3-1. All system procedures are described more formally in the

"MAINSAIL Language Manual" .

6.3.1. eRead

The procedure cRead removes the first character from the string s and returns the character code of that character. For example, after the statements:

s

:=

"ABC";

ch := cRead(s) are executed, s has the value "BC", and ch the value 'A'.

If the string is the null string, it is unchanged, and the character code returned is -1.

6.3.2. eves

The procedure cvcs returns a string consisting of the character that is its argument. For example, "cvcs('X')" is equal to the string "X". .

6.3.3. evl and evu

These procedures return the lowercase and uppercase versions of their arguments, respectively.

The case of a string is changed by changing the case of every letter in the string; non-letter characters are not affected. For example, "cvl(ItABC")" is equal to "abc"; "cvu("Hello,

INTEGER PROCEDURE eRead (MODIFIES STRING S)i

STRING PROCEDURE cves (INTEGER eharaeterCode) i

STRING PROCEDURE cvl (STRING S)i

INTEGER PROCEDURE evl (INTEGER eharaeterCode);

STRING PROCEDURE evu (STRING S)i

INTEGER PROCEDURE evu (INTEGER eharaeterCode)i STRING PROCEDURE cWrite (MODIFIES STRING Si

REPEATABLE INTEGER char)i INTEGER PROCEDURE first (STRING S)i

INTEGER PROCEDURE last (STRING S)i

INTEGER PROCEDURE length (STRING S)i

INTEGER PROCEDURE reRead (MODIFIES STRING S)i

PROCEDURE reWrite (MODIFIES STRING Si

REPEATABLE INTEGER char) i

BOOLEAN PROCEDURE isUpperCase (INTEGER eharacterCode);

BOOLEAN PROCEDURE isLowerCase (INTEGER eharaeterCode)i BOOLEAN PROCEDURE isAlpha (INTEGER eharaeterCode) i

Table 6.3-1. Some System Procedures for String and Character Manipulation there.")" is equal to "HELLO, THERE.". Integer arguments are treated in the obvious way;

e.g., "cvu('a')" is

'A'.

These procedures are examples of generics; the compiler distinguishes

between the forms to use based on whether the argument is a string or an integer.

6.3.4. cWrite

cWrite appends a character (or more than one, since its second argument is repeatable) to a string. After executing:

s has the value" ABCxy".

6.3.5. first

s : = "ABC";

cWrite(s,'x','y')

The procedure "first" returns the character code of the first character of its string argument.

Unlike cRead, it does not remove the character from the string. For example, after the statements:

s := "ABC";

ch := first(s) are executed, s is unchanged, and ch has the value 'A'.

If the string is the null string, first returns -1.

6.3.(i. last

last returns the character code of the last character of a string, without removing it from the string. The expression "last("ABC")" has the value 'C'.

If the string is the null string, last returns -1.

6.3.7. length

length returns the number of characters in a string. The expression "length("ABC")" has the value 3.

6.3.8. reRead

rcRead returns the character code of the last character in a string. Unlike the procedure "last", it removes the character from the string. The "r" in "rcRead" stands for "reverse"; i.e., rcRead is the reverse of cRead, since it operates on the opposite end of the string.

I

If the string is the null string, it is unchanged, and the character code returned is -1.

6.3.9. reWrite

rcWrite prepends a character to the beginning of a string (being the "reverse" of cWrite, which appends a character to the end).

6.3.10. isUpperCase, isLowerCase, and isAlpha

isUpperCase and isLowerCase return true if their arguments are the character codes for an upper- or lowercase letter, respectively, and false otherwise (they always return false for non-letters). isAlpha returns true if and only if its argument is a letter, i.e .• if isUpperCase or isLowerCase is true of its argument.

6.3.11. String Processing Example

The program of Example 6.3.11-1 produces a substring of a given string, given the first and last character positions in the string to include in the substring (this is not really necessary, since MAINSAIL has a built-in substring mechanism, which is described in Section 10.5). Enter, compile, and execute the module of Example 6.3.11-1.

6.4. Scopes

So far the only declarations and definitions encountered have been "local", i.e., confined to the scope of a single procedure. When the MAINSAIL compiler reaches the end of a procedure, it forgets that it has ever seen the locally defined identifiers.

An "outer" declaration may be used to create an identifier that is visible to all subsequently declared procedures in the same module. Every procedure declaration is an outer declaration in the sense that every following procedure may call it (preceding procedures may also call it under some circumstances; see Section 7.2). Outer macros may be used by several procedures in a module, and outer variables may be used instead of parameters to pass information among procedures. Outer variables do not lose their values when a procedure exits; they persist as long as the containing module does.

Outer declarations appear between the initial "BEGIN" and final "END" of a module, outside of a procedure. Their format is exactly the same as that of local declarations. Outer macro defintions, variable declarations, and procedure declarations may appear in any order, as long as each identifier is declared before it is used.

BEGIN "subStr"

PROCEDURE convertPos (MODIFIES INTEGER i;

STRING s);

# I is a string position. If negative, convert to

# equivalent positive position; otherwise, don't change

# i t . See comment at procedure subString.

BEGIN

IF i < 0 THEN i := length(s) + i + 1;

# If less than 1, i t ' s before the beginning of the string:

IF i

<

1 THEN i := 1;

END;

STRING PROCEDURE subString (STRING s;

INTEGER startPos,stopPos);

# String positions are numbered starting at 1. If

# startPos or stopPos is negative, i t specifies a position

# from the end of the string, which is position -1.

# position 0 for either start or stop causes the null

# string to be returned.

# positions beyond the end (or beginning) of the string

# are converted to the end (or beginning) of the string.

# If stopPos is less than startPos, the null string is

# returned.

BEGIN INTEGER i;

IF startPos

=

0 OR stopPos

=

0 THEN RETURN("");

# Convert positions to equivalent positive positions convertPos(startPos,s); convertPos(stopPos,s);

# Now remove extra trailing characters, if any WHILE length(s) > stopPos DO

rcRead(s); # Remove and discard last character of s

# Now remove initial characters, if any FOR i := 1 UPTO startPos - 1 DO

cRead(s); # Remove and discard first character of s RETURN(s);

END;

Example 6.3.11-1. Getting a Substring (continued)

INITIAL PROCEDURE;

BEGIN

STRING s,t;

INTEGER start, stop;

DOB write(logFile,"String of which to take substring" &

" «eol> to quit): H);

END;

read(cmdFile,s);

IF s NEQ "" THENB

write (logFile, "Start position: H);

read(cmdFile,t); read(t,start);

write (logFile, "Stop position: H);

read(cmdFile,t); read(t,stop);

write (logFile, "Substring is """,

subString(s,start,stop),"""" & eol);

END END UNTIL s

= "";

END "subStr"

Example 6.3.11-1. Getting a Substring (end)

In MAINSAIL, unlike Pascal and some other languages, procedures may not contain other ("nested") procedures.

Example 6.4-1 shows the use of some outer variables in a simple Reverse Polish Notation calculator that performs only addition. Each line typed by the user may consist of unsigned integers, plus signs, the command

"s"

(show the contents of the stack), and the commanq "Q"

(quit), separated from one another by spaces and tab characters. When it sees an integer, if pushes it onto its "stack" of integers. When it sees a plus sign, it removes the top two integers from the stack, adds them, and pushes the result back onto the stack, unless there are fewer than two integers, in which case it gives an error message. When it sees an "S", it prints the contents of the stack, bottom to top. When it sees a "Q", it stops. At the end of each command line, it prints the value at the top of the stack, if any. Example 6.4-2 shows a sample execution.