Google
 

Trailing-Edge - PDP-10 Archives - decuslib20-02 - decus/20-0028/snobol.rno
There are 2 other files named snobol.rno in the archive. Click here to see a list.
.;SNOBOL MANUAL EDITED 9-4-70 LP WADE
.TITLE ^^PDP\\-10 ^SNOBOL4 ^USER'S ^GUIDE
.SKIP 5
.SPACING 1
.SUBTITLE ^^CHAPTER 1\\
.SPACING 1






.SKIP 5
.CENTER
^^PDP-10 SNOBOL4 USER'S GUIDE\\
.SKIP 3
.INDENT 29
^AUTHOR: ^L. ^P. ^WADE
.INDENT 31
^DATE: ^OCTOBER 17, 1970
.INDENT 28
^VERSION: %004
.SKIP 5
.CENTER
^^PREFACE\\
.SKIP 3

.PARAGRAPH
^THIS MANUAL IS INTENDED TO SERVE AS AN INTRODUCTION TO ^^SNOBOL\\4 ON
THE ^^PDP\\-10.  ^THE MATERIAL PRESENTED HERE DESCRIBES ALL THE UNIQUE
ASPECTS OF THE ^^PDP\\-10 VERSION AND INCLUDES THE INTRODUCTORY CHAPTERS
OF THE REFERENCE MANUAL (^GRISWOLD, ^POAGE & ^POLONSKY,
^^THE SNOBOL4 PROGRAMMING LANGUAGE\\ ^COPYRIGHT 1968.  ^REPRINTED BY
PERMISSION OF ^PRENTICE-^HALL, ^INC., ^ENGLEWOOD ^CLIFFS, ^N. ^J.)
FOR THOSE UNFAMILIAR WITH THE LANGUAGE.
.BREAK
.SKIP 2
^THIS MANUAL DESCRIBES VERSION 3.4 ON THE ^^PDP\\-10.
.BREAK
.SKIP 2
^COPYRIGHT 1970, ^DIGITAL ^EQUIPMENT ^CORPORATION ^MAYNARD,
^MASS., 01754.

.NOFILL
.NOJUSTIFY
.SUBTITLE ^^TABLE OF CONTENTS\\
.PAGE
.SPACING 2
.CENTER
----- ^^TABLE OF CONTENTS -----\\
.SKIP 1
1. ^^INTRODUCTION\\
2. ^^PDP-10 DIFFERENCES AND FEATURES\\
#####^A. ^CHARACTER ^SET
#####^B. ^INPUT/^OUTPUT
#####^C. ^OMISSIONS
#####^D. ^CHANGES
#####^E. ^ADDITIONS
###^NOTES FOR THE ^NOVICE
3. ^^INTRODUCTION TO THE SNOBOL4 PROGRAMMING LANGUAGE\\
#####^A. ^ASSIGNMENT ^STATEMENTS
########AND ^BASIC ^DATA ^TYPES
#####^B. ^PATTERN ^MATCHING ^STATEMENTS
#####^C. ^REPLACEMENT ^STATEMENTS
#####^D. ^PATTERNS
#####^E. ^CONDITIONAL ^VALUE ^ASSIGNMENT
#####^F. ^FLOW OF ^CONTROL
#####^G. ^INDIRECT ^REFERENCE
#####^H. ^FUNCTIONS
#####^I. ^KEYWORDS
#####^J. ^ARRAYS
#####^K. ^PROGRAMMER-DEFINED ^DATA ^TYPES
#####^L. ^PROGRAM ^EXAMPLE
#####^M. ^TABLES
4. ^^INPUT AND OUTPUT\\
#####^A. ^PRINTED ^OUTPUT
#####^B. ^PUNCHED ^OUTPUT
#####^C. ^INPUT
#####^D. ^THE ^I/^O ^SYSTEM
#####^E. ^OUTPUT ^ASSOCIATIONS
#####^F. ^INPUT ^ASSOCIATIONS
#####^G. ^OTHER ^I/^O ^FUNCTIONS
5. ^^STRUCTURE OF A SNOBOL4 RUN\\
#####^A. ^COMPILATION
#####^B. ^EXECUTION
#####^C. ^TERMINATION
^^APPENDIX A - SYSTEM PROGRAMMER'S NOTES\\
^^APPENDIX B - DEVICE NUMBER ASSIGNMENTS
.SPACING 1
\\
.FILL
.JUSTIFY
.;.FOOTNOTE 6
.;.CENTER
.;----------------------------------------------------
.;^THE MATERIAL IN ^CHAPTERS 3 AND 4 WERE TAKEN ALMOST DIRECTLY
.;FROM THE ^PRENTICE ^HALL REFERENCE MANUAL
.;WITH THEIR PERMISSION. ^THE MATERIAL IN CHAPTER 5 WAS ALSO
.;LARGELY BORROWED FROM THAT MANUAL.
.;!
.SUBTITLE ^^CHAPTER 1\\
.PAGE
.SPACING 1
^^INTRODUCTION\\
.BREAK
.PARAGRAPH

^THE ^^PDP\\-10 VERSION OF ^^SNOBOL\\4 IS ALMOST WHOLLY COMPATIBLE WITH THE
^BELL ^TELEPHONE ^LABORATORIES VERSION RUNNING ON  OTHER SYSTEMS.
^MINOR CHANGES WERE REQUIRED BECAUSE OF SLIGHTLY DIFFERENT CHARACTER
SETS AND OPERATING SYSTEMS.  ^IN ADDITION
SEVERAL MODIFICATIONS WERE MADE TO TAKE ADVANTAGE OF THE  ^^PDP\\-10 TIME SHARING
FEATURES.  ^THESE UNIQUE CHARACTERISTICS ARE ITEMIZED
LATER IN THIS CHAPTER.


.BREAK
.SKIP 1
^^BACKGROUND\\
.BREAK
.PARAGRAPH
^^SNOBOL\\ STANDS FOR ^STRI^NG-^ORIENTED SYM^B^OLIC ^LANGUAGE (1) AND WAS
.FOOTNOTE 8
.CENTER
------------------------------------------------------

(1) ^FARBER WAS ONCE OVERHEARD TO SAY THAT THIS NAME WAS LARGELY
CONTRIVED WHEN THE ORIGINAL ^^JACM\\ ARTICLE WAS PUBLISHED. ^THE
NAME WAS APPARENTLY PICKED WHEN ONE OF THE ORIGINAL  IMPLEMENTORS MADE A
STATMENT SUCH AS, "^THIS PROGRAM DOESN'T HAVE A SNOWBALL'S
CHANCE IN HELL OF ...".
!
DEVELOPED AT ^BELL ^TELEPHONE ^LABORATORIES, ^INCORPORATED, IN 1962
BY ^D.#^J.#^FARBER, ^R.#^E.#^GRISWOLD AND ^I.#^P.#^POLONSKY.  ^^SNOBOL\\4 IS
THE LATEST IN THE SERIES AND CONTAINS FEATURES NOT COMMONLY
FOUND IN OTHER PROGRAMMING LANGUAGES.  ^AS SUCH IT IS A USEFUL
TOOL IN SUCH AREAS AS COMPILATION TECHNIQUES, MACHINE SIMULATION,
SYMBOLIC MATHEMATICS, TEXT PREPARATION, NATURAL LANGUAGE TRANSLATION,
 LINGUISTICS, AND MUSIC ANALYSIS.
.BREAK
.PARAGRAPH
^THE BASIC ELEMENT OF ^^SNOBOL\\4 IS A STRING OF CHARACTERS.  ^THE 
LANGUAGE HAS FACILITIES FOR JOINING AND SEPARATING STRINGS, FOR
TESTING THEIR CONTENTS, AND FOR MAKING REPLACEMENTS IN THEM.
^IF THE STRING IS A PARAGRAPH, IT CAN BE BROKEN INTO SENTENCES,
PHRASES OR WORDS.  ^A COMMON OPERATION ON A STRING IS EXAMINATION
OF ITS CONTENTS FOR A DESIRED STRUCTURE OF CHARACTERS.  ^THIS 
.INDEX PATTERN
STRUCTURE IS KNOWN AS A PATTERN AND CAN BE AS SIMPLE AS A
STRING OR CAN BE EXTREMELY COMPLICATED.  ^THE BASIC FACILITY OF
.INDEX PATTERN MATCHING
^^SNOBOL\\ IS THE USE OF THE PATTERN IN A PATTERN MATCHING STATEMENT.
.BREAK
.PARAGRAPH
^^SNOBOL\\4 PROVIDES NUMERICAL CAPABILITIES WITH BOTH REAL AND INTEGER
NUMBERS.  ^HOWEVER, THE ARITHMETICAL FACILITIES ARE NOT EXTENSIVE
SINCE THE LANGUAGE IS ESSENTIALLY CHARACTER ORIENTED.  ^ALSO A 
.INDEX FUNCTION
.INDEX PRIMITIVE FUNCTIONS
NUMBER OF BUILT-IN FUNCTIONS, CALLED PRIMITIVE FUNCTIONS, ARE
AVAILABLE WHICH ARE A STANDARD PART OF THE LANGUAGE.  ^AS EXAMPLES,
.INDEX ^^LGT\\
 THE FUNCTION ^^LGT\\ (FOR LEXICAL COMPARISON) WILL TEST
TWO STRINGS TO DETERMINE WHETHER THE FIRST IS ALPHABETICALLY
.INDEX ^^REPLACE\\
GREATER THAN THE SECOND, AND THE FUNCTION ^^REPLACE\\ WILL REPLACE
ALL CHARACTERS IN ONE SET WHICH APPEAR IN A GIVEN STRING WITH
CORRESPONDING MEMBERS OF ANOTHER SET.
.BREAK
.PARAGRAPH
.INDEX INTERPRETIVE
.INDEX INTERPRETER
^EXECUTION OF ^^SNOBOL\\4 PROGRAMS IN INTERPRETIVE.  ^THE SYSTEM
COMPILES A PROGRAM INTO A NOTATION THE INTERPRETER CAN EASILY
EXECUTE.  ^THIS APPROACH MAKES IT FAIRLY SIMPLE TO PROVIDE
CAPABILITIES SUCH AS TRACING OF NEW VALUES FOR VARIABLES, AN
OPERATION THAT IS OTHERWISE QUITE DIFFICULT.  ^ANOTHER IMPORTANT
PRODUCT OF INTERPRETATION IS FLEXIBILITY.  ^FUNCTIONS CAN BE DEFINED
 AND REDEFINED DURING PROGRAM EXECUTION.  ^FUNCTION CALLS
CAN BE MADE RECURSIVELY WITH NO SPECIAL PROGRAM NOTATION.
^CONSULT "^^THE ^^SNOBOL\\4 ^^PROGRAMMING LANGUAGE\\\\, FOR
A COMPLETE DESCRIPTION.
.BREAK
.SKIP 1
.INDEX ^USER'S ^GUIDE
^^USER'S GUIDE\\
.BREAK
.PARAGRAPH
^^SNOBOL\\4 ON THE ^^PDP\\-10 CORRESPONDS TO THE LATEST COPY RELEASED BY
.INDEX VERSION
.INDEX CURRENT VERSION
^BELL ^TELEPHONE ^LABORATORIES.  ^THIS IS CURRENTLY VERSION 3.4.
.BREAK
.PARAGRAPH
.INDEX CORE
.INDEX CORE SIZE
^THE PROGRAM TAKES UP A GOOD DEAL OF CORE.  ^SMALL PROGRAMS WILL
REQUIRE 35^K TO RUN AND SERIOUS ^^SNOBOL\\ PROGRAMMING
.INDEX HIGH SEGMENT
.INDEX LOW SEGMENT
WILL LIKELY REQUIRE 45^K TO 50^K OF USER CORE. ^THE HIGH
SEGMENT REQUIRES ABOUT 16^K AND THE LOW SEGMENT WILL INITIALLY TAKE
17^K AND EXPAND AS MORE CORE IS NEEDED.
.BREAK
.PARAGRAPH
^THE FOLLOWING REMARKS ASSUME OPERATION ON A 10/50 SYSTEM.  ^IF
USING A 10/40 SYSTEM, REFER TO THE ^SYSTEM ^PROGRAMMER'S ^NOTES
IN ^APPENDIX ^A FOR ADDITIONAL DETAILS.
.BREAK
.PARAGRAPH
^IN GENERAL, SOURCE PROGRAMS WILL BE PREPARED WITH ONE OF THE
SYSTEM EDITORS AND SAVED WITH AN EXTENSION OF "^^SNO\\".  ^ALTERNATIVELY
THE SOURCE PROGRAM CAN BE TYPED IN DIRECTLY, BUT THIS METHOD SHOULD
BE DISCOURAGED SINCE A COPY OF THE PROGRAM IS NOT SAVED.
.BREAK
.SKIP 1

^AFTER GETTING ^^SNOBOL\\ INTO CORE BY TYPING
.SKIP 1

			^R ^^SNOBOL\\<^C^R>
.SKIP 1

IT WILL TYPE AN ASTERISK INDICATING THE USER IS EXPECTED TO GIVE
.INDEX STANDARD INPUT
.INDEX STANDARD OUTPUT
IT INPUT.  ^AT THIS TIME THE USER SHOULD SPECIFY THE STANDARD INPUT
AND OUTPUT DEVICE FILES, AS DESCRIBED BELOW

.BREAK
.SKIP 1
^^GENERAL FORMAT\\
.BREAK
.SKIP 2

.INDEX ^^LISTING-DEVICE\\
.INDEX ^^SOURCE DEVICE\\
^^LISTING-DEVICE:FILENAME.EXT__SOURCE-DEVICE:FILENAME.EXT(S)\\
.BREAK
.SKIP 1

^^LISTING-DEVICE\\
.BREAK
.SKIP 1
^THE DEVICE ON WHICH THE OUTPUT
PRODUCED BY ^^SNOBOL\\ IS TO BE WRITTEN.
^IF A DEVICE IS NOT SPECIFIED ^^DSK\\ IS ASSUMED.
.BREAK
.SKIP 1

.NOFILL
.NOJUSTIFY
^^MTA\\N:##^MAGNETIC ^TAPE
^^DTA\\N:##^^DEC\\ ^TAPE
^^DSK\\:###^DISK
^^PTP\\:###^PAPER ^TAPE ^PUNCH
^^LPT\\:###^LINE ^PRINTER
^^TTY\\:###^TELETYPE
.FILL
.JUSTIFY

.BREAK
.SKIP 1
.INDEX ^^SOURCE-DEVICE\\
^^SOURCE-DEVICE\\
.BREAK
.SKIP 1
^THE DEVICE FROM WHICH THE SOURCE
PROGRAM INPUT TO COMPILATION IS
TO BE READ. ^IF A DEVICE IS NOT SPECIFIED, ^^"DSK"\\ IS ASSUMED.
.BREAK
.SKIP 1

.NOFILL
.NOJUSTIFY
^^MTA\\N:##^MAGNETIC ^TAPE
^^DTA\\N:##^^DEC\\ ^TAPE
^^TTY\\:###^TELETYPE
^^CDR\\:###^CARD ^READER
^^PTR\\:###^PAPER ^TAPE ^READER
.FILL
.JUSTIFY
.BREAK
.SKIP 2


^^FILENAME.EXT (DSK: AND DTA\\N: ONLY)
.BREAK
.SKIP 1
	^THE FILENAME AND FILENAME
					EXTENSION OF THE LISTING
					FILE AND THE SOURCE FILE.

.PARAGRAPH
.SKIP 1
.INDEX ^^_.LST\\
.INDEX ^^_.SNO\\
					^IF .^^EXT\\ IS OMITTED, .^^LST\\
					IS ASSUMED FOR THE LISTING
					FILE AND .^^SNO\\ IS ASSUMED
					FOR THE SOURCE FILE.

.BREAK
.PARAGRAPH
					^THE LISTING DEVICE IS SEPARATED
					FROM THE SOURCE DEVICE BY A
					LEFT ARROW.
.BREAK
.FILL
.JUSTIFY

.BREAK
.PARAGRAPH

^NOTE THAT A SHORTHAND FORM IS POSSIBLE WHERE ONLY THE NAME OF THE
INPUT FILE NEEDS TO BE SPECIFIED.  ^FOR EXAMPLE THE USER WOULD TYPE
.BREAK
.SKIP 1
^^
			SNOPRG<CARRIAGE RETURN>
\\
.BREAK
.PARAGRAPH
^THIS WOULD RESULT IN THE SOURCE PROGRAM ^^SNOPRG.SNO\\ TO BE COMPILED
AND THE OUTPUT TO BE WRITTEN ON THE FILE NAMED ^^SNOPRG.LST\\.
.BREAK
.PARAGRAPH
^THE OUTPUT FILE CAN BE LISTED EITHER WITH ^^PIP\\ OR THE ^^LIST\\ COMMAND,
OR CAN BE EXAMINED WITH AN EDITOR TO LOOK FOR THE DESIRED RESULTS.
.BREAK
.PARAGRAPH
^WHILE SPECIFYING THE STANDARD ^I^O DEVICES THE USER CAN SPECIFY SEVERAL
.INDEX SWITCHES
SWITCHES AS DESCRIBED BELOW.
.PARAGRAPH
.INDEX ^D ^SWITCH
.INDEX ^^DUMP\\
/^D - ^SET THE ^^SNOBOL\\ KEYWORD ^^DUMP\\ IN ORDER TO CAUSE A DUMP OF VARIABLE
STORAGE AT PROGRAM TERMINATION.
.BREAK
.PARAGRAPH
.INDEX ^I ^SWITCH
.INDEX ^I^O ^^BUFFERS\\
/^I - ^INCREASE THE SIZE OF THE RESERVED ^I^O BUFFER SPACE  FOR
EACH OCCURRENCE OF THIS SWITCH.  ^FOR EACH INPUT/OUTPUT ASSOCIATION
WHICH YOUR PROGRAM HAS WHICH IS NOT ON DEVICE NUMBERS 5 OR 6, YOU
MUST USE THIS SWITCH TO RESERVE ^I^O BUFFER SPACE.  ^INITIALLY, ENOUGH
BUFFER SPACE FOR A TOTAL OF SIX SEPARATE FILES IS RESERVED (INCLUDING THE STANDARD ^^INPUT\\ AND ^^OUTPUT\\ FILES).
.BREAK
.PARAGRAPH
.INDEX ^U ^SWITCH
.INDEX ^^UNLIST\\
/^U - ^EQUIVALENT TO -^^UNLIST\\ TO SUPPRESS PRINTOUT OF THE SOURCE
PROGRAM LISTING.
.BREAK
.PARAGRAPH
^LATER VERSIONS OF THE ^^CCL\\ PROGRAM RELEASED BY ^^^^DEC\\\\ WILL LIKELY HAVE AN INTERFACE TO
^^SNOBOL\\.  ^IF THIS VERSION IS ON THE SYSTEM THE SOURCE PROGRAM CAN BE
EXECUTED WITH THE ^^EXECUTE\\ COMMAND.  FOR EXAMPLE, YOU WOULD TYPE
.BREAK
.SKIP 1
^^
			.EXECUTE SNOPRG<CARRIAGE RETURN>
\\
.BREAK
.SKIP 1

^THE "^E^G" COMMAND OF ^^TECO\\ COULD ALSO BE USED TO EXPEDITE THE 
DEBUGGING
PROCESS.
.;TAPE2.RNO
.TITLE ^^PDP\\-10 ^SNOBOL4 ^USER'S ^GUIDE
.SUBTITLE ^^CHAPTER 2\\
.SPACING 1
.PAGE
.BREAK
.SKIP 1


.CENTER
^^PDP-10 DIFFERENCES AND FEATURES\\
.BREAK
.SKIP 2

.INDEX ^^DIFFERENCES\\
.INDEX ^^FEATURES\\
.INDEX ^^CHARACTER SET\\
^^A.  CHARACTER SET\\
.BREAK
.SKIP 1

.PARAGRAPH

.INDEX ALTERNATION SYMBOL
.INDEX ALTERNATION
.INDEX EXCLAMATION MARK
	1.  ^THE ALTERNATION SYMBOL IS THE EXCLAMATION MARK (!) INSTEAD
OF THE VERTICAL BAR.
.BREAK
.PARAGRAPH
.INDEX NEGATION
.INDEX NEGATION SYMBOL
	2.  ^THE NEGATION SYMBOL IS THE BACK SLASH (_\).
.BREAK
.PARAGRAPH
.INDEX UNDERLINE
.INDEX UNDERLINE SYMBOL
	3.  ^THE UNDERLINE SYMBOL IS NOT DEFINED.
.BREAK
.PARAGRAPH
.INDEX ^^TAB\\
.INDEX ^^FORM FEED\\
.INDEX ^^VERTICAL TAB\\
	4.  ^OF THE CONTROL CHARACTERS, ^^TAB\\, ^^FORM\\-^^FEED\\ AND ^^VERTICAL\\
.INDEX ^^BLANK\\
^^TAB\\ ARE SYNTACTICALLY EQUIVALENT TO ^^BLANK\\.
.BREAK
.PARAGRAPH
	5.  ^SINCE THE EXCLAMATION MARK HAS BEEN USED FOR THE
ALTERNATION SYMBOL, IT CANNOT BE USED FOR EXPONENTIATION.
.BREAK
.PARAGRAPH
	6.  ^SINCE THE VERTICAL BAR IS UNDEFINED, IT CANNOT BE USED
.INDEX COMMENT LINE
TO INDICATE A COMMENT LINE.  ^ADDITIONAL COMMENT CHARACTERS INCLUDE
.INDEX SEMICOLON
THE EXCLAMATION MARK AND SEMICOLON.
.BREAK
.PARAGRAPH
	7.  ^BOTH UPPER AND LOWER CASE LETTERS ARE ALLOWED.
.BREAK
.SKIP 1

.BREAK
.SKIP 2
.INDEX ^^INPUT\\
.INDEX ^^OUTPUT\\
^^B.  INPUT/OUTPUT
\\
.BREAK
.SKIP 1
.PARAGRAPH
	1.  ^THE DEVICES AND FILES ASSOCIATED WITH THE 
STANDARD INPUT AND OUTPUT REFERENCE NUMBERS ARE SELECTED BY THE 
USER AT RUN TIME.  ^THIS MECHANISM IS A SUBSTITUTE FOR THE ^^JCL\\
PROCEDURE ON THE ^^IBM\\/360.
.BREAK
.PARAGRAPH
.INDEX DEVICE REFERENCE NUMBERS
.INDEX DEVICE NUMBERS
	2.  ^THE ^I^O DEVICE REFERENCE NUMBERS AVAILABLE TO THE
PROGRAMMER ARE LISTED IN  ^APPENDIX ^B.
.BREAK
.PARAGRAPH
.INDEX ^^FORMAT\\
.INDEX ^A5 ^^FORMAT\\
.INDEX ^A1 ^^FORMAT\\
3. ^THE STANDARD ^^FORMAT\\  STATEMENT FOR ^^OUTPUT\\ ASSOCIATIONS
SHOULD INCLUDE THE ^^A5\\  CONVERSION RATHER THAN THE TYPICAL ^^A1\\
CONVERSION WITH ^^IBM\\ INSTALLATIONS.
.BREAK
.SKIP 1
.INDEX ^^OMISSIONS\\
^^C.  OMISSIONS
\\
\\
.BREAK
.SKIP 1
.PARAGRAPH
.INDEX ^^DUMP\\
	1.  ^VARIABLES ARE NOT ALPHABETIZED ON A ^^DUMP\\ REQUEST.
.BREAK
.PARAGRAPH
.INDEX ^^EXTERNAL FUNCTIONS\\
	2.  ^THE ^^EXTERNAL FUNCTION\\ FEATURE IS NOT IMPLEMENTED.
