





             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_, _1_9_9_7 _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_6_)








































                            - 1 -



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

     "But  I  don't want to go among mad people," Alice
     remarked.

     "Oh, you ca'n't help that," said the  Cat:  "We're
     all mad here. I'm mad. You're mad."

     "How do you know I'm mad?" said Alice.
     "You must be," said the Cat, "or you wouldn't have
     come here."

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".










                            - 2 -



_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.

























































                            - 3 -



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

     "There's  nothing  like  eating  hay  when  you're
     faint," the White King remarked to  Alice,  as  he
     munched away.

     "I should think throwing cold water over you would
     be better," Alice  suggested:  "--  or  some  sal-
     volatile."
     "I  didn't say there was nothing _b_e_t_t_e_r," the King
     replied. "I said there was nothing _l_i_k_e it." Which
     Alice did not venture to deny.

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.

































                            - 4 -



        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~'#0c/#65535'"'~'#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
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 23-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!=[]<-|[]









                            - 5 -



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.







































                            - 6 -



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

     "I  quite  agree with you," said the Duchess; "and
     the moral of that is -- 'Be what you would seem to
     be'  --  or,  if  you'd like it put more simply --
     'Never imagine yourself not to be  otherwise  than
     what  it might appear to others that what you were
     or might have been was not otherwise than what you
     had  been  would  have  appeared  to  them  to  be
     otherwise."

     "I think I should understand that  better,"  Alice
     said very politely, "if I had it written down: but
     I ca'n't quite follow it as you say it."

     "That's nothing to what I could say if  I  chose,"
     the Duchess replied, in a pleased tone.

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

_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 _n_o_t 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








                            - 7 -



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 1.
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
[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.

Perhaps  a simpler way of understanding the operation of the
select operator would be to examine  the  logic  diagram  in
Figure 1, which performs the select operation upon two 8-bit
values, A and B.  The  gates  used  are  Warmenhovian  logic
gates,  which  means  the outputs have four possible values:
low, high, undefined (value of an uninitialized  flip-flop),
and oscillating (output of a NOR gate with one input low and
the other input connected to the output). These  values  are
represented symbolically by '0', '1', '?', and '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

____________________

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







                            - 8 -



the various gates are listed in Table 1.

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


























































                            - 9 -



 --+-+----     --+----  +--+----   --+----  +--+----
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









                           - 10 -



   __________________________________________________________
  |\                                                         \
  | \ 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.












                           - 11 -



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










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



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










                  FIGURE 2. FLIP FLAP FLOP











                           - 12 -



[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 O1-8 = A1-8~B1-8
-----   -----
-----
-----   -----

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











              FIGURE 1  (CONTINUED).  NEW YORK




























                           - 13 -



_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
depend on whether the return type is 16 or 32 bits.

_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,  V-  is
replaced  by what (?). The compiler recognizes V<backspace>-
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.









                           - 14 -



_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)2





































____________________

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







                           - 15 -



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.

























                           - 16 -



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

     "There's glory for you!"

     "I don't know what you  mean  by  'glory,'"  Alice
     said.

     Humpty  Dumpty  smiled  contemptuously. "Of course
     you don't -- till I tell you. I meant  'there's  a
     nice knock-down argument for you!'"

     "But  'glory'  doesn't  mean  'a  nice  knock-down
     argument.'" Alice objected.

     "When _I use a word,"  Humpty  Dumpty  said,  in  a
     rather scornful tone, "it means just what I choose
     it to mean -- neither more nor less."

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.











                           - 17 -



_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
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  14  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#1"c/#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








                           - 18 -



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.

_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








                           - 19 -



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:

        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 has 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








                           - 20 -



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

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 (see 4.4.12)
and RETRIEVE (see 4.4.6) statements. 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.  Using RETRIEVE on an IGNOREd variable will
pop the variable's stash stack without actually changing its
value.

_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








                           - 21 -



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

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,








                           - 22 -



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
of   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
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."

(See  also  section  5  for  a  description  of C-INTERCAL's
character I/O.)

_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








                           - 23 -



are 4000 or greater,
_
I
is used. Thus #3999 would read  out  as  MMMCMXCIX  3  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.

(See also  section  5  for  a  description  of  C-INTERCAL's
character I/O.)

_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)

____________________

