





             TTHHEE IINNTTEERRCCAALL PPRROOGGRRAAMMMMIINNGG LLAANNGGUUAAGGEE
                  RREEVVIISSEEDD RREEFFEERREENNCCEE MMAANNUUAALL

                      _D_o_n_a_l_d _R_. _W_o_o_d_s
                            _a_n_d
                       _J_a_m_e_s _M_. _L_y_o_n

                   _C_-_I_N_T_E_R_C_A_L _r_e_v_i_s_i_o_n_s_:
                        _L_o_u_i_s _H_o_w_e_l_l
                            _a_n_d
                      _E_r_i_c _S_. _R_a_y_m_o_n_d






           _C_o_p_y_r_i_g_h_t _(_C_) _1_9_7_3 _b_y _D_o_n_a_l_d _R_. _W_o_o_d_s
                     _a_n_d _J_a_m_e_s _M_. _L_y_o_n
           _C_o_p_y_r_i_g_h_t _(_C_) _1_9_9_6 _b_y _E_r_i_c _S_. _R_a_y_m_o_n_d
            _R_e_d_i_s_t_r_i_b_u_t_i_o_n _e_n_c_o_u_r_a_g_e_d _u_n_d_e_r _G_P_L

      _(_T_h_i_s _v_e_r_s_i_o_n _d_i_s_t_r_i_b_u_t_e_d _w_i_t_h _C_-_I_N_T_E_R_C_A_L _0_._1_5_)








































                            - 1 -



_1_.  _I_N_T_R_O_D_U_C_T_I_O_N

The  names  you  are  about to ignore are true. However, the
story has been changed significantly. Any resemblance of the
programming  language  portrayed  here  to other programming
languages, living or dead, is purely coincidental.

_1_._1  _O_r_i_g_i_n _a_n_d _P_u_r_p_o_s_e

The INTERCAL programming language was designed  the  morning
of  May  26,  1972  by Donald R. Woods and James M. Lyon, at
Princeton University.  Exactly  when  in  the  morning  will
become apparent in the course of this manual.

Eighteen  years  later  (give  or take a few months) Eric S.
Raymond perpetrated a UNIX-hosted  INTERCAL  compiler  as  a
weekend  hack.  The C-INTERCAL implementation has since been
maintained and extended by  an  international  community  of
technomasochists,  including  Louis  Howell,  Steve  Swales,
Michael Ernst, and Brian Raiter.

(There  was  evidently  an  Atari  implementation   sometime
between   these  two;  notes  on  it  got  appended  to  the
INTERCAL-72 manual.  The culprits have sensibly declined  to
identify themselves.)

INTERCAL  was  inspired  by one ambition: to have a compiler
language which has nothing at all in common with  any  other
major language. By 'major' was meant anything with which the
authors were at all familiar, e.g., FORTRAN,  BASIC,  COBOL,
ALGOL,  SNOBOL, SPITBOL, FOCAL, SOLVE, TEACH, APL, LISP, and
PL/I. For the most part, INTERCAL has remained true to  this
goal,  sharing  only  the  basic elements such as variables,
arrays, and  the  ability  to  do  I/O,  and  eschewing  all
conventional  operations other than the assignment statement
(FORTRAN "=").

_1_._2  _A_c_r_o_n_y_m

The full name of the compiler is "Compiler Language With  No
Pronounceable  Acronym",  which  is,  for  obvious  reasons,
abbreviated "INTERCAL".

_1_._3  _A_c_k_n_o_w_l_e_d_g_m_e_n_t_s

The authors are deeply indebted to Eric M. Van and Daniel J.
Warmenhoven,  without whose unwitting assistance this manual
would still have been possible.














                            - 2 -



_2_.  _F_U_N_D_A_M_E_N_T_A_L _C_O_N_C_E_P_T_S

In this section an attempt is made to describe how  and  why
INTERCAL  may  be used; i.e., what it is like and what it is
good for.

_2_._1  _S_a_m_p_l_e _P_r_o_g_r_a_m

Shown below is a relatively simple  INTERCAL  program  which
will read in 32-bit unsigned integers, treat them as signed,
2's-complement numbers, and print out their absolute values.
The  program  exits  if  the absolute value is zero. Note in
particular the inversion routine (statements 6 through  14),
which  could be greatly simplified if the subroutine library
(see section 7) were used.

A more detailed analysis of a program is made in  section  8
of this manual.

        DO (5) NEXT
    (5) DO FORGET #1
        PLEASE WRITE IN :1
        DO .1 <- 'V-":1~'#32768c/#0'"c/#1'~#3
        DO (1) NEXT
        DO :1 <- "'V-":1~'#65535c/#0'"c/#65535'
                ~'#0c/#65535'"c/"'V-":1~'#0c/#65535'"
                c/#65535'~'#0c/#65535'"
        DO :2 <- #1
        PLEASE DO (4) NEXT
    (4) DO FORGET #1
        DO .1 <- "V-':1~:2'c/#1"~#3
        DO :1 <- "'V-":1~'#65535c/#0'"c/":2~'#65535
                c/#0'"'~'#0c/#65535'"c/"'V-":1~'#0
                c/#65535'"c/":2~'#65535c/#0'"'~'#0c/#65535'"
        DO (1) NEXT
        DO :2 <- ":2~'#0c/#65535'"
                c/"'":2~'#65535c/#0'"c/#0'~'#32767c/#1'"
        DO (4) NEXT
    (2) DO RESUME .1
    (1) PLEASE DO (2) NEXT
        PLEASE FORGET #1
        DO READ OUT :1
        PLEASE DO .1 <- 'V-"':1~:1'~#1"c/#1'~#3
        DO (3) NEXT
        PLEASE DO (5) NEXT
    (3) DO (2) NEXT
        PLEASE GIVE UP

_2_._2  _U_s_e_s _f_o_r _I_N_T_E_R_C_A_L

INTERCAL's  main  advantage over other programming languages
is its strict simplicity. It has few capabilities, and  thus
there  are  few restrictions to be kept in mind. Since it is
an exceedingly easy language to learn, one might  expect  it








                            - 3 -



