Each line of input to SNOBOL4 consists of a sequence of ASCII characters, terminated by a carriage return.
Comment and control statements are always one line long. However, a program statement may occupy several lines if necessary. A continuation mark (plus sign or period) is placed in the first column of the additional lines.
n Fold lower-case names to upper-case if n is nonzero. Treat upper- and lower-case names as distinct if n is zero or absent.
Start a new page on the listing file.
Equivalent to -LIST LEFT.
LEFT Turn on list output, produce statement numbers at left end of line.
RIGHT Turn on list output, produce statement numbers at right end of line.
Turn off list output. Errors are not shown on the screen.
LABEL SUBJECT PATTERN = REPLACEMENT :GOTOStatement elements are separated by blank or tab.
Ignoring the LABEL and GOTO fields for a moment, the remaining elements may appear in various combinations to create different types of statements:
If the equal sign (=) is present but the replacement field is absent, the null string is assumed as the value of the replacement field.
If case-folding is in effect, lower-case letters are converted to upper-case before defining the label.
In an assignment statement, the subject must be a variable name, an unprotected keyword, or a field-reference function from a program-defined data type. If a string is produced by evaluating an expression, the indirect ($) operator must be used to reference the underlying variable.
If the subject appears in pattern matching without replacement, the subject must evaluate to a string. The string is scanned left to right during the pattern match. If the subject evaluates to an integer, it is automatically converted to a string. If replacement is present, the same subject restrictions of assignment statements apply. Thus, a literal string is a valid subject only if replacement is absent.
If the expression comprising the subject contains the concatenation operator, the subject must be surrounded by parenthesis. This allows SNOBOL4 to distinguish concatenation blanks within the subject from the blank between subject and pattern.
The pattern may assign various matching components to variables with the binary assignment operators dot and dollar sign (., $).
If there is pattern matching on the left side of the statement, the replacement field must evaluate to a string, so that it may be inserted into the matched portion of the subject string.
Replacement occurs only if evaluation of the subject, pattern, and replacement succeed. Primitive functions which return success or failure may be used in the replacement field as predicate functions. Since they return the null string, they do not alter the replacement value. However, their failure can prevent replacement from occurring, and can be tested in the GOTO field.
The "unconditional GOTO" causes control to be transferred to the specified labeled statement. The label is enclosed in parenthesis, and may be a name, or the result of evaluating an expression and applying the indirect operator ($). Transfer is made to the labeled statement regardless of the success or failure outcome of the earlier parts of the statement.
The "conditional GOTO" similarly specifies control transfer to a labeled statement, but it depends on the success or failure of the statement. The letter S precedes the parenthesized label where control goes next if the statement succeeds. The letter F specifies the branch to be taken if the statement fails. For example:
:S(LOOP) Branches to label LOOP if the statement succeeds. :F(ERROR) Branches to label ERROR if the statement fails. :S(OK) F(NOGO) Branches to label OK on success, to NOGO on failure. :(AGAIN) Unconditionally transfers control to label AGAIN. :($('VAR' N)) Branches to the label obtained by concatenating the string 'VAR' with the value of variable N.The "direct GOTO" is used to branch to a block of code compiled with the CODE function. If the code contains labels, a regular GOTO could branch to the label and begin execution in the code block. The direct GOTO will branch to the start of the code block, labeled or not. A direct GOTO is specified by placing in angle brackets the name of the variable which points to the code block.
Direct GOTOs may be made conditional by preceding them with S or F. They may also appear with regular GOTOs:
VAR = CODE(string) :S<VAR> F(COMPILE_ERROR)The lower-case letters "s" and "f" may be used interchangeably with "S" and "F", regardless of case-folding.
The GOTO field may appear on a line without any subject, pattern, and replacement. The absent SNOBOL4 statement is assumed to have succeeded.
Very long strings may be entered on multiple lines, using the implicit blank between lines as a concatenation operator:
LONG_STRING = "This is an example of a very long " + "string that wends its way across multiple continua" + "tion statements. There is an implicit blank at the " + "beginning of each line that provides the concatenation" + " operator between segments."
I = 1; J = 2; S PAT = 'HENRI' :S(YES) I = 1;OUT OUTPUT = A<I> :F(END); I = I + 1 :(OUT)Because of its poor readability, placing labels in the middle of a statement is strongly discouraged.
As a language extension, Vanilla SNOBOL4 permits a comment statement after the semicolon. This provides a simple device for end-of-line comments:
PARA NEXT = GETNEXT() :F(FRETURN) ;* Return if EOF IDENT(NEXT) :S(RETURN) ;* Return on empty line PARA = PARA NEXT :(PARA) ;* Splice line
. . . OUTPUT = 'All done' ENDAfter reading the END statement, compilation ends, and execution begins immediately with the very first program statement. When the program is done, it should flow into the END statement, or use a GOTO to transfer to it.
Occasionally, we would like to begin execution at other than the first statement. If we place a statement label in the subject field of the END statement, execution will begin there. For example, this statement will cause execution to begin at the statement labeled START:
END START