3. 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.







                           - 24 -



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 %
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








                           - 25 -



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 comment
example above 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.




















































                           - 26 -



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

     She puzzled over this for some time, but at last a
     bright  thought  struck her. "Why, it's a Looking-
     glass book, of course! And, if I hold it up  to  a
     glass, the words will all go the right way again."

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








                           - 27 -



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 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 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








                           - 28 -



(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
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!



















































                           - 29 -



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

     "-- oh dear, how puzzling it all is! I'll try if I
     know  all  the  things I used to know. Let me see:
     four times five is twelve, and four times  six  is
     thirteen,  and  four  times seven is -- oh dear! I
     shall never get to twenty at that rate!"

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  cannot
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,








                           - 30 -



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.

_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,








                           - 31 -



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.

_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 (@) denotes the  unary
tritwise  BUT  operation.  You can think of the whirlpool as








                           - 32 -



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.

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 C-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 (^), while the
old what (?) 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








                           - 33 -



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.

_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








                           - 34 -



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 @ to indicate the operation that
prefers one of the digits not already 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.




































                           - 35 -



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

     "You don't know what you're talking about!"  cried
     Humpty  Dumpty.  "How  many  days  are  there in a
     year?"

     "Three hundred and sixty-five," said Alice.

     "And how many birthdays have you?"
     "One."

     "And if you take one from three hundred and sixty-
     five, what remains?"

     "Three hundred and sixty-four, of course."

     Humpty  Dumpty  looked  doubtful.  "I'd rather see
     that done on paper," he said.

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
stores  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  core  to
implement. These functions, along with  their  corresponding
entry points (entered via DO (entry) NEXT) are listed below.





















                           - 36 -



 (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

 (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.






















                           - 37 -



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

     "If any one of them can explain it,"  said  Alice,
     "I'll  give  him sixpence. _I don't believe there's
     an atom of meaning in it."   The  jury  all  wrote
     down,   on  their  slates,  "_S_h_e  doesn't  believe
     there's an atom of meaning in  it,"  but  none  of
     them attempted to explain the paper.

     "If  there's  no  meaning  in  it," said the King,
     "that saves a world of trouble, you  know,  as  we
     needn't  try  to find any. And yet, I don't know,"
     he went on, spreading out the verses on one  knee,
     and  looking  at them with one eye: "I seem to see
     some meaning in them, after all...."

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 is in section 8.3. 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








                           - 38 -



bit (see statement 54).  To test for  all  bits  being  1's,
select  the  value  from itself and select the top bit.  The
test for greater than, performed in statements 219  and  220
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'"

(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.

















                           - 39 -



_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








                           - 40 -



    52                  DO .3 <- :1~#65535
    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








                           - 41 -



   106                  DO (1501) NEXT
   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/#65535'"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'
                            ~'#32767c/#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'








                           - 42 -



   156                  DO :2 <- ":2~'#0c/#65535'"c/"'":2~'#32767
                            c/#0'"c/#0'~'#32767c/#1'"
   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/":4~'#65280c/#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"'~#172
   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








                           - 43 -



   208                  PLEASE DO (1551) NEXT
   209                  DO :4 <- #1
   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~'#32767
                            c/#0'"c/#0'~'#32767c/#1'"
   215                  PLEASE DO :4 <- ":4~'#0c/#65535'"c/"'":4
                            ~'#32767c/#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
                            "~"#65535c/#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~'#65535
                            c/#0'"'~'#0c/#65535'"c/"'V":4~'#0
                            c/#65535'"c/":5~'#0c/#65535'"'~'#0
                            c/#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








                           - 44 -



   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
   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





































                           - 45 -



_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.

(Working programs for each of these projects are included in
the C-INTERCAL distribution's pit directory of sample code.)
































                           - 46 -



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

     Alice felt dreadfully puzzled. The Hatter's remark
     seemed  to  her  to have no sort of meaning in it,
     and yet it was certainly English. "I  don't  quite
     understand  you,"  she  said,  as  politely as she
     could.

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.









                           - 47 -



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

 182 A line label has been multiply defined.

 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, or attempt to stash  an  undeclared
     array.

 333 Too many variables.

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









                           - 48 -



 555 More than one COME FROM references the same label.

 666 Too many source lines.

 777 No such source file.

 888 Can't open C output file.

 999 Can't open C skeleton file.

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

 997 Illegal possession of a controlled unary operator.
















































                           - 49 -



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

     "And  yet it was a very clever pudding to invent."

     "What did you mean it to be made of?" Alice asked,
     hoping to cheer him up, for the poor Knight seemed
     quite low-spirited about it.

     "It  began  with   blotting-paper,"   the   Knight
     answered with a groan.

     "That wouldn't be very nice, I'm afraid --"

     "Not  very  nice  _a_l_o_n_e,"  he  interrupted,  quite
     eagerly, "but you've no idea what a difference  it
     makes,  mixing  it  with  other  things -- such as
     gunpowder and sealing-wax."

This section  describes  the  use  of  ick,  the  C-INTERCAL
compiler.  Information  specific to the other known INTERCAL
compilers appears in the following sections. These  sections
are  less  useful,  since  the other compilers are no longer
available, but they are  retained  to  provide  a  sense  of
history,  and  because any information regarding INTERCAL is
really too scarce to discard.

_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  (see  section 11) 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 XOR 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 (error 774), 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








                           - 50 -



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 _l_e_s_s 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  an  '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.  _n_o_t  wimp
mode)."

_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 "PLEASE DO" 1/4th of the time.























                           - 51 -



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

     "Perhaps it doesn't understand  English,"  thought
     Alice.  "I  daresay it's a French mouse, come over
     with William the Conqueror." (For,  with  all  her
     knowledge  of  history,  Alice  had  no very clear
     notion how long ago anything had happened.)

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.
































                           - 52 -



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

     "My  name  is Alice, so please your Majesty," said
     Alice very politely; but she  added,  to  herself,
     "Why,  they're  only a pack of cards, after all. I
     needn't be afraid of them!"

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  in  Figure  3  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.











                           - 53 -



        //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)
        //SOURCES DD DSN=U.INTERCAL.SOURCES,DISP=SHR   4
        //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_P_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_P_T_S_U_B
NOOPTSUB
NOSUB
     Unless 'NOOPTSUB' is requested, the System  Library  is
     optimized,  resulting  in much more rapid processing of
     function calls. Specifying  NOOPTSUB  causes  the  non-
     optimized  INTERCAL  code  shown  in  section 8.3 to be
     used, whereas NOSUB requests that the System Library be
     omitted altogether.

IAMBIC
_P_R_O_S_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

____________________

4. 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








                           - 54 -



     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_O_R_M_A_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_O_S_E_Q
     If the source deck has sequence numbers in  columns  73
     through  80,  specifying  'SEQ'  will  cause them to be
     ignored.

SOURCE
_N_O_S_O_U_R_C_E
     If  NOSOURCE  is  selected,  all  source   listing   is
     suppressed.

LIST
_N_O_L_I_S_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_O_C_O_D_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_O_D_E_C_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_I_D_D_I_N_G









                           - 55 -



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

_G_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_U_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 9).
     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. 5


























____________________

5. 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?







                           - 56 -



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







     "Of course they answer to their names?"  the  Gnat
     remarked carelessly.

     "I never knew them to do it."

     "What's  the  use of their having names," the Gnat
     said, "if they wo'n't answer to them?"
     "No use to _t_h_e_m," said Alice; "but it's useful  to
     the  people that name them, I suppose. If not, why
     do things have names at all?"

     "I ca'n't say," the Gnat replied. "Further on,  in
     the  wood  down  there,  they've  got  no names --
     however, go on with your list...."

            The Official INTERCAL Character Set

Tabulated  on  page  57  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.


















____________________

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

7. This footnote intentionally unreferenced.







                           - 57 -



+-----------------------------------------------------------------------------+
|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                             unary logical XOR               |
|"           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        |
|&           ampersand 9                      unary logical AND               |
|V           V (or book)                      unary logical OR                |
|V-           bookworm (universal qualifier)   unary logical XOR (INTERCAL-72) |
|$           big money                        binary mingle                   |
|c/           change                           binary mingle (INTERCAL-72)     |
|~           sqiggle                          binary select                   |
|_           flat worm                                                        |
|-           overline                         indicates "times 1000"          |
|+           intersection                     separates list items            |
|/           slat                                                             |
|\           backslat                                                         |
|@           whirlpool                        unary logical BUT (TriINTERCAL) |
|-'           hookworm                                                         |
|^           shark (or simply sharkfin)       unary logical XOR (TriINTERCAL) |
|#*[]          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-.---------------------------+










____________________

9. Got any better ideas?