would  be a good language for initiating novice programmers.
Perhaps surprising, than, is the fact that it would be  more
likely  to  initiate a novice into a search for another line
of work. As it turns out, INTERCAL  is  more  useful  (which
isn't   saying   much)   as   a  challenge  to  professional
programmers.  Those who doubt this need only refer  back  to
the sample program in section 2.1. This 22-statement program
took somewhere from 15 to 30 minutes to write,  whereas  the
same objectives can be achieved by single-statement programs
in either SNOBOL;

        PLEASE INPUT POS(0) ('-' ! '')
        + (SPAN('0123456789') $ OUTPUT)
        + *NE(OUTPUT) :S(PLEASE)F(END)

or APL;

        [1] ->0!=[]<-|[]

Admittedly, neither  of  these  is  likely  to  appear  more
intelligible   to   anyone  unfamiliar  with  the  languages
involved, but they took roughly 60 seconds and  15  seconds,
respectively,  to  write.  Such is the overwhelming power of
INTERCAL!

The other major importance of INTERCAL lies in its seemingly
inexhaustible capacity for amazing one's fellow programmers,
confounding programming shop managers, winning friends,  and
influencing  people. It is a well-known and oft-demonstrated
fact that a person whose work is incomprehensible is held in
high  esteem.  For  example,  if  one were to state that the
simplest way to store a value of 65536 in a 32-bit  INTERCAL
variable is:

        DO :1 <- #0c/#256

any  sensible  programmer  would  say  that that was absurd.
Since this is indeed the  simplest  method,  the  programmer
would  be  made  to  look  foolish in front of his boss, who
would of course happened to turn up, as bosses are  wont  to
do.  The  effect  would  be  no  less  devastating  for  the
programmer having been correct.




















                            - 4 -



_3_.  _D_E_S_C_R_I_P_T_I_O_N

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  _V_a_r_i_a_b_l_e_s

INTERCAL allows only 2 different  types  of  variables,  the
1166--bbiitt   iinntteeggeerr   and   the   3322--bbiitt  iinntteeggeerr..   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  _C_o_n_s_t_a_n_t_s

CCoonnssttaannttss 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  _A_r_r_a_y_s

AArrrraayyss 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  _O_p_e_r_a_t_o_r_s

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  _B_i_n_a_r_y _O_p_e_r_a_t_o_r_s

The binary operators are iinntteerrlleeaavvee (also called mmiinnggllee) and
sseelleecctt,  which are represented by a change (c/) and a sqiggle








                            - 5 -



[sic]   (~),   respectively.    (In    C-INTERCAL'S    ASCII
environment, EBCDIC c/ is replaced by a big money ($).)

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

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.  If more than 16 bits are selected, the result
is  a  32-bit  value,  otherwise  it  is a 16-bit value. 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.

_3_._4_._1_._1  _R_e_t_u_r_n _t_y_p_e _o_f _S_E_L_E_C_T

INTERCAL-72 defined the return type of a SELECT operation to
depend on the  number  of  bits  SELECTed.   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
first SELECT the result against #65535c/#65535 to insure that
XOR  sees  a  32-bit  value.  With the current compiler this
extra step is unnecessary, but harmless.

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








                            - 6 -



depend on whether the return type is 16 or 32 bits.

Perhaps a simpler way of understanding the operation of  the
select operator would be to examine the logic diagram on the
following  page  (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 'O|'.  Note in particular that, while NOT-0 is
1 and NOT-1 is 0 as in two-valued  logic,  NOT-?  is  ?  and
NOT-O| is O|. The functions of the various gates are listed in
Table 1.

[Warning: The following picture will be garbled or  missing.
Get a better output device.]












































                            - 7 -



 --+-+----     --+----  +--+----   --+----  +--+----
A1   | | 1  +-+--+-+ 2  +-++-+ 3  ++-+-+ 3  ++|--+ 1  +--
B --+++    | |--+-+    | || |    ||||++    |||| |    |       TO
1   +++------++-+-+------+|-+---  +++++-----++|-+---      ---NEW
    +-------++-+---------+-------+++++-----+ |             YORK
   +-+------++-+-+-----+ | +---- ||| +-----+ | +----        TO
A2 --+-+    | || +-+    || --+    |+++-+    |+-+-+    |    ---NEW
 --+-+ 1  +-++-+-+ 2  +++--+ 7  +-++-+ 3  +--+-+ 2  +--    YOTROK
B2   |-+---   |||+-+---  || -+---   |+-+------++-+-------  ---NEW
   +--------+++-+------++---------+--------+|+---------    YORK
   +-+------+++-++-----++--+-----+| ++-----++--+-----+      TO
A --+-+    | +++-++    |++--+    |++-++    ||+--+    || B ---NEW
3     | 1  +-+++-+| 2  +-++-+ 3  +-++++ 3  ++++-+ 3  ++-    YORK
B3 --+-+---  ||||+++---  |||-+---  ++|++---  ||+++---  |      TO
   +-------++++++------+++-------++++------++++------+-U ---NEW
   +-+-----+++-+++-----+++-+-----+++||     ++++|     |     YORK
A --+-+----|||| ||+----||++-+----||++++----|+++++----|| S    TO
4     | 1  +++++|++ 2  ++++-+ 7  ++++++ 3  ++++-+ 4  ++-  ---NEW
B --+-+---  ||||+-+---  ||+-+---  |||++--- ++--++---  |     YOTROK
4   |       |||+++      ++--+ +---++++++++++|+-+------+   ---NEW
   +-------+++-++-------++++-+--+||+++++++-++++--+         YORK
 --+-+-----+++-+++-----+++++-+--+++-++++++ +++++-+--   L    TO
A5     | 1  ++++++++ 2  ++++++ 3  +++ ++ 3  +-++++ 5  +--  ---NEW
B --+-+    |||+++++    |  |||    ||| ||    |++++|    |      YORK
5   |-+---  |||||++-------|++----+|+--+-----+++++-------I    TO
   +-------+++++--------++------++++ +---  |+++          ---NEW
   +-+-----+++++-+-----+|| +----++++++-----+|||+----   N   YORK
A6 --+-+    |||-++++    |+++-+    |+++++    | ++++    |       TO
 --+-+ 1  +++-++++ 2  ++++-+ 3  +-++++ 4  ++++++ 4  +--  ---NEW
B6   |-+---  +++++++---  +++-+-----+||++-----+++++-------E   YORK
   +--------++++--------++------+|||       ++-+          ---TO
   +-+------++++-+-----+|| +----++++++---- ||  +----       NEW
A --+-+    | -+++-+    |+++-+    |+++++    ||+--+    |      YOTROK
7     | 1  +--+|+-+ 2  +-++-+ 3  ++|+++ 4  ++-+-+ 5  +--  ---NEW
B7 --+-+---   ||++-+---   ||++---  || ++---  --+++---        YORK
   +----+---++++--------+++------++ +------+-++------+-     TO
   +-+--+---++++-+-------+||     |  ||     |  ||     |   ---NEW
A --+-+----| |+++-+----|+-+++----|+--++----||+--+----||     YORK
8     | 1  +-+ |+-+ 2  ++ +++ 4  ++ +++ 3  ++++-+ 5  ++-8    TO
B --+-+---     +--+---  |  ++---  | |++---  | |-+---  |   ---NEW
8   +----------------+  ++-+      +-++---+ ++-+------+|     YORK
                    +--+++--------+||   +-++++------++-     TO
     +----  +-+--+-----+++-+----  ++++----+|++-+----++-  ---NEW
     | 6  +-+ +--+ 2  ++-+-+ 7  +-++-+ 3  +++|++ 4  ++-    YOTROK
     |    |  -+--+    |+---+    |  | |    || |||    ||   --P-HILA-
    -+---    |  -+---     -+---    |-+---  +-+++---  |   DELPHIA
             +---------------------+---------+-------+-
     +----   |+--+---------+------++-+-----+   +----
     |    |  ++--+    |  +-+    | |--+    ||+--+    |
     | 6  +--++--+ 1  +-++-+ 1  +-+--+ 1  +++--+ 1  ++
    -+---       -+--- --++-+---   | -+---  |  -+-----+-
                        ---                         ---
                FIGURE 1. CIRCUITOUS DIAGRAM









                            - 8 -



   __________________________________________________________
  |\                                                         \
  | \ 1. Logic gate.  Inputs A, B.  Output O = AB.            \
  |  \                                                         \
  | \ \ 2. Logic gate.  Inputs A, B, C.  Output O = A+BC.       \
  | |\ \                                                         \
  | | \ \ 3. Logic gate.  Inputs A, B.  Output O = A+AB.          \
  | |  \ \                                                         \
  | |  |\ \ 4. Logic gate.  Inputs A, B.  Output O = AB O+ -(A+-B)   \
  | |  | \ \                                                         \
  | |  |  \ \ 5. Logic gate.  Inputs A, B.  Output O = AO+A + AA       \
  | |  |   \ \                                                         \
  | |  |    \ \ 6. Uninitialized flip-flop.  Inputs none.  Output O = ? \
  | |  |     \ \                                                         \
  | |  |      \ \ 7. Flip-flop-flap.  Inputs A, B, C.  Output O = 1 if    \
  | |  |       \ \    A=0 or B+C=0 and A=1.  O = 0 if AC=1, B=0.  O = O| if \
  | |  |        \ \    AB=1, C=0.  O = ? if ABC=1.  O as yet undetermined   \
  | |  |         \ \    for other Warmenhovian inputs.  See Figure 2.        \
  | |  |          \ \                                                         \
  | |  |           \ \ 8. Bus line.                                            \
  | |  |            \ \_________________________________________________________\
  | |  |             \ |                                                         |
  | |  |             | |  _____________________________________________________  |
  | |  |             | |  |                              | |  |             | |  |
  | |  |             | |  |                              | |  |             | |  |
  | |  |             | |  |                              | |  |             | |  |
  | |  |             | |  |                              | |  |             | |  |
  | |  |             | |  |                              | |  |             | |  |
   \|__|             | |  |                               \|__|             | |  |
                     | |  |                                                 | |  |
                     | |  |                                                 | |  |
                     | |  |                                                 | |  |
                     | |  |                                                 | |  |
                     | |  |                                                 | |  |
                     | |  |                                                 | |  |
                     | |  |                                                 | |  |
                     | |  |                                                 | |  |
                     | |  |                                                 | |  |
                     | |  |                                                 | |  |
                     | |  |                                                 | |  |
                     | |  |                                                 | |  |
                     | |  |                                                 | |  |
                     | |  |                                                 | |  |
                     | |  |                                                 | |  |
                     | |  |                                                 | |  |
                     | |  |                                                 | |  |
                     | |  |                                                 | |  |
                      \|__|                                                  \|__|

          Table 1.  Logical (and other) functions.












                            - 9 -



[Warning:  The following picture will be garbled or missing.
Get a better output device.]










-------------------------+----
A                     +---+    |----+------------D
                     |   |    |    |
                         +----



                     |   |            |
                     +---+----        |
B-------------------------+    |----+  |
                         +----|    |  |
                                   |  |
                                   |  |
                                   |  |
                                   |  |
                         |         |  |
C-------------------------+----|    |  |
        +----------------+    |--+ |  |
        |                +----   | |  |
        |                        | |  |
        |                             |
        |                             |
        |                             |
        |            | | |            |
        |            | +-+----|       |
        |            +---+ +- +-------+
        |                +-+--
  1-----+










                  FIGURE 2. FLIP FLAP FLOP











                           - 10 -



[Warning: The following picture will be garbled or  missing.
Get a better output device.]

-----
-----   -----
-----
-----   -----

-----   -----
-----
-----   -----
-----                         GATE TYPE 9.  BLACK BOX
----- 9 -----                 INPUTS A1-8,  B1-8.
-----                         OUTPUT D1-8 = A1-8~B1=8
-----   -----
-----
-----   -----

-----   -----
-----
-----   -----
-----











              FIGURE 1  (CONTINUED).  NEW YORK




























                           - 11 -



_3_._4_._2  _U_n_a_r_y _O_p_e_r_a_t_o_r_s

The unary operators are & (logical AANNDD), V (logical OORR), and
V-  (logical  XXOORR).  This  last  character  is  obtained   by
overpunching  a worm (-) on a V (V).  (In C-INTERCAL'S ASCII
environment, EBCDIC V- is  replaced  by  the  what  (?).  The
compiler  recognizes -<backspace>V as a valid equivalent, in
case  you  are  concerned  about  compatibility   with   the
Princeton  compiler.   The  operator is inserted between the
spot, two-spot, mesh, or  what-have-you,  and  the  integer,
thus:  .&123,  #V-123.  Multiple  unary  operators may not be
concatenated, thus the form #V-&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    #V-77    is    binary
1000000001101011 = 32875.

_3_._4_._3  _P_r_e_c_e_d_e_n_c_e

Precedence of operators is as follows:










(The remainder of this page intentionally left blank)1















____________________

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







                           - 12 -



This precedence  (or  lack  thereof)  may  be  overruled  by
grouping  expressions between pairs of sparks (') or rabbit-
ears    (").    Thus    '#165c/#203'~#358    (binary    value
'10100101c/11001011'~101100110)   has   the   value  15,  but
#165c/'#203~#358' has the value 34915, and #165c/#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 #V-&123, which
was  described  earlier,  could  be  coded  as  'V-#&123'  or
'V-"&#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.1c/.2'
is equivalent to "V!1c/.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.

























                           - 13 -



_4_.  _S_T_A_T_E_M_E_N_T_S

In  this  section  is  described  the  format  of   INTERCAL
statements.

_4_._1  _G_e_n_e_r_a_l _F_o_r_m_a_t

Statements  may  be  entered in 'free format'. That is, more
than one statement  may  occur  on  a  single  card,  and  a
statement may begin on one card and end on a later one. Note
that if this is done, all  intervening  cards  and  portions
thereof  must  be  part  of  the  same  statement. That this
restriction is necessary is immediately  apparent  from  the
following example of what might occur if statements could be
interlaced.

        DO .1 <- ".1c/'&:51~"#V-1c!12~;&75SUB"V-'V.1~
        DO .2 <- '"!1c/"&';V-79SUB",&7SUB:173"'~!V-9c/
        .2'c/,&1SUB:5~#33578"'"'"~'#65535c/"V-'V#&85'"'
        #8196'"'~.1"c/.2'~'#&5c/"'#1279c/#4351'~#65535"'

The above statements are obviously  meaningless.  (For  that
matter, so are the statements

        DO .1 <- ".1c/"&:51~"#V-1c/!12~;&75SUB"V-'V.1~
        .2'c/,&1SUB:5~#333578"'"'"~#65535c/"V-'V#&85'"'
        DO .2 <- '"!1c/"&';V-79SUB",&7SUB:173"'~!V-9c/
        #8196'"'~.1"c/.2'~'#&5c/"'#1279c/#4351'~#65535"'

but this is not of interest here.)

Spaces  may be used freely to enhance program legibility (or
at least reduce program illegibility), with the  restriction
that no word of a statement identifier (see section 4.3) may
contain any spaces.

_4_._2  _L_a_b_e_l_s

A statement may begin with a llooggiiccaall lliinnee llaabbeell enclosed  in
wax-wane  pairs (()). A statement may not have more than one
label, although it is possible to omit the label entirely. A
line  label  is  any  integer from 1 to 65535, which must be
unique within each program. The user is cautioned,  however,
that  many line labels between 1000 and 1999 are used in the
INTERCAL System Library functions.

_4_._3  _I_d_e_n_t_i_f_i_e_r_s _a_n_d _Q_u_a_l_i_f_i_e_r_s

After the line label  (if  any),  must  follow  one  of  the
following  statement  identifiers: DO, PLEASE, or PLEASE DO.
These may be used interchangeably to improve the  aesthetics
of  the  program. The identifier is then followed by either,
neither,  or  both  of  the  following  optional  parameters
(qualifiers):  (1)  either  of  the character strings NOT or








                           - 14 -



N'T,  which  causes  the  statement  to   be   automatically
abstained  from  (see  section 4.4.9) when execution begins,
and (2) a number between 0 and 100, preceded by a double-oh-
seven  (%),  which  causes  the  statement  to have only the
specified percent chance of being executed each time  it  is
encountered in the course of execution.

_4_._4  _S_t_a_t_e_m_e_n_t_s

Following   the  qualifiers  (or,  if  none  are  used,  the
identifier) must occur  one  of  the  13  valid  operations.
(Exception:   see   section   4.5.)   These   are  described
individually in sections 4.4.1 through 4.4.14.2.

_4_._4_._1  _C_a_l_c_u_l_a_t_e

The INTERCAL equivalent of the  half-mesh  (=)  in  FORTRAN,
BASIC,  PL/I,  and  others,  is  represented by an angle (<)
followed by a worm (-). This  combination  is  read  'gets'.
32-bit  variables  may  be assigned 16-bit values, which are
padded on the left with 16 zero bits. 16-bit  variables  may
be  assigned  32-bit  values  only if the value is less than
65535. Thus, to invert the  least  significant  bit  of  the
first  element  of  16-bit 2-dimensional array number 1, one
could write:

,1SUB#1#1 <- 'V-,1SUB#1#1c/#1'~'#0c/#65535'

Similarly to SNOBOL and SPITBOL, INTERCAL  uses  the  angle-
worm  to  define  the  dimensions of arrays. An example will
probably best describe the format.  To define  32-bit  array
number  7 as 3-dimensional, the first dimension being seven,
the second being the current value of 16-bit variable number
seven,  and the third being the current value of the seventh
element  of  16-bit  array  number  seven  (which  is   one-
dimensional)  mingled  with  the  last  three bits of 32-bit
variable number seven, one would  write  (just  before  they
came to take him away):

;7 <- #7 BY .7 BY ",7SUB#7"c/':7~#7'

This is, of course, different from the statement:

;7 <- #7 BY .7 BY ,7SUB"#7c/':7~#7'"

INTERCAL  also permits the redefining of array dimensioning,
which is done the same way as is the  initial  dimensioning.
All   values   of   items   in   an   array  are  lost  upon
redimensioning, unless they have been STASHed  (see  section
4.4.5),  in  which case restoring them also restores the old
dimensions.











                           - 15 -



_4_._4_._2  _N_E_X_T

The NEXT statement is used both for subroutine calls and for
unconditional transfers. This statement takes the form:

DO (label) NEXT

(or, of course,

PLEASE DO (label) NEXT

etc.), where (label) represents any logical line label which
appears in the program. The effect of such a statement is to
transfer control to the statement specified, and to store in
a push down list (which is  initially  empty)  the  location
from  which  the  transfer takes place. Items may be removed
from this list and may be discarded or used to return to the
statement  immediately  following  the NEXT statement. These
operations  are  described  in  sections  4.4.3  and   4.4.4
respectively. The programmer is generally advised to discard
any stack entries which he does not intend to utilize, since
the  stack  has  a  maximum depth of 79 entries. A program's
attempting to initiate an 80th level of NEXTing will  result
in  the  fatal  error message, "PROGRAM HAS DISAPPEARED INTO
THE BLACK LAGOON."

_4_._4_._3  _F_O_R_G_E_T

The statement PLEASE FORGET exp, where  exp  represents  any
expression   (except  colloquial  and  facial  expressions),
causes the expression to be  evaluated,  and  the  specified
number  of  entries to be removed from the NEXTing stack and
discarded. An attempt to FORGET more levels of NEXTing  than
are  currently  stacked  will cause the stack to be emptied,
and no error condition is indicated.  This  is  because  the
condition  is not considered to be an error. As described in
section 4.4.2, it is good programming practice to execute  a
DO   FORGET   #1   after   using  a  NEXT  statement  as  an
unconditional transfer, so  that  the  stack  does  not  get
cluttered up with unused entries:

        DO (123) NEXT
        .
        .
  (123) DO FORGET #1

_4_._4_._4  _R_E_S_U_M_E

The  statement  PLEASE  RESUME  exp  has  the same effect as
FORGET, except that  program  control  is  returned  to  the
statement  immediately  following  the  NEXT statement which
stored in the stack the last entry to be removed. Note  that
a  rough  equivalent of the FORTRAN computed GO TO and BASIC
ON exp GO TO is performed by a sequence of the form:








                           - 16 -



        DO (1) NEXT
        .
        .
    (1) DO (2) NEXT
        PLEASE FORGET #1
        .
        .
    (2) DO RESUME .1

Unlike the FORGET  statement,  an  attempt  to  RESUME  more
levels  of  NEXTing  than  been  stacked  will cause program
termination. See also section 4.4.11.

_4_._4_._5  _S_T_A_S_H

Since  subroutines  are  not   explicitly   implemented   in
INTERCAL,  the  NEXT  and  RESUME statements must be used to
execute common routines. However, as  these  routines  might
use  the same variables as the main program, it is necessary
for them to save the values of any  variables  whose  values
they   alter,  and  later  restore  them.  This  process  is
simplified by the STASH statement, which  has  the  form  DO
STASH  list,  where  list represents a string of one or more
variable or array names,  separated  by  intersections  (+).
Thus

PLEASE STASH .123+:123+,123

stashes  the  values  of two variables and one entire array.
The values are left intact, and copies thereof are saved for
later retrieval by (what else?)  the RETRIEVE statement (see
section 4.4.6). It is not possible  to  STASH  single  array
items.

_4_._4_._6  _R_E_T_R_I_E_V_E

PLEASE  RETRIEVE list restores the previously STASHed values
of the variables and arrays named in the list.  If  a  value
has  been  stashed more than once, the most recently STASHed
values are RETRIEVEd, and a second RETRIEVE will restore the
second  most recent values STASHed. Attempting to RETRIEVE a
value which has not been STASHed will result  in  the  error
message, "THROW STICK BEFORE RETRIEVING."

_4_._4_._7  _I_G_N_O_R_E

The   statement   DO   IGNORE  list  causes  all  subsequent
statements to have no effect upon  variables  and/or  arrays
named in the list. Thus, for example, after the sequence

        DO .1 <- #1
        PLEASE IGNORE .1
        DO .1 <- #0









                           - 17 -



16-bit  variable  number  1  would  have the value 1, not 0.
Inputting (see section 4.4.12) into an IGNOREd variable also
has  no  effect.  The condition is annulled via the REMEMBER
statement (see section 4.4.8). Note that, when a variable is
being   IGNOREd,  its  value,  though  immutable,  is  still
available for use in expressions and the like.

Though the INTERCAL-72 manual laid down that the value of an
IGNOREd variable cannot change, it was unclear about whether
or not a  statement  which  appears  to  change  an  IGNOREd
variable  is executed or not.  This may appear to be a "If a
tree falls in the forest..." type of question,  but  if  the
statement in question has other side effects it is not.

Since another mechanism already exists for ABSTAINing from a
statement, C-INTERCAL's IGNORE only prevents the changing of
the  specific variable in question, not the execution of the
entire statement.  In the present version  of  the  language
this  only  makes  a  difference for the WRITE IN statement.
Attempting to WRITE IN to an IGNOREd variable will  cause  a
number  to  be  read from the input, which will be discarded
since it cannot be stored in the variable.

_4_._4_._8  _R_E_M_E_M_B_E_R

PLEASE REMEMBER list terminates the  effect  of  the  IGNORE
statement for all variables and/or arrays named in the list.
It does not matter if a variable has been IGNOREd more  than
once,  nor  is  it  an  error  if  the variable has not been
IGNOREd at all.

_4_._4_._9  _A_B_S_T_A_I_N

INTERCAL contains no simple equivalent to an IF statement or
computed  GO  TO,  making  it  difficult  to combine similar
sections of code into a single  routine  which  occasionally
skips  around  certain statements. The IGNORE statement (see
section 4.4.7) is helpful in some cases, but a  more  viable
method  is  often  required.  In  keeping  with  the goal of
INTERCAL having nothing in common with any  other  language,
this is made possible via the ABSTAIN statement.

This statement takes on one of two forms. It may not take on
both at any one time. DO ABSTAIN  FROM  (label)  causes  the
statement   whose  logical  line  label  is  (label)  to  be
abstained from. PLEASE ABSTAIN FROM gerund list  causes  all
statements of the specified type(s) to be abstained from, as
in

        PLEASE ABSTAIN FROM STASHING
        PLEASE ABSTAIN FROM IGNORING + FORGETTING
        PLEASE ABSTAIN FROM NEXTING
     or PLEASE ABSTAIN FROM CALCULATING









                           - 18 -



Statements may also be automatically abstained from  at  the
start of execution via the NOT or N'T parameter (see section
4.3).

If, in the course of execution, a statement  is  encountered
which  is  being  abstained  from, it is ignored and control
passes to the next statement in the program (unless it, too,
is being abstained from).

The statement DO ABSTAIN FROM ABSTAINING is perfectly valid,
as is DO ABSTAIN FROM REINSTATING (although this  latter  is
not  usually recommended). However, the statement DO ABSTAIN
FROM GIVING UP is not accepted, even though  DON'T  GIVE  UP
is.

_4_._4_._1_0  _R_E_I_N_S_T_A_T_E

The  REINSTATE  statement,  like  the  ABSTAIN,  takes as an
argument either a line label or a gerund list. No other form
of  argument  is permitted. For example, the following is an
invalid argument:

        Given: x!=0, y!=0,  Prove: x+y=0
        Since x!=0, then x+1!=1, x+a!=a, x+y!=y.
        But what is y? y is anything but 0.
        Thus x+y != anything but 0.
        Since x+y cannot equal anything but 0, x+y=0.
                                                         Q.E.D.

REINSTATEment nullifies the effects of an abstention. Either
form  of  REINSTATEment  can  be used to "free" a statement,
regardless of whether the statement was  abstained  from  by
gerund  list,  line  label,  or  NOT. Thus, PLEASE REINSTATE
REINSTATING is  not  necessarily  an  irrelevant  statement,
since it might free a DON'T REINSTATE command or a REINSTATE
the line label of which  was  abstained  from.  However,  DO
REINSTATE  GIVING UP is invalid, and attempting to REINSTATE
a GIVE UP statement by line label will have no effect.  Note
that  this  insures that DON'T GIVE UP will always be a "do-
nothing" statement.

_4_._4_._1_1  _G_I_V_E _U_P

PLEASE GIVE UP is used to exit from a program.  It  has  the
effect  of  a  PLEASE RESUME #80. DON'T GIVE UP, as noted in
section 4.4.10, is effectively a null statement.

_4_._4_._1_2  _I_n_p_u_t

Input is accomplished with the statement DO WRITE  IN  list,
where  list represents a string of variables and/or elements
or  arrays,  separated   by   intersections.   Numbers   are
represented  on  cards,  each  number on a separate card, by
spelling out each digit  (in  English)  and  separating  the








                           - 19 -



digits with one or more spaces. A zero (0) may be spelled as
either ZERO or OH.  Thus the range of (32-bit) input  values
permissible  extends from ZERO (or OH) through FOUR TWO NINE
FOUR NINE SIX SEVEN TWO NINE FIVE.  (For the convenience  of
aviators,  C-INTERCAL  accepts  the spelling NINER for NINE.
In the  service  of  internationalization,  C-INTERCAL  also
accepts input digits in Sanskrit, Basque, Tagalog, Classical
Nahuatl, Georgian, Kwakiutl, and Volapuk.

Attempting to write in a value greater than or equal to  SIX
FIVE FIVE THREE SIX for a 16-bit variable will result in the
error message, "DON'T BYTE OFF MORE THAN YOU CAN CHEW."

_4_._4_._1_3  _O_u_t_p_u_t

Values may be output to the printer, one value per line, via
the  statement  DO  READ  OUT  list, where the list contains
variables, array elements, and/or constants.  Output  is  in
the   form   of   "extended"  Roman  numerals  (also  called
"butchered" Roman numerals), with an overline indicating the
value   below   is  "times  1000",  and  lower-case  letters
indicating "times 1000000". Zero is indicated by an overline
with  no  character  underneath. Thus, the range of (32-bit)
output values possible is from
_

through
__      ____________
ivccxcivCMLXVIICCXCV.
Note: For values whose residues modulo 1000000 are less than
4000, M is used to represent 1000; for values whose residues
are 4000 or greater,
_
I
is used. Thus #3999 would read  out  as  MMMCMXCIX  2  while
#4000 would readout as
__
IV
Similar rules apply to the use of
_
M
and i for 1000000, and to that of m and
_
i
for 1000000000.




____________________

2. The original INTERCAL-72 manual claimed that #3999 should
   render as MMMIM, but the C-INTERCAL developers have  been
   unable  to  find  an  algorithm  that  does  this  and is
   consistent with the rest of the rules.







                           - 20 -



_4_._4_._1_4  _C_O_M_E _F_R_O_M

In which we try to precisely define a statement that  should
never  have  been  born, but is nevertheless one of the more
useful statements in INTERCAL.

_4_._4_._1_4_._1  _B_a_c_k_g_r_o_u_n_d

The earliest known description of the COME FROM statement in
the  computing  literature is in [R. L. Clark, "A linguistic
contribution  to  GOTO-less  programming,"  Commun.  ACM  27
(1984),  pp. 349--350], part of the famous April Fools issue
of CACM.  The  subsequent  rush  by  language  designers  to
include  the statement in their languages was underwhelming,
one might even say nonexistent.  It  was  therefore  decided
that  COME  FROM  would  be  an  appropriate  addition to C-
INTERCAL.

_4_._4_._1_4_._2  _D_e_s_c_r_i_p_t_i_o_n

There are two useful ways to visualize  the  action  of  the
COME  FROM  statement.   The  simpler is to see that it acts
like a GOTO when the program is traced  backwards  in  time.
More precisely, the statements

(1)     DO <any statement>
        .
        .
        .
(2)     DO COME FROM (1)

should be thought of as being equivalent to

(1)     DO <any statement>
(2)     DO GOTO (3)
        .
        .
        .
(3)     DO NOTHING

if  INTERCAL  actually had a GOTO statement at all, which of
course it doesn't.

What this boils down to is that the statement DO  COME  FROM
(label), anywhere in the program, places a kind of invisible
trap door immediately after statement (label).  Execution or
abstention  of  that statement is immediately followed by an
unconditional jump to the COME FROM,  unless  the  (label)ed
statement is an executed NEXT, in which case the jump occurs
if  the  program  attempts  to  RESUME  back  to  that  NEXT
statement.   It  is  an error for more than one COME FROM to
refer to the same (label).

Modification of the target statement by ABSTAIN or by the  %








                           - 21 -



qualifier  affects  only  that statement, not the subsequent
jump.  Such modifications to the COME FROM itself,  however,
do  affect  the  jump.  Encountering the COME FROM statement
itself, rather than its target, has no effect.

_4_._5  _C_o_m_m_e_n_t_s

Unrecognizable  statements,  as  noted  in  section  9,  are
flagged  with  a  splat  (*) during compilation, and are not
considered fatal errors unless they are  encountered  during
execution,   at  which  time  the  statement  (as  input  at
compilation time) is printed and  execution  is  terminated.
This  allows  for an interesting (and, by necessity, unique)
means of including comments  in  an  INTERCAL  listing.  For
example, the statement:

*       PLEASE NOTE THAT THIS LINE HAS NO EFFECT

will be ignored during execution due to the inclusion of the
NOT qualifier.  User-supplied error messages are  also  easy
to implement:

*       DO SOMETHING ABOUT OVERFLOW IN ;3

as are certain simple conditional errors:

* (123) DON'T YOU REALIZE THIS STATEMENT SHOULD ONLY BE ENCOUNTERED
                ONCE?
        PLEASE REINSTATE (123)

This  pair of statements will cause an error exit the second
time they are encountered. Caution!!  The  appearance  of  a
statement identifier in an intended comment will be taken as
the beginning of a new statement. Thus, the first example on
the preceding page could not have been:

*       PLEASE NOTE THAT THIS LINE DOES NOTHING

The third example, however, is valid, despite the appearance
of two cases of D-space-O, since INTERCAL  does  not  ignore
extraneous spaces in statement identifiers.





















                           - 22 -



_5_.  _O_U_T_S_I_D_E _C_O_M_M_U_N_I_C_A_T_I_O_N

In  which  we  try  to  remedy  the  fact  that,  due to I/O
limitations, INTERCAL can not even in principle perform  the
same  tasks  as  other  languages.   It  is  hoped that this
addition will permit INTERCAL users to waste vast quantities
of computer time well into the 21st century.

_5_._1  _M_o_t_i_v_a_t_i_o_n

One  of  the  goals  of  INTERCAL  was to provide a language
which,  though  different  from  all  other  languages,   is
nevertheless  theoretically  capable  of all the same tasks.
INTERCAL-72  failed  to  accomplish  this  because  its  I/O
functions  could  not  handle  arbitrary streams of bits, or
even arbitrary sequences of characters.   A  language  which
can't  even send its input directly to its output can hardly
be considered as capable as other languages.

_5_._2  _T_u_r_i_n_g _T_e_x_t _M_o_d_e_l

To remedy this problem, character I/O is now provided  in  a
form  based  on the "Turing Text" model, originally proposed
by Jon Blow.  The  C-INTERCAL  programmer  can  access  this
capability  by  placing a one- dimensional array in the list
of items given to a WRITE IN  or  READ  OUT  statement.   On
execution  of the statement, the elements of the array will,
from first to last, be either loaded from the input or  sent
to  the  output,  as  appropriate,  in  the manner described
below.  There is currently  no  support  for  I/O  involving
higher-dimensional  arrays,  but some form of graphics might
be a possible 2-D interpretation.

The heart of  the  Turing  Text  model  is  the  idea  of  a
continuous  loop  of  tape  containing,  in  order,  all the
characters in the machine's character set.  When a character
is  received  by the input routine, the tape is advanced the
appropriate number of spaces to bring that  character  under
the  tape  head, and the number of spaces the tape was moved
is the number that is actually seen by the INTERCAL program.
Another  way  to  say  this  is that the number placed in an
INTERCAL array is the difference between the character  just
received  and  the  previous character, modulo the number of
characters in the machine character set.

Output works in just the opposite fashion, except  that  the
characters  being  output  come  from  the other side of the
tape.  From this position the characters on the tape  appear
to  be  in  reverse order, and are individually backwards as
well.  (We would show you what it looks like, but  we  don't
have  a  font  with  backwards  letters available.  Use your
imagination.)  The effect is that a number is taken  out  of
an  INTERCAL  array,  subtracted  from  the  last  character
output--- i.e., the result  of  the  last  subtraction---and








                           - 23 -



then  sent  on  down  the output channel.  The only catch is
that the character as seen by the INTERCAL  program  is  the
mirror-image of the character as seen by the machine and the
user.  The bits of the  character  are  therefore  taken  in
reverse  order  as it is sent to the output.  Note that this
bit reversal affects only the character seen by the  outside
world; it does not affect the character stored internally by
the program, from which  the  next  output  number  will  be
subtracted.   All subtractions are done modulo the number of
characters in the character set.

Two different tapes are used for input  and  for  output  to
allow  for  future  expansion  of  the  language  to include
multiple input and output channels.   Both  tapes  start  at
character 0 when a program begins execution.  On input, when
an end of file marker is reached the number  placed  in  the
array is one greater than the highest- numbered character on
the tape.

_5_._3  _E_x_a_m_p_l_e _P_r_o_g_r_a_m

If all this seems terribly complicated, it  should  be  made
perfectly  clear  by  the  following  example program, which
simply maps its input to its output (like a simplified  UNIX
"cat").   It  assumes  that  characters are 8 bits long, but
that's fine since the current  version  of  C-INTERCAL  does
too.  It uses the standard library routines for addition and
subtraction.

        DO ,1 <- #1
        DO .4 <- #0
        DO .5 <- #0
        DO COME FROM (30)
        DO WRITE IN ,1
        DO .1 <- ,1SUB#1
        DO (10) NEXT
        PLEASE GIVE UP
(20)    PLEASE RESUME '?.1$#256'~'#256$#256'
(10)    DO (20) NEXT
        DO FORGET #1
        DO .2 <- .4
        DO (1000) NEXT
        DO .4 <- .3~#255
        DO .3 <- !3~#15'$!3~#240'
        DO .3 <- !3~#15'$!3~#240'
        DO .2 <- !3~#15'$!3~#240'
        DO .1 <- .5
        DO (1010) NEXT
        DO .5 <- .2
        DO ,1SUB#1 <- .3
(30)    PLEASE READ OUT ,1

For each number received in the  input  array,  the  program
first  tests the #256 bit to see if the end of file has been








                           - 24 -



reached.  If not, the previous input character is subtracted
off  to  obtain the current input character.  Then the order
of the bits is reversed to find out what character should be
sent  to  the  output, and the result is subtracted from the
last character sent.  Finally, the difference is  placed  in
an  array  and given to a READ OUT statement.  See?  We told
you it was simple!























































                           - 25 -



_6_.  _T_r_i_I_N_T_E_R_C_A_L

In which it is revealed  that  bitwise  operations  are  too
ordinary  for hard-core INTERCAL programmers, and extensions
to other bases  are  discussed.   These  are  not,  strictly
speaking,  extensions  to  INTERCAL  itself,  but rather new
dialects  sharing  most  of  the  features  of  the   parent
language.

_6_._1  _M_o_t_i_v_a_t_i_o_n

INTERCAL  is  really a pretty sissy language.  It tries hard
to be different, but when you get right down to  its  roots,
what  do  you  find?  You find bits, that's what.  Plain old
ones and zeroes, in groups of 16 and  32,  just  like  every
other  language  you've  ever heard of.  And what operations
can you perform on these bits?  The INTERCAL  operators  may
arrange and permute them in weird and wonderful ways, but at
the bit level the operators are the same  AND,  OR  and  XOR
you've seen countless times before.

Once the prospective INTERCAL programmer masters the unusual
syntax, she finds herself working with the familiar  Boolean
operators  on  perfectly  ordinary  unsigned  integer words.
Even the constants she uses are familiar.   After  all,  who
would  not  immediately recognize #65535 and #32768?  It may
take a just a moment more to figure out #65280,  and  #21845
and  #43690 could be puzzles until she notices that they sum
to #65535, but basically she's still on her home turf.   The
16-bit limit on constants actually works in the programmer's
favor by insuring that very long anonymous constants can not
appear in INTERCAL programs.  And this is in a language that
is supposed to be different from any other!

_6_._2  _A_b_a_n_d_o_n _A_l_l _H_o_p_e_._._.

Standard  INTERCAL  is  based  on  variables  consisting  of
ordinary bits and familiar Boolean operations on those bits.
In pursuit of uniqueness, it seems appropriate to provide  a
new  dialect, otherwise identical to INTERCAL, which instead
uses variables consisting of trits, i.e. ternary digits, and
operators  based  on  tritwise  logical operations.  This is
intended to be a separate dialect, rather than an  extension
to  INTERCAL itself, for a number of reasons.  Doing it this
way  avoids  word-length  conflicts,  does  not  spoil   the
elegance  of  the  Spartan INTERCAL operator set, and dodges
the objections of those who  might  feel  it  too  great  an
alteration  to  the  original  language.  Primarily, though,
giving INTERCAL programmers the ability  to  switch  numeric
base  at  will  amounts to excessive functionality.  So much
better that a programmer choose a base  at  the  outset  and
then  be  forced  to  stick with it for the remainder of the
program.









                           - 26 -



_6_._3  _C_o_m_p_i_l_e_r _O_p_e_r_a_t_i_o_n

The  same  compiler,  ick,  supports   both   INTERCAL   and
TriINTERCAL.   This  has the advantage that future bug fixes
and additions to the  language  not  related  to  arithmetic
immediately apply to both versions.  The compiler recognizes
INTERCAL source files by the extension '.i', and TriINTERCAL
source  files  by  the  extension  '.3i'.  It's as simple as
that.  There is no  way  to  mix  INTERCAL  and  TriINTERCAL
source in the same program, and it is not always possible to
determine which dialect a program  is  written  in  just  by
looking at the source code.

_6_._4  _D_a_t_a _T_y_p_e_s

The two TriINTERCAL data types are 10-trit unsigned integers
and 20-trit unsigned  integers.   All  INTERCAL  syntax  for
distinguishing  data  types  is ported to these new types in
the obvious way.  Small words may contain numbers from #0 to
#59048,  large  words  may  contain  numbers  from  #0$#0 to
#59048$#59048.  Errors are signaled  for  constants  greater
than  #59048  and for attempts to WRITE IN numbers too large
for a given variable or array element to hold.

Note that though TriINTERCAL considers  all  numbers  to  be
unsigned,  nothing prevents the programmer from implementing
arithmetic operations that treat their operands  as  signed.
Three's  complement  is  one  obvious  choice,  but balanced
ternary notation is also a possibility.  This  latter  is  a
very  pretty and symmetrical system in which all 2 trits are
treated as if they had the value -1.

_6_._5  _O_p_e_r_a_t_o_r_s

The  TriINTERCAL  operators  are  designed  to  inherit  the
relevant  properties  of the standard INTERCAL operators, so
that both can be considered as merely different  aspects  of
the same Platonic ideal.  (Not that the word "ideal" is ever
particularly  relevant  when   used   in   connection   with
INTERCAL.)

_6_._5_._1  _B_i_n_a_r_y _O_p_e_r_a_t_o_r_s _I

The  binary  operators carry over from the original language
with only minor changes.  The MINGLE operator ($) creates  a
20-trit  word  by  alternating  trits  from  its two 10-trit
operands.   The  SELECT  operator  (~)  is  a  little   more
complicated,  since  the  ternary tritmask may contain 0, 1,
and 2 trits.  If we observe that  the  SELECT  operation  on
binary   operands   amounts   to  a  bitwise  AND  and  some
rearrangement of bits, it  seems  appropriate  to  base  the
SELECT  for  ternary  operands  on  a  tritwise  AND  in the
analogous fashion.  We therefore postpone the definition  of
SELECT until we know what a tritwise AND looks like.








                           - 27 -



_6_._5_._2  _U_n_a_r_y _O_p_e_r_a_t_o_r_s

The  unary  operators  in  INTERCAL are all derived from the
familiar Boolean operations on single bits.  To extend these
operations  to  trits,  we  first  ask  ourselves  what  the
important properties of these operations are that we wish to
be  preserved,  then  design  the tritwise operators so that
they behave in a similar fashion.

_6_._5_._2_._1  _U_n_a_r_y _L_o_g_i_c_a_l _O_p_e_r_a_t_o_r_s

Let's start with AND and OR.  To begin with,  these  can  be
considered  "choice"  or  "preference"  operators,  as  they
always return one of their operands.  AND can  be  described
as  wanting  to  return 0, but returning 1 if it is given no
other choice, i.e., if both operands are 1.   Similarly,  OR
wants  to return 1 but returns 0 if that is its only choice.
From this it is immediately apparent that each operator  has
an  identity  element  that  "always loses", and a dominator
element that "always wins".

AND  and  OR  are  commutative  and  associative,  and  each
distributes  over  the  other.  They are also symmetric with
each other, in the sense that AND looks like OR and OR looks
like  AND  when  the  roles  of 0 and 1 are interchanged (De
Morgan's Laws).  This symmetry property seems to  be  a  key
element  to  the  idea  that  these are logical, rather than
arithmetic, operators.  In a  three-valued  logic  we  would
similarly  expect  a  three-  way  symmetry  among the three
values 0, 1 and 2 and the three operators AND,  OR  and  (of
course) BUT.

The  following  tritwise  operations  have  all  the desired
properties: OR returns the  greater  of  its  two  operands.
That  is,  it  returns  2 if it can get it, else it tries to
return 1, and it returns 0 only if both operands are 0.  AND
wants  to  return  0,  will  return 2 if it can't get 0, and
returns 1 only if forced.  BUT wants 1,  will  take  0,  and
tries to avoid 2.  The equivalents to De Morgan's Laws apply
to rotations of the three elements, e.g., 0 -> 1, 1 -> 2,  2
->  0.   Each  operator  distributes  over exactly one other
operator, so the property "X  distributes  over  Y"  is  not
transitive.   The  question of which way this distributivity
ring goes around is left as an exercise for the student.

In TriINTERCAL programs the whirlpool (@) symbol denotes the
unary   tritwise  BUT  operation.   You  can  think  of  the
whirlpool  as  drawing  values  preferentially  towards  the
central  value  1.   Alternatively,  you  can think of it as
drawing your soul and your sanity inexorably down...

On the other hand, maybe it's best you _n_o_t think of it  that
way.









                           - 28 -



A  few  comments  about how these operators can be used.  OR
acts like a tritwise maximum operation.   AND  can  be  used
with  tritmasks.   0's  in a mask wipe out the corresponding
elements  in  the  other  operand,   while   1's   let   the
corresponding  elements  pass  through  unchanged.  2's in a
mask consolidate the values of nonzero elements, as both 1's
and  2's  in the other operand yield 2's in the output.  BUT
can be used to create "partial tritmasks".  0's  in  a  mask
let  BUT  eliminate 2's from the other operand while leaving
other values unchanged.  Of course,  the  symmetry  property
guarantees   that   the   operators   don't   really  behave
differently from each other  in  any  fundamental  way;  the
apparent  differences  come from the intuitive view that a 0
trit is "not set" while a 1 or 2 trit is "set".

_6_._5_._2_._2  _B_i_n_a_r_y _O_p_e_r_a_t_o_r_s _I_I

At this point we can define SELECT, since we now  know  what
the  tritwise  AND  looks  like.   SELECT  takes  the binary
tritwise AND of its two operands.  It shifts all  the  trits
of the result corresponding to 2's in the right operand over
to the right (low) end of the result, then follows them with
all  the  output  trits  corresponding  to  1's in the right
operand.  Trits corresponding to 0's in the  right  operand,
which  are  all  0 anyway, occupy the remaining space at the
left end of the  output  word.   Both  10-trit  and  20-trit
operands  are  accepted,  and  are padded with zeroes on the
left if necessary.  The output type is determined  the  same
way as in standard INTERCAL.

_6_._5_._2_._3  _U_n_a_r_y _A_r_i_t_h_m_e_t_i_c _O_p_e_r_a_t_o_r_s

Now  that  we've got all that settled, what about XOR?  This
is easily  the  most-useful  of  the  three  unary  INTERCAL
operators, because it combines in one package the operations
ADD WITHOUT CARRY, SUBTRACT  WITHOUT  BORROW,  BITWISE  NOT-
EQUAL, and BITWISE NOT.  In TriINTERCAL we can't have all of
these in the same operator, since addition  and  subtraction
are  no longer the same thing.  The solution is to split the
XOR concept into  two  operators.   The  ADD  WITHOUT  CARRY
operation  is  represented  by  the new sharkfin (^) symbol,
while the old what (?) symbol  represents  SUBTRACT  WITHOUT
BORROW.  The reason for this choice is so that what (?) will
also represent the TRITWISE NOT-EQUAL operation.

Note that what (?), unlike the other four  unary  operators,
is not symmetrical.  It should be thought of as rotating its
operand one trit to the right  (with  wraparound)  and  then
subtracting  off  the  trits  of the original number.  These
subtractions are done without borrowing, i.e.,  trit-by-trit
modulo 3.











                           - 29 -



_6_._5_._3  _E_x_a_m_p_l_e_s

The  TriINTERCAL  operators  really aren't all that bad once
you get used to them.  Let's look at a few examples to  show
how  they can be used in practice.  In all of these examples
the input value is contained in the 10-trit variable .3.

In INTERCAL, single-bit values often have  to  be  converted
from  {0,1} to {1,2} for use in RESUME statements.  Examples
of how to  do  this  appear  in  the  original  manual.   In
TriINTERCAL the expression "^.3$#1"~#1 sends 0 -> 1 and 1 ->
2.  If the 1-trit input value can take on any of  its  three
possible states, however, we will also have to deal with the
2 case.  The expression "V.3$#1"~#1 sends {0,1} -> 1  and  2
->   2.    To   test   if   a   trit  is  set,  we  can  use
"V'"&.3$#2"~#1'$#1"~#1, sending 0 -> 1 and {1,2} ->  2.   To
reverse the test we use "?'"&.3$#2"~#1'$#1"~#1, sending 0 ->
2 and {1,2} -> 1.  Note that we have not  been  taking  full
advantage  of  the  new  SELECT  operator.   These  last two
expressions  can  be  simplified  into  "V!3~#2'$#1"~#1  and
"?!3~#2'$#1"~#1,  which  perform  exactly the same mappings.
Finally,  if  we   need   a   3-way   test,   we   can   use
"@'"^.3$#7"~#4'$#2"~#10,  which obviously sends 0 -> 1, 1 ->
2, and 2 -> 3.

For     an     unrelated     example,     the     expression
"^.3$.3"~"#0$#29524"  converts all of the 1-trits of .3 into
2's and all of the 2-trits into 1's.  In  balanced  ternary,
where  2-trits  represent  -1  values,  this is the negation
operation.

_6_._6  _B_e_y_o_n_d _T_e_r_n_a_r_y_._._.

While we're at it, we might as  well  extend  this  multiple
bases  business a little farther.  The ick compiler actually
recognizes filename suffixes of the form '.Ni', where  N  is
any  number  from  2  to  7.   2  of  course  gives standard
INTERCAL, while 3 gives TriINTERCAL.  We cut  off  before  8
because   octal  notation  is  the  smallest  base  used  to
facilitate human-to-machine communication,  and  this  seems
quite contrary to the basic principles behind INTERCAL.  The
small data types hold 16 bits, 10 trits, 8 quarts, 6 quints,
6  sexts,  or  5 septs, and the large types are always twice
this size.

As for operators, '?' is always SUBTRACT WITHOUT BORROW, and
'^'  is  always  ADD WITHOUT CARRY.  'V' is the OR operation
and always returns the max of its inputs.  '&'  is  the  AND
operation, which chooses 0 if possible but otherwise returns
the max of the inputs.  '@' is BUT, which prefers 1, then 0,
then  the  max  of the remaining possibilities.  Rather than
add more special symbols forever, a numeric modifier may  be
placed  directly  before  the  '@'  symbol  to  indicate the
operation  that  prefers  one  of  the  digits  not  already








                           - 30 -



represented.   Thus  in files ending in '.5i', the permitted
unary operators are '?', '^', '&', '@', '2@', '3@', and 'V'.
Use  of  such  barbarisms  as  '0@' to represent '&' are not
permitted, nor is the use of '@' or '^' in files with either
of  the extensions '.i' or '.2i'.  Why not?  You just can't,
that's why.  Don't ask so many questions.

As a closing example,  we  note  that  in  balanced  quinary
notation,  where  3  means  -2  and 4 means -1, the negation
operation can be written as either

  DO .1 <- "^'"^.3$.3"~"#0$#3906"'$'"^.3$.3"~"#0$#3906"'"~"#0$#3906"

or as

  DO .1 <- "^.3$.3"~"#0$#3906"
  DO .1 <- "^.1$.1"~"#0$#3906"

These work because multiplication  by  -1  is  the  same  as
multiplication by 4, modulo 5.

Now go beat your head against the wall for a while.








































                           - 31 -



_7_.  _S_U_B_R_O_U_T_I_N_E _L_I_B_R_A_R_Y

INTERCAL  provides  several  built-in  subroutines  to which
control can be transferred to  perform  various  operations.
These operations include many useful functions which are not
easily  representable  in  INTERCAL,   such   as   addition,
subtraction, etc.

_7_._1  _U_s_a_g_e

In  general, the operands are .1, .2, etc., or :1, :2, etc.,
and the result(s) are stored in what  would  have  been  the
next operand(s). For instance, one routine adds .1 to .2 and
store the  sum  in  .3,  with  .4  being  used  to  indicate
overflow.  All  variables  not  used  for  results  are left
unchanged.

_7_._2  _A_v_a_i_l_a_b_l_e _F_u_n_c_t_i_o_n_s

At the time of  this  writing,  only  the  most  fundamental
operations  are  offered  in the library, as a more complete
selection  would  require  prohibitive  time  and  coree  to
implement.  These  functions, along with their corresponding
entry points (entered via DO (entry) NEXT) are listed below.






































                           - 32 -



 (1000) .3 <- .1 plus .2, error exit on overflow
 (1009) .3 <- .1 plus .2
        .4 <- #1 if no overflow, else .4 <- #2
 (1010) .3 <- .1 minus .2, no action on overflow
 (1020) .1 <- .1 plus #1, no action on overflow
 (1030) .3 <- .1 times .2, error exit on overflow
 (1039) .3 <- .1 times .2
        .4 <- #1 if no overflow, else .4 <- #2
 (1040) .3 <- .1 divided by .2
        .3 <- #0 if .2 is #0
 (1050) .2 <- :1 divided by .1, error exit on overflow
        .2 <- #0 if .1 is #0
(1060) .3 <- logical or of .1 and .2
 (1070) .3 <- logical and of .1 and .2
 (1080) .3 <- logical xor of .1 and .2

 (1500) :3 <- :1 plus :2, error exit on overflow
 (1509) :3 <- :1 plus :2
        :4 <- #1 if no overflow, else :4 <- #2
 (1510) :3 <- :1 minus :2, no action on overflow
 (1520) :1 <- .1 concatenated with .2
 (1525) This subroutine is intended solely for internal
        use within the subroutine library and is therefore
        not described here. Its effect is to shift .3
        logically 8 bits to the left.
 (1530) :1 <- .1 times .2
 (1540) :3 <- :1 times :2, error exit on overflow
 (1549) :3 <- :1 times :2
        :4 <- #1 if no overflow, else :4 <- #2
 (1550) :3 <- :1 divided by :2
        :3 <- #0 if :2 is #0

 (1900) .1 <- uniform random no. from #0 to #65535
 (1910) .2 <- normal random no. from #0 to .1, with
              standard deviation .1 divided by #12

_7_._3  _A_u_t_o_m_a_g_i_c_a_l _I_n_c_l_u_s_i_o_n _O_f _T_h_e _S_u_b_r_o_u_t_i_n_e _L_i_b_r_a_r_y

The  C-INTERCAL  compiler  will  automatically  include  the
system library if a DO (1xxx) NEXT statement is used, and if
no  (1xxx)  labels  are  defined anywhere, where (1xxx) is a
label in the 1000-1999 range, inclusive.  This  was  not  an
INTERCAL-72 feature.



















                           - 33 -



_8_.  _P_R_O_G_R_A_M_M_I_N_G _H_I_N_T_S

For  the  user  looking  to  become  more  familiar with the
INTERCAL language, we present in this section an analysis of
a  complex  program,  as well as some suggested projects for
the ambitious programmer.

Considering the  effort  involved  in  writing  an  INTERCAL
program,  it  was decided in putting together this manual to
use an already existing program  for  instructive  analysis.
Since  there  was  only  one such program available, we have
proceeded to use it. It is known  as  the  "INTERCAL  System
Library."

_8_._1  _D_e_s_c_r_i_p_t_i_o_n

The  program listing begins on the second page following. It
is in the same format as would be produced by the  Princeton
INTERCAL  compiler in FORMAT mode with WIDTH=62 (see section
12). For a description of the  functions  performed  by  the
Library, see section 7.2.

_8_._2  _A_n_a_l_y_s_i_s

We  shall  not  attempt to discuss here the algorithms used,
but rather we shall point out some of the general techniques
applicable to a wide range of problems.

Statements 10, 14, 15, and 26 make up a virtual "computed GO
TO".  When  statement  10  is   executed,   control   passes
eventually  to  statement  16 or 11, depending on whether .5
contains  #1  or  #2,  respectively.  The  value  of  .5  is
determined  in statement 9, which demonstrates another handy
technique.  To turn an expression, exp, with value #0 or #1,
into  #1  or  #2 (for use in a "GO TO"), use "V-'exp'c/#1"~#3.
To reverse the condition (i.e., convert #0 to #2  and  leave
#1 alone) use "V-'exp'c/#2"~#3.

Certain  conditions are easily checked. For example, to test
for zero, select the value from itself and select the bottom
bit  (see  statement  54).   To test for all bits being 1's,
select the value from itself and select  the  top  bit  (see
statement  261).  The  test  for  greater than, performed in
statements 192 and 193  on  32-bit  values,  employs  binary
logical operations, which are performed as follows:

'V-.1c/.2'~'#0c/#65535'

for 16-bit values or, for 32-bit values:

        "'V-":1~'#65535c/30'"c/":2~'#65535c/#0'"'~'#0
        c/#65535'"c/"'V-":1~'#0c/#65535'"c/":2~'#0
        c/#65535'"'~'#0c/#65535'"









                           - 34 -



(The proofs are left as an exercise to the reader.)

Testing  for  greater-than  with  16-bit  values is somewhat
simpler and is done with the pair of statements:

        DO .C <- 'V-.Ac.B'~'#0c/#65535'
        DO .C <- '&"'.A~.C'~'"V-'V-.C~.C'c/#32768"
                ~"#0c/#65535"'"c/".C~.C"'~#1

This sets .C (a dummy variable) to #1 if .A  >  .B,  and  #0
otherwise. The expression may be expanded as described above
to instead set .C to #1 or #2.

Note   also   in   statement   220   the    occurrence    of
~"#65535c/#65535".   Although  these  operations  select  the
entire value, they are not extraneous, as they  ensure  that
the forthcoming V-s will be operating on 32-bit values.

In  several  virtual  computed  GO  TOs  the  DO  FORGET  #1
(statement 15 in the  earlier  example)  has  been  omitted,
since  the next transfer of control would be a DO RESUME #1.
By making this a DO RESUME #2 instead,  the  FORGET  may  be
forgotten.

In  statement  64, note that .2 is STASHed twice by a single
statement. This is perfectly legal.

Lastly,  note  in  statements  243  and  214   respectively,
expressions  for shifting 16- and 32-bit variables logically
one place to the left.  Statement  231  demonstrates  right-
shifting for 32-bit variables.































                           - 35 -



_8_._3  _P_r_o_g_r_a_m _L_i_s_t_i_n_g

    1   (1000)  PLEASE IGNORE .4
    2           PLEASE ABSTAIN FROM (1005)
    3   (1009)  DO STASH .1 + .2 + .5 + .6
    4           DO .4 <- #1
    5           DO (1004) NEXT
    6   (1004)  PLEASE FORGET #1
    7           DO .3 <- 'V-.1c/.2'~'#0c/#65535'
    8           DO .6 <- '&.1c/.2'~'#0c/#65535'
    9           PLEASE DO .5 <- "V-!6~#32768'c/#1"~#3
   10           DO (1002) NEXT
   11           DO .4 <- #2
   12   (1005)  DO (1006) NEXT
*  13   (1999)  DOUBLE OR SINGLE PRECISION OVERFLOW
   14   (1002)  DO (1001) NEXT
   15   (1006)  PLEASE FORGET #1
   16           DO .5 <- 'V-"!6~.6'~#1"c/#1'~#3
   17           DO (1003) NEXT
   18           DO .1 <- .3
   19           DO .2 <- !6c/#0'~'#32767c/#1'
   20           DO (1004) NEXT
   21   (1003)  DO (1001) NEXT
   22           DO REINSTATE (1005)
   23   (1007)  PLEASE RETRIEVE .1 + .2 + .5 + .6
   24           DO REMEMBER .4
   25           PLEASE RESUME #2
   26   (1001)  DO RESUME .5
   27   (1010)  DO STASH .1 + .2 + .4
   28           DO .4 <- .1
   29           DO .1 <- 'V-.2c/#65535'~'#0c/#65535'
   30           DO (1020) NEXT
   31           PLEASE DO .2 <- .4
   32           PLEASE DO (1009) NEXT
   33           DO RETRIEVE .1 + .2 + .4
   34           PLEASE RESUME #1
   35   (1020)  DO STASH .2 + .3
   36           DO .2 <- #1
   37           PLEASE DO (1021) NEXT
   38   (1021)  DO FORGET #1
   39           DO .3 <- "V-!1~.2'c/#1"~#3
   40           PLEASE DO .1 <- 'V-.1c/.2'~'#0c/#65535'
   41           DO (1022) NEXT
   42           DO .2 <- !2c/#0'~'#32767c/#1'
   43           DO (1021) NEXT
   44   (1023)  PLEASE RESUME .3
   45   (1022)  DO (1023) NEXT
   46           PLEASE RETRIEVE .2 + .3
   47           PLEASE RESUME #2
   48   (1030)  DO ABSTAIN FROM (1033)
   49           PLEASE ABSTAIN FROM (1032)
   50   (1039)  DO STASH :1 + .5
   51           DO (1530) NEXT
   52           DO .3 <- :1~#65535








                           - 36 -



   53           PLEASE DO .5 <- :1~'#65280c/#65280'
   54           DO .5 <- 'V-"!5~.5'~#1"c/#1'~#3
   55           DO (1031) NEXT
   56   (1032)  DO (1033) NEXT
   57           DO (1999) NEXT
   58   (1031)  DO (1001) NEXT
   59   (1033)  DO .4 <- .5
   60           DO REINSTATE (1032)
   61           PLEASE REINSTATE (1033)
   62           DO RETRIEVE :1 + .5
   63           PLEASE RESUME #2
   64   (1040)  PLEASE STASH .1 + .2 + .2 + :1 + :2 + :3
   65           DO .2 <- #0
   66           DO (1520) NEXT
   67           DO STASH :1
   68           PLEASE RETRIEVE .2
   69           DO .1 <- .2
   70           DO .2 <- #0
   71           PLEASE DO (1520) NEXT
   72           DO :2 <- :1
   73           DO RETRIEVE .1 + .2 + :1
   74           DO (1550) NEXT
   75           PLEASE DO .3 <- :3
   76           DO RETRIEVE :1 + :2 + :3
   77           DO RESUME #1
   78   (1050)  PLEASE STASH :2 + :3 + .5
   79           DO :2 <- .1
   80           PLEASE DO (1550) NEXT
   81           DO .5 <- :3~'#65280c/#65280'
   82           DO .5 <- 'V-"!5~.5'~#1"c/#1'~#3
   83           DO (1051) NEXT
   84           DO (1999) NEXT
   85   (1051)  DO (1001) NEXT
   86           DO .2 <- :3
   87           PLEASE RETRIEVE :2 + :3 + .5
   88           DO RESUME #2
   89   (1500)  PLEASE ABSTAIN FROM (1502)
   90           PLEASE ABSTAIN FROM (1506)
   91   (1509)  PLEASE STASH :1 + .1 + .2 + .3 + .4 + .5 + .6
   92           DO .1 <- :1~#65535
   93           PLEASE DO .2 <- :2~#65535
   94           DO (1009) NEXT
   95           DO .5 <- .3
   96           PLEASE DO .6 <- .4
   97           DO .1 <- :1~'#65280c/#65280'
   98           DO .2 <- :2~'#65280c/#65280'
   99           DO (1009) NEXT
  100           DO .1 <- .3
  101           PLEASE DO (1503) NEXT
  102           DO .6 <- .4
  103           DO .2 <- #1
  104           DO (1009) NEXT
  105           DO .1 <- .3
  106           DO (1501) NEXT








                           - 37 -



  107   (1504)  PLEASE RESUME .6
  108   (1503)  DO (1504) NEXT
  109   (1501)  DO .2 <- .5
  110           DO .5 <- 'V-"'&.6c/.4'~#1"c/#2'~#3
  111           DO (1505) NEXT
  112   (1506)  DO (1502) NEXT
  113           PLEASE DO (1999) NEXT
  114   (1505)  DO (1001) NEXT
  115   (1502)  DO :4 <- .5
  116           DO (1520) NEXT
  117           DO :3 <- :1
  118           PLEASE RETRIEVE :1 + .1 + .2 + .3 + .4 + .5 + .6
  119           DO REINSTATE (1502)
  120           DO REINSTATE (1506)
  121           PLEASE RESUME #3
  122   (1510)  DO STASH :1 + :2 + :4
  123           DO :1 <- "'V-":2~'#65535c/#0'"c/#65535'~'#0c/#6553
            5'"c/"'V-":2~'#0c/#65535'"c/#65535'~'#0c/#65535
            '"
  124           DO :2 <- #1
  125           DO (1509) NEXT
  126           PLEASE RETRIEVE :1
  127           DO :2 <- :3
  128           PLEASE DO (1509) NEXT
  129           DO RETRIEVE :2 + :4
  130           PLEASE RESUME #1
  131   (1520)  PLEASE STASH .3 + .4
  132           DO .3 <- .1~#43690
  133           DO (1525) NEXT
  134           PLEASE DO .4 <- 'V.3c/".2~#43690"'~'#0c/#65535'
  135           DO .3 <- .1~#21845
  136           PLEASE DO (1525) NEXT
  137           DO :1 <- .4c/"'V.3c/".2~#21845"'~'#0c/#65535'"
  138           PLEASE RETRIEVE .3 + .4
  139           DO RESUME #1
  140   (1525)  DO .3 <- '"'"'"!3c/#0'~'#32767c/#1'"c/#0'~'#32767
            c/#1'"c/#0'~'#16383c/#3'"c/#0'~'#4095c/#15'
  141           PLEASE RESUME #1
  142   (1530)  DO STASH :2 + :3 + .3 + .5
  143           DO :1 <- #0
  144           DO :2 <- .2
  145           DO .3 <- #1
  146           DO (1535) NEXT
  147   (1535)  PLEASE FORGET #1
  148           DO .5 <- "V-!1~.3'c/#1"~#3
  149           DO (1531) NEXT
  150           DO (1500) NEXT
  151           DO :1 <- :3
  152           PLEASE DO (1533) NEXT
  153   (1531)  PLEASE DO (1001) NEXT
  154   (1533)  DO FORGET #1
  155           DO .3 <- !3c/#0'~'#32767c/#1'
  156           DO :2 <- ":2~'#0c/#65535'"c/"'":2~'#32767c/#0'"c/#
            0'~'#32767c/#1'"








                           - 38 -



  157           PLEASE DO .5 <- "V-!3~.3'c/#1"~#3
  158           DO (1532) NEXT
  159           DO (1535) NEXT
  160   (1532)  DO (1001) NEXT
  161           PLEASE RETRIEVE :2 + :3 + .3 + .5
  162           DO RESUME #2
  163   (1540)  PLEASE ABSTAIN FROM (1541)
  164           DO ABSTAIN FROM (1542)
  165   (1549)  PLEASE STASH :1 + :2 + :4 + :5 + .1 + .2 + .5
  166           DO .1 <- :1~#65535
  167           PLEASE DO .2 <- :2~'#65280c/#65280'
  168           DO .5 <- :1~'#65280c/#65280'
  169           DO (1530) NEXT
  170           DO :3 <- :1
  171           DO .2 <- :2~#65535
  172           PLEASE DO (1530) NEXT
  173           DO :5 <- :1
  174           DO .1 <- .5
  175           DO (1530) NEXT
  176           DO :4 <- :1
  177           PLEASE DO :1 <- ":3~'#65280c/#65280'"c/":5~'#652
            80c/#65280'"
  178           DO .5 <- ':1~:1'~#1
  179           DO .2 <- :2~'#65280c/#65280'
  180           DO (1530) NEXT
  181           PLEASE DO .5 <- '"':1~:1'~#1"c/.5'~#3
  182           DO .1 <- :3~#65535
  183           DO .2 <- #0
  184           DO (1520) NEXT
  185           PLEASE DO :2 <- :1
  186           PLEASE DO .1 <- :4~#65535
  187           DO (1520) NEXT
  188           DO (1509) NEXT
  189           DO .5 <- !5c/":4~#3"'~#15
  190           DO :1 <- :3
  191           DO :2 <- :5
  192           DO (1509) NEXT
  193           PLEASE DO .5 <- !5c/":4~#3"'~#63
  194           DO .5 <- 'V-"!5~.5'~#1"c/#1'~#3
  195           PLEASE RETRIEVE :4
  196   (1541)  DO :4 <- .5
  197           DO (1543) NEXT
  198   (1542)  DO (1544) NEXT
  199           PLEASE DO (1999) NEXT
  200   (1543)  DO (1001) NEXT
  201   (1544)  DO REINSTATE (1541)
  202           PLEASE REINSTATE (1542)
  203           PLEASE RETRIEVE :1 + :2 + :5 + .1 + .2 + .5
  204           DO RESUME #2
  205   (1550)  DO STASH :1 + :4 + :5 + .5
  206           DO :3 <- #0
  207           DO .5 <- 'V-"':2~:2'~#1"c/#1'~#3
  208           PLEASE DO (1551) NEXT
  209           DO :4 <- #1








                           - 39 -



  210           PLEASE DO (1553) NEXT
  211   (1553)  DO FORGET #1
  212           DO .5 <- 'V-":2~'#32768c/#0'"c/#2'~#3
  213           DO (1552) NEXT
  214           DO :2 <- ":2~'#0c/#65535'"c/"'":2~'#32767c/#0'"c/#
                   0'~'#32767c/#1'"
  215           PLEASE DO :4 <- ":4~'#0c/#65535'"c/"'":4~'#32767
                     c/#0'"c/#0'~'#32767c/#1'"
  216           DO (1553) NEXT
  217   (1552)  DO (1001) NEXT
  218   (1556)  PLEASE FORGET #1
  219           DO :5 <- "'V-":1~'#65535c/#0'"c/":2~'#65535c/#0'"'
                     ~'#0c/#65535'"c/"'V-":1~'#0c/#65535'"c/":2~'#0c/
                     #65535'"'~'#0c/#65535'"
  220           DO .5 <- 'V-"'&"':2~:5'~'"'V-"'V-":5~:5"~"#65535~
                     #65535"'~'#65535c/#0'"c/#32768'~'#0c/#65535'"
                     c/"'V-":5~:5"~"#65535c/#65535"'~'#0c/#65535'"'
                     "c/"':5~:5'~#1"'~#1"c/#2'~#3
  221           DO (1554) NEXT
  222           DO :5 <- :3
  223           DO (1510) NEXT
  224           PLEASE DO :1 <- :3
  225           DO :3 <- "'V":4~'#65535c/#0'"c/":5~'#65535c/#0'"'
                     ~'#0c/#65535'"c/"'V":4~'#0c/#65535'"c/":5~'#0c/
                     #65535'"'~'#0c/#65535'"
  226           DO (1555) NEXT
  227   (1554)  PLEASE DO (1001) NEXT
  228   (1555)  DO FORGET #1
  229           DO .5 <- "V-':4~#1'c/#2"~#3
  230           DO (1551) NEXT
  231           DO :2 <- ":2~'#0c/#65534'"c/":2~'#65535c/#0'"
  232           DO :4 <- ":4~'#0c/#65534'"c/":4~'#65535c/#0'"
  233           PLEASE DO (1556) NEXT
  234   (1551)  DO (1001) NEXT
  235           PLEASE RETRIEVE :1 + :4 + :5 + .5
  236           PLEASE RESUME #2
  237   (1900)  DO STASH .2 + .3 + .5
  238           DO .1 <- #0
  239           DO .2 <- #1
  240           PLEASE DO (1901) NEXT
  241   (1901)  DO FORGET #1
  242           DO %50 .1 <- 'V.1c/.2'~'#0c/#65535'
  243           DO .2 <- !2c/#0'~'#32767c/#1'
  244           PLEASE DO .5 <- "V-!2~.2'c/#1"~#3
  245           DO (1902) NEXT
  246           DO (1901) NEXT
  247   (1902)  DO (1001) NEXT
  248           DO RETRIEVE .2 + .3 + .5
  249           PLEASE RESUME #2
  250   (1910)  PLEASE STASH .1 + .3 + .5 + :1 + :2 + :3
  251           DO .3 <- #65524
  252           DO :1 <- #6
  253           DO (1911) NEXT
* 254           PLEASE NOTE THAT YOU CAN'T GET THERE FROM HERE








                           - 40 -



  255   (1912)  DO (1001) NEXT
  256   (1911)  DO FORGET #1
  257           PLEASE DO (1900) NEXT
  258           DO :2 <- .1
  259           DO (1500) NEXT
  260           PLEASE DO :1 <- :3
  261           DO .1 <- .3
  262           DO (1020) NEXT
  263           PLEASE DO .3 <- .1
  264           DO .5 <- 'V-"!3~.3'~#1"c/#2'~#3
  265           DO (1912) NEXT
  266           DO .1 <- #12
  267           PLEASE DO (1050) NEXT
  268           DO RETRIEVE .1
  269           DO (1530) NEXT
  270           DO :2 <- #32768
  271           DO (1500) NEXT
  272           PLEASE DO .2 <- :3~'#65280c/#65280'
  273           PLEASE RETRIEVE .3 + .5 + :1 + :2 + :3
  274           DO RESUME #1
275   (1060)  DO .3<-'V".1c/.2"'~'#0c/#65535'
  276   (1070)  DO .3<-'&".1c/.2"'~'#0c/#65535'
  277   (1080)  DO .3<-'V-".1c/.2"'~'#0c/#65535'







































                           - 41 -



_8_._4  _P_r_o_g_r_a_m_m_i_n_g _S_u_g_g_e_s_t_i_o_n_s

For  the  novice INTERCAL programmer, we provide here a list
of suggested INTERCAL programming projects:

Write an integer exponentiation subroutine.  :1 <- .1 raised
to the .2 power.

Write  a  double-precision  sorting subroutine. Given 32-bit
array ;1 of size :1,  sort  the  contents  into  numerically
increasing order, leaving the results in ;1.

Generate a table of prime numbers.

Put   together   a   floating-point  library,  using  32-bit
variables to represent floating-point numbers (let the upper
half   be   the   mantissa   and   the  lower  half  be  the
characteristic).   The  library   should   be   capable   of
performing     floating-point     addition,     subtraction,
multiplication,  and  division,  as  well  as  the   natural
logarithm function.

Program  a Fast Fourier Transform (FFT).  This project would
probably entail the writing of the floating-point library as
well as sine and cosine functions.

Calculate, to :1 places, the value of pi.

(The  first  three  and  last one of the preceding suggested
projects from the INTERCAL-72 manual are included in the  C-
INTERCAL  distribution's  pit directory of sample code.  The
floating-point library and  FFT  routine  remain  as  worthy
challenges...)





























                           - 42 -



_9_.  _E_R_R_O_R _M_E_S_S_A_G_E_S

Due  to  INTERCAL's  implementation  of  comment  lines (see
section  4.5),  most  error  messages  are  produced  during
execution  instead of during compilation.  All errors except
those not causing immediate termination of program execution
are treated as fatal.

_9_._1  _F_o_r_m_a_t

All error messages appear in the following form:

        ICLnnnI (error message)
                ON THE WAY TO STATEMENT nnnn
                CORRECT SOURCE AND RESUBMIT

The  message  varies depending upon the error involved.  For
undecodable statements the message is the statement  itself.
The  second  line  tells  which  statement  would  have been
executed next had the error not occurred.  Note that if  the
error  is  due  to  80  attempted  levels  of  NEXTing,  the
statement which would have been executed next  need  not  be
anywhere near the statement causing the error.

_9_._2  _M_e_s_s_a_g_e_s

Brief  descriptions  of the different error types are listed
below according to message number.

 000 An undecodable statement has been  encountered  in  the
     course  of  execution. Note that keypunching errors can
     be  slightly  disastrous,  since   if   'FORGET'   were
     misspelled  F-O-R-G-E-R, the results would probably not
     be those desired. Extreme misspellings  may  have  even
     more  surprising consequences. For example, misspelling
     'FORGET' R-E-S-U-M-E could have drastic results.

 017 An expression contains a syntax error.

 079 Improper use has been made of statement identifiers.

 099 Improper use has been made of statement identifiers.

 123 Program has attempted 80 levels of NEXTing.

 129 Program has attempted to  transfer  to  a  non-existent
     line label.

 139 An  ABSTAIN  or  REINSTATE  statement references a non-
     existent line label.

 182 A line label has been multiply defined.










                           - 43 -



 197 An invalid line label has been encountered.

 200 An expression involves an unidentified variable.

 240 An attempt has been made to give an array  a  dimension
     of zero.

 241 Invalid   dimensioning   information  was  supplied  in
     defining or using an array.

 275 A 32-bit value has been assigned to a 16-bit  variable.

 436 A  retrieval has been attempted for an unSTASHed value.

 533 A WRITE IN statement or interleave  (c/)  operation  has
     produced a value requiring over 32 bits to represent.

 562 Insufficient data.

 579 Input data is invalid.

 621 The expression of a RESUME statement evaluated to #0.

 632 Program execution was terminated via a RESUME statement
     instead of GIVE UP.

 633 Execution has passed beyond the last statement  of  the
     program.

 774 A compiler error has occurred (see section 12).

 778 An unexplainable compiler error has occurred.

The following error codes are new in C-INTERCAL:

 111 You  tried  to  use  a  C-INTERCAL  extension  with the
     `traditional' flag on.

 127 Can't find syslib.i file when it's needed  for  magical
     inclusion.

 222 Out of stash space.

 333 Too many variables.

 444 A  COME  FROM  statement references a non-existent line
     label.

 555 More than one COME FROM references the same label.

 666 Too many source lines.

 777 No such source file.









                           - 44 -



 888 Can't open C output file

 999 Can't open C skeleton file.

 998 Source file name with  invalid  extension  (use  .i  or
     .[3-7]i).

 997 Illegal possession of a controlled unary operator.






















































                           - 45 -



_1_0_.  _T_h_e _C_-_I_N_T_E_R_C_A_L _C_o_m_p_i_l_e_r

_1_0_._1  _C_h_a_r_a_c_t_e_r _S_e_t

The  C-INTERCAL  compiler  uses ASCII rather than EBCDIC. We
follow the Atari implementation by (a) replacing the  change
sign  (c/) with big money ($) as the mingle operator, and (b)
replacing the bookworm (V-)  symbol  with  what  (?)  as  the
exclusive-or operator.

_1_0_._2  _U_s_a_g_e _a_n_d _C_o_m_p_i_l_a_t_i_o_n _O_p_t_i_o_n_s

To  compile  an INTERCAL program `foo.i' to executable code,
just do

        ick foo.i

There's a -c option that leaves  the  generated  C  code  in
place  for  inspection  (suppressing  compilation to machine
code), a -d option that enables verbose parse reporting from
the  yacc/bison  parser,  a  -t  option that requires strict
INTERCAL-72  compliance  (rejecting  COME   FROM   and   the
extensions  for  bases  other  than  two),  a -b option that
disables the INTERCAL-72 random-bug feature (E774),  and  an
-O  option  that enables the (hah!) optimizer.  Invoking ick
-?  prints a usage message.

Another  compilation  switch  affects  C-INTERCAL's  runtime
behavior.   The  `-C'  option  forces  output in "clockface"
mode, for  superstitious  users  who  believe  writing  "IV"
upside-down offends IVPITER and would rather see IIII.

_1_0_._3  _R_u_n_t_i_m_e _O_p_t_i_o_n_s

Every  C-INTERCAL  runtime  also  accepts certain options at
runtime.  These  include  [+/-]help,  [+/-]traditional,  and
[+/-]wimpmode.   The  help  option  (with  either  +  or  -)
triggers a  'usage'  message.  The  +traditional  option  is
presently a no-op.

Steve   explains:   "The   wimpmode   option   is  the  most
interesting. I found myself always running my test  programs
with  filters  on  both  ends  to  work  around  the 'nifty'
INTERCAL number representations. This was so painful that  I
decided  it would be LESS painful (and a lot less code) if I
added a 'wimp' option.  With the +wimpmode option, the  user
is  subjected  to a humiliating message about what a wimp he
or she is to use this mode, but after that is allowed to use
conventional   numerical   notation.    While  such  a  mode
doubtless violates to some extent the  INTERCAL  philosophy,
the  fact that a 'unbutcher' command has been posted clearly
indicates the need for it. Anyway... if you don't  like  it,
don't  use  it...  the  default  is -wimpmode (i.e. NOT wimp
mode)."








                           - 46 -



_1_0_._4  _P_L_E_A_S_E _P_o_l_i_t_e_s_s_e _C_h_e_c_k_i_n_g

A feature of INTERCAL-72  not  documented  in  the  original
manual  was  that  it  required a certain level of politesse
from the programmer.  If fewer than  1/5th  of  the  program
statements  included the PLEASE qualifier, the program would
be rejected as insufficiently polite.  If more than 1/3rd of
them  included  PLEASE,  the  program  would  be rejected as
excessively polite.

This check has been implemented in  C-INTERCAL.   To  assist
programmers in coping with it, the intercal.el mode included
with the distribution randomly  expands  "do  "  in  entered
source to "DO PLEASE" or "PLEASE DO" 1/4th of the time.
















































                           - 47 -



_1_1_.  _T_h_e _A_t_a_r_i _I_m_p_l_e_m_e_n_t_a_t_i_o_n

The  Atari  implementation  of  INTERCAL  differs  from  the
original Princeton version primarily in  the  use  of  ASCII
rather  than  EBCDIC. Since there is no "change" sign (c/) in
ASCII, we have substituted the "big money" ($) as the mingle
operator.   We  feel  that  this  correctly  represents  the
increasing  cost  of  software  in  relation  to   hardware.
(Consider that in 1970 one could get RUNOFF for free, to run
on a $20K machine, whereas today a  not  quite  as  powerful
formatter  costs  $99  and  runs on a $75 machine.)  We also
feel that there should  be  no  defensible  contention  that
INTERCAL   has  any  sense.   Also,  since  overpunches  are
difficult to read  on  the  average  VDT,  the  exclusive-or
operator  may  be  written  ?.  This correctly expresses the
average person's reaction on first  encountering  exclusive-
or,  especially  on  a  PDP-11.   Note that in both of these
cases, the over-punched symbol may also be used  if  one  is
masochistic,  or concerned with portability to the Princeton
compiler.   The   correct   over-punch   for   "change"   is
"c<backspace>/"   and   the  correct  over-punch  for  V-  is
"V<backspace>-".  These codes will be  properly  printed  if
you have a proper printer, and the corresponding EBCDIC code
will be produced by the /IBM option on the LIST command.






































                           - 48 -



_1_2_.  _T_h_e _P_r_i_n_c_e_t_o_n _C_o_m_p_i_l_e_r

The Princeton compiler, written in  SPITBOL  (a  variant  of
SNOBOL),  performs  the compilation in two stages. First the
INTERCAL source is converted into SPITBOL source,  then  the
latter is compiled and executed.

It  should  be  noted  that  the Princeton compiler fails to
properly interpret certain multiply-subscripted expressions,
such as:

        ",1SUB",2SUB#1"#2"

This  is  not  a  "bug".  Being  documented,  it is merely a
"restriction". Such cases may  be  resolved  by  alternating
sparks and ears in various levels of expression nesting:

        ",1SUB',2SUB#1'#2"

which  is  advisable in any case, since INTERCAL expressions
are unreadable enough as is.

Since  there  is  currently  no  catalogued  procedure   for
invoking  the  compiler,  the  user must include the in-line
procedure shown on the following page in his job before  the
compilation  step.  Copies  of this in-line procedure may be
obtained at any keypunch if the proper keys are struck.

The compiler is then executed in the usual manner:


        // EXEC INTERCAL[,PARM='parameters']
        //COMPILE.SYSIN DD *
        {INTERCAL source deck}
        /*
        //EXECUTE.SYSWRITE DD *
        {input data}
        /*


The various parameters are described following  the  in-line
procedure.  At most one parameter from each set may apply to
a given compilation; if more than  one  are  specified,  the
results  are  undefined,  and  may  vary  depending upon the
particular  set  of  options.  The  default  parameters  are
underlined.
















                           - 49 -



        //INTERCAL PROC
        //COMPILE EXEC PGM=INTERCAL
        //STEPLIB DD DSN=U.INTERCAL.LIBRARY,DISP=SHR
        //             DD DSN=SYS1.FORTLIB,DISP=SHR
        //SYSPRINT DD SYSOUT=A,DCB=(BLKSIZE=992,LRECL=137,RECFM=VBA)
        //SYSPUNCH DD DUMMY
        //SCRATCH DD DSN=&COMPSET,UNIT=SYSDA,SPACE=(CYL,(3,1)),DISP=(,PASS)
        //EXECUTE EXEC PGM=EXECUTE,COND=(4,LT)   3
        //SOURCES DD DSN=U.INTERCAL.SOURCES,DISP=SHR
        //STEPLIB DD DSN=U.INTERCAL.LIBRARY,DISP=SHR
        //             DD DSN=SYS5.SPITLIB,DISP=SHR
        //             DD DSN=SYS1.FORTLIB,DISP=SHR
        //SYSIN DD DSN=&COMPSET,DISP=(OLD,DELETE)
        //SYSOBJ DD SYSOUT=B,DCB=(BLKSIZE=80,LRECL=80,RECFM=F)
        //SYSPRINT DD SYSOUT=A,DCB=(BLKSIZE=992,LRECL=137,RECFM=VBA)
        //SYSPUNCH DD DUMMY
        // PEND

      Figure 3.  Inline procedure for using INTERCAL.

OOPPTT
NOOPT
     In the default mode, the compiler will print a list  of
     all  options  in  effect,  including  the  defaults for
     unspecified parameter groups and the  effective  option
     for  those  sets  where  one was specified. If NOOPT is
     requested, it causes the default mode to be assumed.

OOPPTTSSUUBB
NOOPTSUB
NOSUB
     Unless 'NOOPTSUB' is requested, the System  Library  is
     optimized,   resulting   in   much   more  rapid  NOSUB
     processing  of  function  calls.  Specifying   NOOPTSUB
     causes the non-optimized INTERCAL code shown in section
     6.3 to be used, whereas NOSUB requests that the  System
     Library be omitted altogether.

IAMBIC
PPRROOSSEE
     The  IAMBIC  parameter  permits  the  programmer to use
     poetic license and thus write in verse. If  the  reader
     does   not  believe  it  possible  to  write  verse  in

____________________

3. Pending  acquisition  of SPITBOL release 3.0, the SOURCES
   DD card must be replaced by the five cards:

           //NOOPTPFX DD DSN=U.INTERCAL.SOURCES(NOOPTPFX),DISP=SHR
           //NOOPTSUB DD DSN=U.INTERCAL.SOURCES(NOOPTSUB),DISP=SHR
           //OPTPFX DD DSN=U.INTERCAL.SOURCES(OPTPFX),DISP=SHR
           //OPTSUB DD DSN=U.INTERCAL.SOURCES(OPTSUB),DISP=SHR
           //PRELIM DD DSN=U.INTERCAL.SOURCES(PRELIM),DISP=SHR








                           - 50 -



     INTERCAL, he should send the authors a  stamped,  self-
     addressed  envelope,  along  with any INTERCAL program,
     and they will provide one which is verse.

FFOORRMMAATT
NOFORMAT
     In FORMAT mode, each statement  printed  is  put  on  a
     separate  line  (or lines). In NOFORMAT mode, the free-
     format source is printed exactly  as  input.   In  this
     latter  case,  statement  numbers are provided only for
     the first statement on a card, and  they  may  be  only
     approximate.  Also,  unrecognizable  statements are not
     flagged.

SEQ
NNOOSSEEQQ
     If the source deck has sequence numbers in  columns  73
     through  80,  specifying  'SEQ'  will  cause them to be
     ignored.

SOURCE
NNOOSSOOUURRCCEE
     If  NOSOURCE  is  selected,  all  source   listing   is
     suppressed.

LIST
NNOOLLIISSTT
     If  LIST is specified, the compiler will provide a list
     of statement numbers catalogued according  to  type  of
     statement.  The  compiler  uses  this  table to perform
     abstentions by gerund.

WIDTH=nn
     This sets the width (in number of  characters)  of  the
     output line for FORMAT mode output. The default is 113322..

CODE
NNOOCCOODDEE
     Include 'CODE'  in  the  parameter  list  to  obtain  a
     listing  of the SPITBOL code produced for each INTERCAL
     statement.

LINES=nn
     This determines the number of lines  per  page,  during
     both compilation and execution. The default is 6600..

DECK
NNOODDEECCKK
     Selecting 'DECK' will cause the compiler to punch out a
     SPITBOL object deck  which  may  then  be  run  without
     reinvoking the INTERCAL (or SPITBOL) compiler.

KKIIDDDDIINNGG









                           - 51 -



NOKIDDING
     Select  NOKIDDING  to eliminate the snide remarks which
     ordinarily accompany INTERCAL error messages.

GGOO
NOGO
     Specifying  'NOGO'  will  cause   the  program  to   be
     compiled  but  not  executed.  EXECUTE/NOEXECUTE may be
     substituted for GO/NOGO, but this  will  result  in  an
     error, and GO will be assumed.

BBUUGG
NOBUG
     Under  the  default,  there is a fixed probability of a
     fatal compiler bug being  worked  at  random  into  the
     program  being  compiled.  Encountering this bug during
     execution results in error  message  774  (see  section
     7.2).   This  probability  is  reduced  to  zero  under
     'NOBUG'.  This  does   not   affect   the   probability
     (presumably negligible) of error message 778.
_1_2_._1  _O_t_h_e_r _I_N_T_E_R_C_A_L _C_o_m_p_i_l_e_r_s

There are no other INTERCAL compilers. 4


























____________________

4. This  assertion  in  the INTERCAL-72 manual was blatantly
   contradicted by some notes  on  an  Atari  implementation
   included  at  the  end  of  the  manual.   So, you expect
   compiler manuals to be consistent?







                           - 52 -



                          TTOONNSSIILL AA







            The Official INTERCAL Character Set

Tabulated  on  page  53  are  all  the  characters  used  in
INTERCAL,  excepting  letters  and  digits, along with their
names  and  interpretations.  Also  included   are   several
characters  not  used  in  INTERCAL, which are presented for
completeness and to allow for future expansion.

































____________________

4. Since all other reference manuals have Appendices, it was
   decided  that  the  INTERCAL  manual  should contain some
   other type of removable organ.

4. 5 This footnote intentionally unreferenced.







                           - 53 -



+-----------------------------------------------------------------------+
|             Character       Name    Use (if any)                      |
+-----------------------------------------------------------------------+
|.     spot    identify 16-bit variable                                 |
|:       two-spot        identify 32-bit variable                       |
|,       tail    identify 16-bit array                                  |
|;       hybrid  identify 32-bit array                                  |
|#       mesh    identify constant                                      |
|=     half-mesh                                                        |
|'      spark   grouper                                                 |
|`       backspark                                                      |
|!       wow     equivalent to spark-spot                               |
|?       what    _u_n_a_r_y _e_x_l_u_s_i_v_e _O_R _(_A_S_C_I_I_)                              |
|"       rabbit-ears     grouper                                        |
|".  rabbit  equivalent to ears-spot                                     |
||       spike                                                          |
|%       double-oh-seven percentage qualifier                           |
|-      worm    used with angles                                        |
|<       angle   used with worms                                        |
|>       right angle                                                    |
|(       wax     precedes line label                                    |
|)       wane    follows line label                                     |
|[       U turn                                                         |
|]       U turn back                                                    |
|{       embrace                                                        |
|}       bracelet                                                       |
|*       splat   flags invalid statements                               |
|&       ampersand7    unary logical AND                                |
|V       V (or book)     unary logical OR                               |
|V-   bookworm (or universal qualifier)       unary exclusive OR         |
|$       big money       _b_i_n_a_r_y _m_i_n_g_l_e _(_A_S_C_I_I_)                          |
|c/   change  binary mingle                                              |
|~       sqiggle binary select                                          |
|_     flat worm                                                        |
|-   overline        indicates "times 1000"                             |
|+       intersection    separates list items                           |
|/       slat                                                           |
|\      backslat                                                        |
|@       whirlpool                                                      |
|-'   hookworm                                                           |
|^       shark (or simply sharkfin)                                     |
|#*[]      blotch                                                         |
+--------T-a-b-l-e--2--(-t-o-p--v-i-e-w-)-.--I-N-T-E-R-C-A-L--c-h-a-r-a-c-t-e-r--s-e-t-.---------------------+









____________________

7. Got any better ideas?