.BREAK
.SKIP 2
.INDEX ^^CHANGES\\
^^
D.  CHANGES
\\
.BREAK
.SKIP 1
.PARAGRAPH
.INDEX ^^LIST LEFT\\
	1.  ^^LIST LEFT\\ HAS BEEN MADE THE DEFAULT IN ORDER TO MAKE IT
MORE PRACTICAL TO USE A ^^TTY\\ (IT REDUCES THE AMOUNT OF TYPEOUT).
.BREAK
.SKIP 1

.INDEX ^^ADDITIONS\\
^^E.  ADDITIONS
\\
.BREAK
.SKIP 1
.PARAGRAPH
.INDEX ^^IFILE\\
	1.  ^THE ^^IFILE\\ PRIMITIVE FUNCTION HAS BEEN DEFINED TO ALLOW THE
USER TO SELECT THE DISK FILENAME FOR INPUT FILES AT EXECUTION TIME.
.BREAK
.PARAGRAPH
.INDEX ^^OFILE\\
2.  ^THE ^^OFILE\\ PRIMITIVE FUNCTION HAS BEEN DEFINED TO ALLOW THE
USER TO SELECT THE DISK FILENAME FOR OUTPUT FILES AT EXECUTION TIME.
.BREAK
.PARAGRAPH
.INDEX ^^MSTIME\\
	3.  ^THE ^^MSTIME\\ PRIMITIVE FUNCTION HAS BEEN DEFINED TO RETURN THE
ELAPSED TIME IN MILLISECONDS SINCE MIDNIGHT.  ^THIS IS IN CONTRAST TO
THE ^^TIME\\ FUNCTION WHICH RETURNS ONLY THE RUNTIME.
.BREAK
.PARAGRAPH
.INDEX ^^INPUT\\
.INDEX ^^TTCALL\\
	4.  ^AN ^^INPUT\\ ASSOCIATION TO DEVICE REFERENCE NUMBER 99 IS AN
INTERFACE TO THE ^^PDP\\-10 ^^TTCALL\\ FACILITY.  ^EACH TIME SUCH AN
ASSOCIATION IS MADE, ONE CHARACTER WILL BE INPUT FROM THE USER'S TERMINAL (INCLUDING PERHAPS
CONTROL CHARACTERS).
.BREAK
.PARAGRAPH
	5.  ^AN ^^OUTPUT\\ ASSOCIATION TO DEVICE REFERENCE NUMBER 99 IS
INTERFACED TO THE ^^PDP\\-10 ^^TTCALL\\ FACILITY.  ^EACH TIME SUCH AN
ASSOCIATION IS MADE, THE REFERENCED STRING WILL BE OUTPUT.  ^NO
FREE ^^CARRIAGE-RETURN/LINE-FEED\\ WILL BE ADDED.
.BREAK
.PARAGRAPH
.INDEX ^^ASCII\\
	6.  ^THE ^^ASCII\\ PRIMITIVE FUNCTION HAS BEEN DEFINED TO ALLOW
REFERENCING NONPRINTING AND CONTROL CHARACTERS.
.BREAK
.PARAGRAPH
.INDEX ^D ^SWITCH
.INDEX ^^DUMP\\
	7.  ^THE "^D" SWITCH IS EQUIVALENT TO _&^^DUMP\\ = 1 AND CAUSES A 
DUMP OF VARIABLE STORAGE AT PROGRAM TERMINATION.
.BREAK
.PARAGRAPH
.INDEX ^U ^SWITCH
.INDEX ^^UNLIST\\
	8.  ^THE "^U" SWITCH IS EQUIVALENT TO -^^UNLIST\\ AND SUPPRESSES
ALL COMPILER OUTPUT UP TO THE "^^ERRORS DETECTED\\" MESSAGE.
.BREAK
.PARAGRAPH
.INDEX CORE EXPANSION
	9.  ^DYNAMIC CORE EXPANSION HAS BEEN ADDED TO REDUCE THE AMOUNT
OF START-UP CORE REQUIRED.  ^AS MORE CORE FOR FREE STORAGE IS NEEDED,
IT IS RETRIEVED.  ^THE PROGRAM SHRINKS BACK TO ITS ORIGINAL SIZE
UPON TERMINATION.  ^A MESSAGE HAS BEEN ADDED TO THE STATISTICS
PRINTOUT TO INDICATE TO THE USER HOW MUCH CORE HIS PROGRAM USED.
.BREAK
.PARAGRAPH
.INDEX REENTRANT
	10.  ^THE PROGRAM HAS BEEN MADE REENTRANT, TO MAKE MULTIPROGRAMMING
 OF ^^SNOBOL\\ PRACTICAL.
.BREAK
.SKIP 2
^^
.INDEX BEGINNER'S NOTES
.CENTER
NOTES FOR THE NOVICE
\\
.BREAK
.SKIP 2

^THESE NOTES MAY HELP YOU AVOID SOME OF THE COMMON PITFALLS USUALLY
MADE BY NEW ^^SNOBOL\\ PROGRAMMERS.
.BREAK
.PARAGRAPH
.INDEX ^^BLANK\\
1.  ^ALWAYS REMEMBER THAT THE "^^BLANK\\" IS SYNTACTICALLY SIGNIFICANT 
IN ^^SNOBOL\\ AND IT MUST BE PRESENT IN A NUMBER OF KEY PLACES.  ^FOR
EXAMPLE,
.BREAK
.SKIP 1

#######	^A.  ^BLANKS MUST BE ON BOTH SIDES OF AN "=" SIGN IN AN
	    ASSIGNMENT STATEMENT.
.BREAK
.SKIP 1

#######	^B.  ^BLANKS MUST BE ON BOTH SIDES OF BINARY OPERATORS,
#####	    ^I.^E. ^I = ^I + 1.
.BREAK
.PARAGRAPH
^IN ADDITION, BLANKS MUST NOT BE INSERTED IN RANDOM PLACES.  ^FOR
EXAMPLE, IF IN THE LABEL
.BREAK
.SKIP 1

^^
		END.OF.FILE
\\
.BREAK
.SKIP 1
ONE OF THE DOTS WAS MISSING AND A ^^BLANK\\ INSERTED INSTEAD, ERROR
TERMINATION WILL LIKELY RESULT IN A "^^TRANSFER TO UNDEFINED
LABEL\\" MESSAGE OR CAUSE INCORRECT RESULTS.  ^BLANKS MUST ALSO NOT
BE INSERTED BETWEEN A FUNCTION NAME AND THE LEFT PARENTHESIS.
.BREAK
.PARAGRAPH
2.  ^REMEMBER THAT STRINGS ARE ALWAYS INITIALIZED TO THE 
.INDEX ^^NULL\\
.INDEX ^^NULL STRING\\
^^NULL\\ STRING.  ^CONSEQUENTLY, MISSPELLED KEY VARIABLES CAN CAUSE
CONFUSING RESULTS.  ^FOR EXAMPLE, IF THE WORD ^^OUTPUT\\ WAS SPELLED
AS ^^OUTPVT\\ THEN THE STATEMENT
.BREAK
.SKIP 1

#####		^^OUTPVT\\^^ = 'DATE IS '  DATE()
\\
.BREAK
.SKIP 1

WILL ASSIGN THE CORRECT RESULT BUT NO OUTPUT WILL OCCUR.
.BREAK
.PARAGRAPH
.INDEX ^^DUMP\\
3.  ^IT IS GOOD PRACTICE TO ALWAYS SET THE ^^DUMP\\ KEYWORD IN ORDER
TO PROVIDE THE MAXIMUM AMOUNT OF INFORMATION.
.BREAK
.PARAGRAPH
.INDEX ^^TRIM\\
4.  ^IT IS GOOD PRACTICE TO ALWAYS SET THE ^^TRIM\\ KEYWORD TO WORK
WITH TRIMMED STRINGS, ESPECIALLY UNTIL YOU SEE A NEED TO LEAVE
TRAILING BLANKS ON.
.BREAK
.PARAGRAPH
.INDEX ^^OUTPUT\\ ASOCIAITONS
.INDEX ^^FORMAT\\
5.  ^WHEN MAKING ^^OUTPUT\\ ASSOCIATIONS, YOU SHOULD USE THE FOLLOWING
^^FORMAT\\
.BREAK
.SKIP 1

#####		^^OUTPUT\\('^^TYPE\\',5,'(1^X,16^A5)')
.BREAK
.SKIP 1

^THE ^A5 FORMAT IS THE ONLY PRACTICAL "^A" ^^FORMAT\\ ON THE ^^PDP\\-10.  ^IN
PARTICULAR ^A1 FORMATS WILL GIVE YOU EVERY FIFTH CHARACTER.
.BREAK
.PARAGRAPH
6.  ^ACCESS TO DISK FILES IS POSSIBLE THROUGH THE ^^IFILE\\ AND ^^OFILE\\
PRIMITIVE FUNCTIONS (DESCRIBED ELSEWHERE).
.SKIP 1
.;CHAPTER 3 EDITED 9-5-70 LP WADE
.TITLE ^^PDP\\-10 ^SNOBOL4 ^USER'S ^GUIDE
.SPACING 1
.SKIP 1
.SUBTITLE ^^CHAPTER 3\\
.PAGE

.CENTER

.INDEX ^^INTRODUCTION\\
^^ INTRODUCTION TO THE ^^SNOBOL4 PROGRAMMING LANGUAGE
\\
.PARAGRAPH
.SKIP 1
	^THIS CHAPTER IS AN INTRODUCTORY OVERVIEW OF THE ^^SNOBOL\\4 PROGRAMMING
LANGUAGE.  ^IT DESCRIBES THE FORMAT OF STATEMENTS, SOME OF THE OPERATIONS,
AND SOME OF THE TYPES OF DATA HANDLED BY THE LANGUAGE.
^THE REFERENCE MANUAL DESCRIBES IN MORE DETAIL   THE MATERIAL IN THIS INTRODUCTORY 
CHAPTER.
.BREAK
.SKIP 1
	^A ^^SNOBOL\\4 PROGRAM CONSISTS OF A SEQUENCE OF STATEMENTS.  ^THERE
ARE FOUR BASIC TYPES OF STATEMENTS:
.BREAK
.SKIP 1
^^

.NOFILL
.NOJUSTIFY
#####	1)  THE ASSIGNMENT STATEMENT,
#####	2)  THE PATTERN MATCHING STATEMENT,
#####	3)  THE REPLACEMENT STATEMENT, AND
.INDEX ^^END\\
^^#####	4)  THE END STATEMENT.
\
.FILL
.JUSTIFY
.BREAK
.SKIP 1
^THE ^^END\\ STATEMENT TERMINATES THE PROGRAM.
.BREAK
.SKIP 1
.INDEX ASSIGNMENT STATEMENT
.INDEX ASSIGNMENTS
^^A.  ASSIGNMENT STATEMENTS AND BASIC DATA TYPES
\\
.BREAK
.SKIP 1
^THE SIMPLEST TYPE OF STATEMENT IS THE ASSIGNMENT STATEMENT.  ^IT
HAS THE FORM
.BREAK
.SKIP 1
#####^^	VARIABLE = VALUE
\\
.BREAK
.SKIP 1
^THE ASSIGNMENT STATEMENT MAY BE SAID TO HAVE THE FOLLOWING MEANING:
^^"LET VARIABLE HAVE THE GIVEN VALUE."\\  ^FOR EXAMPLE, LET ^V HAVE THE VALUE
5, OR
.BREAK
.SKIP 1
#####^^	V = 5
\\
.BREAK
.SKIP 1
^THE VALUE MAY BE GIVEN BY A EXPRESSION, CONSISTING, FOR EXAMPLE, OF
ARITHMETIC OPERATIONS AS IN THE STATEMENT
.BREAK
.SKIP 1
#####^^	W = 14 + (16 - 10)
\\

.BREAK
.SKIP 1
.INDEX ^^BLANK\\
WHICH ASSIGNS THE VALUE 20 TO THE VARIABLE ^W.  ^BLANKS ARE REQUIRED
AROUND ARITHMETIC OPERATORS SUCH AS + AND - .  ^THE VALUE NEED NOT BE AN
INTEGER, WHICH IS JUST ONE TYPE OF DATA HANDLED BY ^^SNOBOL\\4.  ^FOR
EXAMPLE, THE VALUE MAY BE A STRING OF CHARACTERS, INDICATED BY ENCLOSING
QUOTES.  ^AN EXAMPLE IS THE ASSIGNMENT STATEMENT
.BREAK
.SKIP 1
#####^^	V = 'DOG'
\\
.BREAK
.SKIP 1
WHICH ASSIGNS THE STRING ^^DOG\\ TO THE VARIABLE ^V.  ^VARIOUS TYPES OF DATA
AND OPERATIONS THAT MAY BE PERFORMED ON THEM ARE DESCRIBED
LATER.
.BREAK
.SKIP 1
^TYPICALLY A VARIABLE IS A NAME SUCH AS ^V, ^X, OR ^^ANS\\.  ^VARIABLES
APPEARING EXPLICITLY IN A PROGRAM MUST BEGIN WITH A LETTER WHICH MAY BE
FOLLOWED BY ANY NUMBER OF LETTERS, DIGITS AND PERIODS.
.BREAK
.SKIP 1
^THE VALUE OF A VARIABLE MAY BE USED IN AN ASSIGNMENT STATEMENT.
^THUS
.BREAK
.SKIP 1
#####^^	RESULT = ANS.1
\\
.BREAK
.SKIP 1
ASSIGNS TO THE VARIABLE ^^RESULT\\ THE VALUE OF ^^ANS.1\\.  (^QUOTATION MARKS
DISTINGUISH LITERAL STRINGS FROM VARIABLES.)
.BREAK
.SKIP 1
.INDEX ^^BLANK\\
^BLANKS ARE REQUIRED TO SEPARATE THE PARTS OF A STATEMENT.  ^IN 
AN ASSIGNMENT STATEMENT, THE EQUAL SIGN MUST BE SEPARATED FROM THE 
VARIABLE ON THE LEFT AND THE VALUE ON THE RIGHT BY AT LEAST ONE BLANK.
.BREAK
.SKIP 1
.INDEX CONTINUATION LINES
^A STATEMENT WHICH IS LONGER THAN ONE LINE CAN BE CONTINUED ONTO
SUCCESSIVE LINES BY STARTING THE CONINUATION LINES WITH A PERIOD OR PLUS
SIGN.  ^AN EXAMPLE IS
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	   N   =   (3 + M)  (2 + SUM)  -
_.   (^F - 2)
\\
.FILL
.JUSTIFY
.BREAK
.SKIP 1
^WHEN CONTINUING A STATEMENT OVER A LINE BOUNDARY, THE STATEMENT MAY BE
BROKEN WHEREVER A BLANK IS REQUIRED. 
.BREAK
.SKIP 1
.INDEX SEMICOLON
^SEVERAL STATEMENTS MAY BE PLACED ON ONE LINE BY USING SEMICOLONS
WHICH INDICATE THE ENDS OF STATEMENTS.  ^AN EXAMPLE IS
.BREAK
.SKIP 1
#####^^	X  =  2;  Y  =  3;  Z  =  10
\\
.BREAK
.SKIP 1
.INDEX COMMENT LINE
.INDEX ASTERISK
^A LINE BEGINNING WITH AN ASTERISK IS TREATED AS A COMMENT AND
DOES NOT AFFECT THE OPERATION OF THE PROGRAM.
.BREAK
.SKIP 1
#####^^	1.  INTEGERS
\\
.BREAK
.SKIP 1
.INDEX ARITHMETIC OPERATIONS
.INDEX ADDITION
.INDEX SUBTRACTION
.INDEX MULTIPLICATION
^THE ARITHMETIC OPERATIONS OF ADDITION, SUBTRACTION, MULTIPLICATION,
.INDEX DIVISION
.INDEX EXPONENTIATION
.INDEX INTEGER
 DIVISION, AND EXPONENTIATION OF INTEGERS MAY BE USED IN 
EXPRESSIONS.  ^THE STATEMENTS
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	N  =  5;  M  =  4
#####	P  =  N * M / (N - 1)
\\
.FILL
.JUSTIFY
.BREAK
.SKIP 1
ASSIGN THE VALUE 5 TO ^P.  ^WHILE BLANKS ARE REQUIRED BETWEEN THE BINARY
OPERATORS AND THEIR OPERANDS, UNARY OPERATORS SUCH AS THE MINUS SIGN 
MUST BE ADJACENT TO THEIR OPERANDS.  ^AN EXAMPLE IS THE STATEMENT
.BREAK
.SKIP 1
#####^^ Q2 = -P / -N
\\
.BREAK
.SKIP 1

WHICH ASSIGNS THE VALUE 1 TO ^Q2 .
.BREAK
.SKIP 1
.INDEX ARITHMETIC EXPRESSIONS
^ARITHMETIC EXPRESSIONS CAN BE ARBITRARILY COMPLEX.  ^WHEN EVALUATING
 ARITHMETIC EXPRESSIONS, THE NATURAL ORDER OF OPERATOR PRECEDENCE
APPLIES.  ^THE UNARY OPERATIONS ARE PERFORMED FIRST, THEN EXPONENTIATION
(**), THEN MULTIPLICATION, FOLLOWED BY DIVISION, AND FINALLY ADDITION
AND SUBTRACTION.  ^ALL OPERATIONS ASSOCIATE TO THE LEFT EXCEPT EXPONENTIATION.
  ^HENCE,
.BREAK
.SKIP 1
#####^^	X  =  2 ** 3 ** 2
\\
.BREAK
.SKIP 1
IS EQUIVALENT TO
.BREAK
.SKIP 1
#####^^	X  =  2 ** (3 ** 2)
\\
.BREAK
.SKIP 1
.INDEX PARENTHESES
^PARENTHESES MAY BE USED TO EMPHASIZE OR ALTER THE ORDER OF 
EVALUATION OF AN EXPRESSION.
.BREAK
.SKIP 1
^IN THE ABOVE EXAMPLES ALL THE OPERANDS ARE INTEGERS AND THE
RESULTS ARE INTEGERS.  ^THE QUOTIENT OF TWO INTEGERS IS ALSO AN
INTEGER. ^THE
REMAINDER IS DISCARDED.  ^THUS
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	Q1  =  5 / 2
#####	Q2  =  5 / -2
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
GIVE ^Q1 AND ^Q2 THE VALUES 2 AND -2, RESPECTIVELY.  ^SIMILARLY,
.BREAK
.SKIP 1
.INDEX ^^MOD\\
#####^^	MOD  =  N - (N / M) * M
\\
.BREAK
.SKIP 1
GIVES ^^MOD\\ THE VALUE ^N MODULO ^M IF ^N AND ^M ARE POSITIVE INTEGERS.
.BREAK
.SKIP 1
.INDEX REAL NUMBERS
#####^^	2.  REAL NUMBERS
\\
.BREAK
.SKIP 1
.INDEX ARITHMETIC EXPRESSIONS
^ARITHMETIC EXPRESSIONS INVOLVING REAL OPERANDS ARE ALSO PERMITTED
 IN ASSIGNMENT STATEMENTS.  ^THE STATEMENTS
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	PI  =  3.14159
#####	CIRCUM  =  2. * PI * 5.
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
ASSIGN REAL VALUES TO ^P^I AND ^^CIRCUM\\.
.BREAK
.SKIP 1
^EXPONENTIATION CAN BE PERFORMED ON REAL OPERANDS.  ^IN ADDITION
.INDEX MIXED MODE EXPRESSIONS
INTEGER AND REAL NUMBERS CAN BE MIXED FREELY TO PERMIT MIXED-MODE 
ARITHMETIC.
.BREAK
.SKIP 1
.BREAK
.SKIP 1
#####^^	3.  STRINGS
\\
.BREAK
.SKIP 1
.INDEX EXPRESSIONS
^EXPRESSIONS INVOLVING OPERANDS THAT ARE CHARACTER STRINGS ARE
ALSO PERMITTED IN ASSIGNMENT STATEMENTS.  ^FOR EXAMPLE, THE ASSIGNMENT
STATEMENT
.BREAK
.SKIP 1
#####^^	SCREAM  =  'HELP'
\\
.BREAK
.SKIP 1
ASSIGNS THE STRING ^^HELP\\ AS THE VALUE OF ^^SCREAM\\ .
.BREAK
.SKIP 1
.INDEX QUOTES
.INDEX QUOTATION MARKS
^THE STRING IS SPECIFIED BY ENCLOSING IT WITHIN A PAIR OF QUOTATION 
MARKS.  ^ANY CHARACTER MAY APPEAR IN A STRING.  ^A PAIR OF DOUBLE
QUOTATION MARKS CAN BE USED INSTEAD OF SINGLE QUOTATION MARKS.  ^THIS 
PERMITS THE USE OF QUOTATION MARKS WITHIN A STRING AS IN THE STATEMENTS
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	PLEA  =  'HE SHOUTED, "HELP."'
#####	QUOTE  =  '"'
#####	APOSTROPHE  =  "'"
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
.INDEX ^^NULL\\
.INDEX ^^NULL\\ STRING
^^THE ^^NULL STRING
\\
\\
.BREAK
.SKIP 1
^THE ^^NULL\\ STRING, WHICH IS A STRING OF LENGTH ZERO, IS FREQUENTLY
USED IN ^^SNOBOL\\4.  ^WITH A FEW EXCEPTIONS, EXPLAINED LATER, ALL VARIABLES
HAVE THE ^^NULL\\ STRING AS THEIR INITIAL VALUE.  ^A VARIABLE CAN ALSO BE 
ASSIGNED THE ^^NULL\\ STRING BY A STATEMENT LIKE
.BREAK
.SKIP 1
#####	^^NULL\\  =  ''
.BREAK
.SKIP 1
OR, MORE BRIEFLY,
.BREAK
.SKIP 1
#####	^^NULL\\  =
.BREAK
.SKIP 1
^THE VARIABLE ^^NULL\\ IS USED IN MANY EXAMPLES THAT FOLLOW TO REPRESENT THE
^^NULL\\ STRING.
.BREAK
.SKIP 1
^THE ^^NULL\\ STRING IS DIFFERENT FROM THE FOLLOWING STRINGS, EACH OF
WHICH HAS LENGTH ONE:
.BREAK
.NOFILL
.NOJUSTIFY
.SKIP 1
#####	'0'
#####	" "
.BREAK
.SKIP 1
^^STRINGS IN ARITHMETIC EXPRESSIONS
\\
.SKIP 2
.BREAK
.SKIP 1
^NUMERAL STRINGS CAN BE USED IN ARITHMETIC EXPRESSIONS WITH
INTEGERS.  ^FOR EXAMPLE, AS A RESULT OF THE STATEMENTS
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
##### ^Z = '10'
#####^^	Z  =  "10"
#####	X  =  5 * -Z + '10'
\\
.BREAK
.FILL
.JUSTIFY
.SKIP 1
^X HAS THE VALUE -40.  ^NUMERAL STRINGS CONTAIN ONLY DIGITS AND A DECIMAL
POINT AND PERHAPS A PRECEDING SIGN.  ^THUS, THE FOLLOWING STRINGS CAN BE
USED IN ARITHMETIC EXPRESSIONS:
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####	'-3.50'
#####	'3.257'
.FILL
.JUSTIFY
.BREAK
.SKIP 1
^THE FOLLOWING STRINGS CANNOT BE USED IN ARITHMETIC EXPRESSIONS:
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####	'1,253,465'
#####	'.364 ^E-03'
.FILL
.JUSTIFY
.BREAK
.SKIP 1
^THEY CAUSE EXECUTION OF THE PROGRAM TO TERMINATE WITH THE COMMENT 
.INDEX ^^ILLEGAL DATA TYPE\\
^^"ILLEGAL DATA TYPE.\\"
.BREAK
.SKIP 1
^STRINGS CAN BE USED IN EXPRESSIONS INVOLVING REAL NUMBERS.
.BREAK
.SKIP 1
.INDEX ^^NULL\\
.INDEX ZERO
^THE ^^NULL\\ STRING IS EQUIVALENT TO THE INTEGER ZERO IN ARITHMETIC
EXPRESSIONS.
.BREAK
.SKIP 1
^^STRING-VALUED EXPRESSIONS
\\
.SKIP 1
.BREAK
.SKIP 1
.INDEX CONCATENATION
^CONCATENATION IS THE BASIC OPERATION FOR COMBINING TWO STRINGS
TO FORM A THIRD.  ^THE FOLLOWING STATEMENTS ILLUSTRATE THE FORMAT OF AN
EXPRESSION INVOLVING CONCATENATION.
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	TYPE  =  'SEMI'
#####	OBJECT  =  TYPE 'GROUP'
\\
.FILL
.JUSTIFY
.BREAK
.SKIP 1
^THE RESULTING VALUE OF ^^OBJECT\\ IS THE STRING ^^SEMIGROUP\\ .  ^NOTICE THERE IS
NO EXPLICIT OPERATOR FOR CONCATENATION.  ^CONCATENATION IS INDICATED BY
SPECIFYING TWO STRING VALUED OPERANDS SEPARATED BY AT LEAST ONE BLANK.
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	FIRST  =  'WINTER'
LT###	SECOND  =  'SPRING'
#####	TWO.SEASONS  =  FIRST ',' SECOND
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
ARE EQUIVALENT TO
.BREAK
.SKIP 1
#####^^	TWO.SEASONS  =  'WINTER,SPRING'
\\
.BREAK
.SKIP 1
^STRINGS CAN ALSO BE CONCATENATED WITH INTEGERS AS IN
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	ROW  =  'K'
#####	NO.  =  22
#####	SEAT  =  ROW NO.
\\
.FILL
.JUSTIFY
.BREAK
.SKIP 1
WHICH GIVES ^^SEAT\\ THE VALUE ^K22 .
.BREAK
.SKIP 1
^IN AN EXPRESSION INVOLVING CONCATENATION AND INTEGER ARITHMETIC,
.INDEX PRECEDENCE
CONCATENATION HAS THE LOWEST PRECEDENCE.  ^THUS
.BREAK
.SKIP 1
#####^^	SEAT  =  ROW NO. + 4 / 2
\\
.BREAK
.SKIP 1
IS EQUIVALENT TO
.BREAK
.SKIP 1
#####^^	SEAT  =  ROW (NO. + 4 / 2))
\\
.BREAK
.SKIP 1
OR 
.BREAK
.SKIP 1
#####^^	SEAT  =  'K24'
\\
.BREAK
.SKIP 1
.INDEX ^^INPUT\\
.INDEX ^^OUTPUT\\
.SKIP 1
^^INPUT AND OUTPUT OF STRINGS
\\
.SKIP 2
.BREAK
.SKIP 1
.INDEX READING
.INDEX WRITING
^THREE VARIABLES PROVIDE MEANS FOR READING AND WRITING DATA.  ^THE
VARIABLES ^^OUTPUT\\ AND ^^PUNCH\\ ARE FOR PRINTING AND PUNCHING.  ^WHENEVER 
EITHER OF THEM IS ASSIGNED A STRING OR INTEGER VALUE, A COPY OF THE VALUE
IS PUT OUT.
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	OUTPUT  =  'THE RESULTS ARE:'
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
ASSIGNS ^^THE RESULTS ARE:\\  TO ^^OUTPUT\\ AND ALSO PRINTS IT.
.BREAK
.SKIP 1
#####^^	PUNCH  =  OUTPUT
\\
.BREAK
.SKIP 1
CAUSES THE SAME LINE TO BE PUNCHED ON THE CARD PUNCH.  ^THE STATEMENTS
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	OUTPUT  =
#####	PUNCH  =
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
CAUSE A BLANK LINE TO BE PRINTED AND A BLANK CARD TO BE PUNCHED.
.BREAK
.SKIP 1
.INDEX ^^INPUT\\
^THE VARIABLE ^^INPUT\\ IS USED FOR READING IN STRINGS.  ^EACH TIME
THE VALUE OF ^^INPUT\\ IS REQUIRED IN A STATEMENT, ANOTHER CARD IS READ IN
AND THE 80 CHARACTER STRING ON IT IS ASSIGNED AS THE VALUE OF ^^INPUT\\. 
^THUS
.BREAK
.SKIP 1
#####^^	PUNCH  =  INPUT
\\
.BREAK
.SKIP 1
PRODUCES A COPY OF THE INPUT CARD ON THE CARD PUNCH.
.BREAK
.SKIP 1
.INDEX PATTERNS
.INDEX PATERN MATCHING
^^B.  PATTERN MATCHING STATEMENTS
\\
.SKIP 1
.BREAK
.SKIP 1
^THE OPERATION OF EXAMINING SUBSTRINGS FOR THE OCCURRENCE OF 
SPECIFIED SUBSTRINGS (I.E. PATTERN MATCHING) IS FUNDAMENTAL TO THE 
^^SNOBOL\\4 LANGUAGE.  ^PATTERN MATCHING CAN BE SPECIFIED IN TWO TYPES OF
STATEMENTS:
.BREAK
.SKIP 1
^^
.NOFILL
	1)  ^THE PATTERN MATCHING STATEMENT, AND
	2)  ^THE REPLACEMENT STATEMENT.

