# CLC-INTERCAL Reference

## ... The command-line compiler tool

Table of contents:

- Parent directory
- The command-line compiler tool
- Command-line options
- Embedding INTERCAL in Perl source

## The command-line compiler tool

Starting from CLC-INTERCAL 1.-94, the preferred method to compile programs is to use the Integrated Programming Environment, sick (which stands for Superior INTERCAL Compiler Kluge or something like that). A program compatible with the old "oo, ick" is planned and will be made available if and when.

sick requires CLC-INTERCAL 1.-94 and newer. It won't work with older versions.

Although there are plans to provide some sort of interesting user interface to sick, at present it only works in batch mode, compiling programs using options specified on the command line, and either producing objects or running the program as soon as the compiler finishes.

The arguments on the command line are either options (in the form --name=value or -xvalue), or filenames. If a filename is encountered, it is immediately compiled with the options which precede it in the command line, and then optionally executed. After processing the command line, sick terminates.

## Command-line options

There is a large number of command-line options, which are grouped by type for easy reference.

### Source character set options

Before compiling a program, sick needs to know what character set has been used to encode the source. These days it's mostly ASCII but you never can tell. The default is --guess.

Long option | Short | Meaning
--- | --- | ---
--ascii | -a | ASCII
--baudot | -b | Extended Baudot
--ebcdic | -e | Nonstandard EBCDIC
--hollerith | -h | Hollerith, straight from punched cards
--charset=NAME |  | Select a character set
--guess | -g | Try to guess looking at the program source

See the chapter about character sets for more information on supported character sets.

### Compiler options

Once sick has loaded the source, and converted it to ASCII if necessary, it needs to compile it. This requires loading a compiler object and any necessary compiler options and extensions. This is done by specifying preloads, which, as the name suggests, are loaded before the program source. If no preloads are specified, sick attempts to guess the correct list of preloads by looking at the program suffix (or an alternative suffix specified on the command line).

Long option | Short | Meaning
--- | --- | ---
--include=DIR | -IDIR | Add directory to search path for compiler objects
--nopreload |  | Clears the list of preloads, reverting to the suffix-based guess
--preload=NAME | -pNAME | Add NAME to the list of preloads
--add-preload | -A | Guesses preloads by suffix, even if -p is specified
--suffix=SUFFIX |  | If using suffix-based guess, use SUFFIX instead of the source file's suffix
--imitate=WHO |  | Pretends to be a different compiler
--clc-intercal |  | Same as --imitate=sick
--c-intercal |  | Same as --imitate=ick
--intercal-72 |  | Same as --imitate=1972
--intercal-1972 |  | Same as --imitate=1972

By default, the compiler pretends to be itself, which means that the rules described here are valid; specifying --imitate causes the compiler to pretend it's somebody else, and use different rules, which will be described later. The default value can be requested explicitely with --imitate=sick or --clc-intercal

The suffix-based guessing of preloads relies on the the sickrc files found, which in turn depends on which extensions are installed, on which directories are specified with the --include option, and whether user and system sickrc files are considered: see Misc options below, and also see the sickrc specification). The defaults provided with the distributions will use the following table (if a suffix belongs to more than one row, it will use the first matching one):

Suffix | Preloads | Meaning
--- | --- | ---
.iacc | iacc | Compiler source
.iasm | asm | CLC-INTERCAL assembler
.clci | sick | CLC-INTERCAL source
.clcti | sick, thick | Threaded CLC-INTERCAL source
.ti | ick, thick | Threaded INTERCAL source
.ci | ick | C-INTERCAL source
.1972 | 1972 | Traditional INTERCAL source
.1972i | 1972 | Traditional INTERCAL source
.i | sick | CLC-INTERCAL source

If the compiler is making an attempt of imitating C-INTERCAL, because you said --imitate=ick or --c-intercalM, the suffix rules will be:

Suffix | Preloads | Meaning
--- | --- | ---
.iacc | iacc | Compiler source
.iasm | asm | CLC-INTERCAL assembler
.clci | sick | CLC-INTERCAL source
.clcti | sick, thick | Threaded CLC-INTERCAL source
.ti | ick, thick | Threaded INTERCAL source
.i | ick | C-INTERCAL source
.1972 | 1972 | Traditional INTERCAL source
.1972i | 1972 | Traditional INTERCAL source

If the compiler is making an attempt of imitatind Traditional INTERCAL, because you said --imitate=1972, --intercal-72 or --intercal-1972, the suffix rules will be:

