X-NEWS: spcvxb alt.lang.intercal: 4 Relay-Version: VMS News - V5.9C-01 30/04/90 VAX/VMS V5.3; site spcvxb.spc.edu Path: spcvxb!njin!rutgers!cbmvax!snark!eric Newsgroups: alt.lang.intercal Subject: Heeere she is, Miss Amerrr....No! No! AAAGH! it's C-INTERCAL! Message-ID: <1WPqh8#5Oh1SB3CPSfC04BdgW9ZP25p=eric@snark.uu.net> From: eric@snark.uu.net (Eric S. Raymond) Date: 12 May 90 16:29:49 GMT Lines: 2638 Yes, masochist hackers of the world, it's that horrible moment you've all been waiting for...THE RETURN OF INTERCAL! #!/bin/sh : "This is a shell archive, meaning: " : "1. Remove everything above the #! /bin/sh line. " : "2. Save the resulting test in a file. " : "3. Execute the file with /bin/sh (not csh) to create the files:" : " READ.ME" : " intercal.man" : " intercal.tex" : " intercal.sty" : " BUGS" : " THEORY" : " Makefile" : " cesspool.c" : " cesspool.h" : " feh.c" : " fiddle.c" : " ick.h" : " ick.y" : " lose.c" : " lose.h" : " lexer.l" : " ick-wrapper.c" : " sample.i" : "This archive created: "Sat May 12 12:24:39 EDT 1990 echo file: READ.ME sed 's/^X//' >READ.ME << 'END-of-READ.ME' X C-INTERCAL (v 0.3) X X NOTE! THIS IS A PRE-RELEASE VERSION WITH SOME KNOWN BUGS! X SEE THE `BUGS' FILE FOR DETAILS, AND EARN THE ETERNAL GRATITUDE X OF THE HUGE, BUSTLING INTERCAL COMMUNITY BY FIXING THEM! X XThis package is an implementation of the language INTERCAL designed by Don XWoods and James Lyon, who have since spent most of twenty years trying to Xlive it down. X XThe implementation was created by Eric S. Raymond (...!uunet!snark!eric) Xduring a fit of lunacy from which he has since mostly recovered. The files Xincluded are: X XREAD.ME -- this file Xintercal.man -- The INTERCAL manual (read this next!) Xintercal.tex -- TeX source form Xintercal.sty -- TeX style file XTHEORY -- some notes on the internals of the INTERCAL compiler XBUGS -- notes pertaining to this release X XMakefile -- makefile for the INTERCAL compiler Xlexer.l -- the lexical analyzer specification (in LEX) Xick.y -- the grammar specification (in YACC) Xick.h -- compilation types and defines Xfeh.c -- INTERCAL-to-C code generator Xfiddle.c -- the INTERCAL operators Xlose.[ch] -- INTERCAL compile- and run-time error handling Xick-wrapper.c -- the driver for generated C-from-INTERCAL code Xcesspool.c -- the INTERCAL runtime support code Xcesspool.h -- interface fr. generated code to the INTERCAL runtime support X Xsample.i -- a sample INTERCAL program (from the manual) X XYou want a man page? Man pages are for wimps. To compile an INTERCAL Xprogram `foo.i' to executable code, just do X X ick foo.i X XThere's a -d option that leaves the generated `foo.c' in place for Xinspection (suppressing compilation to machine code), and an -O option Xthat enables the (hah!) optimizer. Other than that, yer on yer own. X XOne other switch affects C-intercal's runtime behavior. The `-C' Xoption forces output in "clockface" mode, for superstitious users who Xbelieve writing "IV" upside-down offends IVPITER and would rather Xsee IIII. X XReport bugs, if you absolutely must, to the author. Or post them to Xalt.lang.intercal. Or something. END-of-READ.ME echo file: intercal.man sed 's/^X//' >intercal.man << 'END-of-intercal.man' X X X X X X X THE INTERCAL PROGRAMMING LANGUAGE X REFERENCE MANUAL X X X Donald R. Woods & James M. Lyon X X Copyright Donald R. Woods & James M. Lyon 1973 X X X X X X X X INTERCAL X X1. INTRODUCTION X XThe names you are about to ignore are true. However, the story has been changed Xsignificantly. Any resemblance of the programming language portrayed here Xto other programming languages, living or dead, is purely coincidental. X X1.1 ORIGIN AND PURPOSE X XThe INTERCAL programming language was designed the morning of May 26, 1972 Xby Donald R. Woods and James M. Lyon, at Princeton University. Exactly when Xin the morning will become apparent in the course of this manual. It was Xinspired by one ambition; to have a compiler language which has nothing at Xall in common with any other major language. By 'major' was meant anything Xwith which the authors were at all familiar, e.g., FORTRAN, BASIC, COBOL, XALGOL, SNOBOL, SPITBOL, FOCAL, SOLVE, TEACH, APL, LISP, and PI/I. For the Xmost part, INTERCAL has remained true to this goal, sharing only the basic Xelements such as variables, arrays, and the ability to do I/O, and eschewing Xall conventional operations other than the assignment statement (FORTRAN X"="). X X1.2 ACRONYM X XThe full name of the compiler is "Compiler Language With No Pronounceable XAcronym", which is, for obvious reasons, abbreviated "INTERCAL". X X1.3 ACKNOWLEDGMENTS X XThe authors are deeply indebted to Eric M. Van and Daniel J. Warmenhoven, Xwithout whose unwitting assistance this manual would still have been Xpossible. X X X X X X X X X2. FUNDAMENTAL CONCEPTS X XIn this section an attempt is made to describe how and why INTERCAL may be Xused; i.e., what it is like and what it is good for. X X2.1 SAMPLE PROGRAM X XShown below is a relatively simple INTERCAL program which will read in 32-bit Xunsigned integers, treat them as signed, 2's-complement numbers, and print out Xtheir absolute values. The program exits if the absolute value is zero. Note Xin particular the inversion routine (statements 6 through 14), which could Xbe greatly simplified if the subroutine library (see section 5) were used. X XA more detailed analysis of a program is made in section 6 of this manual. X X DO (5) NEXT X (5) DO FORGET #1 X PLEASE WRITE IN :1 X DO .1 <- 'V":1~'#32768$#0'"$#1'~#3 X DO (1) NEXT X DO :1 <- "'V":1~'#65535$#0'"$#65535' X ~'#0$#65535'"$"'V":1~'#0$#65535'" X $#65535'~'#0$#65535'" X DO :2 <- #1 X PLEASE DO (4) NEXT X (4) DO FORGET #1 X DO .1 <- "'V":1~'#65535$#0'"$":2~'#65535 X $#0'"'~'#0$#65535'"$"'V":1~'#0 X $#65535'"$":2~'#65535$#0'"'~'#0$#65535'" X DO (1) NEXT X DO :2 <- ":2~'#0$#65535'" X $"'":2~'#65535$#0'"$#0'~'#32767$#1'" X DO (4) NEXT X (2) DO RESUME .1 X (1) PLEASE DO (2) NEXT X PLEASE FORGET #1 X DO READ OUT :1 X PLEASE DO .1 <- 'V"':1~:1'~#1"$#1'~#3 X DO (3) NEXT X PLEASE DO (5) NEXT X (3) DO (2) NEXT X PLEASE GIVE UP X X2.2 USES FOR INTERCAL X XINTERCAL's main advantage over other programming languages is its strict Xsimplicity. It has few capabilities, and thus there are few restrictions to Xbe kept in mind. Since it is an exceedingly easy language to learn, one Xmight expect it would be a good language for initiating novice programmers. XPerhaps surprising, than, is the fact that it would be more likely to Xinitiate a novice into a search for another line of work. As it turns out, XINTERCAL is more useful (which isn't saying much) as a challenge to Xprofessional programmers. Those who doubt this need only refer back to the Xsample program in section 2.1. This 23-statement program took somewhere Xfrom 15 to 30 minutes to write, whereas the same objectives can be achieved Xby single-statement programs in either SNOBOL; X X PLEASE INPUT POS(0) ('-' ! '') X + (SPAN('0123456789') $ OUTPUT) X + *NE(OUTPUT) :S(PLEASE)F(END) X Xor APL; X X [1] >-0=/?<-? X XAdmittedly, neither of these is likely to appear more intelligible to Xanyone unfamiliar with the languages involved, but they took roughly 60 Xseconds and 15 seconds, respectively, to write. Such is the overwhelming Xpower of INTERCAL! X XThe other major importance of INTERCAL lies in its seemingly inexhaustible Xcapacity for amazing one's fellow programmers, confounding programming shop Xmanagers, winning friends, and influencing people. It is a well-known and Xoft-demonstrated fact that a person whose work is incomprehensible is held Xin high esteem. For example, if one were to state that the simplest way to Xstore a value of 65535 in a 32-bit INTERCAL variable is: X X DO :1 <- #0?#256 X Xany sensible programmer would say that that was absurd. Since this is Xindeed the simplest method, the programmer would be made to look foolish in Xfront of his boss, who would of course happened to turn up, as bosses are Xwont to do. The effect would be no less devastating for the programmer Xhaving been correct. X X X X X X X X3. DESCRIPTION X XThe examples of INTERCAL programming which have appeared in the preceding Xsections of this manual have probably seemed highly esoteric to the reader Xunfamiliar with the language. With the aim of making them more so, we Xpresent here a description of INTERCAL. X X X3.1 VARIABLES X XINTERCAL allows only 2 different types of variables, the 16-bit integer Xand the 32-bit integer. These are represented by a spot (.) or two-spot X(:), respectively, followed by any number between 1 and 65535, inclusive. XThese variables may contain only non-negative numbers; thus they have the Xrespective ranges of values: 0 to 65535 and 0 to 4294967295. Note: .123 and X:123 are two distinct variables. On the other hand, .1 and .0001 are Xidentical. Furthermore, the latter may NOT be written as 1E-3. X X3.2 CONSTANTS X XConstants are 16-bit values only and may range from 0 to 65535. They are Xprefixed by a mesh (#). Caution! Under no circumstances confuse the mesh Xwith the interleave operator, except under confusing circumstances! X X3.3 ARRAYS X XArrays are represented by a tail (,) for 16-bit values, or a hybrid (;) for X32-bit values, followed by a number between 1 and 65535, inclusive. The Xnumber is suffixed by the word SUB, followed by the subscripts, separated Xoptionally by spaces. Subscripts may be any expressions, including those Xinvolving subscripted variables. This occasionally leads to ambiguous Xconstructions, which are resolved as discussed in section 3.4.3. Definition Xof array dimensions will be discussed later in greater detail, since Xdiscussing it in less detail would be difficult. As before, ,123 and ;123 Xare distinct. In summary, .123, :123, #123, ,123, and :123 are all Xdistinct. X X3.4 OPERATORS X XINTERCAL recognizes 5 operators--2 binary and 3 unary. Please be kind to Xour operators: they may not be very intelligent, but they're all we've got. XIn a sense, all 5 operators are binary, as they are all bit-oriented, but Xit is not our purpose here to quibble about bits of trivia. X X X X******* proofread versus the paper copy only this far !!!! ************ X X X X X3.4.1 BINARY OPERATORS X XThe binary operators are INTERLEAVE (also called MINGLE) and SELECT, which Xare represented by a change (c/) and a sqiggle [sic] (~), respectively. X XThe interleave operator takes two 16-bit values and produces a 32-bit result Xby alternating the bits of the operands. Thus, #65535c/#0 has the 32-bit Xbinary form 101010....10 or 2863311530 decimal, while #0c/#65535 = X0101....01 binary = 1431655765 decimal, and #255c/#255 is equivalent to X#65535. X XThe select operator takes from the first operand whichever bits correspond Xto 1's in the second operand, and packs these bits as the right in the result. XBoth operands are automatically padded on the left with zeros to 32 bits Xbefore the selection takes place, so the variable types are unrestricted. XIf more than 16 bits are selected, the result is a 32-bit value, otherwise Xit is a 16-bit value. For example, #179~#201 (binary value 10110011~11001001) Xselects from the first argument the 8th, 7th, 4th, and 1st from last bits, Xnamely, 1001, which = 9. But #201~#179 selects from binary 11001001 the 8th, X6th, 5th, 2nd, and 1st from last bits, giving 10001 = 17. #179~#179 has the Xvalue 31, while #201~#201 has the value 15. X XPerhaps a simpler way of understanding the operation of the select operator Xwould be to examine the logic diagram on the following page (Figure 1), which Xperforms the select operation upon two 8-bit values, A and B. The gates used Xare Warmenhovian logic gates, which means the outputs have four possible Xvalues: low, high, undefined (value of an uninitialized flip-flop), and Xoscillating (output of a NOR gate with one input low and the other input Xconnected to the output). These values are represented symbolically by '0', X'1', '2', and 'F'. Note in particular that, while NOT-0 is 1 and NOT-2 Xis 0 as in two-valued logic, NOT-? is ? and NOT-F is F. The functions Xof the various gates are listed on Table 1. X X X X X X X X3.4.2 UNARY OPERATORS X XThe unary operators are & (logical AND), V (logical OR), and V- (logical XXOR). This last character is obtained by overpunching a worm (-) on a V X(V). The operator is inserted between the spot, two-spot, mesh, or Xwhat-have-you, and the integer, thus: .&123, #V123. Multiple unary Xoperators may not be concatenated, thus the form #V&123 is invalid. This Xwill be covered later when precedence is discussed. These operators perform Xtheir respective logical operations on all pairs of adjacent bits, the Xresult from the first and last bits going into the first bit of the result. XThe effect is that of rotating the operand one place to the right and XANDing, ORing, or XORing with its initial value. Thus, #&77 (binary = X1001101) is binary 0000000000000100 = 4, #V77 is binary 1000000001101111 = X32879, and #V77 is binary 1000000001101011 = 32875. X X3.4.3 PRECEDENCE X XPrecedence of operators is as follows: X X X X X X X X X X X X [1] X(The remainder of this page intentionally left blank) X X X X X X X X X X X X X X_________________ X1) Keep in mind that the aim in designing INTERCAL was to have no X precedents. X X X X X X X XThis precedence (or lack thereof) may be overruled by grouping expressions Xbetween pairs of sparks (') or rabbit-ears ("). Thus '#165c/#203'~#358 X(binary value '10100101c11001011'~101100110) has the value 15, but X#165c/'#203~#358' has the value 34815, and #165c/#203~#358 is invalid Xsyntax and is completely valueless (except perhaps as an educational tool Xto the programmer). A unary operator is applied to a sparked or rabbit-eared Xexpression by inserting the operator immediately following the opening spark Xor ears. Thus, the invalid expression #V&123, which was described earlier, Xcould be coded as 'V#&123' or 'V"{"'. Note: In the interests of Xsimplifying the sometimes overly-complex form of expressions, INTERCAL allows Xa spark-spot combination ('.) to be replaced with a wow (!). Thus '.1~.2' Xis equivalent to !1~.2', and 'V.1c.2' is equivalent to "V!1c.2'". X XCombining a rabbit-ears with a spot to form a rabbit (V) is not permitted, Xalthough the programmer is free to use it should he find an EBCDIC reader Xwhich will properly translate a 12-3-7-8 punch. X XSparks and/or rabbit-ears must also be used to distinguish among such Xotherwise ambiguous subscripted and multiply-subscripted expressions as: X X ,1 SUB #1 ~ #2 X ,1 SUB ,2 SUB #1 #2 #3 X ,1 SUB " ,2 SUB " ,3 SUB #1 " #2 " " #3 " X XThe third case may be isolated into either of its possible interpretations Xby simply changing some pairs of rabbit-ears to sparks, instead of adding Xmore ears (which would only confuse the issue further). Ambiguous cases are Xdefined as those for which the compiler being used finds a legitimate Xinterpretation which is different from that which the user had in mind. See Xalso section 8.1. X X X X X X X4. STATEMENTS X XIn this section is described the format of INTERCAL statements. X X4.1 GENERAL FORMAT X XStatements may be entered in 'free format'. That is, more than one statement Xmay occur on a single card, and a statement may begin on one card and end Xon a later one. Note that if this is done, all intervening cards and portions Xthereof must be part of the same statement. That this restriction is necessary Xis immediately apparent from the following example of what might occur if Xstatements could be interlaced. X X DO .1 <- ".1c/'&:51~"#V1c!12~;&75SUB"V'V.1~ X DO .2 <- '"!1c/"&';V79SUB",&7SUB:173"'~!V9c X .2'c,&1SUB:5~#33578"'"'"~'#65535c/"V'V#&85'"' X #8196'"'~.1"c.2'~'#&5c/"'#1279c/#4351'~#65535"' X XThe above statements are obviously meaningless. (For that matter, so are Xthe statements X X DO .1 <- ".1c/"&:51~"#V1C!12~;&75SUB"V'V.1~ X .2'C,&1SUB:5~/333578"'"'"~#65535c/"V'V#&85'"' X DO .2 <- '"!1c/"&';V79SUB",&7SUB:173"'~!V9c X #8196'"'~.1"c.2'~'#&5c/"'#1279c!4351'~#65535"' X Xbut this is not of interest here.) X XSpaces may be used freely to enhance program legibility (or at least reduce Xprogram illegibility), with the restriction that no word of a statement Xidentifier (see section 4.3) may contain any spaces. X X4.2 LABELS X XA statement may begin with a LOGICAL LINE LABEL enclosed in wax-wane pairs X(()). A statement may not have more than one label, although it is possible Xto omit the label entirely. A line label is any integer from 1 to 65535, Xwhich must be unique within each program. The user is cautioned, however, Xthat many line labels between 1000 and 1999 are used in the INTERCAL System XLibrary functions. X X4.3 IDENTIFIERS AND QUALIFIERS X XAfter the line label (if any), must follow one of the following statement Xidentifiers: DO, PLEASE, or PLEASE DO. These may be used interchangeably to Ximprove the aesthetics of the program. The identifier is then followed by Xeither, neither, or both of the following optional parameters (qualifiers): X(1) either of the character strings NOT or N'T, which causes the statement Xto be automatically abstained from (see section 4.4.9) when execution Xbegins, and (2) a number between 0 and 100, preceded by a double-oh-seven X(%), which causes the statement to have only the specified percent chance Xof being executed each time it is encountered in the course of execution. X X X X X X X X4.4 STATEMENTS X XFollowing the qualifiers (or, if none are used, the identifier) must occur Xone of the 13 valid operations. (Exception: see section 4.5.) These are Xdescribed individually in sections 4.4.1 through 4.4.13. X X4.4.1 CALCULATE X XThe INTERCAL equivalent of the half-mesh (=) in FORTRAN, BASIC, PL/I, and Xothers, is represented by an angle (<) followed by a worm (-). This Xcombination is read 'gets'. 32-bit variables may be assigned 16-bit values, Xwhich are padded on the left with 16 zero bits. 16-bit variables may be Xassigned 32-bit values only if the value is less than 65535. Thus, to Xinvert the least significant bit of the first element of 16-bit X2-dimensional array number 1, one could write: X X ,1SUB#1#1 <- 'V,1SUB#1#1c/#1'~'#0c/#65535' X XSimilarly to SNOBOL and SPITBOL, INTERCAL uses the angle-worm to define the Xdimensions of arrays. An example will probably best describe the format. XTo define 32-bit array number 7 as 3-dimensional, the first dimension being Xseven, the second being the current value of 16-bit variable number seven, Xand the third being the current value of the seventh element of 16-bit array Xnumber seven (which is one-dimensional) mingled with the last three bits of X32-bit variable number seven, one would write (just before they came to take Xhim away): X X ;7 <- #7 BY .7 BY ",7SUB#7"c/':7~#7' X XThis is, of course, different from the statement: X X ;7 <- #7 BY .7 BY ,7SUB"#7c/':7~#7'" X XINTERCAL also permits the redefining of array dimensioning, which is done Xthe same way as is the initial dimensioning. All values of items in an array Xare lost upon redimensioning, unless they have been STASHed (see section X4.4.5), in which case restoring them also restores the old dimensions. X X X X X X X X4.4.2 NEXT X XThe NEXT statement is used both for subroutine calls and for unconditional Xtransfers. This statement takes the form: X X DO (label) NEXT X X(or, of course, X X PLEASE DO (label) NEXT X Xetc.), where (label) represents any logical line label which appears in the Xprogram. The effect of such a statement is to transfer control to the Xstatement specified, and to store in a push down list (which is initially Xempty) the location from which the transfer takes place. Items may be Xremoved from this list and may be discarded or used to return to the Xstatement immediately following the NEXT statement. These operations are Xdescribed in sections 4.4.3 and 4.4.4 respectively. The programmer is Xgenerally advised to discard any stack entries which he does not intend to Xutilize, since the stack has a maximum depth of 79 entries. A program's Xattempting to initiate an 80th level of NEXTing will result on the fatal Xerror message, "PROGRAM HAS DISAPPEARED INTO THE BLACK LAGOON." X X4.4.3 FORGET X XThe statement PLEASE FORGET exp, where exp represents any expression X(except colloquial and facial expressions), causes the expression to be Xevaluated, and the specified number of entries to be removed from the XNEXTing stack and discarded. An attempt to FORGET more levels of NEXTing Xthan are currently stacked will cause the stack to be emptied, and no error Xcondition is indicated. This is because the condition is not considered to Xbe an error. As described in section 4.4.2, it is good programming practice Xto execute a DO FORGET #1 after using a NEXT statement as an unconditional Xtransfer, so that the stack does not get cluttered up with unused entries: X X DO (123) NEXT X . X . X (123) DO FORGET #1 X X4.4.4 RESUME X XThe statement PLEASE RESUME exp has the same effect as FORGET, except that Xprogram control is returned to the statement immediately following the NEXT Xstatement which stored in the stack the last entry to be removed. Note that Xa rough equivalent of the FORTRAN computed GO TO and BASIC ON exp GO TO is Xperformed by a sequence of the form: X X DO (1) NEXT X . X . X (1) DO (2) NEXT X PLEASE FORGET #1 X . X . X (2) DO RESUME .1 X XUnlike the FORGET statement, an attempt to RESUME more levels of NEXTing than Xbeen stacked will cause program termination. See also section 4.4.11. X X X4.4.5 STASH X XSince subroutines are not explicitly implemented in INTERCAL, the NEXT and XRESUME statements must be used to execute common routines. However, as Xthese routines might use the same variables as the main program, it is Xnecessary for them to save the values of any variables whose values they Xalter, and later restore them. This process is simplified by the STASH Xstate ment, which has the form DO STASH list, where list represents a Xstring of one or more variable or array names, separated by intersections X(+). Thus X X PLEASE STASH .123+:123+,123 X Xstashes the values of two variables and one entire array. The values are Xleft intact, and copies thereof are saved for later retrieval by (what else?) Xthe RETRIEVE statement (see section 4.4.6). It is not possible to STASH Xsingle array items. X X4.4.6 RETRIEVE X XPLEASE RETRIEVE list restores the previously STASHed values of the variables Xand arrays named in the list. If a value has been stashed more than once, Xthe most recently STASHed values are RETRIEVEd, and a second RETRIEVE will Xrestore the second most recent values STASHed. Attempting to RETRIEVE a Xvalue which has not been STASHed will result in the error message, "THROW XSTICK BEFORE RETRIEVING." X X4.4.7 IGNORE X XThe statement DO IGNORE list causes all subsequent statements to have no Xeffect upon variables and/or arrays named in the list. Thus, for example, Xafter the sequence X X DO .1 <- #1 X PLEASE IGNORE .1 X DO .1 <- #0 X X16-bit variable number 1 would have the value 1, not 0. Inputting (see Xsection 4.4.12) into an IGNOREd variable also has no effect. The condition Xis annulled via the REMEMBER statement (see section 4.4.8). Note that, when Xa variable is being IGNOREd, its value, though immutable, is still Xavailable for use in expressions and the like. X X4.4.8 REMEMBER X XPLEASE REMEMBER list terminates the effect of the IGNORE statement for all Xvariables and/or arrays named in the list. It does not matter if a variable Xhas been IGNOREd more than once, nor is it an error if the variable has not Xbeen IGNOREd at all. X X4.4.9 ABSTAIN X XINTERCAL contains no simple equivalent to an IF statement or computed GO XTO, making it difficult to combine similar sections of code into a single Xroutine which occasionally skips around certain statements. The IGNORE Xstatement (see section 4.4.7) is helpful in some cases, but a more viable Xmethod is often required. In keeping with the goal of INTERCAL having Xnothing in common with any other language, this is made possible via the XABSTAIN statement. X XThis statement takes on one of two forms. It may not take on both at any one Xtime. DO ABSTAIN FROM (label) causes the statement whose logical line label Xis (label) to be abstained form. PLEASE ABSTAIN FROM gerund list causes all Xstatements of the specified type(s) to be abstained from, as in X X PLEASE ABSTAIN FROM STASHING X PLEASE ABSTAIN FROM IGNORING + FORGETTING X PLEASE ABSTAIN FROM NEXTING X or PLEASE ABSTAIN FROM CALCULATING X XStatements may also be automatically abstained from at the start of Xexecution via the NOT or N'T parameter (see section 4.3). X X XIf, in the course of execution, a statement is encountered which is being Xabstained from, it is ignored and control passes to the next statement in Xthe program (unless it, too, is being abstained from). X XThe statement DO ABSTAIN FROM ABSTAINING is perfectly valid, as is DO ABSTAIN XFROM REINSTATING (although this latter is not usually recommended). However, Xthe statement DO ABSTAIN FROM GIVING UP is not accepted, even though DON'T XGIVE UP is. X X4.4.10 REINSTATE X XThe REINSTATE statement, like the ABSTAIN, takes as an argument either a Xline label or a gerund list. No other form of argument is permitted. For Xexample, the following is an invalid argument: X X Given: x=/0, y=/0, Prove: x+y=0 X Since x=/0, then x+1=/1, x+a=/a, x+y=/y. X Thus x+y =/ anything but 0. X Since x+y cannot equal anything but 0, x+y=0. X X Q.E.D. X XREINSTATEment nullifies the effects of an abstention. Either form of XREINSTATEment can be used to "free" a statement, regardless of whether the Xstatement was abstained from by gerund list, line label, or NOT. Thus, XPLEASE REINSTATE REINSTATING is not necessarily an irrelevant statement, Xsince it might free a DON'T REINSTATE command or a REINSTATE the line label Xof which was abstained from. However, DO REINSTATE GIVING UP is invalid, Xand attempting to REINSTATE a GIVE UP statement by line label will have no Xeffect. Note that this insures that DON'T GIVE UP will always be a X"do-nothing" statement. X X4.4.11 GIVE UP X XPLEASE GIVE UP is used to exit from a program. It has the effect of a PLEASE XRESUME #80. DON'T GIVE UP, as noted in section 4.4.10, is effectively a null Xstatement. X X4.4.12 Input X XInput is accomplished with the statement DO WRITE IN list, where list Xrepresents a string of variables and/or elements or arrays, separated by Xintersections. Numbers are represented on cards, each number on a separate Xcard, by spelling out each digit (in English) and separating the digits Xwith one or more spaces. A zero (0) may be spelled as either ZERO or OH. XThus the range of (32-bit) input values permissible extends from ZERO (or XOH) through FOUR TWO NINE FOUR NINE SIX SEVEN TWO NINE FIVE. X XAttempting to write in a value greater than or equal to SIX FIVE FIVE THREE XSIX for a 16-bit variable will result in the error message, "DON'T BYTE OFF XMORE THAN YOU CAN CHEW." X X4.4.13 Output X XValues may be output to the printer, one value per line, via the statement XDO READ OUT list, where the list contains variables, array elements, and/or Xconstants. Output is in the form of "extended" Roman numerals (also called X _ X"butchered" Roman numerals), with an overline ( ) indicating the value below Xis "times 1000", and lower-case letters indicating "times 1000000". Zero Xis indicated by an overline with no character underneath. Thus, the range X _ __ _______ Xof (32-bit) output values possible is from through ivccxcivCMLXVIICCXCV. XNote: For values whose residues modulo 1000000 are less than 4000, M is Xused to represent 1000; for values whose residues are 4000 or greater, I is X __ Xused. Thus #3999 would read out as MMMIM while #4000 would read out as IV. X _ _ _ XSimilar rules apply to the use of M and i for 1000000, and to that of m and i Xfor 1000000000. X X X X X X X X4.5 Comments X XUnrecognizable statements, as noted in section 7, are flagged with a splat X(*) during compilation, and are not considered fatal errors unless they Xare encountered during execution, at which time the statement (as input at Xcompilation time) is printed and execution is terminated. This allows for Xan interesting (and, by necessity, unique) means of including comments in Xan INTERCAL listing. For example, the statement: X X* PLEASE NOTE THAT THIS LINE HAS NO EFFECT X Xwill be ignored during execution due to the inclusion of the NOT qualifier. XUser-supplied error messages are also easy to implement: X X* DO SOMETHING ABOUT OVERFLOW IN ;3 X Xas are certain simple conditional errors: X X* (123) DON'T YOU REALIZE THIS STATEMENT SHOULD ONLY BE ENCOUNTERED X ONCE? X PLEASE REINSTATE (123) X XThis pair of statements will cause an error exit the second time they are Xencountered. Caution!! The appearance of a statement identifier in an Xintended comment will be taken as the beginning of a new statement. Thus, Xthe first example on the preceding page could not have been: X X* PLEASE NOTE THAT THIS LINE DOES NOTHING X XThe third example, however, is valid, despite the appearance of two cases Xof D-space-O, since INTERCAL does not ignore extraneous spaces in statement Xidentifiers. X X X X X X X5. SUBROUTINE LIBRARY X XINTERCAL provides several built-in subroutines to which control can be Xtransferred to perform various operations. These operations include many Xuseful functions which are not easily representable in INTERCAL, such as Xaddition, subtraction, etc. X X5.1 Usage X XIn general, the operands are .1, .2, etc., or :1, :2, etc., and the result(s) Xare stored in what would have been the next operand(s). For instance, one Xroutine adds .1 to .2 and store the sum in .3, with .4 being used to indicate Xoverflow. All variables not used for results are left unchanged. X X5.2 Available Functions X XAt the time of this writing, only the most fundamental operations are offered Xin the library, as a more complete selection would require prohibitive time Xand coree to implement. These functions, along with their corresponding entry Xpoints (entered via DO (entry) NEXT) are listed below. X X (1000) .3 <- .1 plus .2, error exit on overflow X (1009) .3 <- .1 plus .2 X .4 <- #1 if no overflow, else .4 <- #2 X (1010) .3 <- .1 minus .2, no action on overflow X (1020) .1 <- .1 plus #1, no action on overflow X (1030) .3 <- .1 times .2, error exit on overflow X (1039) .3 <- .1 times .2 X .4 <- #1 if no overflow, else .4 <- #2 X (1040) .3 <- .1 divided by .2 X .3 <- #0 if .2 is #0 X (1050) .2 <- :1 divided by .1, error exit on overflow X .2 <- #0 if .1 is #0 X X (1500) :3 <- :1 plus :2, error exit on overflow X (1509) :3 <- :1 plus :2 X :4 <- #1 if no overflow, else :4 <- #2 X (1510) :3 <- :1 minus :2, no action on overflow X (1520) :1 <- .1 concatenated with .2 X (1525) This subroutine is intended solely for internal X use within the subroutine library and is therefore X not described here. Its effect is to shift .3 X logically 8 bits to the left. X (1530) :1 <- .1 times .2 X (1540) :3 <- :1 times :2, error exit on overflow X (1549) :3 <- :1 times :2 X :4 <- #1 if no overflow, else :4 <- #2 X (1550) :3 <- :1 divided by :2 X :3 <- #0 if :2 is #0 X X (1900) .1 <- uniform random no. from #1 to #65535 X (1910) .2 <- normal random no. from #0 to .1, with X standard deviation .1 divided by #12 X X X X X X X X6. PROGRAMMING HINTS X XFor the user looking to become more familiar with the INTERCAL language, we Xpresent in this section an analysis of a complex program, as well as some Xsuggested projects for the ambitious programmer. X XConsidering the effort involved in writing an INTERCAL program, it was Xdecided in putting together this manual to use an already existing program Xfor instructive analysis. Since there was only one such program available, Xwe have proceeded to use it. It is known as the "INTERCAL System Library." X X6.1 Description X XThe program listing begins on the second page following. It is in the same Xformat as would be produced by the Princeton INTERCAL compiler in FORMAT Xmode with WDITH=62 (see section 8). For a description of the functions Xperformed by the Library, see section 5.2. X X6.2 Analysis X XWe shall not attempt to discuss here the algorithms used, but rather we Xshall point out some of the general techniques applicable to a wide range Xof problems. X XStatements 10, 14, 15, and 26 make up a virtual "computed GO TO". When Xstatement 10 is executed, control passes eventually to statement 16 or 11, Xdepending on whether .5 contains #1 or #2, respectively. The value of .5 Xis determined in statement 9, which demonstrates another handy technique. XTo turn an expression, exp, with value #0 or #1, into #1 or #2 (for use in Xa "GO TO"), use "V'exp'c/#1"~#3. To reverse the condition (i.e., convert #0 Xto #2 and leave #1 alone) use "V'exp'c/#2"~#3. X XCertain conditions are easily checked. For example, to test for zero, Xselect the value from itself and select the bottom bit (see statement 54). XTo test for all bits being 1's, select the value from itself and select the Xtop bit (see statement 261). The test to greater than, performed in Xstatements 192 and 193 on 32-bit values, employs binary logical operations, Xwhich are performed as follows: X X 'V.1c.2'~'#0c/#65535' X Xfor 16-bit values or, for 32-bit values: X X "'V":1~'#65535c30'"c/":2~'#65535c/#0'"'~'#0 X c/#65535'"c/"'V":1~'#0c/#65535'"c/":2~'#0 X c/#65535'"'~'#0c/#65535'" X X(The proofs are left as an exercise to the reader.) X XTesting for greater-than with 16-bit values is somewhat simpler and is done Xwith the pair of statements: X X DO .C <- 'V.Ac.B'~'#0c/#65535' X DO .C <- '&"'.A~.C'~'"V'V.C~.C'c/#32768" X ~"#0c/#65535"'"c/".C~.CZ''ZZZ`#1 X XThis sets .C (a dummy variable) to #1 if .A > .B, and #0 otherwise. The Xexpression may be expanded as described above to instead set .C to #1 or X#2. X XNote also in statement 220 the occurrence of ~"#65535c65535". Although Xthese operations select the entire value, they are not extraneous, as they Xensure that the forthcoming Vs will be operating on 32-bit values. X XIn several virtual computed GO TOs the DO FORGET #1 (statement 15 in the Xearlier example) has been omitted, since the next transfer of control would Xbe a DO RESUME #1. By making this a DO RESUME #2 instead, the FORGET may Xbe forgotten. X XIn statement 64, note that .2 is STASHed twice by a single statement. This Xis perfectly legal. X XLastly, note in statements 243 and 214 respectively, expressions for Xshifting 16- and 32-bit variables logically one place to the left. XStatement 231 demonstrates right-shifting for 32-bit variables. X XMIKE GETS TO INSERT THE PROGRAM HERE! X X6.3 Program Listing X X 1 (1000) PLEASE IGNORE .4 X 2 PLEASE ABSTAIN FROM (1005) X 3 (1009) DO STASH .1 + .2 + .5 + .6 X 4 DO .4 <- #1 X 5 DO (1004) NEXT X 6 (1004) PLEASE FORGET #1 X 7 DO .3 <- 'V.1c.2'~'#0c/#65535' X 8 DO .6 <- '&.1c.2'~'#0c/#65535' X 9 PLEASE DO .5 <- "V!6~#32768'c/#1"~#3 X 10 DO (1002) NEXT X 11 DO .4 <- #2 X 12 (1005) DO (1006) NEXT X* 13 (1999) DOUBLE OR SINGLE PRECISION OVERFLOW X 14 (1002) DO (1001) NEXT X 15 (1006) PLEASE FORGET #1 X 16 DO .5 <- 'V"!6~.6'~#1"c/#1'~#3 X 17 DO (1003) NEXT X 18 DO .1 <- .3 X 19 DO .2 <- !6c/#0'~'#32767c/#1' X 20 DO (1004) NEXT X 21 (1003) DO (1001) NEXT X 22 DO REINSTATE (1005) X 23 (1007) PLEASE RETRIEVE .1 + .2 + .5 + .6 X 24 DO REMEMBER .4 X 25 PLEASE RESUME #2 X 26 (1001) DO RESUME .5 X 27 (1010) DO STASH .1 + .2 + .4 X 28 DO .4 <- .1 X 29 DO .1 <- 'V.2c/#65535'~'#0c/#65535' X 30 DO (1020) NEXT X 31 PLEASE DO .2 <- .4 X 32 PLEASE DO (1009) NEXT X 33 DO RETRIEVE .1 + .2 + .4 X 34 PLEASE RESUME #1 X 35 (1020) DO STASH .2 + .3 X 36 DO .2 <- #1 X 37 PLEASE DO (1021) NEXT X 38 (1021) DO FORGET #1 X 39 DO .3 <- "V!1~.2'c/#1"~#3 X 40 PLEASE DO .1 <- 'V.1c.2'~'#0c/#65535' X 41 DO (1022) NEXT X 42 DO .2 <- !2c/#0'~'#32767c/#1' X 43 DO (1021) NEXT X 44 (1023) PLEASE RESUME .3 X 45 (1022) DO (1023) NEXT X 46 PLEASE RETRIEVE .2 + .3 X 47 PLEASE RESUME #2 X 48 (1030) DO ABSTAIN FROM (1033) X 49 PLEASE ABSTAIN FROM (1032) X 50 (1039) DO STASH :1 + .5 X 51 DO (1530) NEXT X 52 DO .3 <- :1~#65535 X 53 PLEASE DO .5 <- :1~'#65280c/#65280' X 54 DO .5 <- 'V"!5~.5'~#1"c/#1'~#3 X 55 DO (1031) NEXT X 56 (1032) DO (1033) NEXT X 57 DO (1999) NEXT X 58 (1031) DO (1001) NEXT X 59 (1033) DO .4 <- .5 X 60 DO REINSTATE (1032) X 61 PLEASE REINSTATE (1033) X 62 DO RETRIEVE :1 + .5 X 63 PLEASE RESUME #2 X 64 (1040) PLEASE STASH .1 + .2 + .2 + :1 + :2 + :3 X 65 DO .2 <- #0 X 66 DO (1520) NEXT X 67 DO STASH :1 X 68 PLEASE RETRIEVE .2 X 69 DO .1 <- .2 X 70 DO .2 <- #0 X 71 PLEASE DO (1520) NEXT X 72 DO :2 <- :1 X 73 DO RETRIEVE .1 + .2 + :1 X 74 DO (1550) NEXT X 75 PLEASE DO .3 <- :3 X 76 DO RETRIEVE :1 + :2 + :3 X 77 DO RESUME #1 X 78 (1050) PLEASE STASH :2 + :3 + .5 X 79 DO :2 <- .1 X 80 PLEASE DO (1550) NEXT X 81 DO .5 <- :3~'#65280c/#65280' X 82 DO .5 <- 'V"!5~.5'~#1"c/#1'~#3 X 83 DO (1051) NEXT X 84 DO (1999) NEXT X 85 (1051) DO (1001) NEXT X 86 DO .2 <- :3 X 87 PLEASE RETRIEVE :2 + :3 + .5 X 88 DO RESUME #2 X 89 (1500) PLEASE ABSTAIN FROM (1502) X 90 PLEASE ABSTAIN FROM (1506) X 91 (1509) PLEASE STASH :1 + .1 + .2 + .3 + .4 + .5 + .6 X 92 DO .1 <- :1~#65535 X 93 PLEASE DO .2 <- :2~#65535 X 94 DO (1009) NEXT X 95 DO .5 <- .3 X 96 PLEASE DO .6 <- .4 X 97 DO .1 <- :1~'#65280c/#65280' X 98 DO .2 <- :2~'#65280c/#65280' X 99 DO (1009) NEXT X 100 DO .1 <- .3 X 101 PLEASE DO (1503) NEXT X 102 DO .6 <- .4 X 103 DO .2 <- #1 X 104 DO (1009) NEXT X 105 DO .1 <- .3 X 106 DO (1501) NEXT X 107 (1504) PLEASE RESUME .6 X 108 (1503) DO (1504) NEXT X 109 (1501) DO .2 <- .5 X 110 DO .5 <- 'V"'&.6c.4'~#1"c/#2'~#3 X 111 DO (1505) NEXT X 112 (1506) DO (1502) NEXT X 113 PLEASE DO (1999) NEXT X 114 (1505) DO (1001) NEXT X 115 (1502) DO :4 <- .5 X 116 DO (1520) NEXT X 117 DO :3 <- :1 X 118 PLEASE RETRIEVE :1 + .1 + .2 + .3 + .4 + .5 + .6 X 119 DO REINSTATE (1502) X 120 DO REINSTATE (1506) X 121 PLEASE RESUME #3 X 122 (1510) DO STASH :1 + :2 + :4 X 123 DO :1 <- "'V/":2~'#65535c/#0'"c/#65535'~'#0c/#6553 X 5'"c/"'V":2~'#0c/#65535'"c/#65535'~'#0c65535 X '" X 124 DO :2 <- #1 X 125 DO (1509) NEXT X 126 PLEASE RETRIEVE :1 X 127 DO :2 <- :3 X 128 PLEASE DO (1509) NEXT X 129 DO RETRIEVE :2 + :4 X 130 PLEASE RESUME #1 X 131 (1520) PLEASE STASH .3 + .4 X 132 DO .3 <- .1~#43690 X 133 DO (1525) NEXT X 134 PLEASE DO .4 <- 'V.3c/".2~#43690"'~'#0c/#65535' X 135 DO .3 <- .1~#21845 X 136 PLEASE DO (1525) NEXT X 137 DO :1 <- .4c/"'V.3c/".2~#21845"'~'#0c/#65535'" X 138 PLEASE RETRIEVE .3 + .4 X 139 DO RESUME #1 X 140 (1525) DO .3 <- '"'"'"!3c/#0'~'#32767c/#1'"c/#0'~'#32767 X c/#1'"c/#0'~'#16383c/#3'"c/#0'~'#4095c/#15' X 141 PLEASE RESUME #1 X 142 (1530) DO STASH :2 + :3 + .3 + .5 X 143 DO :1 <- #0 X 144 DO :2 <- .2 X 145 DO .3 <- #1 X 146 DO (1535) NEXT X 147 (1535) PLEASE FORGET #1 X 148 DO .5 <- "V!1~.3'c/#1"~#3 X 149 DO (1531) NEXT X 150 DO (1500) NEXT X 151 DO :1 <- :3 X 152 PLEASE DO (1533) NEXT X 153 (1531) PLEASE DO (1001) NEXT X 154 (1533) DO FORGET #1 X 155 DO .3 <- !3c/#0'~'#32767c/#1' X 156 DO :2 <- ":2~'#0c/#65535'"c/"'":2~'#32767c/#0'"c/# X 0'~'#32767c/#1'" X 157 PLEASE DO .5 <- "V!3~.3'c/#1"~#3 X 158 DO (1532) NEXT X 159 DO (1535) NEXT X 160 (1532) DO (1001) NEXT X 161 PLEASE RETRIEVE :2 + :3 + .3 + .5 X 162 DO RESUME #2 X 163 (1540) PLEASE ABSTAIN FROM (1541) X 164 DO ABSTAIN FROM (1542) X 165 (1549) PLEASE STASH :1 + :2 + :4 + :5 + .1 + .2 + .5 X 166 DO .1 <- :1~#65535 X 167 PLEASE DO .2 <- :2~'#65280c/#65280' X 168 DO .5 <- :1~'#65280c/#65280' X 169 DO (1530) NEXT X 170 DO :3 <- :1 X 171 DO .2 <- :2~#65535 X 172 PLEASE DO (1530) NEXT X 173 DO :5 <- :1 X 174 DO .1 <- .5 X 175 DO (1530) NEXT X 176 DO :4 <- :1 X 177 PLEASE DO :1 <- ":3~'#65280c/#65280'"c/":5~'652 X 80c/#65280'" X 178 DO .5 <- ':1~:1'~#1 X 179 DO .2 <- :2~'#65280c/#65280' X 180 DO (1530) NEXT X 181 PLEASE DO .5 <- '"':1~:1'~#1"c.5'~#3 X 182 DO .1 <- :3~#65535 X 183 DO .2 <- #0 X 184 DO (1520) NEXT X 185 PLEASE DO :2 <- :1 X 186 PLEASE DO .1 <- :4~#65535 X 187 DO (1520) NEXT X 188 DO (1509) NEXT X 189 DO .5 <- !5c/":4~#3"'~#15 X 190 DO :1 <- :3 X 191 DO :2 <- :5 X 192 DO (1509) NEXT X 193 PLEASE DO .5 <- !5c/"4~#3"'~#63 X 194 DO .5 <- 'V"!5~.5'~#1"c/#1'~#3 X 195 PLEASE RETRIEVE :4 X 196 (1541) DO :4 <- .5 X 197 DO (1543) NEXT X 198 (1542) DO (1544) NEXT X 199 PLEASE DO (1999) NEXT X 200 (1543) DO (1001) NEXT X 201 (1544) DO REINSTATE (1541) X 202 PLEASE REINSTATE (1542) X 203 PLEASE RETRIEVE :1 + :2 + :5 + .1 + .2 + .5 X 204 DO RESUME #2 X 205 (1550) DO STASH :1 + :4 + :5 + .5 X 206 DO :3 <- #0 X 207 DO .5 <- 'V"':2~:2'~#1"c/#1'~#3 X 208 PLEASE DO (1551) NEXT X X X X X X X6.4 Programming Suggestions X XFor the novice INTERCAL programmer, we provide here a list of suggested XINTERCAL programming projects: X XWrite an integer exponentiation subroutine. :1 <- .1 raised to the .2 power. X XWrite a double-precision sorting subroutine. Given 32-bit array ;1 of size X:1, sort the contents into numerically increasing order, leaving the results Xin ;1. X XGenerate a table of prime numbers. X XPut together a floating-point library, using 32-bit variables to represent Xfloating-point numbers (let the upper half be the mantissa and the lower Xhalf be the characteristic). The library should be capable of performing Xfloating-point addition, subtraction, multiplication, and division, as well Xas the natural logarithm function. X XProgram a Fast Fourier Transform (FFT). This project would probably entail Xthe writing of the floating-point library as well as sine and cosine functions. X XCalculate, to :1 places, the value of pi. X X X X X X X X7. ERROR MESSAGES X XDue to INTERCAL's implementation of comment lines (see section 4.5), most Xerror messages are produced during execution instead of during compilation. XAll errors except those not causing immediate termination of program execution Xare treated as fatal. X X7.1 Format X XAll error messages appear in the following form: X X ICLnnnI (error message) X ON THE WAY TO STATEMENT nnnn X CORRECT SOURCE AND RESUBMIT X XThe message varies depending upon the error involved. For undecodable Xstatements the message is the statement itself. The second line tells Xwhich statement would have been executed next had the error not occurred. XNote that if the error is due to 80 attempted levels of NEXTing, the Xstatement which would have been executed next need not be anywhere near the Xstatement causing the error. X X7.2 Messages X XBrief descriptions of the different error types are listed below according Xto message number. X X 000 An undecodable statement has been encountered in the course of X execution. Note that keypunching errors can be slightly disastrous, X since if 'FORGET' were misspelled F-O-R-G-E-R, the results would X probably not be those desired. Extreme misspellings may have even X more surprising consequences. For example, misspelling 'FORGET' X R-E-S-U-M-E could have drastic results. X X 017 An expression contains a syntax error. X X 079 Improper use has been made of statement identifiers. X X 099 Improper use has been made of statement identifiers. X X 123 Program has attempted 80 levels of NEXTing. X X 129 Program has attempted to transfer to a non-existent line label. X X 139 An ABSTAIN or REINSTATE statement references a non-existent line label. X X 182 A line label has been multiply defined. X X 197 An invalid line label has been encountered. X X 200 An expression involves an unidentified variable. X X 240 An attempt has been made to give an array a dimension of zero. X X 241 Invalid dimensioning information was supplied in defining or using X an array. X X 275 A 32-bit value has been assigned to a 16-bit variable. X X 436 A retrieval has been attempted for an unSTASHed value. X X 533 A WRITE IN statement or interleave (c) operation has produced a X value requiring over 32 bits to represent. X X 562 Insufficient data. X X 579 Input data is invalid. X X 621 The expression of a RESUME statement evaluated to #0. X X 632 Program execution was terminated via a RESUME statement instead of X GIVE UP. X X 633 Execution has passed beyond the last statement of the program. X X 774 A compiler error has occurred (see section 8.1). X X 778 An unexplainable compiler error has occurred (see J. Lyon or B. Woods). X X X X X X X [3] X TONSIL A X X X XThe Official INTERCAL Character Set X XTabulated on page XX are all the characters used in INTERCAL, excepting Xletters and digits, along with their names and interpretations. Also Xincluded are several characters not used in INTERCAL, which are presented Xfor completeness and to allow for future expansion. X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X_____________________ X3) Since all other reference manuals have Appendices, it was decided that Xthe INTERCAL manual should contain some other type of removable organ. X X4) This footnote intentionally unreferenced. X X X X X X X_______________________________________________________________________ X| | X|Character Name Use (if any) | X| | X| . spot identify 16-bit variable | X| : two-spot identify 32-bit variable | X| , tail identify 16-bit array | X| ; hybrid identify 32-bit array | X| # mesh identify constant | X| = half-mesh | X| ' spark grouper | X| ` backspark | X| ! wow equivalent to spark-spot | X| ? what unary exlusive OR (ATARI only)| X| " rabbit-ears grouper | X| !` rabbit equivalent to ears-spot | X| | spike | X| % double-oh-seven percentage qualifier | X| - worm used with angles | X| < angle used with worms | X| > right angle | X| ( wax precedes line label | X| ) wane follows line label | X| [ U turn | X| ] U turn back | X| { embrace | X| } bracelet | X| * splat flags invalid statements | X| & ampersand[5] unary logical AND | X| V V unary logical OR | X| (or book) | X| V- bookworm unary exclusive OR | X| (or universal qualifier) | X| $ big money | X| c| change binary mingle | X| ~ sqiggle binary select | X| _ flat worm | X| overline indicates "times 1000" | X| + intersection separates list items | X| / slat | X| \ backslat | X| @ whirlpool | X| -' hookworm | X| ^ shark | X| (or simply sharkfin) | X| #I[] blotch | X|_____________________________________________________________________| X X X Table 2 (top view). INTERCAL character set. X X__________________________________ X X5) Got any better ideas? X X XNOTES ON THE ATARI IMPLEMENTATION X XThe Atari implementation of INTERCAL differs from the original Princeton Xversion primarily in the use of ASCII rather than EBCDIC. Since there is no X"change" sign (c) in ASCII, we have substituted the "big money" ($) as the Xmingle operator. We feel that this correctly represents the increasing cost Xof software in relation to hardware. (Consider that in 1970 one could get XRUNOFF for free, to run on a $20K machine, whereas today a not quite as Xpowerful formatter costs $99 and runs on a $75 machine.) We also feel that Xthere should be no defensible contention that INTERCAL has any sense. XAlso, since overpunches are difficult to read on the average VDT, the Xexclusive-or operator may be written ?. This correctly expresses the Xaverage person's reaction on first encountering exclusive-or, especially on Xa PDP-11. Note that in both of these cases, the over-punched symbol may Xalso be used if one is masochistic, or concerned with portability to the XPrinceton compiler. The correct over-punch for "change" is "c/" Xand the correct over-punch for V is "V-". These codes will be Xproperly printed if you have a proper printer, and the corresponding EBCDIC Xcode will be produced by the /IBM option on the LIST command. X END-of-intercal.man echo file: intercal.tex sed 's/^X//' >intercal.tex << 'END-of-intercal.tex' X% -*- Mode: TeX -*- X% for LaTeX X\documentstyle[ick]{article} X X\title{ The INTERCAL Programming Language \\ X Reference Manual} X\author{ Donald R. Woods \& James M. Lyon} X\date{ Copyright Donald R. Woods \& James M. Lyon 1973} X X\begin{document} X X\maketitle X\thispagestyle{empty} X\newpage X X\tableofcontents X\thispagestyle{empty} X\newpage X\setcounter{page}{1} X X\section{Introduction} X XThe names you are about to ignore are true. However, the story has been Xchanged significantly. Any resemblance of the programming language Xportrayed here to other programming languages, living or dead, is purely Xcoincidental. X X\subsection{Origin and Purpose} X XThe INTERCAL programming language was designed the morning of May 26, 1972 Xby Donald R. Woods and James M. Lyon, at Princeton University. Exactly Xwhen in the morning will become apparent in the course of this manual. It Xwas inspired by one ambition; to have a compiler language which has nothing Xat all in common with any other major language. By 'major' was meant Xanything with which the authors were at all familiar, e.g., FORTRAN, BASIC, XCOBOL, ALGOL, SNOBOL, SPITBOL, FOCAL, SOLVE, TEACH, APL, LISP, and PI/I. XFor the most part, INTERCAL has remained true to this goal, sharing only Xthe basic elements such as variables, arrays, and the ability to do I/O, Xand eschewing all conventional operations other than the assignment Xstatement (FORTRAN ``|=|''). X X\subsection{Acronym} X XThe full name of the compiler is ``Compiler Language With No Pronounceable XAcronym'', which is, for obvious reasons, abbreviated ``INTERCAL''. X X\subsection{Acknowledgments} X XThe authors are deeply indebted to Eric M. Van and Daniel J. Warmenhoven, Xwithout whose unwitting assistance this manual would still have been Xpossible. X X X X X X X X X\section{Fundamental Concepts} X XIn this section an attempt is made to describe how and why INTERCAL may be Xused; i.e., what it is like and what it is good for. X X\subsection{Sample Program} X XShown below is a relatively simple INTERCAL program which will read in X32-bit unsigned integers, treat them as signed, 2's-complement numbers, and Xprint out their absolute values. The program exits if the absolute value Xis zero. Note in particular the inversion routine (statements 6 through X14), which could be greatly simplified if the subroutine library (see Xsection 5) were used. X XA more detailed analysis of a program is made in section 6 of this manual. X X\continuationchartrue % sample.i uses the continuation character convention X\ICverbatimlisting{sample.i} X X X\subsection{Uses For INTERCAL} X XINTERCAL's main advantage over other programming languages is its strict Xsimplicity. It has few capabilities, and thus there are few restrictions Xto be kept in mind. Since it is an exceedingly easy language to learn, one Xmight expect it would be a good language for initiating novice programmers. XPerhaps surprising, than, is the fact that it would be more likely to Xinitiate a novice into a search for another line of work. As it turns out, XINTERCAL is more useful (which isn't saying much) as a challenge to Xprofessional programmers. Those who doubt this need only refer back to the Xsample program in section 2.1. This 23-statement program took somewhere Xfrom 15 to 30 minutes to write, whereas the same objectives can be achieved Xby single-statement programs in either SNOBOL; X X\begin{verbatim} X PLEASE INPUT POS(0) ('-' ! '') X + (SPAN('0123456789') $ OUTPUT) X + *NE(OUTPUT) :S(PLEASE)F(END) X\end{verbatim} X\noindent or APL; X X\IConeline{|[1] >\llap -0=\llap /?<\llap -?|} X XAdmittedly, neither of these is likely to appear more intelligible to Xanyone unfamiliar with the languages involved, but they took roughly 60 Xseconds and 15 seconds, respectively, to write. Such is the overwhelming Xpower of INTERCAL! X XThe other major importance of INTERCAL lies in its seemingly inexhaustible Xcapacity for amazing one's fellow programmers, confounding programming shop Xmanagers, winning friends, and influencing people. It is a well-known and Xoft-demonstrated fact that a person whose work is incomprehensible is held Xin high esteem. For example, if one were to state that the simplest way to Xstore a value of 65535 in a 32-bit INTERCAL variable is: X X\begin{verbatim} X DO :1 <- #0?#256 X\end{verbatim} Xany sensible programmer would say that that was absurd. Since this is Xindeed the simplest method, the programmer would be made to look foolish in Xfront of his boss, who would of course happened to turn up, as bosses are Xwont to do. The effect would be no less devastating for the programmer Xhaving been correct. X X X X X X X X\section{Description} X XThe examples of INTERCAL programming which have appeared in the preceding Xsections of this manual have probably seemed highly esoteric to the reader Xunfamiliar with the language. With the aim of making them more so, we Xpresent here a description of INTERCAL. X X X\subsection{Variables} X XINTERCAL allows only 2 different types of variables, the 16-bit integer Xand the 32-bit integer. These are represented by a spot (|.|) or two-spot X(|:|), respectively, followed by any number between 1 and 65535, inclusive. XThese variables may contain only non-negative numbers; thus they have the Xrespective ranges of values: 0 to 65535 and 0 to 4294967295. Note: |.123| Xand |:123| are two distinct variables. On the other hand, |.1| and |.0001| Xare identical. Furthermore, the latter may NOT be written as |1E-3|. X X\subsection{Constants} X XConstants are 16-bit values only and may range from 0 to 65535. They are Xprefixed by a mesh (|#|). Caution! Under no circumstances confuse the mesh Xwith the interleave operator, except under confusing circumstances! X X\subsection{Arrays} X XArrays are represented by a tail (|,|) for 16-bit values, or a hybrid (|;|) Xfor 32-bit values, followed by a number between 1 and 65535, inclusive. XThe number is suffixed by the word |SUB|, followed by the subscripts, Xseparated optionally by spaces. Subscripts may be any expressions, Xincluding those involving subscripted variables. This occasionally leads Xto ambiguous constructions, which are resolved as discussed in section X3.4.3. Definition of array dimensions will be discussed later in greater Xdetail, since discussing it in less detail would be difficult. As before, X|,123| and |;123| are distinct. In summary, |.123|, |:123|, |#123|, X|,123|, and |:123| are all distinct. X X\subsection{Operators} X XINTERCAL recognizes 5 operators---2 binary and 3 unary. Please be kind to Xour operators: they may not be very intelligent, but they're all we've got. XIn a sense, all 5 operators are binary, as they are all bit-oriented, but Xit is not our purpose here to quibble about bits of trivia. X X X X% ******* proofread versus the paper copy only this far !!!! ************ X X X X X\subsubsection{Binary Operators} X XThe binary operators are INTERLEAVE (also called MINGLE) and SELECT, which Xare represented by a change (|\change|) and a sqiggle (|~|), respectively. X XThe interleave operator takes two 16-bit values and produces a 32-bit Xresult by alternating the bits of the operands. Thus, |#65535c#0| has the X32-bit binary form 101010....10 or 2863311530 decimal, while |#0c#65535| = X0101....01 binary = 1431655765 decimal, and |#255c#255| is equivalent to X|#65535|. X XThe select operator takes from the first operand whichever bits correspond Xto 1's in the second operand, and packs these bits as the right in the Xresult. Both operands are automatically padded on the left with zeros to X32 bits before the selection takes place, so the variable types are Xunrestricted. If more than 16 bits are selected, the result is a 32-bit Xvalue, otherwise it is a 16-bit value. For example, |#179~#201| (binary Xvalue 10110011|~|11001001) selects from the first argument the 8th, 7th, X4th, and 1st from last bits, namely, 1001, which = 9. But |#201~#179| Xselects from binary 11001001 the 8th, 6th, 5th, 2nd, and 1st from last Xbits, giving 10001 = 17. |#179~#179| has the value 31, while |#201~#201| Xhas the value 15. X XPerhaps a simpler way of understanding the operation of the select operator Xwould be to examine the logic diagram on the following page (Figure 1), Xwhich performs the select operation upon two 8-bit values, A and B. The Xgates used are Warmenhovian logic gates, which means the outputs have four Xpossible values: low, high, undefined (value of an uninitialized Xflip-flop), and oscillating (output of a NOR gate with one input low and Xthe other input connected to the output). These values are represented Xsymbolically by '|0|', '|1|', '{\tt ?}', and '|F|'. Note in particular that, Xwhile NOT-|0| is |1| and NOT-|1| is |0| as in two-valued logic, NOT-{\tt ?} is X{\tt ?} and NOT-|F| is |F|. The functions of the various gates are listed in XTable 1. X\stepcounter{table} X X X X X X X X X\subsubsection{Unary Operators} X XThe unary operators are |&| (logical AND), |V| (logical OR), and X|\bookworm| (logical XOR). This last character is obtained by overpunching Xa worm (|-|) on a V (|V|). The operator is inserted between the spot, Xtwo-spot, mesh, or what-have-you, and the integer, thus: |.&123|, |#V123|. XMultiple unary operators may not be concatenated, thus the form |#V&123| is Xinvalid. This will be covered later when precedence is discussed. These Xoperators perform their respective logical operations on all pairs of Xadjacent bits, the result from the first and last bits going into the first Xbit of the result. The effect is that of rotating the operand one place to Xthe right and ANDing, ORing, or XORing with its initial value. Thus, X|#&77| (binary = 1001101) is binary 0000000000000100 = 4, |#V77| is binary X1000000001101111 = 32879, and |#V77| is binary 1000000001101011 = 32875. X\typeout{typo here} X X\subsubsection{Precedence} X XPrecedence of operators is as follows: X X X\vspace{2 in} X\hspace{4 in} X\footnote{Keep in mind that the aim in designing INTERCAL was to have no Xprecedents.} X\stepcounter{footnote} X\vspace{1 in} X X(The remainder of this page intentionally left blank.) X X\newpage X X X X X X X X X X X X X X X X X X X X XThis precedence (or lack thereof) may be overruled by grouping expressions Xbetween pairs of sparks (|'|) or rabbit-ears (|"|). Thus X|'#165c#203'~#358| (binary value |'|10100101|c|11001011|'~|101100110) has Xthe value 15, but |#165c'#203~#358'| has the value 34815, and X|#165c#203~#358| is invalid syntax and is completely valueless (except Xperhaps as an educational tool to the programmer). A unary operator is Xapplied to a sparked or rabbit-eared expression by inserting the operator Ximmediately following the opening spark or ears. Thus, the invalid Xexpression |#V&123|, which was described earlier, could be coded as X|'V#&123'| or |'V"{"'|. Note: In the interests of simplifying the Xsometimes overly-complex form of expressions, INTERCAL allows a spark-spot Xcombination (|'.|) to be replaced with a wow (|!|). Thus |'.1~.2'| is Xequivalent to |!1~.2'|, and |'V.1c.2'| is equivalent to |"V!1c.2'"|. X XCombining a rabbit-ears with a spot to form a rabbit (|V|\typeout{Rabbit?}) Xis not permitted, although the programmer is free to use it should he find Xan EBCDIC reader which will properly translate a 12-3-7-8 punch. X XSparks and/or rabbit-ears must also be used to distinguish among such Xotherwise ambiguous subscripted and multiply-subscripted expressions as: X X\begin{verbatim} X ,1 SUB #1 ~ #2 X ,1 SUB ,2 SUB #1 #2 #3 X ,1 SUB " ,2 SUB " ,3 SUB #1 " #2 " " #3 " X\end{verbatim} X XThe third case may be isolated into either of its possible interpretations Xby simply changing some pairs of rabbit-ears to sparks, instead of adding Xmore ears (which would only confuse the issue further). Ambiguous cases Xare defined as those for which the compiler being used finds a legitimate Xinterpretation which is different from that which the user had in mind. XSee also section 8.1. X X X X X X X\section{Statements} X XIn this section is described the format of INTERCAL statements. X X\subsection{General Format} X XStatements may be entered in ``free format.'' That is, more than one Xstatement may occur on a single card, and a statement may begin on one card Xand end on a later one. Note that if this is done, all intervening cards Xand portions thereof must be part of the same statement. That this Xrestriction is necessary is immediately apparent from the following example Xof what might occur if statements could be interlaced. X X\begin{verbatim} X DO .1 <- ".1c'&:51~"#V1c!12~;&75SUB"V'V.1~ X DO .2 <- '"!1c"&';V79SUB",&7SUB:173"'~!V9c X .2'c,&1SUB:5~#33578"'"'"~'#65535c"V'V#&85'"' X #8196'"'~.1"c.2'~'#&5c"'#1279c#4351'~#65535"' X\end{verbatim} XThe above statements are obviously meaningless. (For that matter, so are Xthe statements X X\begin{verbatim} X DO .1 <- ".1c"&:51~"#V1C!12~;&75SUB"V'V.1~ X .2'C,&1SUB:5~/333578"'"'"~#65535c"V'V#&85'"' X DO .2 <- '"!1c"&';V79SUB",&7SUB:173"'~!V9c X #8196'"'~.1"c.2'~'#&5c"'#1279c!4351'~#65535"' X\end{verbatim} Xbut this is not of interest here.) X XSpaces may be used freely to enhance program legibility (or at least reduce Xprogram illegibility), with the restriction that no word of a statement Xidentifier (see section 4.3) may contain any spaces. X X\subsection{Labels} X XA statement may begin with a LOGICAL LINE LABEL enclosed in wax-wane pairs X(|()|). A statement may not have more than one label, although it is Xpossible to omit the label entirely. A line label is any integer from 1 to X65535, which must be unique within each program. The user is cautioned, Xhowever, that many line labels between 1000 and 1999 are used in the XINTERCAL System Library functions. X X\subsection{Identifiers and Qualifiers} X XAfter the line label (if any), must follow one of the following statement Xidentifiers: |DO|, |PLEASE|, or |PLEASE DO|. These may be used Xinterchangeably to improve the aesthetics of the program. The identifier Xis then followed by either, neither, or both of the following optional Xparameters (qualifiers): X\begin{enumerate} X\item either of the character strings |NOT| or |N'T|, which causes the statement Xto be automatically abstained from (see section 4.4.9) when execution Xbegins, and X\item a number between 0 and 100, preceded by a double-oh-seven X(|%|), which causes the statement to have only the specified percent chance Xof being executed each time it is encountered in the course of execution. X\end{enumerate} X X X X X X X X\subsection{Statements} X XFollowing the qualifiers (or, if none are used, the identifier) must occur Xone of the 13 valid operations. (Exception: see section 4.5.) These are Xdescribed individually in sections 4.4.1 through 4.4.13. X X\subsubsection{Calculate} X XThe INTERCAL equivalent of the half-mesh (|=|) in FORTRAN, BASIC, PL/I, and Xothers, is represented by an angle (|<|) followed by a worm (|-|). This Xcombination is read ``gets.'' 32-bit variables may be assigned 16-bit Xvalues, which are padded on the left with 16 zero bits. 16-bit variables Xmay be assigned 32-bit values only if the value is less than 65535. Thus, Xto invert the least significant bit of the first element of 16-bit X2-dimensional array number 1, one could write: X X\begin{verbatim} X ,1SUB#1#1 <- 'V,1SUB#1#1c#1'~'#0c#65535' X\end{verbatim} X XSimilarly to SNOBOL and SPITBOL, INTERCAL uses the angle-worm to define the Xdimensions of arrays. An example will probably best describe the format. XTo define 32-bit array number 7 as 3-dimensional, the first dimension being Xseven, the second being the current value of 16-bit variable number seven, Xand the third being the current value of the seventh element of 16-bit Xarray number seven (which is one-dimensional) mingled with the last three Xbits of 32-bit variable number seven, one would write (just before they Xcame to take him away): X X\begin{verbatim} X ;7 <- #7 BY .7 BY ",7SUB#7"c':7~#7' X\end{verbatim} XThis is, of course, different from the statement: X X\begin{verbatim} X ;7 <- #7 BY .7 BY ,7SUB"#7c':7~#7'" X\end{verbatim} X XINTERCAL also permits the redefining of array dimensioning, which is done Xthe same way as is the initial dimensioning. All values of items in an Xarray are lost upon redimensioning, unless they have been |STASH|ed (see Xsection 4.4.5), in which case restoring them also restores the old Xdimensions. X X X X X X X X\subsubsection{Next} X XThe |NEXT| statement is used both for subroutine calls and for Xunconditional transfers. This statement takes the form: X X\IConeline{|DO ({\em label}) NEXT|} X X\noindent X(or, of course, X\IConeline{|PLEASE DO ({\em label}) NEXT|} X X\noindent Xetc.), where |({\em label})| represents any logical line label which Xappears in the program. The effect of such a statement is to transfer Xcontrol to the statement specified, and to store in a push down list (which Xis initially empty) the location from which the transfer takes place. XItems may be removed from this list and may be discarded or used to return Xto the statement immediately following the |NEXT| statement. These Xoperations are described in sections 4.4.3 and 4.4.4 respectively. The Xprogrammer is generally advised to discard any stack entries which he does Xnot intend to utilize, since the stack has a maximum depth of 79 entries. XA program's attempting to initiate an 80th level of |NEXT|ing will result Xon the fatal error message, ``PROGRAM HAS DISAPPEARED INTO THE BLACK XLAGOON.'' X X\subsubsection{Forget} X XThe statement |PLEASE FORGET| {\em exp}, where {\em exp} represents any Xexpression (except colloquial and facial expressions), causes the Xexpression to be evaluated, and the specified number of entries to be Xremoved from the |NEXT|ing stack and discarded. An attempt to |FORGET| Xmore levels of |NEXT|ing than are currently stacked will cause the stack to Xbe emptied, and no error condition is indicated. This is because the Xcondition is not considered to be an error. As described in section 4.4.2, Xit is good programming practice to execute a |DO FORGET #1| after using a X|NEXT| statement as an unconditional transfer, so that the stack does not Xget cluttered up with unused entries: X X\begin{verbatim} X DO (123) NEXT X . X . X (123) DO FORGET #1 X\end{verbatim} X X\subsubsection{Resume} X XThe statement |PLEASE RESUME| {\em exp} has the same effect as |FORGET|, Xexcept that program control is returned to the statement immediately Xfollowing the |NEXT| statement which stored in the stack the last entry to Xbe removed. Note that a rough equivalent of the FORTRAN computed |GO TO| Xand BASIC |ON| {\em exp} |GO TO| is performed by a sequence of the form: X X\begin{verbatim} X DO (1) NEXT X . X . X (1) DO (2) NEXT X PLEASE FORGET #1 X . X . X (2) DO RESUME .1 X\end{verbatim} X XUnlike the |FORGET| statement, an attempt to |RESUME| more levels of X|NEXT|ing than been stacked will cause program termination. See also Xsection 4.4.11. X X X\subsubsection{Stash} X XSince subroutines are not explicitly implemented in INTERCAL, the |NEXT| Xand |RESUME| statements must be used to execute common routines. However, Xas these routines might use the same variables as the main program, it is Xnecessary for them to save the values of any variables whose values they Xalter, and later restore them. This process is simplified by the |STASH| Xstate ment, which has the form |DO STASH| {\em list}, where {\em list} Xrepresents a string of one or more variable or array names, separated by Xintersections (|+|). Thus X X\begin{verbatim} X PLEASE STASH .123+:123+,123 X\end{verbatim} Xstashes the values of two variables and one entire array. The values are Xleft intact, and copies thereof are saved for later retrieval by (what Xelse?) the |RETRIEVE| statement (see section 4.4.6). It is not possible Xto |STASH| single array items. X X\subsubsection{Retrieve} X X|PLEASE RETRIEVE| {\em list} restores the previously |STASH|ed values of Xthe variables and arrays named in the list. If a value has been Xstashed more than once, the most recently |STASH|ed values are |RETRIEVE|d, Xand a second |RETRIEVE| will restore the second most recent values X|STASH|ed. Attempting to |RETRIEVE| a value which has not been |STASH|ed Xwill result in the error message, ``THROW STICK BEFORE RETRIEVING.'' X X\subsubsection{Ignore} X XThe statement |DO IGNORE| {\em list} causes all subsequent statements to Xhave no effect upon variables and/or arrays named in the list. Thus, for Xexample, after the sequence X X\begin{verbatim} X DO .1 <- #1 X PLEASE IGNORE .1 X DO .1 <- #0 X\end{verbatim} X16-bit variable number 1 would have the value 1, not 0. Inputting (see Xsection 4.4.12) into an |IGNORE|d variable also has no effect. The Xcondition is annulled via the |REMEMBER| statement (see section 4.4.8). XNote that, when a variable is being |IGNORE|d, its value, though immutable, Xis still available for use in expressions and the like. X X\subsubsection{Remember} X X|PLEASE REMEMBER| {\em list} terminates the effect of the |IGNORE| Xstatement for all variables and/or arrays named in the list. It does not Xmatter if a variable has been |IGNORE|d more than once, nor is it an error Xif the variable has not been |IGNORE|d at all. X X\subsubsection{Abstain} X XINTERCAL contains no simple equivalent to an |IF| statement or computed |GO XTO|, making it difficult to combine similar sections of code into a single Xroutine which occasionally skips around certain statements. The |IGNORE| Xstatement (see section 4.4.7) is helpful in some cases, but a more viable Xmethod is often required. In keeping with the goal of INTERCAL having Xnothing in common with any other language, this is made possible via the X|ABSTAIN| statement. X XThis statement takes on one of two forms. It may not take on both at any Xone time. |DO ABSTAIN FROM ({\em label})| causes the statement whose Xlogical line label is |({\em label})| to be abstained form. |PLEASE XABSTAIN FROM| {\em gerund list} causes all statements of the specified Xtype(s) to be abstained from, as in X X\begin{verbatim} X PLEASE ABSTAIN FROM STASHING X PLEASE ABSTAIN FROM IGNORING + FORGETTING X PLEASE ABSTAIN FROM NEXTING X PLEASE ABSTAIN FROM CALCULATING X\end{verbatim} X X XStatements may also be automatically abstained from at the start of Xexecution via the |NOT| or |N'T| parameter (see section 4.3). X X XIf, in the course of execution, a statement is encountered which is being Xabstained from, it is ignored and control passes to the next statement in Xthe program (unless it, too, is being abstained from). X XThe statement |DO ABSTAIN FROM ABSTAINING| is perfectly valid, as is |DO XABSTAIN FROM REINSTATING| (although this latter is not usually Xrecommended). However, the statement |DO ABSTAIN FROM GIVING UP| is not Xaccepted, even though |DON'T GIVE UP| is. X X\subsubsection{Reinstate} X\newlength{\QEDlen}\settowidth{\QEDlen}{Q.E.D.}\newlength{\lastlinelen} X\settowidth{\lastlinelen}{Since $x+y$ cannot equal anything but 0, $x+y=0$.} X\addtolength{\lastlinelen}{-1\QEDlen} X XThe |REINSTATE| statement, like the |ABSTAIN|, takes as an argument either Xa line label or a gerund list. No other form of argument is permitted. XFor example, the following is an invalid argument: X\begin{quote} X Given: $x\neq0$, $y\neq0$, Prove: $x+y=0$. \\ X Since $x\neq0$, then $x+1\neq1$, $x+a\neq a$, $x+y\neq y$. \\ X Thus $x+y \neq$ anything but 0. \\ X Since $x+y$ cannot equal anything but 0, $x+y=0$. \\ X \hspace*{\lastlinelen} Q.E.D. X\end{quote} X X|REINSTATE|ment nullifies the effects of an abstention. Either form of X|REINSTATE|ment can be used to ``free'' a statement, regardless of whether Xthe statement was abstained from by gerund list, line label, or |NOT|. XThus, |PLEASE REINSTATE REINSTATING| is not necessarily an irrelevant Xstatement, since it might free a |DON'T REINSTATE| command or a |REINSTATE| Xthe line label of which was abstained from. However, |DO REINSTATE GIVING XUP| is invalid, and attempting to |REINSTATE| a |GIVE UP| statement by line Xlabel will have no effect. Note that this insures that |DON'T GIVE UP| Xwill always be a ``do-nothing'' statement. X X\subsubsection{Give Up} X X|PLEASE GIVE UP| is used to exit from a program. It has the effect of a X|PLEASE RESUME #80|. |DON'T GIVE UP|, as noted in section 4.4.10, is Xeffectively a null statement. X X\subsubsection{Input} X XInput is accomplished with the statement |DO WRITE IN| {\em list}, where X{\em list} represents a string of variables and/or elements or arrays, Xseparated by intersections. Numbers are represented on cards, each number Xon a separate card, by spelling out each digit (in English) and separating Xthe digits with one or more spaces. A zero (0) may be spelled as either X|ZERO| or |OH|. Thus the range of (32-bit) input values permissible Xextends from |ZERO| (or |OH|) through |FOUR TWO NINE FOUR NINE SIX SEVEN XTWO NINE FIVE|. X XAttempting to write in a value greater than or equal to |SIX FIVE FIVE XTHREE SIX| for a 16-bit variable will result in the error message, ``DON'T XBYTE OFF MORE THAN YOU CAN CHEW.'' X X\subsubsection{Output} X XValues may be output to the printer, one value per line, via the statement X|DO READ OUT| {\em list}, where the list contains variables, array Xelements, and/or constants. Output is in the form of ``extended'' Roman Xnumerals (also called ``butchered'' Roman numerals), with an overline X(\zero) indicating the value below is ``times 1000'', and lower-case Xletters indicating ``times 1000000''. Zero is indicated by an overline Xwith no character underneath. Thus, the range of (32-bit) output values Xpossible is from \zero\ through \=i\=vccxciv\=C\=M\=L\=X\=V\=I\=ICCXCV. XNote: For values whose residues modulo 1000000 are less than 4000, M is Xused to represent 1000; for values whose residues are 4000 or greater, \=I Xis used. Thus |#3999| would read out as MMMIM while |#4000| would read out Xas \=I\=V. Similar rules apply to the use of \=M and i for 1000000, and to Xthat of \=m and \=i for 1000000000. X\typeout{Do they really mean MMMIM and not MMMCMXCIX??} X X X X X X X X\subsection{Comments} X XUnrecognizable statements, as noted in section 7, are flagged with a splat X(|*|) during compilation, and are not considered fatal errors unless they Xare encountered during execution, at which time the statement (as input at Xcompilation time) is printed and execution is terminated. This allows for Xan interesting (and, by necessity, unique) means of including comments in Xan INTERCAL listing. For example, the statement: X X\begin{verbatim} X* PLEASE NOTE THAT THIS LINE HAS NO EFFECT X\end{verbatim} Xwill be ignored during execution due to the inclusion of the NOT qualifier. XUser-supplied error messages are also easy to implement: X X\begin{verbatim} X* DO SOMETHING ABOUT OVERFLOW IN ;3 X\end{verbatim} Xas are certain simple conditional errors: X X\begin{verbatim} X* (123) DON'T YOU REALIZE THIS STATEMENT SHOULD ONLY BE ENCOUNTERED X ONCE? X PLEASE REINSTATE (123) X\end{verbatim} XThis pair of statements will cause an error exit the second time they are Xencountered. Caution!! The appearance of a statement identifier in an Xintended comment will be taken as the beginning of a new statement. Thus, Xthe first example on the preceding page could not have been: X X\begin{verbatim} X* PLEASE NOTE THAT THIS LINE DOES NOTHING X\end{verbatim} XThe third example, however, is valid, despite the appearance of two cases Xof |D|-space-|O|, since INTERCAL does not ignore extraneous spaces in Xstatement identifiers. X X X X X X X\section{Subroutine Library} X XINTERCAL provides several built-in subroutines to which control can be Xtransferred to perform various operations. These operations include many Xuseful functions which are not easily representable in INTERCAL, such as Xaddition, subtraction, etc. X X\subsection{Usage} X XIn general, the operands are |.1|, |.2|, etc., or |:1|, |:2|, etc., and the Xresult(s) are stored in what would have been the next operand(s). For Xinstance, one routine adds |.1| to |.2| and store the sum in |.3|, with X|.4| being used to indicate overflow. All variables not used for results Xare left unchanged. X X\subsection{Available Functions} X XAt the time of this writing, only the most fundamental operations are Xoffered in the library, as a more complete selection would require Xprohibitive time and coree to implement. These functions, along with their Xcorresponding entry points (entered via |DO ({\em entry}) NEXT|) are listed Xbelow. X X\begin{verbatim} X (1000) .3 <- .1 plus .2, error exit on overflow X (1009) .3 <- .1 plus .2 X .4 <- #1 if no overflow, else .4 <- #2 X (1010) .3 <- .1 minus .2, no action on overflow X (1020) .1 <- .1 plus #1, no action on overflow X (1030) .3 <- .1 times .2, error exit on overflow X (1039) .3 <- .1 times .2 X .4 <- #1 if no overflow, else .4 <- #2 X (1040) .3 <- .1 divided by .2 X .3 <- #0 if .2 is #0 X (1050) .2 <- :1 divided by .1, error exit on overflow X .2 <- #0 if .1 is #0 X X (1500) :3 <- :1 plus :2, error exit on overflow X (1509) :3 <- :1 plus :2 X :4 <- #1 if no overflow, else :4 <- #2 X (1510) :3 <- :1 minus :2, no action on overflow X (1520) :1 <- .1 concatenated with .2 X (1525) This subroutine is intended solely for internal X use within the subroutine library and is therefore X not described here. Its effect is to shift .3 X logically 8 bits to the left. X (1530) :1 <- .1 times .2 X (1540) :3 <- :1 times :2, error exit on overflow X (1549) :3 <- :1 times :2 X :4 <- #1 if no overflow, else :4 <- #2 X (1550) :3 <- :1 divided by :2 X :3 <- #0 if :2 is #0 X X (1900) .1 <- uniform random no. from #1 to #65535 X (1910) .2 <- normal random no. from #0 to .1, with X standard deviation .1 divided by #12 X\end{verbatim} X X X X X X X X\section{Programming Hints} X XFor the user looking to become more familiar with the INTERCAL language, we Xpresent in this section an analysis of a complex program, as well as some Xsuggested projects for the ambitious programmer. X XConsidering the effort involved in writing an INTERCAL program, it was Xdecided in putting together this manual to use an already existing program Xfor instructive analysis. Since there was only one such program available, Xwe have proceeded to use it. It is known as the ``INTERCAL System Library.'' X X\subsection{Description} X XThe program listing begins on the second page following. It is in the same Xformat as would be produced by the Princeton INTERCAL compiler in FORMAT Xmode with WDITH=62 (see section 8). For a description of the functions Xperformed by the Library, see section 5.2. X X\subsection{Analysis} X XWe shall not attempt to discuss here the algorithms used, but rather we Xshall point out some of the general techniques applicable to a wide range Xof problems. X XStatements 10, 14, 15, and 26 make up a virtual ``computed |GO TO|''. When Xstatement 10 is executed, control passes eventually to statement 16 or 11, Xdepending on whether |.5| contains |#1| or |#2|, respectively. The value Xof |.5| is determined in statement 9, which demonstrates another handy Xtechnique. To turn an expression, {\em exp}, with value |#0| or |#1|, into X|#1| or |#2| (for use in a ``|GO TO|''), use |"V'{\em exp}'c#1"~#3|. To Xreverse the condition (i.e., convert |#0| to |#2| and leave |#1| alone) use X|"V'{\em exp}'c#2"~#3|. X XCertain conditions are easily checked. For example, to test for zero, Xselect the value from itself and select the bottom bit (see statement 54). XTo test for all bits being 1's, select the value from itself and select the Xtop bit (see statement 261). The test to greater than, performed in Xstatements 192 and 193 on 32-bit values, employs binary logical operations, Xwhich are performed as follows: X X\begin{verbatim} X 'V.1c.2'~'#0c#65535' X\end{verbatim} Xfor 16-bit values or, for 32-bit values: X X\begin{verbatim} X "'V":1~'#65535c30'"c":2~'#65535c#0'"'~'#0 X c#65535'"c"'V":1~'#0c#65535'"c":2~'#0 X c#65535'"'~'#0c#65535'" X\end{verbatim} X(The proofs are left as an exercise to the reader.) X XTesting for greater-than with 16-bit values is somewhat simpler and is done Xwith the pair of statements: X X\begin{verbatim} X DO .C <- 'V.Ac.B'~'#0c#65535' X DO .C <- '&"'.A~.C'~'"V'V.C~.C'c#32768" X ~"#0c#65535"'"c".C~.CZ''ZZZ`#1 X\end{verbatim} XThis sets |.C| (a dummy variable) to |#1| if |.A| $>$ |.B|, and |#0| Xotherwise. The expression may be expanded as described above to instead Xset |.C| to |#1| or |#2|. X XNote also in statement 220 the occurrence of |~"#65535c65535"|. Although Xthese operations select the entire value, they are not extraneous, as they Xensure that the forthcoming |V|s will be operating on 32-bit values. X XIn several virtual computed |GO TO|s the |DO FORGET #1| (statement 15 in the Xearlier example) has been omitted, since the next transfer of control would Xbe a |DO RESUME #1|. By making this a |DO RESUME #2| instead, the |FORGET| may Xbe forgotten. X XIn statement 64, note that .2 is |STASH|ed twice by a single statement. This Xis perfectly legal. X XLastly, note in statements 243 and 214 respectively, expressions for Xshifting 16- and 32-bit variables logically one place to the left. XStatement 231 demonstrates right-shifting for 32-bit variables. X X% MIKE GETS TO INSERT THE PROGRAM HERE! X X\subsection{Program Listing} X X\continuationchartrue % syslib.i uses the continuation character convention X\ICverbatimlisting{syslib.i} X\typeout{Where's line 1551? 1900? 1910?} X X X X X X X\subsection{Programming Suggestions} X XFor the novice INTERCAL programmer, we provide here a list of suggested XINTERCAL programming projects: X XWrite an integer exponentiation subroutine. |:1 <- .1| raised to the |.2| power. X XWrite a double-precision sorting subroutine. Given 32-bit array |;1| of Xsize |:1|, sort the contents into numerically increasing order, leaving the Xresults in |;1|. X XGenerate a table of prime numbers. X XPut together a floating-point library, using 32-bit variables to represent Xfloating-point numbers (let the upper half be the mantissa and the lower Xhalf be the characteristic). The library should be capable of performing Xfloating-point addition, subtraction, multiplication, and division, as well Xas the natural logarithm function. X XProgram a Fast Fourier Transform (FFT). This project would probably entail Xthe writing of the floating-point library as well as sine and cosine functions. X XCalculate, to |:1| places, the value of pi. X X X X X X X X\section{Error Messages} X XDue to INTERCAL's implementation of comment lines (see section 4.5), most Xerror messages are produced during execution instead of during compilation. XAll errors except those not causing immediate termination of program execution Xare treated as fatal. X X\subsection{Format} X XAll error messages appear in the following form: X X\begin{verbatim} X ICLnnnI (error message) X ON THE WAY TO STATEMENT nnnn X CORRECT SOURCE AND RESUBMIT X\end{verbatim} X XThe message varies depending upon the error involved. For undecodable Xstatements the message is the statement itself. The second line tells Xwhich statement would have been executed next had the error not occurred. XNote that if the error is due to 80 attempted levels of |NEXT|ing, the Xstatement which would have been executed next need not be anywhere near the Xstatement causing the error. X X\subsection{Messages} X XBrief descriptions of the different error types are listed below according Xto message number. X X\begin{description} X\def\ttitem#1{\item[{\tt #1}]} X X\ttitem{000} An undecodable statement has been encountered in the course of X execution. Note that keypunching errors can be slightly disastrous, X since if `|FORGET|' were misspelled F-O-R-G-E-R, the results would X probably not be those desired. Extreme misspellings may have even X more surprising consequences. For example, misspelling `|FORGET|' X R-E-S-U-M-E could have drastic results. X X\ttitem{017} An expression contains a syntax error. X X\ttitem{079} Improper use has been made of statement identifiers. X X\ttitem{099} Improper use has been made of statement identifiers. X X\ttitem{123} Program has attempted 80 levels of |NEXT|ing. X X\ttitem{129} Program has attempted to transfer to a non-existent line label. X X\ttitem{139} An |ABSTAIN| or |REINSTATE| statement references a non-existent line label. X X\ttitem{182} A line label has been multiply defined. X X\ttitem{197} An invalid line label has been encountered. X X\ttitem{200} An expression involves an unidentified variable. X X\ttitem{240} An attempt has been made to give an array a dimension of zero. X X\ttitem{241} Invalid dimensioning information was supplied in defining or using X an array. X X\ttitem{275} A 32-bit value has been assigned to a 16-bit variable. X X\ttitem{436} A retrieval has been attempted for an un|STASH|ed value. X X\ttitem{533} A |WRITE IN| statement or interleave (|\change|) operation has Xproduced a value requiring over 32 bits to represent. X X\ttitem{562} Insufficient data. X X\ttitem{579} Input data is invalid. X X\ttitem{621} The expression of a |RESUME| statement evaluated to |#0|. X X\ttitem{632} Program execution was terminated via a |RESUME| statement instead of X |GIVE UP|. X X\ttitem{633} Execution has passed beyond the last statement of the program. X X\ttitem{774} A compiler error has occurred (see section 8.1). X X\ttitem{778} An unexplainable compiler error has occurred (see J. Lyon or B. Woods). X\end{description} X X X X X\section*{Tonsil\footnote{Since all other reference manuals Xhave Appendices, it was decided that the INTERCAL manual should contain Xsome other type of removable organ.} A: The Official INTERCAL Character Set} X X X X X X XTabulated on page 18 are all the characters used in INTERCAL, excepting Xletters and digits, along with their names and interpretations. Also Xincluded are several characters not used in INTERCAL, which are presented Xfor completeness and to allow for future expansion. X\stepcounter{footnote} X\footnotetext{This footnote intentionally unreferenced.} X X{\catcode`.=\active \catcode`|=12 % Use . instead of | for code mode X\def.{\bgroup\tt\usespecials\def.{\null\egroup}} X\begin{table} X\begin{minipage}{\textwidth} % so the footnote works out. X\begin{tabular}{|r|l|p{3in}|} X\hline XCharacter & Name & Use (if any) \\ X\hline X.\spot. & spot & identify 16-bit variable \\ X.:. & two-spot & identify 32-bit variable \\ X.,. & tail & identify 16-bit array \\ X.;. & hybrid & identify 32-bit array \\ X.\#. & mesh & identify constant \\ X.=. & half-mesh & \\ X.'. & spark & grouper \\ X.`. & backspark & \\ X.!. & wow & equivalent to spark-spot \\ X\verb|?|& what & unary exlusive OR (ASCII) \\ X.". & rabbit-ears & grouper \\ X{\verb|!`|}& rabbit & equivalent to ears-spot \\ X{\verb+|+}& spike & \\ X.\%. & double-oh-seven & percentage qualifier \\ X.-. & worm & used with angles \\ X.<. & angle & used with worms \\ X.>. & right angle & \\ X.(. & wax & precedes line label \\ X.). & wane & follows line label \\ X.[. & U turn & \\ X.]. & U turn back & \\ X.\{. & embrace & \\ X.\}. & bracelet & \\ X.*. & splat & flags invalid statements \\ X.\&. & ampersand\footnotemark & unary logical AND \\ X.V. & V (or book) & unary logical OR \\ X.\bookworm. & bookworm (or universal qualifier) & unary exclusive OR \\ X.\$. & big money & binary mingle (ASCII) \\ X.\change.& change & binary mingle \\ X.\~{}. & sqiggle & binary select \\ X.\_. & flat worm & \\ X.\zero. & overline & indicates ``times 1000'' \\ X.+. & intersection & separates list items \\ X./. & slat & \\ X{\verb|\|}& backslat & \\ X.@. & whirlpool & \\ X.\hookworm.& hookworm & \\ X{\verb|^|}& shark (or simply sharkfin) & \\ X.\blotch.& blotch \\ X\hline X\end{tabular} X\catcode`.=12 X\caption{ INTERCAL character set (top view).} X\typeout{What does Rabbit really look like?} X\def\thempfootnote{\arabic{mpfootnote}} X\footnotetext[\thefootnote]{Got any better ideas?} X\label{character-set} X\end{minipage} X\end{table} X} X X X\section*{Tonsil B: XNotes On The Atari Implementation} X XThe Atari implementation of INTERCAL differs from the original Princeton Xversion primarily in the use of ASCII rather than EBCDIC. Since there is Xno ``change'' sign (|\change|) in ASCII, we have substituted the ``big Xmoney'' (|$|) as the mingle operator. We feel that this correctly Xrepresents the increasing cost of software in relation to hardware. X(Consider that in 1970 one could get RUNOFF for free, to run on a \$20K Xmachine, whereas today a not quite as powerful formatter costs \$99 and Xruns on a \$75 machine.) We also feel that there should be no defensible Xcontention that INTERCAL has any sense. Also, since overpunches are Xdifficult to read on the average VDT, the exclusive-or operator may be Xwritten ?. This correctly expresses the average person's reaction on first Xencountering exclusive-or, especially on a PDP-11. Note that in both of Xthese cases, the over-punched symbol may also be used if one is Xmasochistic, or concerned with portability to the Princeton compiler. The Xcorrect over-punch for ``change'' is ``c{\sc X$\langle$backspace$\rangle$}/'' and the correct over-punch for |\bookworm| Xis "V{\sc $\langle$backspace$\rangle$}-". These codes will be properly Xprinted if you have a proper printer, and the corresponding EBCDIC code Xwill be produced by the |/IBM| option on the |LIST| command. X X\end{document} X END-of-intercal.tex echo file: intercal.sty sed 's/^X//' >intercal.sty << 'END-of-intercal.sty' X% -*- Mode: TeX -*- X% for LaTeX X X% This is the file ick.sty: macros for typesetting the INTERCAL Manual. X X\setlength{\textwidth}{6.5in} X\setlength{\oddsidemargin}{0in} X\setlength{\evensidemargin}{0in} X\setlength{\textheight}{9in} X\setlength{\topmargin}{0in} X\setlength{\headsep}{0in} X\setlength{\headheight}{0in} X X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% X% SPECIAL INTERCAL CHARACTERS X% X X% Save ``regular'' characters. X\def\backslat{\backslash} X\def\embrace{\verb|{|} X\def\bracelet{\verb|}|} X\def\doubleohseven{\%} X\def\ampersand{\&} X\def\sqiggle{\~{}} X\def\bigmoney{\$} X\def\shark{\verb|^|} X\def\flatworm{\verb|_|} X\def\mesh{\#} X\def\spot{.} X\def\what{?} X X% \newcommand{\mathify}[1]{\ifmmode{#1}\else\mbox{$#1$}\fi} X% \def\bookworm{\mathify{\forall}} X\def\bookworm{\rlap V-} X\def\change{\rlap c/} X%\def\altchange{\rlap /c} X\def\zero{\={}} X\def\spike{\verb+|+} X\def\althookworm{-\llap '} X\def\hookworm{'\llap -} X\def\blotch{\#\llap I\llap [\llap ]} X X X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% X% INTERCAL CODE ENVIRONMENT X% X X% Just surround the code with vertical bars. X X X\catcode`|=\active % The `|' is active from now on. X\def|{\ifmmode\vert% X \else\bgroup\tt\usespecials\def|{\null\egroup}% X \fi} X X% To get backslat, embrace, or bracelet in a | | environment, use the X% respective macros. X% I might want to translate $ and ? as in the verbatim macros. X\def\activatespecials{% X \catcode`\%=\active X \catcode`\&=\active X \catcode`\~=\active X \catcode`\$=\active X \catcode`\^=\active X \catcode`\_=\active X \catcode`\#=\active} X X{% Add new comment character X \catcode`+=14 X \activatespecials X \gdef\usespecials{+ X \activatespecials X \def%{\doubleohseven}+ X \def&{\ampersand}+ X \def~{\sqiggle}+ X \def${\bigmoney}+ X \def^{\shark}+ X \def_{\flatworm}+ X \def#{\mesh}}} X X% Typeset a one-line INTERCAL example. This is pretty gross. X\def\IConeline#1{\vspace\topsep\par\noindent{\tt\ \ \ \ \ \ \ \ }#1\vspace\topsep} X X X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% X% VERBATIM FILE LISTING X% X X% --- The macros are based on those distributed with Sunil Podar's X% --- `EPIC.STY' macro package, attributed to Tim Morgan, X% --- modified to keep internal macros internal by Adrian F. Clark, X% --- alien@uk.ac.essex.ese X% --- ---and further latexification by Chris Rowley, X% --- ca_rowley@uk.ac.open.acs.vax. X% And finally, modified for INTERCAL by Michael Ernst. X X\def\verbatimfile#1{\begingroup X \@verbatim \frenchspacing \@vobeyspaces X \input#1 \endgroup X} X X\newcounter{lineno} X X\newif\ifcontinuationchar X% Say \continuationchartrue if the ends of continued program lines are X% flagged by slash-newline. X% This implementation doesn't allow backslashes elsewhere; it would be X% better to make \, clobbered by \@verbatim, the escape character again, X% and then define a whole wad of escape sequences, with \^^M being one. X X\newif\ifnonumber X X\def\activateverbspecials{% X \catcode`$=\active X \catcode`?=\active} X X{\activateverbspecials X \catcode`|=0 X \catcode`\\=\active X |gdef|useverbspecials{% X |def\{|nonumbertrue}% X |def${|change}% X |def?{|bookworm}% X |activateverbspecials}} X X\def\ICverbatimlisting#1{\setcounter{lineno}{0}% X \begingroup \@verbatim \frenchspacing \@vobeyspaces \parindent=20pt X \everypar{\ifnonumber\nonumberfalse X \else\stepcounter{lineno}% X \llap{{\footnotesize\rm\thelineno\ \ \ }}% X \fi}% X \ifcontinuationchar\catcode`\\=\active\fi X \useverbspecials X \input#1 X \endgroup X} X END-of-intercal.sty echo file: BUGS sed 's/^X//' >BUGS << 'END-of-BUGS' X NEW FEATURES IN C-INTERCAL X X1. As a convenience to all you junior birdmen out there, `NINER' is accepted as X a synonym for `NINE' in INTERCAL input. X X2. The COME FROM statement is now compiled. You may write X X PLEASE COME FROM (n) X X and the effect will be that whenever execution reaches statement label n, X it will immediately transfer control to the statement following the X COME FROM. Conditional COME FROM is possible; ABSTAIN FROM COMING FROM and X REINSTATE COMING FROM are both valid. DON'T COME FROM is a no-op (until X reinstated). Finally; NEXTING to the label `target' of an un-abstained X COME FROM *will* cause control to be transferred to the statement following X the COME FROM. X X BUGS X X1) INTERCAL would be intrinsically a crock even if it worked right. X X2) The INTERCAL-72 handling of invalid statements isn't implemented; instead X they raise a normal compile-time error. This is because I haven't figured X out how to force YACC to do the needed thing yet. It means C-INTERCAL X can't compile the INTERCAL-72 system library yet. Isn't compatibility X wonderful? I may have to go to a handcrafted LL(1) parser to fix this... X X3) Error-checking could be improved. Not all the errors listed in the X manual are actually detected (of those listed in lose.h, E123, E621, E632, X E562, E579, E436, E017, E275, E182, E129, E139, and E778 are implemented). X In this respect C-INTERCAL follows nobly in the tradition of many production X compilers. X X4) Proper C code is generated for array operations, but the runtime-library X hooks for the dynamic memory management needed to make the code work are X stubbed out. I'm poor at array-bashing. Rachel Millian has promised to X implement this for the next release. X X5) The Roman-numeral output from INTERCAL isn't quite as butchered as it ought X to be, because neither I nor the implementor could figure out what the frotz X the note in the INTERCAL-72 manual about modulo 4000 and I and M and all X that was really