.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
.INDEX PATTERN
.INDEX PATTERN MATCHING
^THE PATTERN MATCHING STATEMENT HAS THE FORM
.BREAK
.SKIP 1
#####^^	SUBJECT	PATTERN
\\
.BREAK
.SKIP 1
WHERE THE TWO FIELDS ARE SEPARATED BY AT LEAST ONE BLANK.  ^THE SUBJECT
SPECIFIES A STRING THAT IS TO BE EXAMINED, AND THE PATTERN CAN BE 
THOUGHT OF AS SPECIFYING A SET OF STRINGS.  ^THE STATEMENT CAUSES THE 
SUBJECT STRING TO BE SCANNED FROM THE LEFT FOR THE OCCURRENCE OF A 
STRING SPECIFIED BY THE PATTERN.
.BREAK
.SKIP 1
^IF
.BREAK
.SKIP 1
#####^^	TRADE  =  'PROGRAMMER'
\\
.BREAK
.SKIP 1
THE STATEMENT
.BREAK
.SKIP 1
#####^^	TRADE  'GRAM'
\\
.BREAK
.SKIP 1
EXAMINES THE VALUE OF ^^TRADE\\ FOR AN OCCURRENCE OF ^^GRAM\\ . ^IF
.BREAK
.SKIP 1
#####^^	PART  =  'GRAM'
\\
.BREAK
.SKIP 1
THEN AN EQUIVALENT STATEMENT IS
.BREAK
.SKIP 1
#####^^	TRADE	PART
\\
.BREAK
.SKIP 1
^THE FOLLOWING EXAMPLE ILLUSTRATES A PATTERN MATCHING STATEMENT IN WHICH
 THE PATTERN IS A STRING VALUED EXPRESSION.

.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
^^
#####	ROW  =  'K'
#####	NO.  =  20
#####	'K24'  ROW  NO. + 4
\\
.FILL
.JUSTIFY
.BREAK
.SKIP 1
^THE SUBJECT IS A LITERAL AND THE VALUE OF THE EXPRESSION IS THE STRING
^K24 .
.BREAK
.SKIP 1
^NOTICE THAT THERE IS NO EXPLICIT PATTERN MATCHING OPERATOR 
BETWEEN THE SUBJECT AND THE PATTERN.  ^THE TWO FIELDS ARE SEPARATED BY
BLANKS.
.BREAK
.SKIP 1
.INDEX CONCATENATION
^IF IT IS NECESSARY TO HAVE CONCATENATION IN THE SUBJECT, THE
EXPRESSION MUST BE ENCLOSED WITHIN PARENTHESES TO AVOID AMBIGUITY.  ^AN
EXAMPLE IS
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
^^#####	TENS  =  2
#####	UNITS  =  5
#####	(TENS UNITS)  30
\\
.FILL
.JUSTIFY
.BREAK
.SKIP 1
^ON THE OTHER HAND, A PATTERN FORMED BY CONCATENATION DOES NOT
NEED PARENTHESES.  ^THE FOLLOWING STATEMENTS ARE EQUIVALENT:
.BREAK
.SKIP 1
#####^^	TENS UNITS 30
\\
.BREAK
.SKIP 1
#####^^	TENS (UNITS 30)
\\
.BREAK
.SKIP 1
.INDEX REPLACEMENT
.INDEX REPLACEMENT STATEMENT
^^C.  REPLACEMENT STATEMENTS
\\
.BREAK
.SKIP 1
^A REPLACEMENT STATEMENT HAS THE FORM
.BREAK
.SKIP 1
^^#####	SUBJECT  PATTERN  =  OBJECT
\\
.BREAK
.SKIP 1
.INDEX ^^BLANK\\
WHERE THE FIELDS ARE SEPARATED BY AT LEAST ONE BLANK.  ^IF THE PATTERN
MATCHING OPERATION SUCCEDS, THE SUBJECT STRING IS MODIFIED BY REPLACING
THE MATCHED SUBSTRING BY THE OBJECT.  ^FOR EXAMPLE, IF
.BREAK
.SKIP 1
#####^^	WORD  =  'GIRD'
\\
.BREAK
.SKIP 1
THEN THE REPLACEMENT STATEMENT
.BREAK
.SKIP 1
#####^^	WORD  'I'  =  'OU'
\\
.BREAK
.SKIP 1
CAUSES THE SUBJECT STRING ^^GIRD\\ TO BE SCANNED FOR THE STRING ^I AND THEN,
SINCE THE PATTERN MATCHES, ^I IS REPLACED BY ^^OU \\.  ^HENCE WORD HAS AS
VALUE THE STRING ^^GOURD\\ .  ^IF THE STATEMENT IS
.BREAK
.SKIP 1
#####^^	WORD 'AB'  =  'OU'
\\
.BREAK
.SKIP 1
THE VALUE OF ^^WORD\\ DOES NOT CHANGE BECAUSE THE PATTERN FAILS TO MATCH.
.BREAK
.SKIP 1
^ANOTHER EXAMPLE OF THE USE OF REPLACEMENT STATEMENTS IS GIVEN IN
THE FOLLOWING SEQUENCE OF STATEMENTS
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
^^
#####	HAND  =  'AC4DAHKDKS'
#####	RANK  =  4
#####	SUIT  =  'D'
#####	HAND  RANK SUIT  =  'A5'
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
WHICH REPLACES THE SUBSTRING 4^D WITH THE STRING ^A5 .
.BREAK
.SKIP 1
^A MATCHED SUBSTRING IS DELETED FROM THE SUBJECT STRING IF THE
OBJECT IN THE REPLACEMENT STATEMENT IS THE ^^NULL\\ STRING.  ^THUS
.BREAK
.SKIP 1
#####^^	HAND  RANK SUIT  =
\\
.BREAK
.SKIP 1
DELETES 4^D FROM HAND LEAVING IT WITH THE STRING^^ ACAHKDKS\\ AS VALUE.
.SPACING 1
.BREAK
.SKIP 1
.INDEX PATTERNS
^^D.  PATTERNS
\\
.BREAK
.SKIP 1
^THE PATTERNS IN THE PRECEDING EXAMPLES SPECIFY SINGLE STRINGS.
^IT IS ALSO POSSIBLE TO SPECIFY MORE COMPLEX PATTERNS.  ^THERE ARE TWO
OPERATIONS AVAILABLE FOR CONSTRUCTING SUCH PATTERNS:
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
.INDEX ALTERNATION
###    1)  ^ALTERNATION, AND
.INDEX CONCATENATION
###    2)  ^CONCATENATION.
.FILL
.JUSTIFY
.BREAK
.SKIP 1
    ^ALTERNATION IS INDICATED BY AN EXPRESSION OF THE FORM
.BREAK
.SKIP 1
#####^^	P1 ! P2
\\
.BREAK
.SKIP 1
.INDEX ^^BLANK\\
WHERE THE TWO PATTERNS ^P1 AND ^P2 ARE SEPARATED FROM THE ! BY BLANKS.
^THE VALUE OF THE EXPRESSION IS A PATTERN STRUCTURE THAT MATCHES ANY 
STRING SPECIFIED BY EITHER ^P1 OR ^P2.  ^FOR EXAMPLE, THE STATEMENT
.BREAK
.SKIP 1
#####^^	KEYWORD  =  'COMPUTER' ! 'PROGRAM'
\\
.BREAK
.SKIP 1
ASSIGNS TO ^^KEYWORD\\ A PATTERN STRUCTURE THAT MATCHES EITHER OF THESE
TWO STRINGS.
.BREAK
.SKIP 1
    ^SUBSEQUENTLY, ^^KEYWORD\\ MAY BE USED WHEREVER PATTERNS ARE PERMITTED.
FOR EXAMPLE,
.BREAK
.SKIP 1
#####^^	KEYWORD  =  KEYWORD ! 'ALGORITHM'
\\
.BREAK
.SKIP 1
GIVES ^^KEYWORD\\ A NEW PATTERN VALUE EQUIVALENT TO THE VALUE ASSIGNED BY
EXECUTING THE STATEMENT
.BREAK
.SKIP 1
#####^^	KEYWORD  =  'COMPUTER' ! 'PROGRAM' ! 'ALGORITHM'
\\
.BREAK
.SKIP 1
^SIMILARLY,
.BREAK
.SKIP 1
#####^^	TEXT KEYWORD  =
\\
.BREAK
.SKIP 1
EXAMINES THE VALUE OF ^^TEXT\\ FROM THE LEFT AND DELETES THE FIRST
OCCURRENCE OF ONE OF THE ALTERNATIVE STRINGS.  ^IF
.BREAK
.SKIP 1
#####^^	TEXT  =  'PROGRAMMING ALGORITHMS FOR COMPUTERS'
\\
.BREAK
.SKIP 1
THE RESULT OF THE REPLACEMENT STATEMENT IS AS IF THE FOLLOWING STATEMENT
 WERE EXECUTED:
.BREAK
.SKIP 1
#####^^	TEXT  =  'MING ALGORITHMS FOR COMPUTERS'
\\
.BREAK
.SKIP 1
.INDEX CONCATENATION
    ^CONCATENATION OF TWO PATTERNS, ^P1 AND ^P2, IS SPECIFIED IN THE
SAME WAY AS THE CONCATENATION OF TWO STRINGS:
.BREAK
.SKIP 1
#####^^	P1  P2

.BREAK
.SKIP 1
THAT IS, THE TWO PATTERNS ARE SEPARATED BY BLANKS.  ^THE VALUE OF THE
EXPRESSION IS A PATTERN THAT MATCHES A STRING CONSISTING OF TWO SUBSTRINGS,
 THE FIRST MATCHED BY ^P1, THE SECOND MATCHED BY ^P2.  ^FOR
EXAMPLE, IF
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	BASE  =  'BINARY' ! 'DECIMAL' ! 'HEX'
#####	SCALE  =  'FIXED' ! 'FLOAT'
#####	ATTRIBUTE  =  SCALE BASE
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
AND
.BREAK
.SKIP 1
#####^^	DCL  =  'AREAFIXEDDECIMAL'
\\
.BREAK
.SKIP 1
THEN THE PATTERN MATCH SUCCEEDS IN THE STATEMENT
.BREAK
.SKIP 1
#####^^	DCL  ATTRIBUTE
\\
.BREAK
.SKIP 1
.INDEX CONCATENATION
    ^CONCATENATION HAS HIGHER PRECEDENCE THAN ALTERNATION.  ^THUS
.BREAK
.SKIP 1
#####^^	ATTRIBUTE  =  'FIXED' ! 'FLOAT' 'DECIMAL'
\\
.BREAK
.SKIP 1
MATCHES ^^FIXED\\ OF ^^FLOATDECIMAL\\.  ^THE ORDER OF EVALUATION MAY BE ALTERED
BY USING PARENTHESES.
.BREAK
.SKIP 1
#####^^	ATTRIBUTE  =  ('FIXED' ! 'FLOAT') 'DECIMAL'
\\.BREAK
.SKIP 1
MATCHES EITHER ^^FIXEDDECIMAL\\ OR ^^FLOATDECIMAL\\.
.BREAK
.SKIP 1

.INDEX CONDITIONAL VALUE ASSIGNMENT
.INDEX CONDITIONAL ASSIGNMENT
^^E.  CONDITIONAL VALUE ASSIGNMENT
\\
.SKIP 1
.BREAK
.SKIP 1
    ^IT IS POSSIBLE TO ASSOCIATE A VARIABLE WITH A COMPONENT OF A 
PATTERN SUCH THAT IF THE PATTERN MATCHES, THE VARIABLE IS ASSIGNED
.INDEX _.
.INDEX DOT OPERATOR
THE SUBSTRING MATCHED BY THE COMPONENT.  ^THE OPERATOR  _.  IS THE
CONDITIONAL VALUE ASSIGNMENT OPERATOR AND IT IS USED IN AN EXPRESSION
OF THE FORM
.BREAK
.SKIP 1
#####^^	PATTERN _. VARIABLE
\\
.BREAK
.SKIP 1
WHERE THE OPERATOR IS SEPARATED FROM ITS OPERANDS BY BLANKS.  ^FOR
EXAMPLE
.BREAK
.SKIP 1
#####^^	BASE  =  ('HEX' ! 'DEC') . B1
\\
.BREAK
.SKIP 1
ASSIGNS TO ^^BASE\\ A PATTERN THAT MATCHES EITHER ^^HEX\\ OR ^^DEC\\.  ^IF ^^BASE\\ IS
USED SUCCESSFULLY IN A PATTERN MATCH, THE VALUE OF ^B1 IS SET TO THE
SUBSTRING MATCHED BY ^^BASE\\  .
    ^THE OPERATOR _. HAS THE HIGHEST PRECEDENCE OF ALL THE OPERATORS
AND ASSOCIATES TO THE LEFT.  ^THUS
.BREAK
.SKIP 1
#####^^	A_.OR_.B  =  A ! B _. OUTPUT
\\
.BREAK
.SKIP 1
IS EQUIVALENT TO
.BREAK
.SKIP 1
#####^^	A_.OR_.B  =  A  !  (B _. OUTPUT)
\\
.BREAK
.SKIP 1
WHICH ASSIGNS TO ^^A_.OR_.B\\ A PATTERN THAT MATCHES THE VALUE OF ^A OR ^B .
^IF ^B MATCHES, THE SUBSTRING MATCHED IS PRINTED.
.BREAK
.SKIP 1
.INDEX IMMEDIATE VALUE ASSIGNMENT
.INDEX _$ OPERATOR
.INDEX DOLLAR SIGN OPERATOR
    ^THERE IS ALSO AN OPERATOR  $  FOR IMMEDIATE VALUE ASSIGNMENT WHICH
ASSIGNS VALUE TO A VARIABLE IF THE ASSOCIATED COMPONENT OF THE PATTERN
MATCHES REGARDLESS OF WHETHER THE ENTIRE PATTERN MATCHES.  ^IMMEDIATE
VALUE ASSIGNMENT IS DISCUSSED IN MORE DETAIL IN THE REFERENCE MANUAL.
.BREAK
.SKIP 1

^^F.  FLOW OF CONTROL
\\
.SKIP 1
.BREAK
.SKIP 1
    ^A ^^SNOBOL\\4 PROGRAM IS A SEQUENCE OF STATEMENTS TERMINATED BY AN
.INDEX ^^END\\
.INDEX ^^END\\ STATEMENT
^^END\\ STATEMENT.  ^STATEMENTS ARE EXECUTED SEQUENTIALLY UNLESS OTHERWISE
SPECIFIED IN THE PROGRAM.  ^LABELS AND GOTOS ARE PROVIDED TO CONTROL THE
FLOW OF THE PROGRAM.
.BREAK
.SKIP 1
    ^A STATEMENT MAY BEGIN WITH A LABEL, PERMITTING TRANSFER TO THE
STATEMENT.  ^FOR EXAMPLE, THE ASSIGNMENT STATEMENT
.BREAK
.SKIP 1
^^START TEXT  =  INPUT
\\
.BREAK
.SKIP 1
HAS THE LABEL ^^START\\.  ^A LABEL CONSISTS OF A LETTER OR A DIGIT FOLLOWED
 BY ANY NUMBER OF OTHER CHARACTERS UP TO A BLANK.  ^BLANKS SEPARATE
THE LABEL FROM THE SUBJECT.  ^A STATEMENT WITH NO LABEL MUST BEGIN WITH
AT LEAST ONE BLANK.  ^THE ^^END\\ STATEMENT IS DISTINGUISHED BY THE LABEL 
^^END\\, INDICATING THE END OF THE PROGRAM.
.BREAK
.SKIP 1
    ^TRANSFER TO A LABELLED STATEMENT IS SPECIFIED IN THE GOTO FIELD
WHICH MAY APPEAR AT THE END OF A STATEMENT AND IS SEPARATED FROM THE
.INDEX COLON
.INDEX TRANSFERS
REST OF THE STATEMENT BY A COLON.  ^TWO TYPES OF TRANSFERS CAN BE SPECIFIED
.INDEX CONDITIONAL TRANSFER
.INDEX UNCONDITIONAL TRANSFER
.INDEX ^F
.INDEX ^S
.INDEX FAILURE GOTO
.INDEX SUCCESS GOTO
 IN THE GOTO FIELD:  CONDITIONAL AND UNCONDITIONAL.\\
.BREAK
.SKIP 1
    ^A CONDITIONAL TRANSFER CONSISTS OF A LABEL ENCLOSED WITHIN
PARENTHESES AND PRECEDED BY AN ^F  OR  ^S  CORRESPONDING TO FAILURE OR
SUCESS GOTO.  ^AN EXAMPLE IS THE STATEMENT
.BREAK
.SKIP 1
#####^^	TEXT  =  INPUT    :F(DONE)
\\
.BREAK
.SKIP 1
    ^THIS STATEMENT CAUSES A RECORD TO BE READ IN AND ASSIGNED AS THE
VALUE OF ^^TEXT\\.  ^IF, HOWEVER, THERE IS NO DATA IN THE INPUT FILE,
I.E. AN END OF FILE IS ENCOUNTERED, NO NEW VALUE IS ASSIGNED
TO ^^TEXT\\.  ^THEN, BECAUSE OF THE FAILURE TO READ, TRANSFER IS MADE TO
THE STATEMENT LABELLED ^^DONE\\.
.BREAK
.SKIP 1
    ^A USE OF THE SUCCESS GOTO IS ILLUSTRATED IN THE FOLLOWING PROGRAM
WHICH PUNCHES A COPY OF THE INPUT FILE.
.NOFILL
.BREAK
.SKIP 1
.NOJUSTIFY
^^LOOP   PUNCH  =  INPUT     :S(LOOP)
END
\\
.FILL
.JUSTIFY
.BREAK
.SKIP 1
^THE FIRST STATEMENT IS REPEATEDLY EXECUTED UNTIL THE END OF FILE IS
.INDEX ^^END\\
ENCOUNTERED AND THEN THE PROGRAM FLOWS INTO THE ^^END\\ STATEMENT WHICH
CAUSES THE PROGRAM TO TERMINATE.
.BREAK
.SKIP 1
    ^THE SUCCESS OR FAILURE OF A PATTERN MATCH CAN ALSO BE USED TO
CONTROL THE FLOW OF A PROGRAM BY CONDITIONAL GOTOS.  ^FOR EXAMPLE
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	COLOR  =  'RED' ! 'GREEN' ! 'BLUE'
BRIGHT TEXT  COLOR  =     :S(BRIGHT)F(BLAND)
BLAND
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
    ^ALL OCCURRENCES OF THE STRINGS ^^RED\\, ^^GREEN\\ AMD ^^BLUE\\ ARE DELETED