Suffix | Preloads | Meaning
--- | --- | ---
.iacc | iacc | Compiler source
.iasm | asm | CLC-INTERCAL assembler
.clci | sick | CLC-INTERCAL source
.clcti | sick, thick | Threaded CLC-INTERCAL source
.ti | ick, thick | Threaded INTERCAL source
.i | 1972 | Traditional INTERCAL source
.1972 | 1972 | Traditional INTERCAL source
.1972i | 1972 | Traditional INTERCAL source

In addition to the above, extra letters can be present between the spot and the rest of the suffix, indicating extra preloads. Such extra letters can only be used with the ick or sick compilers, because 1972, iacc and iasm do not accept options or extensions.

Letter | Preload | Meaning
--- | --- | ---
2 | 2 | Change base to 2
3 | 3 | Change base to 3
4 | 4 | Change base to 4
5 | 5 | Change base to 5
6 | 6 | Change base to 6
7 | 7 | Change base to 7
b | non-blocking | Make some statements non-blocking
d | bitwise-divide | Select bitwise behaviour for unary divide
g | come-from-gerund | Enable COME FROM gerund and NEXT FROM gerund
h | class-helpers | Load a special class with some useful lectures
l | computed-labels | Allow computed statement labels
n | next | Allow NEXT statements (sick only)
s | syscall | Enable system call interface on label (666)
w | wimp | Set wimp mode as default for compiled program

If more than one base is specified, the first one matched by the sickrc files will be used: in the default, this is the highest base found on the suffix, so for example ".563i" means base 6.

CLC-INTERCAL 1.-94.-2 no longer includes the INTERNET extensions by default. When this extension is installed, an extra letter, "r" will be accepted in the suffix to preload it.

The "class-helpers" object, requested by adding a letter "h" to the suffix, contains class @65535 and a number of useful lectures. They are currently undocumented but the source is in "class-helpers.i" in the distribution.

Non-blocking operation affects WRITE IN and some system calls (if enabled); it also affects CASE, SMUGGLE and STEAL from the INET extension (if loaded). Before 1.-94.-1, all these statements blocked all threads until they completed, this option makes them block the current thread only while other threads can continue: it is the programmer's responsibility to avoid using the values produced by these statements before they are available, which is why the behaviour needs to be enabled explicitly when desired.

Not all these extra options are compatible with ick. See also the chapter about compiler extensions.

Normally, specifying any preloads on the command line disables the preload guess, which means that one might need to specify everything the guess would add. The --add-preloads (or -A) option asks to do the preload guess, then add to the result any preloads specified on the command line: it can be used, for example, to add threads support to sick: the ".ti" suffix would change the compiler to ick, but using -Apthick would use the normal preloads and then add thick. Consider the command:

        sick --add-preloads --preload=thick my-threaded-program.gi

The program being compiled here allows execution of COME FROM gerund statements (as requested by the "g" in the suffix) and additionally creates threads whenever a gerund listed in a COME FROM statement corresponds to more than one statement in the program. This document offers no opinion on whether this is a good idea.

### Code generation options

Once the program source has been compiled, sick needs to use a module to generate the actual code. The default is Object, which produces an INTERCAL object, which can be executed directly or loaded back into sick as a preload.

Long option | Short | Meaning
--- | --- | ---
--nooptimise |  | Disable optimiser (default)
--optimise | -O | Enable optimiser
--backend=NAMES | -lNAMES | Selects one or more modules used to generate code
--listing=NAMES | -LNAMES | Selects one or more modules used to generate source listings
--output=NAME | -oNAME | The output file, defaults to the source file name with a new suffix
--name=NAME | -nNAME | A name passed to the backend. Most backends don't use one
--directory=DIR | -dDIR | Forces all outputs to go to DIR
--bug=NUMBER |  | Change the probability of the compiler bug
--ubug=NUMBER |  | Change the probability of the unexplainable compiler bug

The --backend option takes a comma-separated list of compiler back ends to run. The default is --backend=Object which saves the object to file using the default output file name or the value of any --output option in effect at that point. If more than one backend is specified, they will be executed in order, for example:

    	sick --backend Run,Run,Object prog.i

Will compile "prog.i", run it twice, then save the object to "prog.io".

The --listing option takes a comma-separated list of source listing modules to run. The default is to produce no listings, and this can also be specified with the special value "none". For example, this produces both text and HTML listing of prog1,i but no listing of prog2.i:

    	sick --listing text,html prog1.i --listing none prog2.i

