Most other programming languages require the user to explicitly declare the type of data to be stored in a variable. In SNOBOL4, any variable may contain any data type. Furthermore, the variable's type may be freely altered during program execution. SNOBOL4 remembers what kind of data is in each variable.
The primitive function ARRAY() creates an array storage area, and returns a pointer with this data type. If this pointer is stored in a variable, the variable is said to be of type ARRAY, and may then be subscripted to access the elements of the array.
The primitive function CODE() compiles a string containing SNOBOL4 statements, and returns a pointer to the resulting object code block. If this pointer is stored in a variable, the variable is said to be of type CODE. The variable may then be used with a direct GOTO by enclosing it in angle brackets.
When the unevaluated expression operator (*) is applied to an expression, the result has the data type EXPRESSION. Such expressions are not evaluated when they are defined, only when they are referenced.
E = *(LEN(K) POS(M))defines E as an unevaluated expression. When this statement is executed, the code to concatenate two function calls is compiled, but not executed. It is only when E is referenced in a subsequent pattern match or appears as the argument of the EVAL function that the code is executed to produce a pattern.
The unevaluated expression operator must be at the outermost level to create an object of type EXPRESSION. If buried with the expression, the execution results may appear to be similar, but the object's data type is different. That is, the two statements
P = *LEN(N) P = LEN(*N)produce identical results when P is used in a pattern match (if LEN is not redefined). However, the first statement produces P as type EXPRESSION, while the second produces P as type PATTERN. Expressions may also be produced explicitly with the CONVERT() function (see below).
External assembly language functions may create new data types whose structure is known only to them. This feature is only available in SNOBOL4+, Catspaw's enhanced implementation of the SNOBOL4 language.
A decimal number in the range -32767 to +32767. No fractional part may appear. One computer word (16 bits) is used to contain an integer value.
When the unary name operator (.) is applied to a variable, two results are possible. If the variable's name is a simple string (a "natural variable"), such as ABC, the variable's name is returned as type STRING. For example, .ABC has the value 'ABC'. However, if the variable is a created variable, such as a table or array element, the NAME data type results. In either case, the result of the name operator can be thought of as the "address" or "storage location" of the variable. When the indirect reference operator ($) is applied to such a result, the original, underlying object is obtained. That is, $(.A) is the same as using the variable A.
For natural variables, SNOBOL4 has the surprising property that the string 'XYZ' is the address (or name) of variable XYZ, so $'XYZ' is equivalent to XYZ.
A pattern is created by an expression containing any of the following: other patterns, primitive patterns, pattern functions, the alternation operator (|), the conditional or immediate assignment operator (. or $), or the cursor position operator (@). A simple string is not a pattern data type, even though it may appear in the pattern portion of a statement. The following are examples of the pattern data type:
POS(0) "A" LEN(1) "COLUMN A" | "COLUMN B" "ZIP" . X "MATCH" @Y
Up to 899 new data types may be created with the primitive function DATA. The name specified in the prototype string becomes a new data type in SNOBOL4. Any object created with the data type's creation function is given this name as its data type.
DATA('COMPLEX(REAL, IMAG)') ;* Define new type COMPLEX NUM = COMPLEX(2, -4) ;* Create a COMPLEX object OUTPUT = DATATYPE(NUM) ;* Print string 'COMPLEX'
A floating-point decimal number in the range 2.3E-308 to 1.7E+308. Reals are only available in SNOBOL4+, Catspaw's enhanced implementation of the SNOBOL4 language.
A sequence of characters. Each character occupies one memory byte, and may contain any of the 256 possible bit combinations. A string of length zero is called the null string. Maximum length of a string is determined by the keyword &MAXLNGTH (default 5000). Memory restrictions in Vanilla SNOBOL4 will limit the longest string possible to less than the 32767 characters allowed in SNOBOL4+, Catspaw's enhanced SNOBOL4 implementation.
The primitive function TABLE() creates a table storage area, and returns a pointer with this data type. If this pointer is stored in a variable, the variable is said to be of type TABLE. The variable may then be subscripted to access the elements of the table. A table may be thought of as a one dimensional array in which the array subscripts may be any SNOBOL4 data type. Arrays require integer subscripts, but table subscripts such as T<"TALLY"> or T<13.52> are acceptable.
NEWTYPE = CONVERT(OBJECT, "DESIRED TYPE")
A = ARRAY('1:50,6') OUTPUT = Aproduces the string "ARRAY('1:50,6')".
C = CODE(' PIT2 = .OPPIT4 :(RETURN)') OUTPUT = Cdisplays the string "CODE".
LASTN = *(RTAB(N) REM . LCHARS) . . . N = 4 SUBJECT LASTN :F(TOO_SHORT)
LASTN = *(RTAB(N) REM . LCHARS) OUTPUT = LASTNproduces the string "EXPRESSION".
SUBJECT 19 = ''
A = -23; B = 0; C = 92 OUTPUT = A B Cproduces the string "-23092".
N = .A[2] OUTPUT = Ndisplays the string "NAME".
WPAT = BREAK(LETTERS) SPAN(LETTERS) . WORD OUTPUT = WPATproduces the string "PATTERN".
DATA('COMPLEX(REAL,IMAG)') R1 = COMPLEX(2, 3) OUTPUT = R1produces the string "COMPLEX".
RESULT = ("-14" + "") / "2"stores integer -7 in RESULT.
SUBJECT "HOPE"
T = TABLE(100) . . . A = CONVERT(T, "ARRAY") :F(EMPTY)The table is converted to a rectangular array. Null table entries are omitted, and there must be at least one nonnull entry or the function fails. An N by 2 array is created, where N is the number of nonnull table values. The first array column contains the table subscripts, the second column contains the entry values.
T = TABLE(10,10) . . . ; Insert 45 nonnull elements into T . . . OUTPUT = Tproduces the string "TABLE(50,10)" (because table segments in this case are allocated in multiples of 10).
The following matrix indicates conversions with CONVERT():
| Result Type E | X | P | I P R D | S N A E E | T T T A T S F | R E T N R A C S I | I G E A R B O I N Argument | N E R M A L D O E Type | G R N E Y E E N D -----------+----------------------------------- STRING | * I P C E INTEGER | S * P PATTERN | F * NAME | F * ARRAY | A * 1 TABLE | T 2 * CODE | F * EXPRESSION | F P * DEFINED | F *
* | The argument object is returned unchanged. |
A | The formal data type name "ARRAY" is returned with the defining prototype string if it is less than 20 characters. |
C | CONVERT(string,"CODE) behaves exactly like CODE(string). |
E | Produces an unevaluated expression, that may be subsequently used in a pattern, or evaluated with the EVAL() function. |
F | The formal data type name is returned. |
I | Numeric conversion is conditioned on magnitude and syntax restrictions. No leading or trailing blanks are permitted. |
P | Occurs implicitly within a pattern match. |
S | A number may always be converted to its string form. |
T | The string "TABLE" is returned with the present size of the table and its expansion increment: "TABLE(50,10)". |
1 | The array must be rectangular, with a second dimension of 2 (N rows by 2 columns). A table with N entries is created. The table subscripts are taken from the first column of the array; the table values are copied from the second column. |
2 | The table is converted to a rectangular array. Null table entries are omitted, and there must be at least one nonnull entry or the function fails. An N by 2 array is created, where N is the number of nonnull table values. The first array column contains the table subscripts, the second column contains the entry values. |