FROM THE VALUE OF ^^TEXT\\ BEFORE THE PATTERN FAILS TO MATCH.  ^CONTROL
THEN PASSES TO THE STATEMENT LABELLED ^^BLAND\\.  ^BOTH SUCCESS AND 
.INDEX GOTO FIELD
FAILURE GOTOS CAN BE SPECIFIED IN ONE GOTO FIELD, AND MAY APPEAR IN
EITHER ORDER.
.BREAK
.SKIP 1
    ^FOR AN EXAMPLE OF AN UNCONDITIONAL TRANSFER, CONSIDER THE FOLLOWING
PROGRAM THAT PUNCHES AND LISTS A DECK OF CARDS.
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
^^LOOP   PUNCH   =   INPUT     :F(END)
#####       OUTPUT   =   PUNCH    :(LOOP)
END
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
^THE GOTO FIELD IN THE SECOND STATEMENT SPECIFIES AN UNCONDITIONAL
TRANSFER.
.BREAK
.SKIP 1

.INDEX INDIRECT
.INDEX INDIRECT REFERENCE
^^G.  INDIRECT REFERENCE
\\
.SKIP 1
.BREAK
.SKIP 1
    ^INDIRECT REFERENCING IS INDICATED BY THE UNARY OPERATOR  $ .  ^FOR
EXAMPLE, IF
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	MONTH   =   'APRIL'
\\
.FILL
.JUSTIFY
.BREAK
.SKIP 1
THEN $^^MONTH\\ IS EQUIVALENT TO ^^APRIL\\ .  ^THAT IS, THE STATEMENT
.BREAK
.SKIP 1
#####^^	$MONTH   =   'CRUEL'
\\
.BREAK
.SKIP 1
IS EQUIVALENT TO
.BREAK
.SKIP 1
#####^^	APRIL   =   'CRUEL'
\\
.BREAK
.SKIP 1
    ^THE INDIRECT REFERENCE OPERATOR CAN ALSO BE APPLIED TO A PARENTHESIZED
 EXPRESSION AS IN THE STATEMENTS
.NOFILL
.BREAK
.SKIP 1
.NOJUSTIFY
#####^^	WORD   =   "RUN"
#####	$(WORD ':')   =   $(WORD ':') + 1
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
WHICH INCREMENT THE VALUE OF ^^RUN\\:  .
.BREAK
.SKIP 1
.INDEX UNARY
    ^IN GENERAL, THE UNARY OPERATOR  $  GENERATES A VARIABLE THAT IS THE
VALUE OF ITS OPERAND.  ^THE EXPRESSION
.BREAK
.SKIP 1
#####^^	$("A" ! "B")
\\
.BREAK
.SKIP 1
.INDEX ^^ILLEGAL DATA TYPE\\
CAUSES THE PROGRAM TO TERMINATE WITH THE MESSAGE "^^ILLEGAL DATA TYPE"\\
BECAUSE THE VALUE OF THE OPERAND OF  $  IS A PATTERN, NOT A STRING.
^INDIRECT REFERENCE IN A GOTO IS DEMONSTRATED BY
.BREAK
.SKIP 1
#####^^	N   =   N + 1     :($("PHASE" N))
\\
.BREAK
.SKIP 1
^IF, FOR EXAMPLE, THE ASSIGNMENT STATEMENT SETS ^N EQUAL TO 5, THEN THE
TRANSFER IS TO THE STATEMENT LABELLED^^ PHASE5.\\
.BREAK
.SKIP 1

.INDEX ^^FUNCTIONS\\
.INDEX PRIMITIVE FUNCTIONS
^^H.  FUNCTIONS
\\
.SKIP 1
.BREAK
.SKIP 1
    ^MANY ^^SNOBOL\\4 PROCEDURES ARE INVOKED BY FUNCTIONS BUILT INTO THE
SYSTEM CALLED PRIMITIVE FUNCTIONS.  ^OPERATIONS THAT OCCUR FREQUENTLY
ARE IMPLEMENTED AS PRIMITIVE FUNCTIONS FOR EFFICIENCY.  ^OTHER PRIMITIVE
FUNCTIONS ARE USED TO INVOKE MORE COMPLEX OPERATIONS THAT ARE FUNDAMENTAL
 TO THE LANGUAGE, AFFECT PARAMETERS AND TABLES INTERNAL TO THE
SYSTEM, AND PERFORM OPERATIONS THAT COULD NOT BE PROGRAMMED IN SOURCE
LANGUAGE BY OTHER MEANS.  ^IN ADDITION, FACILITIES ARE AVAILABLE FOR A
PROGRAMMER TO DEFINE HIS OWN SOURCE LANGUAGE FUNCTIONS.
.BREAK
.SKIP 1
^^
.INDEX PRIMITIVE FUNCTIONS
###    1.  ^PRIMITIVE FUNCTIONS
\\
.BREAK
.SKIP 1
.INDEX ^^SIZE\\
    ^CONSIDER THE FUNCTION ^^SIZE\\, WHICH HAS A SINGLE STRING ARGUMENT AND
RETURNS AS VALUE AN INTEGER WHICH IS THE LENGTH (NUMBER OF CHARACTERS)
OF THE STRING.  ^THE STATEMENTS
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
.INDEX ^^APE\\
#####^^	APE   =   'SIMIAN'
#####	OUTPUT   =   SIZE(APE)
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
PRINT THE NUMBER 6 .
.BREAK
.SKIP 1
    ^ARGUMENTS TO ALL FUNCTIONS ARE PASSED BY VALUE, AND AN ARBITRARILY
 COMPLEX EXPRSSION MAY BE USED IN THE ARGUMENT.  ^THUS THE
STATEMENTS
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	N   =   100
#####	OUTPUT   =   SIZE('PART' N + 4)
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
PRINT THE NUMBER 7 , BECAUSE THE VALUE OF THE ARGUMENT IS THE STRING
^^PART104 .\\
.BREAK
.SKIP 1
.INDEX ^^SIZE\\
    ^THE ARGUMENT OF ^^SIZE\\ IS SUPPOSED TO BE A STRING.  ^THEREFORE, A CALL
OF THE FORM
.BREAK
.SKIP 1
#####^^	SIZE("APE" ! "MONKEY")
\\
.BREAK
.SKIP 1
.INDEX ^^ILLEGAL DATA TYPE\\
CAUSES THE PROGRAM TO TERMINATE WITH THE DIAGNOSTIC MESSAGE "^^ILLEGAL
DATA TYPE\\" BECAUSE THE VALUE OF THE ARGUMENT IS A PATTERN.
.BREAK
.SKIP 1
.INDEX ^^TRIM\\
    ^^TRIM\\ IS ANOTHER FUNCTION THAT PERFORMS AN OPERATION FREQUENTLY
REQUIRED.  ^^TRIM(STRING)\\ RETURNS AS VALUE A STRING WHICH IS EQUAL TO
THE ARGUMENT WITH TRAILING BLANKS REMOVED.  ^IT IS OFTEN USED IN A
STATEMENT OF THE FORM
.BREAK
.SKIP 1
^^READ	TEXT  =  TRIM(INPUT)	:F(END)
\\
.BREAK
.SKIP 1
WHICH ASSIGNS AS VALUE TO ^^TEXT\\ THE STRING ON THE NEXT INPUT CARD,
TRIMMED OF TRAILING BLANKS.  ^NOTICE THAT THE USE OF THE VARIABLE 
^^INPUT\\ IN THE ARGUMENT CAUSES A CARD TO BE READ.
.BREAK
.SKIP 1
.INDEX ^^REPLACE\\
	^^REPLACE\\ IS A FUNCTION CALLED WITH THREE STRING VALUED ARGUMENTS.
.BREAK
.SKIP 1
#####^^	REPLACE(TEXT,CH1,CH2)
\\
.BREAK
.SKIP 1
RETURNS AS VALUE A STRING WHICH IS EQUAL TO ^^TEXT\\ WITH EACH OCCURRENCE
 OF A CHARACTER APPEARING IN ^C^H1 REPLACED BY THE CORRESPONDING
CHARACTER IN ^C^H2.  ^FOR EXAMPLE THE STATEMENTS
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	STATEMENT  =  'A(I,J)  =  A(I,J) + 3'
#####	OUTPUT   =   REPLACE(STATEMENT,'()','<>')
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
PRINT THE LINE
.BREAK
.SKIP 1
^^A<I,J>   =   A<I,J> + 3
\\
.BREAK
.SKIP 1
     ^IF THE LAST TWO ARGUMENTS OF THE FUNCTION CALL DO NOT HAVE THE
SAME LENGTH, THE FUNCTION FAILS.  ^FUNCTION FAILURE, LIKE ^^INPUT\\ FAILURE,
CAN BE USED IN A CONDITIONAL TRANSFER.
.BREAK
.SKIP 1
     ^ANOTHER EXAMPLE OF THE USE OF ^^REPLACE\\ IS THE FOLLOWING PROGRAM THAT
PRODUCES A SIMPLE CRYPTOGRAPHIC ENCODING OF AN INPUT DECK.
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	INALPH   =   'ABCDEFGHIJLMNOPQRSTUVWXYZ'
#####	OUTALPH   =   'KLMNOPQRSTUVWXYZABCDEFGHIJ'
LOOP#	PUNCH   =   REPLACE(INPUT,INALPH,OUTALPH)	:S(LOOP)
END
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
^THE ITERATION IS TERMINATED BY ^^INPUT\\ FAILURE.
.BREAK
.SKIP 1
     ^THERE ARE ALSO SEVERAL FUNCTIONS THAT RETURN PATTERNS AS THEIR
.INDEX ^^LEN\\
VALUES.  ^^LEN\\ IS SUCH A FUNCTION.^^  LEN(INTEGER)\\ RETURNS A PATTERN THAT
THAT MATCHES ANY STRING OF THE LENGTH SPECIFIED BY THE INTEGER.
.BREAK
.SKIP 1
     ^THE FOLLOWING EXAMPLE PUNCHES THE VALUE OF ^^STR\\ CENTERED ON A CARD.
.NOFILL
.NOJUSTIFY
#####^^	BLANKS   =   '                                       '
#####	BLANKS   LEN((80 - SIZE(STR)) / 2) . PAD
#####	PUNCH   =   PAD STR
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
^IF THE SIZE OF ^^STR\\ IS GREATER THAN 80, THE ARGUMENT OF ^^LEN\\ IS NEGATIVE,
 CAUSING ERROR TERMINATION WITH THE MESSAGE "^^NEGATIVE 
