"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.
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.
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
.
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!
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.
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.
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.
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.
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.)
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 '?"{"'
. 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]