(note that this is just an example, text listing is at present not supported).

Each module passed to --listing accepts a single argument, specified with an equal sign (=) following the module name, for example the "html" module accepts the name of a stylesheet to load, for example:

    	sick --listing html=clc-intercal.css ...

Specifying the single name "help" for a backend will produce the list of all known backends without making any changes to the compile process. Similarly, specifying the single name "help" for a listing will produce the list of all known source listing modules without making any changes to what is actually produced.

The --output option recognises some special characters in the string passed to it: %p will be replaced by the name of the source file without the suffix and %o by the original name specified on the command line with the suffix removed: the difference is that when the compiler uses the search path to locate the program, %p could have a directory added to it to indicate where the source was found, while %o will be the name as typed. The %s sequence expands to a backend-supplied suffix, and %% is replaced by a single "%". The default is %p.%s. which means that the object is placed in the same directory where the source was found, but with a new suffix. To produce an executable without a suffix, specify "--output=%p"

If the --directory option is present, all objects are sent to that directory, even if the name produced by --output specifies a different directory.

The following backends are currently provided:

Backend | Suffix | Meaning
--- | --- | ---
ListObject | .ilst | Assembler listing of the object
None |  | No-op: this can be used to avoid producing an object
Object | .io | Executable object
Perl | .pl | Perl program
Run |  | Run program immediately - does not save object

If an output file name is not specified with --output, the backend will generate a file name by appending its own suffix (shown in the table) to the base name of the source program. The table identifies backends which do not produce a file by showing an empty suffix for them,

If --directory is specified, it will replace the directory part on all output names. This works whether --output provides a name, or the backend's default is used. Specifying an empty string reinstates the default of using the source file's directory. Note that if --output specifies an absolute path, this will be used in the absence of a --directory but ignored if --directory is present.

Objects produced by the Object and Perl backends will accept the following command-line arguments when executed:

Option | Meaning
--- | ---
--nouserrc | Ignore .sickrc files found
--nosystemrrc | Ignore any files in /etc/sick
--rcfile=NAME | Uses specified file instead of searching for files
--rcskip=VERB | Ignores VERB when processing sickrc files
--trace | Enable tracing for the object
--stdtrace=FILE | Enable tracing and redirect tracing data to FILE
--notrace | Disable tracing (default)
--wimp | Select wimp mode (default if the wimp object was preloaded)
--nowimp | Select normal mode (default if the wimp object was not preloaded)
--interpreter=NAME | Uses an alternative CLC-INTERCAL Interpreter

### Misc options

The following options control the way sick operates:

Long option | Short | Meaning
--- | --- | ---
--nouserrc |  | Ignore .sickrc files found
--nosystemrrc |  | Ignore any files in /etc/sick
--rcfile=NAME | -rNAME | Uses specified file instead of searching for files
--rcskip=VERB | -RVERB | Ignores VERB when processing sickrc files
--extension=NAME |  | Makes sure to load extension NAME
--rclist |  | Lists all .sickrc and system.sickrc files found, marking the ones which would be loaded based on other options
--stdverb=FILE | -sFILE | Send verbose output to FILE
--verbose | -v | Send verbose outout to standard error
--quiet | -q | Do not produce verbose output (default)
--times |  | Print compiler timing information on standard error
--notimes |  | Do not print timing information (default)
--trace |  | Enable tracing - this will trace the compiler, not the object
--stdtrace=FILE |  | Enable tracing and redirect tracing data to FILE
--notrace |  | Disable tracing (default)
--grammar-profile | Enable profiling the compiler's grammar when compiling the object
--stdgrammar-profile=FILE | Enable profiling the compiler's grammar and redirect profiling data to FILE
--nogrammar-profile | Disable profiling the compiler's grammar (default)
--grammar-profile-max=NUMBER | If grammar profiling is enabled, limits the output to NUMBER lines
--grammar-profile-count=NUMBER | If grammar profiling is enabled, only outputs lines with count at least NUMBER
--grammar-profile-cost=NUMBER | If grammar profiling is enabled, only outputs lines with cost at least NUMBER
--interpreter=NAME |  | Uses an alternative CLC-INTERCAL Interpreter

### User interface options

At the time of writing, sick does not use any interface: it just gets its orders from the command line, does what it needs to do, and terminates. A future version may do more. In the meantime, there are a number of command-line options to select a user interface, but the selection is ignored.