NUMBER IN ILLEGAL CONTEXT."\\
.BREAK
.SKIP 1
.INDEX ^^DUPL\\
     ^^DUPL(S,N\\ DUPLICATES A STRING ^S.  ^THE NUMBER OF DUPLICATIONS IS 
DETERMINED BY ^N.  ^THE VALUE OF
.BREAK
.SKIP 1
#####^^     DUPL('.*',5)
\\
.BREAK
.SKIP 1
IS '.*.*.*.*.*'  .  ^IF ^S IS THE ^^NULL\\ STRING OR ^N IS ZERO, ^^DUPL\\ 
RETURNS THE ^^NULL\\ STRING AS VALUE.  ^^DUPL\\ FAILS IF ^N IS NEGATIVE.
.BREAK
.SKIP 1
.INDEX ^^DUMP\\
     ^^DUMP(N)\\ PRINTS A DUMP OF VARIABLE STORAGE AT THE TIME ^^DUMP\\ IS 
CALLED IF ^N IS NONZERO.  ^THE DUMP IS SIMILAR TO THE DUMP PROVIDED
AFTER PROGRAM TERMINATION, EXCEPT THAT THE VARIABLES ARE NOT ALPHABETIZED.
  ^^DUMP\\ RETURNS THE ^^NULL\\ STRING AS VALUE.  ^NO DUMP IS GIVEN
IF ^N IS ZERO.
.BREAK
.SKIP 1
.INDEX ^^REMDR\\
	^THE VALUE OF ^^REMDR(N,M)\\ IS THE REMAINDER OF THE INTEGER
DIVISION ^N / ^M.  ^THE SIGN OF THE REMAINDER IS THE SAME AS THE
SIGN OF THE DIVIDEND.  ^THUS THE VALUE OF
.BREAK
.SKIP 1
#####^^	REMDR(-5,2)
\\
.BREAK
.SKIP 1
IS -1, AND THE VALUE OF
.BREAK
.SKIP 1
#####^^	REMDR(5,-2)
\\
.BREAK
.SKIP 1
IS 1.
.BREAK
.SKIP 1
.INDEX PREDICATES
###^^     2.  PREDICATES
\\
.BREAK
.SKIP 1
     ^A PREDICATE IS A FUNCTION OR OPERATION THAT RETURNS THE ^^NULL\\ 
STRING AS VALUE IF A GIVEN CONDITION IS SATISFIED.  ^OTHERWISE IT
FAILS.
.BREAK
.SKIP 1
     ^L^E IS AN EXAMPLE OF A PREDICATE USED FOR COMPARING INTEGERS.
.BREAK
.SKIP 1
.INDEX ^^LE\\
####^^	LE(N1,N2)
\\
.BREAK
.SKIP 1
RETURNS THE ^^NULL\\ STRING AS VALUE IF ^N1 IS AN INTEGER LESS THAN OR
EQUAL TO ^N2.  ^THUS
.BREAK
.SKIP 1
#####^^	PUNCH   =   LE(SIZE(TEXT),80) TEXT
\\
.BREAK
.SKIP 1
PUNCHES THE STRING ^^TEXT\\ IF ITS LENGTH IS NOT GREATER THAN 80.  ^THE
^^NULL\\ STRING VALUE OF THE PREDICATE DOES NOT AFFECT THE STRING THAT
IS PUNCHED.  ^IF THE PREDICATE FAILS, NO ASSIGNMENT IS MADE TO ^^PUNCH\\,
AND NO CARD IS PUNCHED.

     ^THE SUCCESS OF FAILURE OF A PREDICATE CAN BE USED WITH A CONDITIONAL
 GOTO TO CONTROL THE FLOW OF A PROGRAM.  ^FOR EXAMPLE,
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	N   =   0;   SUM   =   0
ADD##	N   =   LT(N,50) N + 1	  :F(DONE)
#####	SUM   =   SUM + N	  :(ADD)
DONE#	OUTPUT   =   SUM
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
SUMS THE FIRST 50 INTEGERS.  ^ITERATION CONTINUES AS LONG AS ^N IS LESS
THAN 50.  ^WHEN THE PREDICATE FAILS, THE CONDITIONAL TRANSFER TO ^^DONE\\
IS PERFORMED AND THE STRING 1275 IS PRINTED.

    ^THERE ARE SEVERAL PREDICATES FOR COMPARING STRINGS.  ^FOR EXAMPLE,
.BREAK
.SKIP 1
.INDEX ^^DIFFER\\
#####^^	DIFFER(ST1,ST2)
\\
.BREAK
.SKIP 1
RETURNS THE ^^NULL\\ STRING AS VALUE IF THE VALUES OF TWO ARGUMENTS ARE
NOT IDENTICAL.  ^THUS 
.BREAK
.SKIP 1
#####^^	OUPUT   =   DIFFER(FIRST,SECOND) FIRST SECOND
\\
.BREAK
.SKIP 1
CONCATENATES THE VALUES OF ^^FIRST\\ AND ^^SECOND\\ IF THEY ARE NOT THE SAME,
AND THEN PRINTS THEM.
.BREAK
.SKIP 1
     ^FOR ALL FUNCTIONS, AN OMITTED ARGUMENT IS ASSUMED TO BE THE ^^NULL\\
STRING.  ^THUS
.BREAK
.SKIP 1
#####^^	PUNCH   =   DIFFER(TEXT) TEXT
\\
.BREAK
.SKIP 1
PUNCHES THE VALUE OF ^^TEXT\\ IF IT IS NOT THE ^^NULL\\ STRING.
.BREAK
.SKIP 1
.INDEX ^^LGT\\
    ^^LGT\\ IS A PREDICATE THAT LEXICALLY COMPARES TWO STRINGS.
.BREAK
.SKIP 1
#####^^	LGT(ST1,ST2)
\\
.BREAK
.SKIP 1
SUCCEEDS IF ^S^T1 FOLLOWS (IS LEXICALLY GREATER THAN) ^S^T2 IN ALPHABETICAL
 ORDER.  THE STATEMENTS
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	OUTPUT   =   LGT(TEXT1,TEXT2) TEXT2	:S(SKIP)
#####	OUTPUT   =   TEXT1
#####	OUTPUT   =   TEXT2			:(JUMP)
SKIP#	OUTPUT   =   TEXT1
JUMP
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
PRINT THE VALUES OF ^^TEXT\\1 AND ^^TEXT\\2 IN ALPHABETICAL ORDER.
.BREAK
.SKIP 1
.INDEX DEFINED FUNCTIONS
.INDEX FUNCTIONS
###^^     3.  DEFINED FUNCTIONS
\\
.BREAK
.SKIP 1
     ^THE ^^SNOBOL\\4 LANGUAGE PROVIDES THE PROGRAMMER WITH THE CAPABILITY
 TO DEFINE FUNCTIONS IN THE SOURCE LANGUAGE.  ^THIS FEATURE FACILITATES
 THE ORGANIZATION OF A PROGRAM AND MAY IMPROVE ITS EFFICIENCY.
.BREAK
.SKIP 1
    ^A PROGRAMMER MAY DEFINE A FUNCTION BY EXECUTING THE PRIMITIVE FUNCTION
.INDEX ^^DEFINE\\
 ^^DEFINE\\ TO SPECIFY THE FUNCTION NAME, FORMAL ARGUMENTS, LOCAL 
VARIABLES, AND THE ENTRY POINT OF THE FUNCTION.  ^THE ENTRY POINT IS
THE LABEL OF THE FIRST OF A SET OF ^^SNOBOL\\4 STATEMENTS CONSTITUTING 
THE PROCEDURE FOR THE FUNCTION.
.BREAK
.SKIP 1
     ^THE FIRST ARGUMENT OF ^^DEFINE\\ IS A PROTOTYPE DESCRIBING THE FORM
OF THE FUNCTION CALL.  ^THE SECOND ARGUMENT IS THE ENTRY POINT.  ^FOR 
EXAMPLE, EXECUTION OF THE STATEMENT
.BREAK
.SKIP 1
.INDEX ^^DELETE\\
#####^^	DEFINE('DELETE(STRING,CHAR)','D1')
\\
.BREAK
.SKIP 1
DEFINES A FUNCTION ^^DELETE\\ HAVING TWO FORMAL ARGUMENTS, ^^STRING\\ AND
^^CHAR\\, AND ENTRY POINT ^D1.  ^THE STATEMENTS
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
^^
D1###	STRING CHAR   =	   :S(D1)
#####	DELETE   =   STRING	:(RETURN)
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
FORM A PROCEDURE THAT DELETES ALL OCCURRENCES OF ^^CHAR\\ FROM THE VALUE
OF ^^STRING\\.  ^THE STATEMENT ASSIGNING THE RESULTING VALUE TO THE VARIABLE
 ^^DELETE\\ ILLUSTRATES THE ^^SNOBOL\\4 CONVENTION FOR RETURNING A FUNCTION VALUE:
  ^THE FUNCTION NAME MAY BE USED AS A VARIABLE IN THE FUNCTION
 PROCEDURE.  ^ITS VALUE ON RETURN FROM THE PROCEDURE IS THE VALUE
OF THE FUNCTION CALL.  ^RETURN FROM A PROCEDURE IS ACCOMPLISHED BY 
.INDEX ^^RETURN\\
TRANSFER TO THE SYSTEM LABEL ^^RETURN\\.
.BREAK
.SKIP 1
     ^IF THE SECOND ARGUMENT IS OMITTED FROM THE CALL OF ^^DEFINE\\, THE 
ENTRY POINT TO THE PROCEDURE IS TAKEN TO BE THE SAME AS THE FUNCTION
NAME.  ^FOR EXAMPLE
.BREAK
.SKIP 1
#####^^	DEFINE('DELETE(STRING,CHAR)')
\\
.BREAK
.SKIP 1
COULD HAVE THE PROCEDURE
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
^^
DELETE## STRING CHAR   =   :S(DELETE)
########	DELETE  =   STRING	:(RETURN)
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
     ^A CALL OF THE FUNCTION IS ILLUSTRATED IN THE FOLLOWING STATEMENTS
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	MAGIC   =   'ABRACADABRA'
#####	OUTPUT   =   DELETE(MAGIC,'A')
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
WHICH PRINT ^^BRCDBR.\\
     ^ARGUMENTS ARE PASSED BY VALUE AND MAY BE ARBITRARILY COMPLEX 
EXPRESSIONS.  ^THUS THE STATEMENT
.BREAK
.SKIP 1
#####^^	TEXT   =   DELETE(TRIM(INPUT),' ')
.BREAK
\\
.SKIP 1
DELETES ALL BLANKS FROM THE INPUT STRING.
.BREAK
.SKIP 1
     ^FUNCTIONS CAN ALSO FAIL UNDER SPECIFIED CONDITIONS.  ^AS AN EXAMPLE,
CONSIDER THE FOLLOWING VERSION OF ^^DELETE\\, WHICH FAILS IF ^^STRING\\ DOES
NOT CONTAIN AN OCCURRENCE OF ^^CHAR\\.
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
^^
DELETE##	STRING	CHAR   =	:F(FRETURN)
D2######	STRING	CHAR   =	:S(D2)
########	DELETE	=   STRING	  :(RETURN)
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
.INDEX ^^FRETURN\\
^THE TRANSFER TO THE SYSTEM LABEL ^^FRETURN\\ INDICATES FAILURE OF THE
FUNCTION CALL.  ^CONSEQUENTLY,
.BREAK
.SKIP 1
#####^^	PUNCH   =   DELETE(TRIM(INPUT),'*')
\\
.BREAK
.SKIP 1
PUNCHES A CARD ONLY IF THE INPUT STRING CONTAINS AN * .
.BREAK
.SKIP 1
     ^ARGUMENTS TO A FUNCTION AND THE VALUE RETURNED CAN BE ANY TYPE
.INDEX ^^MAXNO\\
OF DATA OBJECT.  ^CONSIDER, FOR EXAMPLE, THE FUNCTION ^^MAXNO\\ WHERE
^^MAXNO(P,N)\\ RETURNS A  PATTERN THAT MATCHES UP TO ^N ADJACENT STRINGS
MATCHED BY THE PATTERN ^P.  ^THAT IS, IF
.BREAK
.SKIP 1
#####^^	PAT   =   MAXNO('A' ! 'B' ! 'C' ,2)
\\
.BREAK
.SKIP 1
THEN IN THE STATEMENT 
.BREAK
.SKIP 1
#####^^	'EBCDIC'  PAT  'D'
\\
.BREAK
.SKIP 1
THE PATTERN MATCH SUCCEEDS WITH ^^PAT\\ MATCHING THE STRING ^B^C.
.BREAK
.SKIP 1
     ^^MAXNO\\ HAS THE DEFINING STATEMENT
.BREAK
.SKIP 1
.INDEX ^^DEFINE\\
#####^^	DEFINE('MAXNO(P,N)')
\\
.BREAK
.SKIP 1
AND THE PROCEDURE
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
^^
MAXNO	N   =   GT(N,0) N - 1	:F(RETURN)
#####	MAXNO   =   NUL ! P MAXNO	:(MAXNO)
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
.INDEX ^^REVERSE\\
     ^CONSIDER THE FUNCTION ^^REVERSE\\ THAT REVERSES A STRING.  ^IT HAS 
THE DEFINING STATEMENT
.BREAK
.SKIP 1
#####^^	DEFINE('REVERSE(STRING)','R1')
\\
.BREAK
.SKIP 1
AND THE PROCEDURE
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
^^
R1###	ONECH   =   LEN(1) . CH
R2###	STRING  ONECH   =		:F(RETURN)
#####	REVERSE   =   CH  REVERSE	:(R2)
.BREAK
.SKIP 1
.FILL
.JUSTIFY
\\
^THERE ARE TWO VARIABLES, ^^ONECH\\ AND ^C^H, USED IN THE FUNCTION DEFINITION
IN ADDITION TO THE FUNCTION NAME AND FORMAL ARGUMENT.  ^IT IS PRUDENT
TO PROTECT THESE VARIABLES SO THEIR USE OUTSIDE THE FUNCTION IS NOT 
AFFECTED WHEN THE FUNCTION IS CALLED.  ^THIS IS ACCOMPLISHED BY DECLARING
THEM TO BE LOCAL VARIABLES IN THE DEFINING STATEMENT:
.BREAK
.SKIP 1
#####^^	DEFINE ('REVERSE(STRING)ONECH,CH','R1')
\\
.BREAK
.SKIP 1
^WHEN THE FUNCTION IS CALLED, THE CURRENT VALUES OF THE LOCAL VARIABLES,
THE FORMAL ARGUMENTS, AND THE FUNCTION NAME ARE SAVED BEFORE THE PROCEDURE
 IS ENTERED.  ^THESE VALUES ARE RESTORED UPON RETURN FROM THE
PROCEDURE.  ^THIS PERMITS THE PROGRAMMER CONSIDERABLE FREEDOM IN DEFINING
.INDEX RECURSIVE
FUNCTIONS.  ^FOR EXAMPLE, A FUNCTION CAN BE RECURSIVE, I.E. INCLUDE A
CALL OF THE FUNCTION ITSELF.  ^CONSIDER THE BINOMIAL COEFFICIENT
^^C(N,M)\\ WHICH CAN BE DEFINED BY EQUATIONS
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	C(N,0) = 1
#####	C(N,M) = N*C(N-1,M-1)/M    FOR M>0
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
^COMPUTATIONAL EFFICIENCY CAN BE IMPROVED BY EMPLOYING THE RELATION
.BREAK
.SKIP 1
#####^^	C(N,M) = C(N,N-M)
\\
.BREAK
.SKIP 1
FOR ^M> ^N/2.
.BREAK
.SKIP 1
^THE CORRESPONDING PROGRAMMER-DEFINED FUNCTION CONSISTS OF THE DEFINING
STATEMENT
#####^^	DEFINE('C(N,M')
\\
.BREAK
.SKIP 1
AND THE PROCEDURE
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
^^
C#####	M  =  LT(N - M,M) N - M
######	C  =  EQ(M,0) 1		    :S(RETURN)
######	C  =  N * C(N - 1,M - 1) / M   :(RETURN)
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
.INDEX ^^COMB\\
	^^COMB\\ IS AN EXAMPLE OF ANOTHER RECURSIVELY DEFINED FUNCTION. 
^^COMB(STR,N)\\ LISTS ALL COMBINATIONS OF ^N CHARACTERS FROM THE STRING
^^STR\\.  ^THE DEFINING STATEMENT AND PROCEDURE ARE
.BREAK
.SKIP 1
#####^^	DEFINE('COMB(STR,N,HEAD)CH')
\\
.BREAK
.SKIP 1
AND
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
^^
COMB###	OUTPUT = EQ(N,0) HEAD	:S(RETURN)
C2#####	STR LE(N,SIZE(STR)) LEN(1) . CH =	:F(RETURN)
#######	COMB(STR,N - 1,HEAD CH)	   :(C2)
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
THEN
.BREAK
.SKIP 1
#####^^	COMB('ABCD',3)
\\
.BREAK
.SKIP 1
PRINTS
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
^^ABC
ABD
ACD
BCD
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
	^NOTICE THAT ^^COMB\\ IS DEFINED WITH THREE FORMAL ARGUMENTS
BUT ONLY TWO VALUES ARE SUPPLIED IN THE INITIAL CALL.  ^THE MISSING
VALUE IS TAKEN TO BE ^^NULL\\.
.BREAK
.SKIP 1
.INDEX KEYWORDS
^^I.	KEYWORDS
\\
.SKIP 1
.BREAK
.SKIP 1
^SEVERAL PARAMETERS AND SWITCHES INTERNAL TO THE ^^SNOBOL\\4 SYSTEM
CAN BE ACCESSED BY MEANS OF KEYWORDS.  ^KEYWORDS ARE SPECIFIED BY
PREFIXING AN AMPERSAND TO CERTAIN IDENTIFIERS.  ^FOR EXAMPLE, IF THE
.INDEX ^^DUMP\\
.INDEX _&^^DUMP\\
VALUE OF THE KEYWORD _&^^DUMP\\ IS A NONZERO INTEGER WHEN A PROGRAM
TERMINATES, A DUMP OF NATURAL VARIABLES IS PRINTED.  ^THUS THE
EXECUTION OF THE STATEMENT
.BREAK
.SKIP 1
#####^^	_&^^DUMP\\ = 1
.BREAK
.SKIP 1
.INDEX ^^TRIM\\
.INDEX _&^^TRIM\\
INDICATES THAT A DUMP IS TO BE PRODUCED.  _&^^TRIM\\ CONTROLS THE TRIMMING
OF TRAILING BLANKS.  ^IF THE VALUE OF _&^^TRIM\\ IS GREATER THAN ZERO, INPUT 
RECORDS ARE TRIMMED.  ^THE DEFAULT VALUE OF _&^^TRIM\\ IS ZERO.
.BREAK
.SKIP 1
.INDEX ^^INPUT\\
.INDEX ^^OUTPUT\\
.INDEX _&^^INPUT\\
.INDEX _&^^OUTPUT\\
_&^^INPUT\\ AND _&^^OUTPUT \\CONTROL INPUT AND OUTPUT.
^IF _&^^INPUT\\ IS GREATER THAN ZERO, AUTOMATIC INPUT IS PERFORMED THROUGH
INPUT ACCOCIATIONS.  ^IF _&^^INPUT\\ IS ZERO, HOWEVER, SUCH ASSOCIATIONS ARE
IGNORED AND AUTOMATIC INPUT CEASES.  _&^^OUTPUT\\ CONTROLS AUTOMATIC OUTPUT
IN A SIMILIAR MANNER.  ^THE DEFAULT VALUE OF _&^^INPUT\\ AND _&^^OUTPUT\\ IS 1.

.BREAK
.SKIP 1
.INDEX ^^ARRAY\\
^^J.  ARRAYS
\\
.BREAK
.SKIP 1
.SKIP 1
^ARRAYS OF VARIABLES CAN BE CREATED BY USING THE PRIMITIVE FUNCTION
^^ARRAY\\.  ^THE ARGUMENTS OF ^^ARRAY\\ DESCRIBE THE NUMBER OF DIMENSIONS, THE
BOUNDS OF EACH DIMENSION, AND THE INITIAL VALUE OF EACH VARIABLE IN THE
ARRAY.  ^THUS
.BREAK
.SKIP 1
#####^^	V  =  ARRAY(10,1.0)
\\
.BREAK
.SKIP 1
CREATES AND ASSIGNS TO ^V A ONE DIMENSIONAL ARRAY OF TEN VARIABLES,
EACH INITIALIZED TO THE REAL VALUE 1.0.  ^THE CREATED VARIABLES CAN
BE REFERENCED BY EXPRESSIONS OF THE FORM ^^V<I>\\ WHERE ^I  =  1,...,10.
THE STATEMENT
.BREAK
.SKIP 1
#####^^	N  =  ARRAY('3,5')
\\
.BREAK
.SKIP 1
CREATES A 2-DIMENSIONAL ARRAY OF VARIABLES
.BREAK
.SKIP 1
.BREAK
.NOFILL
.NOJUSTIFY
^^
#####	N<1,1>   N<1,2>   N<1,3>   N<1,4>   N<1,5>
.BREAK
.SKIP 1
#####	N<2,1>	   _.	    _.	     _.	      _.
.BREAK
.SKIP 1
#####	N<3,1>	   _.	    _.	     _.	    N<3,5>
.BREAK
\\
.SKIP 1
.FILL
.JUSTIFY
THE OMISSION OF THE SECOND ARGUMENT CAUSES EACH OF THE VARIABLES TO
HAVE THE ^^NULL\\ STRING AS INITIAL VALUE.  ^THE ARGUMENTS IN THE CALL OF
.INDEX ^^ARRAY\\
^^ARRAY\\ CAN BE EXPRESSIONS.  ^THUS
.BREAK
.SKIP 1
#####^^	A  =  ARRAY(TRIM(INPUT))
\\
.BREAK
.SKIP 1
CREATES AN ARRAY WITH DIMENSIONALITY THAT IS DATA DEPENDENT.  ^AN ARRAY
REFERENCE, ^^A<I>\\, THAT IS OUTSIDE THE BOUNDS OF THE ARRAY CAUSES FAILURE
THAT CAN BE USED TO CONTROL PROGRAM FLOW.  ^THE STATEMENTS
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####^^	I  = 1
#####	ST  =  ARRAY(TRIM(INPUT))
MORE#	ST<I>  =  INPUT				:F(GO)
#####	I  =  I  +  1				:(MORE)
GO
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
GENERATE AN ARRAY, ^^ST\\, AND ASSIGN VALUES TO EACH OF THE VARIABLES.
^WHEN ALL THE VARIABLES IN THE ARRAY ARE ASSIGNED VALUES, OR AN END
OF FILE IS ENCOUNTERED, THE TRANSFER TO ^^GO\\ IS EXECUTED.
.BREAK
.SKIP 1

.INDEX PROGRAMMER DEFINED
^^K.  PROGRAMMER-DEFINED DATA TYPES
\\
\\
.BREAK
.SKIP 1
.INDEX ^^INTEGER\\
.INDEX ^^REAL\\
.INDEX ^^STRINGS\\
.INDEX ^^PATTERNS\\
.INDEX ^^ARRAY\\
   ^^INTEGERS\\^^, REALS, STRINGS, PATTERNS\\, AND ^^ARRAYS\\ ARE TYPES OF DATA
OBJECTS THAT ARE BUILT INTO THE ^^SNOBOL\\4  LANGUAGE.  ^FACILITIES ARE
PROVIDED IN THE LANGUAGE TO PERMIT A PROGRAMMER TO DEFINE ADDITIONAL
DATA TYPES.  ^THIS FACILITATES REPRESENTATION OF STRUCTURAL RELATIONSHIPS
 INHERENT IN DATA.
    ^FOR EXAMPLE, A SIMPLE LINEAR LINKED LIST IS MADE UP OF NODES, EACH
CONTAINING A ^^VALUE\\ FIELD AND A ^^LINK\\ FIELD.
.BREAK
.SKIP 1

.INDEX ^^DATA\\
    ^THE PRIMITIVE FUNCTION ^^DATA\\ CAN BE USED TO DEFINE THE DATA TYPE
^^NODE\\ AND THE TWO FIELD FUNCTIONS, ^^VALUE\\ AND ^^LINK\\.
.BREAK
.SKIP 1
#####^^	DATA('NODE(VALUE,LINK)')
\\
.BREAK
.SKIP 1
^THE STATEMENT
.BREAK
.SKIP 1
#####^^	P  =  NODE('S',)
\\
.BREAK
.SKIP 1
CREATES A NODE WITH ^^VALUE\\ FIELD  ^S  AND THE ^^NULL\\ STRING IN THE ^^LINK\\
FIELD.  ^THE VALUE OF ^P IS A DATA OBJECT WITH TWO FIELDS THAT CAN BE
REFERENCED BY MEANS OF THE FUNCTION CALLS ^^VALUE(P)\\ AND ^^LINK(P)\\.  ^THE
INSERTION OF A NODE WITH VALUE ^T AT THE HEAD OF THE LIST IS ACCOMPLISHED
 BY THE STATEMENT
.BREAK
.SKIP 1
#####^^	P  =  NODE('T',P)
\\
.BREAK
.SKIP 1
^THE FOLLOWING STATEMENT DELETES A NODE FROM THE HEAD OF THE LIST
.BREAK
.SKIP 1
#####^^	P  =  LINK(P)
\\
.BREAK
.SKIP 1

.INDEX ^^PROGRAM EXAMPLE\\
^^L.  PROGRAM EXAMPLE
\\
.BREAK
.SKIP 1
    ^THIS IS AN EXAMPLE OF A COMPLETE ^^SNOBOL\\4 PROGRAM ILLUSTRATING
THE USE OF COMMENT LINES, CONTINUATION LINES, AND THE ^^END\\ STATEMENT.
^THE PROGRAM READS IN DATA CARDS THAT FOLLOW THE ^^END\\ STATEMENT.
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
^^
************************************************************
*	EXAMPLE OF A FUNCTION THAT PRINTS ALL
*	PERMUTATIONS OF SIZE N FROM A GIVEN STRING.
************************************************************
.BREAK
.SKIP 1
#######	&DUMP	= 1
#######	DEFINE('PERM(STRING,N,HEAD)CH,USED')
.BREAK
.SKIP 1
#######	STRING  =  TRIM(INPUT)			:F(ERROR)
#######	N  =  TRIM(INPUT)			:F(ERROR)
#######	PERM(STRING,N)				:(END)
PERM###	OUTPUT  =  EQ(N,0)  HEAD		:S(RETURN)
PERMA##	STRING  LEN(1)  .  CH  =		:F(RETURN)
#######	USED
_.######	=  PERM(STRING USED,N - 1,HEAD CH)  USED CH	:(PERMA)
END
ABCD
3
.SKIP 1
.FILL
.JUSTIFY
\\
.BREAK
.SKIP 1
.INDEX ^^TABLE\\
.INDEX ^^ARRAY\\
^^M.  TABLES
\\
.SKIP 1
.BREAK
.SKIP 1
   ^A ^^TABLE\\ IS SIMILAR TO AN ^^ARRAY\\ EXCEPT THAT IT IS LIMITED TO ONE
DIMENSION, AND ITS ARGUMENT IS NOT RESTRICTED TO AN ^^INTEGER\\, BUT MAY
BE ANY VALUE.  ^A ^^TABLE\\ MAY BE THOUGHT OF AS AN ^^ARRAY\\ THAT PERMITS
ASSOCIATIVE REFERENCES.
.BREAK
.SKIP 1
.INDEX ^^TABLE\\
    ^A ^^TABLE\\ IS CREATED BY THE ^^TABLE\\ FUNCTION.  ^FOR EXAMPLE,
.BREAK
.SKIP 1
#####^^	T   =   TABLE()
\\
.BREAK
.SKIP 1
CREATES A ^^TABLE\\ AND ASSIGNS IT AS THE VALUE OF ^T.  ^ENTRIES IN THE
TABLE  ^T  MAY SUBSEQUENTLY BE REFERRED TO IN MUCH THE SAME WAY AS
^^ARRAY\\ REFERENCES ARE MADE.  ^FOR EXAMPLE,
.BREAK
.SKIP 1
#####^^	T<'A'>   =   3
\\
.BREAK
.SKIP 1
ASSIGNS THE VALUE 3 TO THE "^ATH" ELEMENT OF ^T.
.BREAK
.SKIP 1
    ^THE REFERENCING ARGUMENT MAY BE ANY VALUE WITH ANY DATA TYPE.
^SIMPLY BY REFERRING TO THE ELEMENT, THE APPROPRIATE TABLE ELEMENT
IS REFERENCED.  ^IF NO SUCH ELEMENT EXISTS, ONE IS CREATED AND
GIVEN THE ^^NULL\\ STRING AS ITS INITIAL VALUE.
.BREAK
.SKIP 1
.INDEX ^^COPY\\
^TABLES CANNOT BE COPIED USING THE ^^COPY\\ FUNCTION.  ^THE FUNCTION ^^ITEM\\
CAN BE USED FOR TABLES AS WELL AS FOR ARRAYS.
.BREAK
.SKIP 1
    ^PROGRAMMERS ARE CAUTIONED THAT ^^T<1>\\ AND ^^T<'1'>\\ REFERENCE DIFFERENT
ELEMENTS OF ^T.  ^PARTICULAR CARE MUST BE USED WHEN THE ARGUMENT IS THE
VALUE OF AN EXPRESSION.
.BREAK
.SKIP 1
    ^THE ^^TABLE\\ FUNCTION ACTUALLY HAS TWO ARGUMENTS, BOTH OF WHICH MAY
BE OMITTED AS ILLUSTRATED IN THE EXAMPLE ABOVE.  ^THE GENERAL FORM OF
THE FUNCTION IS
.BREAK
.SKIP 1
#####^^	TABLE(N,M)
\\
.BREAK
.SKIP 1
WHERE ^N AND ^M CONCERN THE SIZE OF THE TABLE.  ^N  DETERMINES THE
INITIAL SIZE OF THE TABLE, INDICATING HOW MANY ELEMENTS IT CAN
CONTAIN.  ^M IS THE NUMBER OF ADDITIONAL ELEMENTS PROVIDED IF MORE
ARE REQUIRED.  ^FOR EXAMPLE,
.BREAK
.SKIP 1
#####^^	TABLE(20,15)
\\
.BREAK
.SKIP 1
SPECIFIES A ^^TABLE\\ OF 20 ELEMENTS.  ^IF MORE ARE REQUIRED, THE TABLE
SIZE IS INCREASED TO 35.  ^IF THIS IS NOT SUFFICIENT, THE SIZE IS
INCREASED TO 50, AND SO ON.
	^THE DEFAULT VALUES FOR ^N AND ^M ARE 10.  ^IF EITHER ARGUMENT IS
OMITTED (OR ZERO), THE CORRESPONDING DEFAULT IS USED.  ^EFFICIENT USE
OF TABLES IS OBTAINED BY SPECIFYING VALUES CORRESPONDING APPROXIMATELY
TO THE EXPECTED ^^TABLE\\ SIZES.
.BREAK
.SKIP 1
	^CONVERSION BETWEEN TABLES AND ARRAYS MAY BE PERFORMED USING
.INDEX ^^CONVERT\\
THE ^^CONVERT\\ FUNCTION.  ^IF ^T IS A ^^TABLE\\,
.BREAK
.SKIP 1
.INDEX ^^ARRAY\\
.INDEX ^^CONVERT\\
#####^^	A  =  CONVERT(T,'ARRAY')
\\
.BREAK
.SKIP 1
ASSIGNS TO ^A AN ^^ARRAY\\ CORRESPONDING TO THE ^^TABLE T\\.  ^THE ^^PROTOTYPE\\ OF
^A IS '^N,2' WHERE ^N IS THE NUMBER OF ITEMS IN ^T THAT HAVE NONNULL VALUES.
^^A<I,1>\\ IS A REFERENCE ELEMENT OF ^T AND ^A<I,2>\\ IS THE VALUE OF THAT 
ELEMENT.  ^THE ORDER OF THE ITEMS IN ^A IS UNPREDICTABLE.  ^ONLY ITEMS
WITH NONNULL VALUES ARE INCLUDED.  ^CONVERSION FROM ^^TABLE\\ TO ^^ARRAY\\ DATA
TYPE FAILS IF THERE IS NO ITEM WITH A NONNULL VALUE.
.BREAK
.SKIP 1
	^A RECTANGULAR ARRAY WITH A SECOND DIMENSION THAT HAS AN EXTENT
OF TWO CAN BE CONVERTED TO A ^^TABLE\\.  ^FOR EXAMPLE, IF ^R IS AN ^^ARRAY\\ WITH
THE ^^PROTOTYPE\\ '-3:3,2',
.BREAK
.SKIP 1
#####^^	B  =  CONVERT(R,'TABLE')
\\
.BREAK
.SKIP 1
CREATES A ^^TABLE\\ ^B OF 7 ITEMS CORRESPONDING TO ^^R<I,1>\\
AND WITH THE VALUES OF THESE ITEMS BEING ^^R<I,2>\\ RESPECTIVELY.
.BREAK
.SKIP 1
	^THE VALUE USED FOR ADDITIONAL ITEMS (CORRESPONDING TO ^M IN
^^TABLE(N,M)\\ IS THE DEFAULT, 10.
.BREAK
.SKIP 1
	^IN OUTPUT, TRACE MESSAGES, DUMPS AND OTHER SITUATIONS WHERE
DATA TYPE REPRESENTATIONS ARE REQUIRED, TABLES APPEAR AS ^^TABLE(N,M)\\.
^FOR EXAMPLE, THE STATEMENT
.BREAK
.SKIP 1
#####^^	OUTPUT  =  B
\\
.BREAK
.SKIP 1
RESULTS IN THE PRINTOUT
.BREAK
.SKIP 1
^^TABLE(7,10)
\\
.;CHAPTER 4  9-4-70 AT MAYNARD
.TITLE ^^PDP\\-10 ^SNOBOL4 ^USER'S ^GUIDE
.SUBTITLE ^^CHAPTER 4\\
.SPACING 1

.PAGE
.INDEX ^^INPUT\\
.INDEX ^^OUTPUT\\
.INDEX ^I/^O
^^INPUT AND OUTPUT\\ 
.BREAK
.SKIP 2
.BREAK
.SKIP 1

	^^INPUT\\ AND ^^OUTPUT\\ ARE ACCOMPLISHED BY ASSOCIATING VARIABLES
WITH DEVICES OR FILENAMES.  ^IN THE CASE OF A VARIABLE ASSOCIATED IN
THE ^^OUTPUT\\ SENSE, EACH TIME THE VARIABLE IS ASSIGNED A VALUE, A COPY
OF THE VALUE IS PUT OUT ONTO THE ASSOCIATED DEVICE OR FILE.  ^IN THE 
CASE OF A VARIABLE ASSOCIATED IN THE ^^INPUT\\ SENSE, EACH TIME THE VALUE
OF THE VARIABLE IS USED, A NEW VALUE IS READ FROM THE ASSOCIATED 
DEVICE OR FILE AND BECOMES THE NEW VALUE OF THE VARIABLE.  ^THUS INPUT
AND OUTPUT GO ON DURING PROGRAM EXECUTION WITHOUT ANY EXPLICIT ^I/^O 
STATEMENTS, AS A RESULT OF ^I/^O ASSOCIATIONS.  ^VARIABLES HAVING STANDARD
 ASSOCIATIONS ARE DESCRIBED IN THE FOLLOWING SECTIONS.
.BREAK
.SKIP 1

.INDEX ^^PRINTED OUTPUT\\
^^A. PRINTED OUTPUT\\
.SKIP 2
.BREAK
.SKIP 1

	^THE VARIABLE ^^OUTPUT\\ IS ASSOCIATED WITH A DEVICE OR FILE WHICH
IS SELECTED AT RUN TIME BY THE USER, FOR INSTANCE, THE LINE PRINTER.
^CONSEQUENTLY, WHENEVER ^^OUTPUT\\ IS ASSIGNED A VALUE, PRINTOUT IS GENERATED.
  ^FOR EXAMPLE,
.BREAK
.SKIP 1

#####		^^OUTPUT = 'THE SELECTED VALUES ARE\\'
.BREAK
.SKIP 1

PRODUCES THE OUTPUT
.BREAK
.SKIP 1

^^THE SELECTED VALUES ARE\\
.BREAK
.SKIP 1

^OUTPUT MAY ALSO RESULT FROM VALUE ASSIGNMENT SPECIFIED IN PATTERNS.
^FOR EXAMPLE,
.BREAK
.SKIP 1

^^
.NOFILL
.NOJUSTIFY
#####		PEXP = BAL . EXP1 . OUTPUT '+' BAL . EXP2 . OUTPUT
#####		     .
#####		     .
#####		     .
#####		EXP PEXP
\\
.FILL
.JUSTIFY
.BREAK
.SKIP 1

PRINTS THE TWO TERMS IN ^^EXP\\, AND ASSIGNS THEIR VALUES TO ^^EXP\\1 AND ^^EXP\\2.
^THIS TYPE OF OUTPUT IS OFTEN USEFUL FOR DIAGNOSTIC PURPOSES, AND DOES
NOT AFFECT THE PATTERN MATCHING OR THE ASSIGNMENTS MADE TO ^^EXP\\1 AND 
^^EXP\\2.
.BREAK
.SKIP 1

	^ORDINARY PRINTOUT IS PRINTED 132 CHARACTERS PER LINE, WITH
.INDEX ^^NULL\\
AS MANY LINES AS NECESSARY BEING GENERATED. ^THE ^^NULL\\ STRING IS  TREATED
AS A BLANK CHARACTER AND A BLANK LINE IS PRINTED FOR IT. (^ON THE
.INDEX ^^CARRIAGE RETURN\\
.INDEX ^^LINE FEED\\
^^PDP\\-10 THIS IS ACTUALLY OUTPUT AS A ^^CARRIAGE RETURN/LINE FEED\\).
^STRINGS ARE USUALLY ASSIGNED TO OUTPUT VARIABLES.  ^INTEGERS AND REAL
NUMBERS ASSIGNED TO AN OUTPUT VARIABLE ARE AUTOMATICALLY CONVERTED TO 
STRINGS.  ^IF AN ARRAY IS ASSIGNED TO AN OUTPUT VARIABLE, THE PRINTED
.INDEX ^^ARRAY\\
OUTPUT IS ^^ARRAY\\ WITH THE PROTOTYPE OF THE ARRAY ENCLOSED IN PARENTHESES.
^FOR EXAMPLE, THE STATEMENTS
.BREAK
.SKIP 1

^^
.NOFILL
.NOJUSTIFY
#####		MATRIX  =  ARRAY('-2:2,-3:3',0)
#####		OUTPUT  =  MATRIX
\\
.FILL
.JUSTIFY
.BREAK
.SKIP 1

PRINT
.BREAK
.SKIP 1

^^ARRAY('-2:2,-3:3')
\\


.BREAK
.SKIP 1
^IF THE PROTOTYPE IS LONGER THAN TWENTY CHARACTERS, ONLY THE STRING
^^ARRAY\\ IS PRINTED.  ^IF AN OBJECT WITH ANY OTHER DATA TYPE IS ASSIGNED
TO AN OUTPUT VARIABLE, THE FORMAL IDENTIFICATION OF ITS DATA TYPE IS
PRINTED.  ^FOR EXAMPLE,
.BREAK
.SKIP 1

#####^^OUTPUT = LEN(7)\\
.BREAK
.SKIP 1

PRINTS
.BREAK
.SKIP 1

^^PATTERN\\
.BREAK
.SKIP 1

.BREAK
.SKIP 1

.INDEX ^^PUNCHED OUTPUT\\
.INDEX ^^PUNCH\\
^^B. PUNCHED OUTPUT
.SKIP 2
.BREAK
.SKIP 1

\\
	^THE VARIABLE ^^PUNCH\\ IS ASSOCIATED WITH DEVICE NUMBER 7.
^CONSEQUENTLY, WHENEVER ^^PUNCH\\ IS ASSIGNED A VALUE, A LINE IS
PUNCHED ON THE CARD PUNCH. ^FOR EXAMPLE,
.BREAK
.SKIP 1

^^
###		PUNCH  =  0
\\
.BREAK
.SKIP 1

PUNCHES A CARD  WITH A ZERO IN COLUMN ONE.
.BREAK
.SKIP 1

	^ALL THE REMARKS ABOUT PRINT OUTPUT APPLY TO PUNCH OUTPUT.
.BREAK
.SKIP 1

.BREAK
.SKIP 1

.INDEX ^^INPUT\\
^C.  ^^INPUT\\
.BREAK
.SKIP 1

	^THE VARIABLE ^^INPUT\\ IS ASSOCIATED WITH THE STANDARD INPUT DATA
STREAM.  ^WHENEVER THE VALUE OF ^^INPUT\\ IS USED, A CARD IMAGE IS READ
FROM THE INPUT STREAM AND BECOMES THE NEW VALUE OF ^^INPUT\\.  ^FOR 
EXAMPLE,
.BREAK
.SKIP 1

#####		^^OUTPUT\\  =  ^^INPUT\\
.BREAK
.SKIP 1

READS A CARD IMAGE AND PRINTS IT.  ^SIMILARLY,
.BREAK
.SKIP 1

.INDEX ^^TRIM\\
#####		^^TRIM(INPUT)  BAL . EXP
\\
.BREAK
.SKIP 1

READS A CARD IMAGE AND MATCHES FOR A BALANCED STRING.  ^ALL EIGHTY 
COLUMNS OF THE CARD IMAGES ARE READ, BUT THE VALUE OF ^^INPUT\\ IS GENERALLY
 TRIMMED OF TRAILING BLANKS.
.BREAK
.SKIP 1

	^SINCE EACH USE OF ^^INPUT\\ READS A CARD IMAGE, PREVIOUS VALUES 
OF ^^INPUT\\ ARE LOST UNLESS THEY ARE ASSIGNED TO OTHER VARIABLES.
.BREAK
.SKIP 1

.INDEX END OF FILE
.INDEX ^^INPUT\\ FAILURE
	^IF AN END OF FILE IS ENCOUNTERED WHEN A VALUE OF ^^INPUT\\ IS REQUESTED,
 FAILURE RESULTS.  ^THIS FAILURE CAN BE USED TO DETECT THE END
OF A DATA FILE.  ^FOR EXAMPLE,

.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####	^I   =   1
^^
READ#	DATA<I>   =   INPUT		:F(OUT)
#####	I   =   I + 1			:(READ)
OUT
\\
.FILL
.JUSTIFY
.BREAK
.SKIP 1

READS CARD IMAGES INTO THE ARRAY ^^DATA\\ UNTIL THE INPUT DATA STREAM IS
EXHAUSTED (OR ^I EXCEEDS THE RANGE OF DATA).  ^CONTROL IS THEN 
TRANSFERRED TO ^^OUT\\.
.BREAK
.SKIP 1

.BREAK
.SKIP 1

.INDEX ^^I/O SYSTEM\\
^^D.  THE ^I/^O SYSTEM
\\
.BREAK
.SKIP 2
.SKIP 1

.INDEX ^^FORTRAN\\
	^ALL INPUT/OUTPUT IS HANDLED BY ^^FORTRAN IV ^I/^O\\ ROUTINES.  ^THAT
IS, ^^SNOBOL\\4 ^I/^O IS DONE BY THE SAME SYSTEM THAT DOES ^I/^O FOR ^^FORTRAN IV\\
OBJECT PROGRAMS.  ^CONSEQUENTLY, THE CONVENTIONS AND ^I/^O CONCEPTS 
SPECIFIED FOR THE ^^FORTRAN IV\\ LANGUAGE ALSO APPLY TO ^^SNOBOL\\4.  ^IN ADDITION,
 THE VERSION OF THE LANGUAGE DESCRIBED HERE OPERATES UNDER 
THE ^^PDP\\-10 ^TIME-^SHARING ^SYSTEMS, EITHER 10/40 OR 10/50.  ^IT IS 
NECESSARY TO UNDERSTAND BOTH THE FUNDAMENTALS OF ^^FORTRAN IV ^I/^O\\ AND THE
^^PDP\\-10 STANDARD ^^CUSP\\ TO USER INTERFACE IN ORDER TO DO ^^SNOBOL\\4 ^I/^O 
EFFECTIVELY.
.BREAK
.SKIP 1

.INDEX DEVICE NUMBERS
	IN ^^FORTRAN\\, DEVICES AND FILES HAVE ASSOCIATED NUMBERS.  ^THESE
NUMBERS ARE REFERRED TO IN SOURCE LANGUAGE PROGRAMS AND ARE
 ASSOCIATED WITH SPECIFIC DEVICES AND FILES AT RUN TIME.  ^THESE NUMBERS 
CORRESPOND TO AN INDEX INTO THE ^^FORTRAN\\ OPERATING SYSTEM'S DEVICE TABLE,
.INDEX DEVICE TABLE
.INDEX ^^DEVTB\\
CALLED ^^DEVTB\\.  ^A COPY OF THIS TABLE IS LISTED IN  ^APPENDIX ^B.  ^FILENAMES FOR 
DISK AND ^^DEC\\TAPE FILES ARE ESTABLISHED FOR THE STANDARD ^^INPUT\\ AND 
.INDEX ^^OUTPUT\\
^^OUTPUT\\ STREAMS BY THE USER AT STARTUP TIME.  ^FILENAMES CAN ALSO
.INDEX ^^IFILE\\
.INDEX ^^OFILE\\
BE ESTABLISHED VIA THE ^^IFILE\\ AND ^^OFILE\\ PRIMITIVE FUNCTIONS AS DESCRIBED
LATER.
.BREAK
.SKIP 1

	^THE ^^FORTRAN\\ ^I/^O USED IN ^^SNOBOL\\4 ONLY HANDLES SEQUENTIAL DATA 
.INDEX RANDOM ACCESS
SETS. ^IN PARTICULAR, IT CANNOT HANDLE RANDOM ACCESSING OF FILES.
.BREAK
.SKIP 1

.INDEX SOURCE FILES
.INDEX MULTIPLE SOURCE FILES
	^^SNOBOL\\ ON THE ^^PDP\\-10 HANDLES MULTIPLE SEGMENT SOURCE FILES FOR
INPUT.  ^THIS ALLOWS THE USER TO SEGMENT HIS CODING INTO SHORT ROUTINES
AND TO USE COMMON ROUTINES RESIDING ON THE SYSTEM AREA OF THE DISK.
.BREAK
.SKIP 1

.INDEX COMMAND
.INDEX COMMAND STRING
	^THUS, FOR EXAMPLE, A USER MAY SPECIFY THE FOLLOWING COMMAND 
STRING
^^
.BREAK
.SKIP 1
LPT:__SYS:COMMON,DSK:ONE,TWO,THREE
\\
.BREAK
.SKIP 1

.INDEX LISTING
.INDEX LISTING FILE
WHICH WOULD PLACE THE OUTPUT LISTING FILE ON THE LINE PRINTER AND
 COMPILE THE FILE NAMED ^^COMMON\\ (LOCATED ON THE SYSTEM AREA OF THE DISK)
FOLLOWED BY THE FILES NAMED^^ ONE,TWO,THREE\\ LOCATED ON THE USER'S 
DISK AREA.
.BREAK
.SKIP 1

.INDEX ^^END\\
	^IF AFTER THIS COMMAND STRING HAS BEEN EXHAUSTED AND NO ^^END\\ STATEMENT
 HAS BEEN SEEN, THE SYSTEM WILL THEN ACCEPT FURTHER INPUT FROM THE
USER'S TERMINAL.  ^TO LET THE USER KNOW ADDITIONAL INPUT IS EXPECTED
FROM HIM, THE MESSAGE
.BREAK
.SKIP 1
.INDEX ^^WAITING FOR TTY INPUT\\
^^WAITING FOR TTY INPUT\\
.BREAK
.SKIP 1
IS PRINTED ON THIS TERMINAL.

.INDEX COMMAND SYNTAX
^THIS SYNTAX ALLOWS THE USER TO SPECIFY AT RUNTIME WHICH ASSOCIATIONS
HE DESIRES FOR THE STANDARD INPUT AND OUTPUT STREAMS.  ^THIS SPECIFICATION
 DETERMINES WHERE THE RESULTS OF ^^INPUT\\ ARE TO COME FROM AND WHERE
THE RESULTS OF ^^OUTPUT\\ ARE TO GO.
.BREAK
.SKIP 1

^ADDITIONAL EXAMPLES ARE
.BREAK
.SKIP 1

^^
.BREAK
.NOFILL
.NOJUSTIFY
#####LPT:__CDR:
#####TTY:__CDR:
#####LPT:__DSK:PROG1
#####TTY:__TTY:
\\
.FILL
.JUSTIFY
.BREAK
.SKIP 1

^IN GENERAL ANY DEVICE CAPABLE OF OUTPUT CAN BE SPECIFIED ON THE LEFT
SIDE OF THE ARROW AND ANY DEVICE CAPABLE OF INPUT CAN BE SPECIFIED TO
THE RIGHT OF THE ARROW.  ^THESE ARE SUMMARIZED BELOW.
.BREAK
.SKIP 1

^^GENERAL FORMAT
\\
.BREAK
.SKIP 1

.INDEX LISTING DEVICE
.INDEX SOURCE DEVICE
.INDEX SOURCE FILE
^^	LISTING-DEVICE:FILENAME.EXT__SOURCE-DEVICE:FILENAME.EXT, ...
\\
.BREAK
.SKIP 1

^^
	    (1)	LISTING-DEVICE:\\ ^THE DEVICE ON WHICH THE ^^OUTPUT\\
		PRODUCED BY ^^SNOBOL\\ IS TO BE WRITTEN.
.BREAK
.SKIP 1

.NOFILL
.NOJUSTIFY
#####		^^MTA\\N:##^MAGNETIC ^TAPE
#####		^^DTA\\N:##^^DEC\\ ^TAPE
#####		^^DSK\\:###^DISK
#####		^^PTP\\:###^PAPER ^TAPE ^PUNCH
#####		^^LPT\\:###^LINE ^PRINTER
#####		^^TTY\\:###^TELETYPE
#####		^^CDP\\:###^CARD ^PUNCH
.FILL
.JUSTIFY
.BREAK
.SKIP 1

.INDEX SOURCE DEVICE
.INDEX SOURCE FILE
^^	    (1)	SOURCE-DEVICE:\\  ^THE DEVICE FROM WHICH THE SOURCE PROGRAM
\\
		^^INPUT\\ TO COMPILATION IS TO BE READ.
.BREAK
.SKIP 1

.NOFILL
.NOJUSTIFY
#####		^^MTA\\N:##^MAGNETIC ^TAPE
#####		^^DTA\\N:##^^DEC\\ ^TAPE
#####		^^DSK\\:###^DISK
#####		^^TTY\\:###^TELETYPE
#####		^^CDR\\:###^CARD ^READER
#####		^^PTR\\:###^PAPER ^TAPE ^READER
.FILL
.JUSTIFY
.BREAK
.SKIP 1

^^FILENAME.EXT (DSK:\\ AND ^^DTA\\N:ONLY)  ^THE FILENAME AND FILENAME EXTENSION
\\
		OF THE LISTING AND THE SOURCE FILES.
.BREAK
.SKIP 1

		IF .^^EXT\\ IS OMITTED, .^^LST\\ IS ASSUMED FOR THE LISTING
		FILE AND .^^SNO\\ IS ASSUMED FOR THE SOURCE FILE.
.BREAK
.SKIP 1

(1) IF A DEVICE IS NOT SPECIFIED, "^^DSK\\:" IS ALWAYS ASSUMED.

.BREAK
.SKIP 2
.INDEX ^^OUTPUT ASSOCIATIONS\\
^^E. OUTPUT ASSOCIAITONS
\\
.BREAK
.SKIP 2
.BREAK
.SKIP 1

.INDEX ^^OUTPUT\\
.INDEX ^^PUNCH\\
    ^THE VARIABLES ^^OUTPUT\ AND ^^PUNCH\\ HAVE PREDEFINED OUTPUT\ ASSOCIATIONS.
^PROGRAMMER-DEFINED ASSOCIATIONS MAY BE MADE USING THE FUNCTION ^^OUTPUT\\.
^THE FORM OF THE FUNCTION IS
.BREAK
.SKIP 1

.INDEX ^^FORMAT\\
.INDEX ^^OUTPUT\\
#####	^^OUTPUT(NAME,NUMBER,FORMAT)
\\
.BREAK
.SKIP 1

^^OUTPUT\\ ASSOCIATES THE NAME WITH THE DEVICE REFERENCE NUMBER ACCORDING
TO THE GIVEN FORMAT.  ^THE FORMAT IS A STRING SPECIFYING A ^^FORTRAN\\ ^I^V
^^FORMAT\\.  ^THE FOLLOWING STATEMENTS CORRESPOND TO THE ASSOCIATIONS FOR
THE VARIABLES ^^OUTPUT\\ AND ^^PUNCH\\:
.BREAK
.SKIP 1

.NOFILL
.NOJUSTIFY
#####	^^OUTPUT\\('^^OUTPUT\\',6,'(1^X,27^A5)')
#####	^^OUTPUT('PUNCH',7,'(16A5)')
\\
.FILL
.JUSTIFY
.BREAK
.SKIP 1

    ^USING THE ^^OUTPUT\\ FUNCTION, ANY VARIABLE CAN BE ASSOCIATED WITH
ANY DEVICE REFERENCE NUMBER.  ^FOR EXAMPLE,
.BREAK
.SKIP 1

.NOFILL
.NOJUSTIFY
#####^^	PRFORM  =  '(1X,27A5)'
#####	TEST  =  ARRAY('8,8')
#####	OUTPUT(.TEST<1,1>,6,PRFORM)
#####	OUTPUT(.TEST<8,8>,6,PRFORM)
\\
.FILL
.JUSTIFY
.BREAK
.SKIP 1

ASSOCIATE THE ARRAY ELEMENTS ^^TEST\\<1,1> AND ^^TEST\\<8,8> WITH THE ORDINARY
PRINT FILE AND WITH THE STANDARD PRINT FORMAT.  ^AS A RESULT, WHENEVER
EITHER ^^TEST\\<1,1> OR ^^TEST\\<8,8> IS ASSIGNED A VALUE, THE NEW VALUE IS
PRINTED.
.BREAK
.SKIP 1

.INDEX DEVICE NUMBERS
.INDEX DEVICE REFERENCE NUMBERS
    ^DEVICE REFERENCE NUMBERS ARE NOT RESTRICTED TO 5 AND 6, BUT CAN
RANGE FROM 1 THROUGH 37 .  ^ASSOCIATIONS CAN BE MADE WITH REFERENCE
NUMBERS OTHER THAN THE STANDARD ONES.  ^IN THIS CASE, JUST SET UP THE
APPROPRIATE ^^OUTPUT\\ STATEMENT, PERHAPS IN CONJUNCTION WITH THE ^^IFILE\\
PRIMITIVE FUNCTION IF THE DEVICE IS FILE ORIENTED.
.BREAK
.SKIP 1

.INDEX ^^FORMAT\\
.INDEX FORMAT STATEMENT
    ^FORMATS USED IN ^^OUTPUT\\ ASSOCIATION MUST SPECIFY THE CONVERSION OF
AT LEAST ONE ELEMENT BY ^A-CONVERSION.  (^NORMALLY N^A5-CONVERSION IS USED.)
^INTEGERS ARE CONVERTED INTO STRINGS AND ^I CONVERSION MUST NOT BE USED.
.INDEX ^A ^^FORMAT\\
.INDEX ^^X FORMAT\\
.INDEX ^^H FORMAT\\
.INDEX ^^T FORMAT\\
.INDEX CARRIAGE CONTROL
^IN ADDITION TO ^A CONVERSION, QUOTED LITERALS, ^X , ^H , AND ^T CONVERSION
MAY BE SPECIFIED.  ^CARRIAGE CONTROL MUST BE PROVIDED FOR PRINTING;
OTHERWISE THE FIRST CHARACTER OF THE STRING IS CONSUMED FOR THIS 
PURPOSE.  ^CONSIDER
.BREAK
.SKIP 1

#####	^^OUTPUT('TITLE',6,'(1H1,27A5_/(1^X,27^A5))')
\\
.BREAK
.SKIP 1

^WHEN A VALUE IS ASSIGNED TO ^^TITLE\\, A PAGE IS EJECTED AND THE VALUE
TITLES THE NEXT PAGE OF OUTPUT.  ^THE USE OF LITERALS IS ILLUSTRATED
BY
.BREAK
.SKIP 1

#####	^^OUTPUT('SUM',6,"(' SUM='25A5_/(1X,27A5))")
\\
.BREAK
.SKIP 1

WHICH INCLUDES IDENTIFYING INFORMATION WITH THE FORMAT.  ^SUBSEQUENTLY,
.BREAK
.SKIP 1

^^#####	SUM  =  300

\\
.BREAK
.SKIP 1

CAUSES THE PRINTOUT
.BREAK
.SKIP 1

^^SUM=300
\\
.BREAK
.SKIP 1

^THE PREDEFINED ASSOCIATIONS CAN BE CHANGED.  ^THUS,
.BREAK
.SKIP 1

#####		^^OUTPUT('OUTPUT',6,'(1X,24A5)')
\\
.BREAK
.SKIP 1

SHORTENS THE LINE LENGTH FOR ^^OUTPUT\\ TO 120 CHARACTERS.
.BREAK
.SKIP 1

.BREAK
.SKIP 1

.INDEX ^^INPUT ASSOCIATIONS\\
^^F. INPUT ASSOCIATIONS\\
.BREAK
.SKIP 2
.BREAK
.SKIP 1

	^PROGRAMMER-DEFINED INPUT ASSOCIATIONS CAN BE MADE USING THE 
FUNCTION ^^INPUT\\.  ^THE FORM OF THIS FUNCTION IS
.BREAK
.SKIP 1

#####		^^INPUT(NAME,NUMBER,LENGTH)
\\
.BREAK
.SKIP 1

.INDEX DEVICE REFERENCE NUMBER
^^INPUT\\ ASSOCIATES THE NAME WITH THE DEVICE REFERENCE NUMBER, AND
SPECIFIES THAT THE RESULTING STRING IS TO HAVE THE GIVEN LENGTH.
.INDEX ^^FORMAT\\
(^NOTICE IN PARTICULAR THAT NO ^^FORMAT\\ IS SPECIFIED.)  ^^INPUT\\ HAS A
PREDEFINED ASSOCIATION EQUIVALENT TO
.BREAK
.SKIP 1

#####		^^INPUT\\('^^INPUT\\',5,80)
.BREAK
.SKIP 1

^THE SPECIFIED LENGTH HAS SOME SPECIAL PROPERTIES.  ^IF THE LENGTH IS
LESS THAN THE RECORD SIZE ON THE FILE BEING READ, THE LAST PART OF
THE RECORD IS LOST.  ^HENCE,
.BREAK
.SKIP 1

.INDEX ^^INPUT\\
#####		^^INPUT\\('^^INPUT\\',5,72)
.BREAK
.SKIP 1

.INDEX INPUT LENGTH
CHANGES THE ASSOCIATION FOR ^^INPUT\\ SO THAT ONLY 72 COLUMNS ARE READ.
^COLUMNS 73 THROUGH 80 ARE LOST IF DATA SET REFERENCE NUMBER 5 IS
ASSOCIATED WITH ORDINARY CARD ^^INPUT\\.
^A LENGTH LONGER THAN THE RECORD IS USUALLY RECOMMENDED TO AVOID
ANY PROBLEMS WITH TRUNCATION.  ^EVEN THOUGH A LONGER LENGTH IS
ASKED FOR, THE ACTUAL STRING LENGTH WILL ALWAYS BE USED.

.BREAK
.SKIP 1
^FOR EXAMPLE, IF THE USER SPECIFIES A LENGTH OF 130 CHARACTERS
IN THE ^^INPUT\\ FUNCTION, AND A STRING OF 5 CHARACTERS IS
READ, THE SYSTEM WILL ASSIGN THE STRING LENGTH TO BE 5 AND NOT
130.
.BREAK
.SKIP 1

.BREAK
.SKIP 1

.INDEX ^^OTHER I/O FUNCTIONS\\
^^G.  OTHER ^I/^O FUNCTIONS
\\
.BREAK
.SKIP 2
.BREAK
.SKIP 1

	^SEVERAL OTHER FUNCTIONS ARE PROVIDED FOR ^I/^O-RELATED OPERATIONS.
^ALL OF THESE FUNCTIONS RETURN THE ^^NULL\\ STRING AS VALUE.
.BREAK
.SKIP 1

.INDEX ^^DETACH\\
^^	1.  DETACH
\\

.BREAK
.SKIP 1

^^DETACH(NAME)\\ REMOVES ANY ^^INPUT\\ AND ^^OUTPUT\\ ASSOCIATION WHICH THE NAME
MAY HAVE.  ^FOR EXAMPLE,
.BREAK
.SKIP 1

#####^^	DETACH('^^OUTPUT\\')
\\
.BREAK
.SKIP 1

TERMINATES NORMAL PRINT OUTPUT.

.BREAK
.SKIP 2
.INDEX ^^ENDFILE\\
^^	2.  ENDFILE
\\
.BREAK
.SKIP 1

^^ENDFILE(NUMBER)\\ WRITES AN END OF FILE ON (CLOSES) THE FILE SPECIFIED
BY THE NUMBER.  ^FOR EXAMPLE,
.BREAK
.SKIP 1

#####^^		ENDFILE(20)\\
.BREAK
.SKIP 1

CLOSES THE FILE ASSOCIATED WITH DEVICE REFERENCE NUMBER 20.
.BREAK
.SKIP 1

.BREAK
.SKIP 1
.INDEX ^^REWIND\\
^^	3.  REWIND
\\
.BREAK
.SKIP 1

.INDEX ^^REWIND\\
^^REWIND(NUMBER)\\ REPOSITIONS THE FILE ASSOCIATED WITH THE NUMBER TO THE
BEGINNING.  ^FOR EXAMPLE,
.BREAK
.SKIP 1

#####^^	REWIND(10)\\
.BREAK
.SKIP 1

REWINDS THE FILE ASSOCIATED WITH DEVICE REFERENCE NUMBER 10.  ^SUBSEQUENTLY,
 REFERENCE TO 10 REFERS TO THE BEGINNING OF THE FILE SPECIFIED.
^^REWIND\\ WILL CAUSE ANY ^^IFILE\\
FUNCTION ASSOCIATED WITH THIS FILE TO
BE CANCELLED.
.BREAK
.SKIP 1

.INDEX ^^BACKSPACE\\
	4.^^  BACKSPACE
\\
.BREAK
.SKIP 1

^^BACKSPACE(NUMBER)\\ BACKSPACES ONE RECORD ON THE FILE ASSOCIATED WITH THE
NUMBER.
.BREAK
.SKIP 1

.INDEX ^^IFILE\\
^^	5.  IFILE
\\
.BREAK
.SKIP 1

^^IFILE(NUMBER,FILENAME)\\ ALLOWS THE ^^SNOBOL\\ PROGRAMMER TO SELECT THE NAME
OF ^^INPUT\\ DISK OR ^^DEC\\TAPE FILES AT RUNTIME.  ^THIS FUNCTION IS A LINK TO
THE ^^FORTRAN IFILE\\ SUBROUTINE.
.BREAK
.SKIP 1

^THIS FUNCTION WILL SIGNAL A FAILURE RETURN IF THE FILE DOES
NOT EXIST ON THE GIVEN DEVICE.
.BREAK
.SKIP 1

^FOR EXAMPLE,
.BREAK
.SKIP 1
.NOFILL
.NOJUSTIFY
#####	^^IFILE(20,'SURVEY.OMA')
.SKIP 1
#####	FILENAME = 'SNIP.SNO'
#####	IFILE(25,FILENAME)
.SKIP 1
#####	INPUT('ACCEPT',2,80)
#####	IFILE(1,TRIM(ACCEPT))
.FILL
.JUSTIFY
.SKIP 1
\\
ARE ALL VALID USES OF ^^IFILE\\
.BREAK
.SKIP 1
.INDEX ^^OFILE\\
^^	6.  OFILE
\\
.BREAK
.SKIP 1

^^OFILE(NUMBER,FILENAME)\\ ALLOWS THE ^^SNOBOL\\ PROGRAMMER TO SELECT THE NAME
OF ^^OUTPUT\\ DISK OR ^^DEC\\TAPE FILES AT RUNTIME.  ^THIS FUNCTION IS A LINK
TO THE ^^FORTRAN\\ ^^OFILE\\ SUBROUTINE.
.BREAK
.SKIP 1
^THIS FUNCTION WILL SIGNAL A FAILURE RETURN IF THE FILE CANNOT BE
ENTERED ON THE GIVEN DEVICE.
.BREAK
.SKIP 1

.NOFILL
.NOJUSTIFY
^^
#####	I = I + 1
#####	OUTPUT.NAME = SEQ '.' I
#####	OFILE(22,OUTPUT.NAME)
.SKIP 1
#####	OFILE(FINDEVICE('DTA0'),'THISIS.IT')
\\
.BREAK
.SKIP 1
.FILL
.JUSTIFY
^ARE ALL VALID EXAMPLES OF THE USE OF ^^OFILE\\.
.BREAK
.SKIP 1
.INDEX ^^TTCALL\\ INTERFACE
^^	7.  TTCALL INTERFACE
\\
.BREAK
.SKIP 1

^THE ^^PDP\\-10 TIME SHARING SYSTEM HAS A SPECIAL TELETYPE INTERFACE DESIGNED 
TO ALLOW CHARACTER AT A TIME ^I/^O AS OPPOSED TO LINE AT A TIME ^I/^O.
.BREAK
.SKIP 1

^TO TAKE ADVANTAGE OF THIS FEATURE, ANY ^I/^O TO UNIT NUMBER 99 WILL BE
DIRECTED TO OR FROM THE USER'S TELETYPE.
.BREAK
.SKIP 1

^FOR EXAMPLE,
.BREAK
.SKIP 1

.NOFILL
.NOJUSTIFY
#####	^^INPUT('CHARIN',99,1)
#####	OUTPUT('TTYOUT',99)

\\
.FILL
.JUSTIFY
.BREAK
.SKIP 1
^NOTE THAT ONLY ONE CHARACTER IS INPUT EACH TIME AN ^^INPUT\\ ASSOCIATION
IS REFERENCED.
.BREAK
.SKIP 1

^AN ENTIRE STRING WILL BE OUTPUT EACH TIME AN ^^OUTPUT\\ ASSOCIATION IS
REFERENCED.  ^A FREE ^^CARRIAGE-RETURN LINE FEED\\ WILL NOT BE SUPPLIED,
HOWEVER.
.BREAK
.SKIP 1

^SINCE ON INPUT, CONTROL CHARACTERS CAN NOW BE REFERENCED, A MEANS HAS
.INDEX ^^ASCII\\
BEEN PROVIDED VIA THE ^^ASCII\\ PRIMITIVE FUNCTION TO HANDLE THIS CASE.
.BREAK
.SKIP 1

.INDEX ^^ASCII\\
^^	8.  ASCII
\\
.BREAK
.SKIP 1

^^ASCII(NUMBER)\\ TREATS '^^NUMBER\\' AS OCTAL AND GENERATES ONE EQUIVALENT
^^ASCII\\ CHARACTER.  ^THIS MECHANISM IS PROVIDED TO ALLOW REFERENCING OF
CONTROL CHARACTERS.
.BREAK
.SKIP 1

^FOR EXAMPLE,
.BREAK
.SKIP 1

#####^^	CARRIAGE.RETURN.LINE.FEED = ASCII(15) ASCII(12)
\\
.BREAK
.SKIP 1

^OCTAL 15 IS THE ^^CARRIAGE RETURN\\ CHARACTER AND OCTAL 12
IS THE ^^LINE FEED\\ CHARACTER. ^IN THE ABOVE EXAMPLE THE
CONCATENATION OF THE TWO RESULTING CHARACTERS IS ASSIGNED TO
THE VARIABLE NAME ^^CARRIAGE.RETURN.LINE.FEED\\ FOR LATER
USE.
.BREAK
.SKIP 1
.INDEX ^^TTY SWITCHES\\
.INDEX SWITCHES
^^	9.  TTY 'SWITCHES'
\\
.BREAK
.SKIP 1

^SEVERAL SWITCHES HAVE BEEN DEFINED WHICH ALLOW THE USER TO SPECIFY
OPTIONS AT RUNTIME WITHOUT MODIFYING HIS PROGRAM.  ^THESE SWITCHES
ARE ENTERED BY THE "/" CHARACTER FOLLOWED BY A SINGLE LETTER.  ^THEY
ARE DEFINED AS FOLLOWS:
.BREAK
.SKIP 1

.INDEX ^D ^SWITCH
.INDEX ^^DUMP\\
.INDEX _&^^DUMP\\
/^D IS EQUIVALENT TO _&^^DUMP\\ = 1, AND CAUSES A DUMP OF VARIABLE STORAGE
    AT PROGRAM TERMINATION.
.BREAK
.SKIP 1

.INDEX ^U ^SWITCH
.INDEX ^^UNLIST\\
/^U IS EQUIVALENT TO -^^UNLIST\\, AND SUPPRESSES PRINTOUT OF THE SOURCE
    PROGRAM LISTING.
.BREAK
.SKIP 1

.INDEX ^I ^SWITCH
.INDEX ^I/^O BUFFERS
/^I FOR EACH OCCURRENCE OF THIS SWITCH ADDITIONAL
^I/^O BUFFER SPACE FOR ONE MORE DISK FILE IS ALLOCATED. ^THE SYSTEM
CURRENTLY ALLOWS ENOUGH BUFFERING FOR SIX SIMULTANEOUS DISK FILES.
^IF THIS NUMBER IS EXCEEDED, THE ^I SWITCH MUST BE USED ENOUGH
TIMES TO INCREASE THE BUFFERING AREA BY AN APPROPRIATE
AMOUNT.
.BREAK
.;CHAP5.RNO EDITED 9-5-70 LP WADE
.SPACING 1
.SKIP 1
.PAGE
.SUBTITLE ^^CHAPTER 5\\
.BREAK
.SKIP 1
^^STRUCTURE OF A ^^SNOBOL4 RUN
\\
.BREAK
.SKIP 2
.BREAK
.SKIP 1
^A ^^SNOBOL\\4 RUN CONSISTS OF THREE DISTINGUISHABLE PARTS:
.BREAK
.SKIP 2
.BREAK
.SKIP 1
^^
.NOFILL
.NOJUSTIFY
1)  COMPILATION,
2)  EXECUTION, AND
3)  TERMINATION.
\\
.FILL
.JUSTIFY
.BREAK
.SKIP 1
.INDEX ^^COMPILATION\\
^^A.  COMPILATION
\\
.SKIP 1
.PARAGRAPH
	^DURING COMPILATION, THE ^^SNOBOL\\4 SYSTEM IS INITIALIZED AND THE
