"I quite agree with you," said the Duchess; "and the moral of that is--'Be what you would seem to be'--or, if you'd like it put more simply--'Never imagine yourself not to be otherwise than what it might appear to others that what you were or might have been was not otherwise than what you had been would have appeared to them to be otherwise."
"I think I should understand that better," Alice said very politely, "if I had it written down: but I ca'n't quite follow it as you say it."
"That's nothing to what I could say if I chose," the Duchess replied, in a pleased tone.


3. Description

The examples of INTERCAL programming which have appeared in the preceding sections of this manual have probably seemed highly esoteric to the reader unfamiliar with the language. With the aim of making them more so, we present here a description of INTERCAL.

3.1 Variables

INTERCAL allows only 2 different types of variables, the 16-bit integer and the 32-bit integer. These are represented by a spot (.) or two-spot (:), respectively, followed by any number between 1 and 65535, inclusive. These variables may contain only non-negative numbers; thus they have the respective ranges of values: 0 to 65535 and 0 to 4294967295. Note: .123 and :123 are two distinct variables. On the other hand, .1 and .0001 are identical. Furthermore, the latter may not be written as 1E-3.

3.2 Constants

Constants are 16-bit values only and may range from 0 to 65535. They are prefixed by a mesh (#). Caution! Under no circumstances confuse the mesh with the interleave operator, except under confusing circumstances!

3.3 Arrays

Arrays are represented by a tail (,) for 16-bit values, or a hybrid (;) for 32-bit values, followed by a number between 1 and 65535, inclusive. The number is suffixed by the word SUB, followed by the subscripts, separated optionally by spaces. Subscripts may be any expressions, including those involving subscripted variables. This occasionally leads to ambiguous constructions, which are resolved as discussed in section 3.4.3. Definition of array dimensions will be discussed later in greater detail, since discussing it in less detail would be difficult. As before, ,123 and ;123 are distinct. In summary, .123, :123, #123, ,123, and ;123 are all distinct.

3.4 Operators

INTERCAL recognizes 5 operators--2 binary and 3 unary. * Please be kind to our operators: they may not be very intelligent, but they're all we've got. In a sense, all 5 operators are binary, as they are all bit-oriented, but it is not our purpose here to quibble about bits of trivia.

3.4.1 Binary Operators

The binary operators are interleave (also called mingle) and select, which are represented by a big money ($) and a sqiggle [sic] (~), respectively.

The interleave operator takes two 16-bit values and produces a 32-bit result by alternating the bits of the operands. Thus, #65535$#0 has the 32-bit binary form 101010....10 or 2863311530 decimal, while #0$#65535 = 0101....01 binary = 1431655765 decimal, and #255$#255 is equivalent to #65535.

(Note that INTERCAL-72 used change (¢) to represent interleave. For C-INTERCAL's non-EBCDIC environment, big money has been substituted, but change can still be used via the Latin-1 character 0xA2. Since the majority of extant INTERCAL is written in ASCII, big money is used throughout this document. See also section 10.1 and section 11.)

The select operator takes from the first operand whichever bits correspond to 1's in the second operand, and packs these bits to the right in the result. Both operands are automatically padded on the left with zeros to 32 bits before the selection takes place, so the variable types are unrestricted. The resulting value will have the same type as the second operand. For example, #179~#201 (binary value 10110011~11001001) selects from the first argument the 8th, 7th, 4th, and 1st from last bits, namely, 1001, which = 9. But #201~#179 selects from binary 11001001 the 8th, 6th, 5th, 2nd, and 1st from last bits, giving 10001 = 17. #179~#179 has the value 31, while #201~#201 has the value 15.

Perhaps a simpler way of understanding the operation of the select operator would be to examine the logic diagram in Figure 1, which performs the select operation upon two 8-bit values, A and B. The gates used are Warmenhovian logic gates, which means the outputs have four possible values: low, high, undefined (value of an uninitialized flip-flop), and oscillating (output of a NOR gate with one input low and the other input connected to the output). These values are represented symbolically by '0', '1', '?', and 'Ø'. Note in particular that, while NOT-0 is 1 and NOT-1 is 0 as in two-valued logic, NOT-? is ? and NOT-Ø is Ø. The functions of the various gates are listed in Table 1.

3.4.1.1 Return type of SELECT

INTERCAL-72 defined the return type of a select operation to depend on the number of bits selected. That is, if the second operand was a 32-bit variable, but had 15 or fewer bits set to 1, the result would be a 16-bit value. The C-INTERCAL compiler takes the easier route of defining the return type to be that of the right operand, independent of its actual value. This form has the advantage that all types can be determined at compile time. Putting in run-time type-checking would add significant overhead and complication, to effect a very minor change in language semantics.

The only time this distinction makes any difference is when a unary operator is applied to the select result. This happens extremely rarely in practice, the only known instance being the 32-bit greater-than test in the standard library, where an XOR operator is applied to the result of selecting a number against itself. The INTERCAL-72 authors select the result against #65535$#65535, which has no effect in C-INTERCAL, but in the original language it ensures that XOR sees a 32-bit value.

The cautious programmer should write code that does not depend on the compiler version being used. We therefore suggest the following guideline for determining the select return type. A select operation with a 16-bit right operand returns a 16-bit value. The return type of a select operation with a 32-bit right operand is undefined, but is guaranteed to be an acceptable input to a mingle operation so long as 16 or fewer bits are actually selected. Correct code should not depend on whether the return type is 16 or 32 bits.

3.4.2 Unary Operators

The unary operators are ampersand (&) (logical AND), V (or book) (V) (logical OR), and what (?) (logical XOR). The operator is inserted between the spot, two-spot, mesh, or what-have-you, and the integer, thus: .&123, #?123. Multiple unary operators may not be concatenated, thus the form #?&123 is invalid. This will be covered later when precedence is discussed. These operators perform their respective logical operations on all pairs of adjacent bits, the result from the first and last bits going into the first bit of the result. The effect is that of rotating the operand one place to the right and ANDing, ORing, or XORing with its initial value. Thus, #&77 (binary = 1001101) is binary 0000000000000100 = 4, #V77 is binary 1000000001101111 = 32879, and #?77 is binary 1000000001101011 = 32875.

(INTERCAL-72 used the bookworm character to represent XOR, which was obtained by overpunching a worm (-) on a V (V). Since the average user of C-INTERCAL is unlikely to be using a card puncher to submit their programs, and as the modern VDT is notorious for poor rendering of overstrikes, ? is used in its place. However, the C-INTERCAL compiler will recognize the V<backspace>- trigraph as equivalent notation. See also section 10.1 and section 11.)

3.4.3 Precedence

Precedence of operators is as follows:


(This space intentionally left blank) **




This precedence (or lack thereof) may be overruled by grouping expressions between pairs of sparks (') or rabbit-ears ("). Thus '#165$#203'~#358 (binary value '10100101$11001011'~101100110) has the value 15, but #165$'#203~#358' has the value 34915, and #165$#203~#358 is invalid syntax and is completely valueless (except perhaps as an educational tool to the programmer). A unary operator is applied to a sparked or rabbit-eared expression by inserting the operator immediately following the opening spark or ears. Thus, the invalid expression #?&123, which was described earlier, could be coded as '?#&123' or '?"&#123"'. Note: In the interests of simplifying the sometimes overly-complex form of expressions, INTERCAL allows a spark-spot combination ('.) to be replaced with a wow (!). Thus '.1~.2' is equivalent to !1~.2', and 'V.1$.2' is equivalent to "V!1$.2'".

Combining a rabbit-ears with a spot to form a rabbit is not permitted, although the programmer is free to use it should he find an EBCDIC reader which will properly translate a 12-3-7-8 punch.

Sparks and/or rabbit-ears must also be used to distinguish among such otherwise ambiguous subscripted and multiply-subscripted expressions as:

        ,1 SUB #1 ~ #2
        ,1 SUB ,2 SUB #1 #2 #3
        ,1 SUB " ,2 SUB " ,3 SUB #1 " #2 " " #3 "

The third case may be isolated into either of its possible interpretations by simply changing some pairs of rabbit-ears to sparks, instead of adding more ears (which would only confuse the issue further). Ambiguous cases are defined as those for which the compiler being used finds a legitimate interpretation which is different from that which the user had in mind. See also section 12.

* Other operators are also available with C-INTERCAL's non-standard dialects; see section 6.

** Keep in mind that the aim in designing INTERCAL was to have no precedents.


[Next]
[Previous]
[Contents]