Long option | Short | Meaning
--- | --- | ---
--graphic | -X | GTK-based graphical interface
--curses | -c | Curses-based text interface
--line |  | ReadLine-based text interface
--batch |  | Batch mode, no user interface (default)
--interface=NAME | -iNAME | Load the specified interface

CLC-INTERCAL 1.-94.-2 no longer includes the user interfaces in the Base distribution: these are available as separate packages with name UI-Interface, for example UI-X, UI-Curses or UI-Line. This allows new interfaces to be developed and distributed separately.

## Embedding INTERCAL in Perl source

Instead of calling sick from the command line, it is possible to just embed an INTERCAL program in Perl sources. The block of INTERCAL starts by loading the Language::INTERCAL module, and normally extends to the end of file. The generic syntax is:

    	use Language::INTERCAL  [VERSION_REQUIRED,] OPTION => VALUE ...

Where each OPTION is a valid option to the sick command-line tool, or one of the options internally used by the compiler and not documented here. Additionally, there are three options provided by the module but not by the command-line tool: these options will be described below.

By default, the INTERCAL source starts immediately after the module has been loaded and extends to the end of file. For example, this programs will just produce "XLI" on standard read:

    	#!/usr/bin/perl

    	use Language::INTERCAL '1.-94.-2.2';
    	DO READ OUT #42
    	PLEASE GIVE UP

Adding option "debug" with a true value will show what the module is doing to your program by printing it to Perl's standard error.

Adding option "quick" with a true value loads the "sickrc" files in quick mode: this skips some checks, and is generally not recommended, but it may be necessary during testing if not all required modules are installed.

Option "escape" takes a compiled regular expression as argument and instructs the module to stop looking after any bit of source matching that regular expression. For example the following program produces "XLI" followed by "Back to perl":

    	#!/usr/bin/perl -w

    	use Language::INTERCAL
    	    escape => qr/^\s*DO GET ME OUT OF HERE\s*$/m;

    	DO .1 <- #42
    	DO READ OUT .1
    	DO GIVE UP
    	DO GET ME OUT OF HERE

    	print "Back to perl\n";

Note that the INTERCAL source must contain a GIVE UP, otherwise il will splat instead of going back to Perl.

Using the "escape" option it's possible to have multiple blocks of INTERCAL intereleaved with Perl, for example:

    	#!/usr/bin/perl -w

    	use Language::INTERCAL
    	    escape => qr/^\s*DO GET ME OUT OF HERE\s*$/m;
    	DO READ OUT #1
    	DO GIVE UP
    	DO GET ME OUT OF HERE

    	print "Back to perl 1\n";

    	use Language::INTERCAL
    	    escape => qr/^\s*WE ARE HAVING FUN HERE\s*$/m;
    	DO READ OUT #2
    	DO GIVE UP
    	WE ARE HAVING FUN HERE

    	print "Back to perl 2\n";

    	use Language::INTERCAL;
    	DO READ OUT #3
    	DO GIVE UP

This produces: `

    	I
    	Back to perl 1
    	II
    	Back to perl 2
    	III

`

Note that currently each block of INTERCAL is executed by its own independent interpreter, so that there is no communication between them; however a block running in a perl's loop will have all register values preserved across iterations. For example the program: ``

    	#!/usr/bin/perl -w

    	for my $i (1..5) {
    	    print ".1 = ";
    	    use Language::INTERCAL escape => qr/^\s*DO GET ME OUT OF HERE\s*$/m;
    		(2) DO .2 <- #2 ~ .VVVVVVVVVVVVVVVV1
    		(1) DO .1 <- #1
    		    PLEASE COME FROM .2
    		    DO .1 <- .1 ¢ .1
    		    PLEASE COME FROM (1)
    		    DO READ OUT .1
    		    DO GIVE UP
    	    DO GET ME OUT OF HERE
    	    print "i = $i\n";
    	}

Will initialise register .1 to #1 the first time through the loop, subsequent iterations interleave .1 with itself instead, so the output is: `

    	.1 = I
    	i = 1
    	.1 = III
    	i = 2
    	.1 = XV
    	i = 3
    	.1 = CCLV
    	i = 4
    	.1 = lxvDXXXV
    	i = 5

`

Since there is no filename, the module assumes that it is compiling a CLC-INTERCAL source with no special extensions; however, passing the "suffix" option will result in that being used to determine a set of preloads; or else, passing the "preload" option as many times as necessary will work the same as when running the command-line tool.

While most of sick's options will work the same as when provided on the command line, "backend" is ignored and the module will always use the "Run" backend.