SOURCE PROGRAM IS COMPILED INTO AN INTERMEDIATE OBJECT CODE IN A FORM
SUITABLE FOR INTERPRETATION DURING PROGRAM EXECUTION.  ^COMPILATION USES
THE SAME PROCESSES AS CONVERSION OF A STRING TO OBJECT CODE USING THE
^^CODE\\ FUNCTION.  ^ADDITIONAL PROCESSES ARE INVOLVED IN THE READING OF 
LINES TO BE COMPILED FROM THE INPUT DATA SET, PRINTING OF A SOURCE 
LISTING ON AN OUTPUT DATA SET, AND NOTING ERRORS IN THE SOURCE PROGRAM.
.BREAK
.SKIP 1
.INDEX ^^SOURCE PROGRAM INPUT\\
^^#####	1.  SOURCE PROGRAM INPUT
\\
.PARAGRAPH
	^INPUT TO THE COMPILER COMES FROM A DEVICE ASSOCIATED WITH UNIT
REFERENCE NUMBER 5.  ^THE ACTUAL SOURCE DEVICE IS SPECIFIED BY THE USER
AT RUN TIME BY USING THE RELATIVELY STANDARD ^^PDP\\-10 COMMAND STRING SYNTAX.
  ^IF NO DEVICE IS SPECIFIED, ^^DSK\\ IS ASSUMED.  ^IN THIS CASE THE USER
WOULD SPECIFY A FILENAME.  ^ONLY 72 CHARACTERS PER LINE ARE READ, SO 
THAT COLUMNS 73-80 OF THE CARD IMAGE INPUT MAY BE USED FOR SEQUENTIAL
NUMBERING.  ^THE COMPILER CONTINUES TO READ UNTIL IT ENCOUNTERS THE ^^END\\
STATEMENT.  ^IF AN END OF FILE IS ENCOUNTERED BEFORE THE ^^END\\ STATEMENT
IS FOUND, THE COMPILER WILL READ FROM THE NEXT FILE SPECIFIED BY THE
USER.  ^IF NO ADDITIONAL FILES ARE SPECIFIED, CONTROL WILL REVERT TO THE
USER'S TERMINAL SO HE CAN TYPE ADDITIONAL STATEMENTS.  ^IF NO FURTHER 
INPUT IS DESIRED, THE USER CAN TYPE ^^END<CARRIAGE RETURN>\\ TO TERMINATE
THE COMPILATION PHASE.
.BREAK
.SKIP 1
.INDEX ^^SOURCE LISTING\\
#####^^	2.  SOURCE LISTING
\\
.PARAGRAPH
	^THE LISTING OF THE PROGRAM WITH SEQUENTIAL STATEMENT NUMBERS 
GOES ON THE STANDARD PRINT OUTPUT.  ^WHEN THE ^^END\\ STATEMENT IS ENCOUNTERED,
 THE COMPILATION PROCESS STOPS.  ^A LISTING OF THE COMPILATION 
AND PLACEMENT OF STATEMENT NUMBERS CAN BE CONTROLLED BY CONTROL LINES.
.INDEX MINUS SIGN
^A MINUS SIGN AT THE BEGINNING OF A LINE IDENTIFIES A CONTROL LINE. 
^PROGRAM LISTING IS SUPPRESSED BY THE CONTROL LINE.
.BREAK
.SKIP 1
.INDEX ^^UNLIST\\
^^-UNLIST
\\
.BREAK
.SKIP 1
^PROGRAM LISTING IS RESTORED BY THE CONTROL LINE
.BREAK
.SKIP 1
.INDEX ^^LIST\\
-^^LIST
\\
.PARAGRAPH
^THE NORMAL POSITIONING OF STATEMENT NUMBERS IS AT THE LEFT SIDE OF THE
SOURCE LISTING.  ^STATEMENT NUMBERS OPTIONALLY MAY BE PLACED AT THE 
RIGHT SIDE OF THE LISTING.  ^THE CONTROL LINE
.BREAK
.SKIP 1
.INDEX ^^LIST LEFT\\
^^-LIST LEFT
\\
.BREAK
.SKIP 1
CHANGES STATEMENT NUMBERING TO THE LEFT.  ^RIGHT POSITIONING OF THE STATEMENT
 NUMBERS IS RESTORED BY
.BREAK
.SKIP 1
.INDEX ^^LIST RIGHT\\
^^-LIST RIGHT
\\
.BREAK
.SKIP 1
OR SIMPLY
.BREAK
.SKIP 1
^^-LIST
\\
.PARAGRAPH
	^BLANKS MAY APPEAR BETWEEN THE MINUS SIGN AND ^^LIST\\ OR ^^UNLIST\\.  
^ONE OR MORE BLANKS MUST APPEAR BETWEEN THE ^^LIST\\ AND THE ^^LEFT\\ OR ^^RIGHT\\.
^ANY CHARACTERS OTHER THAN ^^LEFT\\ FOLLOWING BLANKS ON THE ^^LIST\\ CONTROL
LINE CAUSE THE SAME ACTION AS ^^RIGHT\\.  ^AN ERRONEOUS CONTROL LINE IS 
IGNORED.
.BREAK
.SKIP 1
.INDEX ^^EJECT\\
^^-EJECT
\\
.BREAK
.SKIP 1
CAUSES A PAGE EJECT TO OCCUR IN THE COMPILATION LISTING WHEN ENCOUNTERED.
.BREAK
.SKIP 1
.INDEX ^^ERRORS\\
.INDEX COMPILATION ERRORS
^^#####	3.  ERRORS DETECTED DURING COMPILATION
\\
.PARAGRAPH
	^CERTAIN KINDS OF ERRORS IN THE SOURCE PROGRAM ARE DETECTED 
DURING COMPILATION.  ^WHEN AN ERROR IS DETECTED IN A STATEMENT, COMPILATION
 OF THAT STATEMENT IS TERMINATED AND AN ERROR MESSAGE IS PRINTED
BELOW THE STATEMENT, DESCRIBING THE NATURE OF THE ERROR.  ^A LIST OF
COMPILATION ERROR MESSAGES IS GIVEN BELOW.  ^A MARKER POINTING
TO THE VICINITY OF THE ERROR IS ALSO PRINTED.  ^THIS MARKER MAY BE 
SOMEWHAT BEFORE OR AFTER THE ERROR, DEPENDING ON THE NATURE OF THE 
ERROR.  ^SINCE COMPILATION OF A STATEMENT STOPS WHEN AN ERROR IS ENCOUNTERED,
 ONLY THE FIRST ERROR IN ANY ON STATEMENT IS DETECTED.
^COMPILATION CONTINUES IN SPITE OF ERRONEOUS STATEMENTS.  ^HOWEVER, IF
MORE THAN FIFTY ERRONEOUS STATEMENTS ARE FOUND, ERROR TERMINATION OCCURS
AND THE PROGRAM IS NOT EXECUTED.
.BREAK
.SKIP 1
.INDEX ^^EXECUTION\\
^^B.  EXECUTION
\\
.PARAGRAPH
	^EXECUTION OF THE COMPILED OBJECT CODE BEGINS WHEN COMPILATION 
IS COMPLETE.  ^ORDINARILY, PROGRAM EXECUTION BEGINS WITH THE FIRST STATEMENT
 OF THE PROGRAM.  ^PROGRAM EXECUTION MAY BE STARTED AT ANY LABELLED
STATEMENT BY SPECIFYING THAT LABEL IN THE ^^END\\ STATEMENT.  ^THE LABEL
OF THE FIRST STATEMENT TO BE EXECUTED IS PLACED IN THE POSITION OF THE
SUBJECT.  ^FOR EXAMPLE,
.BREAK
.SKIP 1
.INDEX ^^END\\
^^END	INIT
\\
.BREAK
.SKIP 1
CAUSES PROGRAM EXECUTION TO BEGIN WITH THE STATEMENT LABELLED ^^INIT\\.
.PARAGRAPH
	^DATA READ FROM THE STANDARD INPUT SOURCE BEINGS WITH THE FIRST
LINE AFTER THE ^^END\\ STATEMENT.  ^DATA PRINTED DURING EXECUTION FOLLOWS
THE SOURCE LISTING.
.BREAK
.SKIP 2
.INDEX ^^TERMINATION\\
^^C.  TERMINATION
\\
.PARAGRAPH
	^UPON TERMINATION, A STATISTICS SUMMARY IS PRINTED TO PROVIDE 
TIMING INFORMATION AND COUNTS OF CERTAIN PROGRAM OPERATIONS.  ^IF THE
KEYWORD _&^^DUMP\\ IS ON AT PROGRAM TERMINATION, A DUMP OF NATURAL VARIABLES
AND UNPROTECTED KEYWORDS IS ALSO PROVIDED.  ^ONLY NATURAL VARIABLES WITH
NONNULL VALUES ARE INCLUDED.  ^IF THE VALUE OF A VARIABLE IS NOT A STRING,
THE SAME REPRESENTATION OF THE VALUE IS GIVEN AS WOULD BE GIVEN IF THE
VALUE WERE PRINTED AS THE RESULT OF AN OUTPUT ASSOCIATION.
.BREAK
.SKIP 1
	^THERE ARE FOUR KINDS OF TERMINATION:
.BREAK
.NOFILL
.NOJUSTIFY
.SKIP 1
#####	1)  NORMAL,
#####	2)  ERROR,
#####	3)  INTERVENTION, AND
#####	4)  CATASTROPHIC.
.FILL
.JUSTIFY
.BREAK
.SKIP 1
.INDEX NORMAL TERMINATION
#####	1.  ^NORMAL ^TERMINATION
.PARAGRAPH
	^NORMAL TERMINATION OCCURS WHEN THE PROGRAM TRANSFERS TO ^^END\\ OR
FLOWS INTO THE ^^END\\ STATEMENT.  ^THE NUMBER OF THE LAST STATEMENT 
EXECUTED AND THE FUNCTION LEVEL ARE PRINTED.  
.BREAK
.SKIP 1
.INDEX ERROR TERMINATION
#####	2.  ^ERROR ^TERMINATION
.PARAGRAPH
	^ERROR TERMINATION OCCURS IN CASE OF A PROGRAMMING ERROR OR 
INTERNAL CONDITION SUFFICIENTLY SERIOUS TO PREVENT CONTINUED EXECUTION.
^THE STATEMENT NUMBER IN WHICH EXECUTION TERMINATED AND THE FUNCTION
LEVEL ARE PRINTED.  ^AN ERROR MESSAGE IS PRINTED INDICATING THE CAUSE
OF THE TERMINATION.  ^DUMPS AND STATISTICS ARE THEN PRINTED AS FOR 
NORMAL TERMINATION.  ^THE ERROR MESSAGES ARE AS FOLLOWS:
.BREAK
.NOFILL
.NOJUSTIFY
.SKIP 1
.INDEX ^^ERRORS\\
.INDEX ^^CONDITIONALLY FATAL ERRORS\\
^^	     THE CONDITIONALLY FATAL ERRORS ARE:
.BREAK
.SKIP 1
#####	1.   ILLEGAL DATA TYPE
#####	2.   ERROR IN ARITHMETIC OPERATION
#####	3.   ERRONEOUS ARRAY OR TABLE REFERENCE
#####	4.   NULL STRING IN ILLEGAL CONTEXT
#####	5.   UNDEFINED FUNCTION OR OPERATION
#####	6.   ERRONEOUS PROTOTYPE
#####	7.   UNKNOWN KEYWORD
#####	8.   VARIABLE NOT PRESENT WHERE REQUIRED
#####	9.   ENTRY POINT OF FUNCTION NOT LABEL
#####	10.  ILLEGAL ARGUMENT TO PRIMITIVE FUNCTION
#####	11.  READING ERROR
#####	12.  ILLEGAL I/O UNIT
#####	13.  LIMIT ON DEFINED DATA TYPES EXCEEDED
#####	14.  NEGATIVE NUMBER IN ILLEGAL CONTEXT
#####	15.  STRING OVERFLOW
#####	16.  OVERFLOW DURING PATTERN MATCHING
.BREAK
.SKIP 1
.INDEX ^^ERRORS\\
^^
.INDEX ^^UNCONDITIONALLY FATAL ERRORS\\
^^
	     THE UNCONDITIONALLY FATAL ERRORS ARE:
.BREAK
.SKIP 1
#####	17.  ERROR IN SNOBOL4 SYSTEM
#####	18.  RETURN FROM LEVEL ZERO
#####	19.  FAILURE DURING GOTO EVALUATION
#####	20.  INSUFFICIENT STORAGE TO CONTINUE
#####	21.  STACK OVERFLOW
#####	22.  LIMIT ON STATEMENT EXECUTION EXCEEDED
#####	23.  OBJECT EXCEEDS SIZE LIMIT
#####	24.  UNDEFINED OR ERRONEOUS GOTO
#####	25.  INCORRECT NUMBER OF ARGUMENTS
#####	26.  LIMIT ON COMPILATION ERRORS EXCEEDED
#####	27.  ERRONEOUS END STATEMENT
#####	28.  EXECUTION OF STATEMENT WITH COMPILATION ERROR
#####	29.  IO BUFFER SPACE EXHAUSTED, RESTART AND USE
###########THE I SWITCH
#####	30.  INSUFFICIENT STORAGE, NOT ENOUGH CORE FOR
###########STARTING
\\
.FILL
.JUSTIFY
.BREAK
.SKIP 1
	     ^WHEN PROGRAM EXECUTION IS TERMINATED BY AN ERROR, THE 
	ERROR NUMBER AS WELL AS THE DESCRIPTIVE PHRASE IS PRINTED ON
	THE PROGRAM LISTING.
.BREAK
.SKIP 1
.BREAK
.SKIP 1
.INDEX ^^INTERVENTION TERMINATION\\
.INDEX ^^REENTER COMMAND\\
^^	3.  INTERVENTION TERMINATION
\\
.BREAK
.SKIP 1
	^ON THE ^^PDP\\-10 INTERVENTION TERMINATION CAN BE FORCED BY THE USER
^WITH THE ^^REENTER\\ COMMAND.  ^WHEN THE USER SUSPECTS THAT HIS 
PROGRAM IS LOOPING HE CAN GET CONTROL BY TYPING TWO CONTROL 
^C'S TO GET INTO MONITOR MODE AGAIN.  ^SHOULD BE DESIRE TO RESUME
PROCESSING THE ^^CONTINUE\\ OR ^^CCONTINUE\\ COMMANDS CAN BE USED TO 
CONTINUE WHERE THE OPERATION WAS INTERRUPTED.  ^IF, HOWEVER, THE
USER DESIRED TO TERMINATE THE RUN IN A SOMEWHAT GRACEFUL FASHION,
HE CAN USE THE ^^REENTER\\ COMMAND.  ^THIS WILL AUTOMATICALLY CAUSE
THE ^^DUMP\\ KEYWORD TO BE SET SO THE USER WILL GET AS MUCH USEFUL INFORMATION
.INDEX ^^CUT BY SYSTEM\\
 AS POSSIBLE.  ^THE MESSAGE "^^CUT BY SYSTEM IN STATEMENT N
AT LEVEL M"\\ IS PRINTED AND THE DUMPS AND STATISTICS ARE THEN 
PRINTED AS FOR NORMAL TERMINATION.
.BREAK
.SKIP 2
^THERE ARE A NUMBER OF SITUATIONS ON THE ^^PDP\\-10 WHERE THE ^^FORTRAN\\
OPERATING SYSTEM WILL DETECT AN ERROR, PRINT AN ERROR MESSAGE
AND RETURN YOU TO MONITOR MODE.
^THE USER HAS NO RECOURSE BUT TO CORRECT THE ERROR CONDITION
AND RESTART HIS PROGRAM.
.BREAK
.SKIP 1
^^	4.  CATASTROPHIC TERMINATION
\\
.BREAK
.SKIP 1
	^CATASTROPHIC TERMINATION OCCURS WHEN SYSTEM OR MACHINE MALFUNCTION
 CAUSES A SITUATION SO SERIOUS THAT INTERVENTION TERMINATION IS 
IMPOSSIBLE.  ^IN THE CASE OF A CATASTROPHIC TERMINATION, THERE MAY BE NO
INDICATION OF THE SOURCE OR CAUSE OF THE TERMINATION.  ^PRINT AND PUNCH
OUTPUTNMAY BEEINCOMPLETE7ORLLACKING ALTOGETHER.
.SUBTITLE ^^APPENDIX A\\
.SPACING 1
.PAGE
.SKIP 1

.BREAK
.SKIP 1
.INDEX ^^SYSTEM PROGRAMMER'S NOTES\\
^^
.CENTER
SYSTEM PROGRAMMER'S NOTES
\\
.BREAK
.SKIP 1

1.  ^A FIXED AMOUNT OF SPACE IS RESERVED FOR THE USER'S ^I^O BUFFERS.
^THE BUFFERS ARE SET UP AT RUN TIME BY ^^FORSE\\ AND THEIR SIZE IS
VARIABLE DEPENDING UPON DEVICE.  ^THE USER CAN INCREASE THIS AMOUNT
WITH THE "^I" SWITCH.  ^EACH OCCURRENCE OF THIS SWITCH ALLOWS SPACE
FOR DOUBLE BUFFERING ONE MORE DEVICE.
.BREAK
.SKIP 1
.INDEX ^^NUMIOB\\
^THE GLOBAL VARIABLE ^^NUMIOB\\ (^N^U^MBER OF ^I^O ^BUFFERS) CONTROLS THE
BUFFERING SPACE.  ^IT IS INITIALLY SET TO FOUR TO PROVIDE SPACE
FOR FOUR DEVICES IN ADDITION TO THE STANDARD INPUT AND OUTPUT
DEVICES.
.BREAK
.SKIP 1
^IF YOUR USERS TEND TO USE MORE DEVICES CHANGE ^^NUMIOB\\ EITHER WITH
.INDEX ^I ^SWITCH
^^DDT\\ OR WITH THE ^I SWITCH BEFORE PUTTING ^^SNOBOL\\ ON ^^SYS\\.
.BREAK
.SKIP 1

2.  ^THE INTERNAL DESIGN OF ^^SNOBOL\\ IS SUCH THAT KEY CONSTANTS ARE
DESTROYED UPON PROGRAM EXECUTION.  ^THIS CREATES A PROBLEM WHEN THE
USER TRIES TO EXECUTE MANY PROGRAMS IN SUCCESSION OR TRIES TO STOP
AND RESTART A PROGRAM.  ^FOR THIS REASON A FILE CALLED ^^SNOBOL\\.^^INI\\
IS READ IN EACH TIME A PROGRAM IS COMPILED IN ORDER TO RESET THESE
CONSTANTS.  ^^SNOBOL\\ LOOKS FOR THIS FILE ON ^^SYS\\ SO BE SURE TO PUT
IT THERE WHEN PUTTING ON ^^SNOBOL\\.^^SHR\\ AND ^^SNOBOL\\.^^LOW\\.  ^FOR NON DISK
SYSTEMS THE USER SHOULD ASSIGN THE ^^DEC\\TAPE DRIVE CONTAINING
.INDEX ^C ^SWITCH
.INDEX ^^SNOBOL_.INI\\
^^SNOBOL\\.^^INI\\ TO ^^SYS\\.  ^THIS FILE IS CREATED USING THE "^C" SWITCH
AS DESCRIBED BELOW.
.BREAK
.SKIP 1
^THE ^C SWITCH IS INTENDED FOR USE BY THE SYSTEM'S PROGRAMMER WHEN
^^SNOBOL\\ IS FIRST PUT ON THE SYSTEM.  ^^SNOBOL\\ HAS THE PROPERTY OF
DESTROYING KEY CONSTANTS DURING A RUN, AND IN ORDER TO ALLOW
RESTARTS THESE CONSTANTS MUST BE REINITIALIZED PRIOR TO EVERY
RUN.
.BREAK
.SKIP 1
^THE INTENDED PROCEDURE IS TO ^^LOGIN\\,
RUN ^^SNOBOL\\, AND TYPE "/^C".
  ^THIS WILL WRITE ^^SNOBOL\\.^^INI\\
ON ^^DSK\\:. ^THEN ^^PIP\\ ^^SNOBOL_.*\\ TO ^^SYS\\:.
  ^HEREAFTER, ANY USER RUNNING ^^SNOBOL\\ WILL ALWAYS ACCESS
THIS FILE FOR HIS INITIALIZATION.  ^SEE ^^SNOBOL\\.^^OPR\\ ON THE SYSTEM
TAPE FOR A BETTER DESCRIPTION.
.BREAK
.SKIP 2
.INDEX ^^FORSE\\
3.  ^SINCE ^I^O IS DONE THROUGH ^^FORSE\\ YOU SHOULD BE AWARE OF SOME
OF THE LIMITATIONS WHICH RESULT.
.BREAK
.SKIP 1
^AT EXECUTION TIME ALL STRINGS ARE READ VIA THE ^^STREAD\\ MACRO WHICH
.INDEX ^^VORMAT\\
EXECUTES THE ^^FORSE\\ ^^IN\\. ^^UUO\\ WITH A ^^FORMAT\\ OF 16^A5.  ^THIS MEANS ONLY
80 CHARACTERS ARE READ AND LONGER STRINGS ARE TRUNCATED.  ^TO READ
IN A LONG STRING IT IS NECESSARY TO CONCATENATE THE PORTIONS OF THE
INPUT.
.BREAK
.SKIP 1
^^FORSE\\ WILL STRIP OFF ALL ^^CR\\ AND ^^LF\\ CHARACTERS ON INPUT AND APPEND
THEM ON OUTPUT.
.BREAK
.SKIP 1
^WHEN OUTPUTTING STRINGS AT EXECUTION TIME, AN ATTEMPT IS MADE TO NOT
MERELY TRUNCATE THE STRING TO 132 CHARACTERS BUT TO OUTPUT THE STRING
IN ITS ENTIRETY.  ^THE STRING IS PLACED IN A PREVIOUSLY ZEROED BUFFER
OF 27 WORDS AND  ENOUGH ^^DATA_.\\ ^^UUO\\S ARE EXECUTED TO OUTPUT THE
CHARACTERS IN THE BUFFER
  ^IF MORE WORDS REMAIN, THE INTERNAL BUFFER IS AGAIN ZEROED, FILLED AND
OUTPUT.  ^AFTER EACH OUTPUT, A ^^CR\\ AND ^^LF\\ WILL BE ADDED BY ^^FORSE\\.
.BREAK
.SKIP 1
^AT COMPILATION TIME ALL INPUT IS READ WITH A ^^FORMAT\\ OF 16^A5 TO LIMIT
THE SOURCE TO CARD IMAGE INPUT.
.BREAK
.SKIP 1
.INDEX ^^FORSE\\
.INDEX ^^REWIND\\
.INDEX ^^BACKSPACE\\
^ALL OF THE MAGTAPE OPERATIONS ARE ALSO DONE BY ^^FORSE\\ SUCH AS ^^REWIND\\
AND ^^BACKSPACE\\.  ^ANY PROBLEMS ENCOUNTERED HERE ARE LIKELY IN ^^FORSE\\.
.BREAK
.SKIP 1
4.  ^ADDING NEW FUNCTIONS IS FAIRLY EASY.  ^I SUGGEST LOOKING AT THE
COMMON FUNCTIONS OF ^^SIZE\\ OR ^^OFILE\\ AND PATTERN
YOUR ADDITIONS AFTER THESE. ^KEYWORDS WILL BE ADDED IN  MUCH THE SAME
WAY.
.BREAK
.SKIP 1
5.  ^EACH INSTALLATION MAY WISH TO CHANGE THE SO CALLED ATTRIBUTION
.INDEX ^^FORMAT\\
PRINTED EACH TIME A RUN IS STARTED.  ^THIS IS ACTUALLY A ^^FORMAT\\
STATEMENT AT THE LABEL ^^SOURCF\\ IN THE FILE NAMED ^^COMMON\\,
WHICH TYPICALLY PRINTS "^^DIGITAL EQUIPMENT CORP.\\ ^^PDP\\-10".
.BREAK
.SKIP 1
.INDEX ^^SNOBOL_.OPR\\
6.  ^I SUGGEST YOU STICK WITH THE LOADING PROCEDURE NOTED IN ^^SNOBOL\\.^^OPR\\.
^THIS LEAVES ^^DDT\\ AT THE VERY END OF THE LOW SEGMENT THEREBY TAKING A
SIMPLE PATCH TO RECLAIM THE SPACE IN THE PRODUCTION VERSION BUT OFFERING
THE BENEFIT OF HAVING ^^DDT\\ AROUND FOR QUICK FIXES.
.BREAK
.SKIP 1
7.  ^A FEW EDITS WERE MADE TO THE ^^FORTRAN\\ OPERATING SYSTEM IN ORDER TO
HANDLE THE ^^SNOBOL\\ INTERFACE.
.BREAK
.SKIP 1
###    A.  ^THE ^^RESET\\. ^^UUO\\ EXECUTES A ^^CALLI\\ 0 WHICH CANNOT BE TOLERATED
SINCE PROGRAM EXECUTION HAS BEGUN WHEN THIS IS CALLED.
.BREAK
.SKIP 1
###    B.  ^THE ^^RESET\\.^^UUO\\ RELEASES ALL CHANNELS 0-17.  ^A CHANGE WAS MADE TO
RELEASE ONLY 0-16 BECAUSE CHANNEL 17 IS KEPT OPEN FOR THE ^^CCL\\ FEATURE.
.BREAK
.SKIP 1
###    C.  ^THE ^^CHINN\\ ROUTINE WHICH DOES CHARACTER INPUT WAS MODIFIED
TO NOT CHANGE CHARACTERS LESS THAN 24 OCTAL (CONTROL CHARACTERS) TO
  BLANKS.  ^THIS WAS PRIMARILY DONE BECAUSE OF ^^TAB\\ BEING
CONVERTED TO A SINGLE BLANK CHARACTER.
.BREAK
.SKIP 1
###    D.  ^THE ^^ALPHO\\ ROUTINE WAS MODIFIED TO NOT CONVERT CONTROL
CHARACTERS TO BLANKS, AGAIN PRIMARILY FOR ^^TAB\\.
.BREAK
.SKIP 1
8.  ^THE COMMAND SCANNER IN ^^EXEC\\  ACCEPTS PROJECT-PROGRAMMER NUMBERS AND
PASSES THEM TO A MODIFIED ^^IFILE\\ ROUTINE.  ^CONSEQUENTLY,
USERS CAN SPECIFY ^^PPNS\\, I.E. ^^FOO__FOO[30,112]\\.
.BREAK
.SKIP 1
.INDEX CORE EXPANSION
9.  ^DYNAMIC CORE EXPANSION IS DONE IN TWO PARTS, AND IS ALWAYS
.INDEX GARBAGE COLLECTION
ASSOCIATED WITH THE GARBAGE COLLECTION ROUTINE.
.BREAK
.SKIP 1
^THE FIRST PART IS INVOKED IF THE GARBAGE COLLECTOR FAILS TO
FIND ENOUGH FREE STORAGE.  ^IN THIS CASE WE ATTEMPT TO GET
2^K MORE, OR 1^K IF THAT IS ALL THAT REMAINS.  ^IF CORE IS
EXHAUSTED THE PROGRAM IS TERMINATED WITH AN APPROPRIATE ERROR
MESSAGE.
.BREAK
.SKIP 1
^THE SECOND PART IS INVOKED ON EVERY FIFTH ENTRY TO THE GARBAGE
COLLECTOR.  ^ON THESE OCCASIONS A 2^K (OR 1^K) PREEXPANSION IS
PERFORMED IN ORDER TO PREVENT REACHING A STATE WHERE JUST
ENOUGH CORE IS OBTAINED AND AN INORDINATE NUMBER OF COLLECTIONS
IS REQUIRED.  ^THIS PREEXPANSION IS ONLY PERFORMED AS LONG AS THE
FREE STORAGE AREA IS LESS THAN 15^K.
.BREAK
.SKIP 1
^AT PROPER TERMINATION THE AMOUNT OF CORE USED IS PRINTED AS A
PART OF THE "^^STATISTICS"\\ PRINTOUT.  ^BEFORE GIVING UP CONTROL,
THE PROGRAM SHRINKS BACK TO THE ORIGINAL STARTING SIZE.
.BREAK
.SKIP 1
10.  ^AS A MEANS OF GETTING MORE INFORMATION FROM THE SYSTEM I
ADDED THE "^V" SWITCH WHICH WILL CAUSE THE NUMBER OF STRING
LOOKUPS TO BE PRINTED AS PART OF THE STATISTICS PRINTOUT.  ^THIS
NUMBER IS REALLY COMPARABLE TO THE NUMBER OF SYMBOL TABLE LOOK-
UPS.  ^EACH TIME THE ^^VARID\\ MACRO IS CALLED TO HASH CODE A STRING,
IT INCREMENTS A COUNT.  ^THE PRINTING OF THIS COUNT IS CONTROLLED
BY THE GLOBAL ^^VARPRT\\ WHICH IN TURN IS CONTROLLED BY THE "^V"
SWITCH.
.BREAK
.SKIP 1
^IF YOU DESIRE THIS PRINTOUT TO ALWAYS BE INCLUDED IN YOUR USER'S
PRINTOUT, SET ^^VARPRT\\ NON ZERO WITH ^^DDT\\ BEFORE PUTTING ^^SNOBOL\\
ON THE SYSTEM.
.NOFILL
.NOJUSTIFY
^^
.BREAK
.SKIP 2
.INDEX ^^SYNTAX TABLES\\
########		  ^^PDP-10 SYNTAX TABLE LAYOUTS
.BREAK
.SKIP 1

.BREAK
.SKIP 1
GENERAL FORM
.BREAK
.SKIP 1
     XXXTAB:
.BREAK
.SKIP 1
##########1#####0
.BREAK
.SKIP 1
##########3#####2
.BREAK
.SKIP 1
##########5#####4
.BREAK
.SKIP 1
##########7#####6
.BREAK
.SKIP 1
#########11####10
.BREAK
.SKIP 1
#########13####12
.BREAK
.SKIP 1

.BREAK
##########_.#####_.
.SKIP 1

.BREAK
.SKIP 1

########177###176
.BREAK
.SKIP 1

^THERE ARE 64 DECIMAL WORDS  IN EACH SYNTAX TABLE,
WITH ONE HALFWORD ENTRY FOR EACH CHARACTER.
.BREAK
.SKIP 1
^^TYPICAL HALFWORD ENTRY
\\
.BREAK
.SKIP 1
#####2 FREE BITS
#####1 BIT FOR ^^ERROR\\
#####1 BIT FOR ^^CONTIN\\
#####1 BIT FOR ^^STOPSH\\
#####1 BIT FOR ^^STOP\\
#####6 BITS FOR ^^SYNTAB\\ INDEX
#####6 BITS FOR ^^PUTTAB\\ INDEX
.BREAK
.SKIP 2
.FILL
.JUSTIFY
^^SYNTAB\\ IS A TABLE OF 18 BIT ADDRESSES WHICH POINT TO THE NEXT
SYNTAX TABLE TO SEARCH THROUGH.  ^THE INDEX INTO THIS TABLE
IS STORED AS OPPOSED TO THE ACTUAL ADDRESS IN ORDER TO MAKE THE
TABLES COMPACT.
.BREAK
.SKIP 1
^^PUTTAB\\ IS A TABLE CONTAINING EITHER CONSTANTS OR FUNCTION ADDRESSES
(POSSIBLY 18 BITS).  ^THE INDEX INTO THIS TABLE IS STORED AS OPPOSED
TO THE ACTUAL VALUE IN ORDER TO MAKE THE TABLES COMPACT.  ^THE SIX BIT
SIZE WAS CHOSEN BY COUNTING THE NUMBER OF POSSIBLE ENTRIES.
.BREAK
.SKIP 1
^THERE ARE LESS THAT 32 SEPARATE SYNTAX TABLES SO FIVE BITS IS
SUFFICIENT FOR THE INDEX.  ^HOWEVER, SIX BITS WAS CHOSEN FOR READABILITY.
.BREAK
.SKIP 1
^THE PARTICULAR ENTRY IS RETRIEVED BY THE ^^STREAM\\ MACRO (WHICH CALLS THE
^^STREEM\\ SUBROUTINE) BY PICKING UP SUCCESSIVE CHARACTERS, DIVIDING
THE ^^ASCII\\ VALUE BY TWO OBSERVING WHETHER THE RESULT IS ODD OR EVEN AND
INDEXING THE APPROPRIATE TABLE HALF.
.BREAK
.SKIP 1
^THE ^^GEN\\ MACRO GENERATES THE TABLES.  ^CARE MUST BE TAKEN IF THESE
TABLES ARE CHANGED.  ^THE APPEARANCE OF THE ARGUMENTS IS OPPOSITE
OF WHAT THE CORE IMAGE WILL GENERATE.  ^FOR EXAMPLE,
.BREAK
.SKIP 1
#####^^		GEN	102, 103, A, B
\\
.BREAK
.SKIP 1
WILL BE THE EQUIVALENT OF SAYING
.BREAK
.SKIP 1
#####^^		XWD  B, A
\\
.BREAK
.SKIP 1
^I FELT IT WAS EASIER TO READ THE SYNTAX TABLE SOURCE CODING BY
DOINGEITITHISEWAY.D 9-5-70 LP WADE
.NOFILL
.NOJUSTIFY
.SPACING 1
.SUBTITLE ^^APPENDIX B\\
.PAGE
^^
.CENTER
DEVICE NUMBER ASSIGNMENTS
\\
.BREAK
.SKIP 1
^^
* THE FOLLOWING ARE THE DEVICE DEFINITIONS AS USED BY SNOBOL
*
* THIS PROGRAM CAN BE ASSEMBLED BEFORE YOUR PROGRAM
* TO PROVIDE A FUNCTION CALLED 'FINDEVICE' WHICH WILL
* ALLOW YOU MORE FLEXIBILTY IN HANDLING I/O.
*
* FOR EXAMPLE, IF THIS PROGRAM IS ON SYS:FIND.SNO
* YOU WOULD TYPE
*
* .R SNOBOL
* *FOO__SYS:FIND,YOURS.SNO
*
.INDEX ^^DEVTB\\
.INDEX DEVICE ASSIGNMENTS
.INDEX ^^FINDEVICE FUNCTION\\
^^
#####	DEVTB = TABLE(40)
#####	DEVTB<'DSK'> = 1
#####	DEVTB<'TTY'> = 2
#####	DEVTB<'PTR'> = 3
#####	DEVTB<'PTP'> = 4
#####	DEVTB<'DSK10'> = 5
#####	DEVTB<'DSK11'> = 6
#####	DEVTB<'CDP'> = 7
#####	DEVTB<'CDR'> = 8
#####	DEVTB<'LPT'> = 9
#####	DEVTB<'DTA0'> = 10
#####	DEVTB<'DTA1'> = 11
#####	DEVTB<'DTA2'> = 12
#####	DEVTB<'DTA3'> = 13
#####	DEVTB<'DTA4'> = 14
#####	DEVTB<'DTA5'> = 15
#####	DEVTB<'DTA6'> = 16
#####	DEVTB<'DTA7'> = 17
#####	DEVTB<'PLT'> = 18
#####	DEVTB<'FORTR'> = 19
#####	DEVTB<'DSK0'> = 20
#####	DEVTB<'DSK1'> = 21
#####	DEVTB<'DSK2'> = 22
#####	DEVTB<'DSK3'> = 23
#####	DEVTB<'DSK4'> = 24
#####	DEVTB<'DSK5'> = 25
#####	DEVTB<'DSK6'> = 26
#####	DEVTB<'DSK7'> = 27
#####	DEVTB<'DSK8'> = 28
#####	DEVTB<'DSK9'> = 29
#####	DEVTB<'MTA0'> = 30
#####	DEVTB<'MTA1'> = 31
#####	DEVTB<'MTA2'> = 32
#####	DEVTB<'MTA3'> = 33
#####	DEVTB<'MTA4'> = 34
#####	DEVTB<'MTA5'> = 35
#####	DEVTB<'MTA6'> = 36
#####	DEVTB<'MTA7'> = 37
*
.INDEX ^^FINDEVICE FUNCTION\\

^^
#####	DEFINE('FINDEVICE(NAME)')	:(FINDEND)
*
FINDEVICE	FINDEVICE = DEVTB<NAME>	
#####	IDENT(FINDEVICE) :S(FRETURN)F(RETURN)
FINDEND
\\
.SUBTITLE ^^INDEX\\
.PAGE
.CENTER
----- ^^INDEX\\ -----
.PRINT INDEX