view interps/clc-intercal/CLC-INTERCAL-Docs-1.-94.-2/blib/htmldoc/statements.html @ 9071:581584df6d82

<fizzie> revert 942e964c81c1
author HackBot
date Sun, 25 Sep 2016 20:17:31 +0000
parents 859f9b4339e6
children
line wrap: on
line source

<HTML>
    <HEAD>
	<TITLE>CLC-INTERCAL Reference</TITLE>
    </HEAD>
    <BODY>
	<H1>CLC-INTERCAL Reference</H1>
	<H2>... Statements</H2>

	<P>
	The statements are described in an order which minimises forward references.
	In other words, the first time you read this page go from beginning to end.
	For easy reference, an alphabetic list follows. See the description for the
	various statements to determine which compilers support them.
	</P>

	<P>
	Table of contents:
	<UL>
	    <LI><A HREF="index.html">Parent directory</A>
	    <LI><A HREF="#abstain_from">ABSTAIN FROM</A>
	    <LI><A HREF="#calculate">Calculate</A>
	    <LI><A HREF="#case">CASE</A>
	    <LI><A HREF="#come_from">COME FROM</A>
	    <LI><A HREF="#comments">Comments</A>
	    <LI><A HREF="#convert">CONVERT</A>
	    <LI><A HREF="#create">CREATE</A>
	    <LI><A HREF="#destroy">DESTROY</A>
	    <LI><A HREF="#enrol">ENROL</A>
	    <LI><A HREF="#enslave">ENSLAVE</A>
	    <LI><A HREF="#finish_lecture">FINISH LECTURE</A>
	    <LI><A HREF="#forget">FORGET</A>
	    <LI><A HREF="#free">FREE</A>
	    <LI><A HREF="#give_up">GIVE UP</A>
	    <LI><A HREF="#graduates">GRADUATES</A>
	    <LI><A HREF="#ignore">IGNORE</A>
	    <LI><A HREF="#learns">LEARNS</A>
	    <LI><A HREF="#next">NEXT</A>
	    <LI><A HREF="#next_from">NEXT FROM</A>
	    <LI><A HREF="#read_out">READ OUT</A>
	    <LI><A HREF="#reinstate">REINSTATE</A>
	    <LI><A HREF="#remember">REMEMBER</A>
	    <LI><A HREF="#resume">RESUME</A>
	    <LI><A HREF="#retrieve">RETRIEVE</A>
	    <LI><A HREF="#steal">SMUGGLE</A>
	    <LI><A HREF="#stash">STASH</A>
	    <LI><A HREF="#steal">STEAL</A>
	    <LI><A HREF="#study">STUDY</A>
	    <LI><A HREF="#swap">SWAP</A>
	    <LI><A HREF="#while">WHILE</A>
	    <LI><A HREF="#write_in">WRITE IN</A>
	</UL>
	</P>

	<H2><A NAME="comments">Comments</A></H2>

	<P>
	Any statement which cannot be recognised is simply inserted in the compiled
	program. Executing this statement is very likely to be an error, however
	one can make sure the comments are ABSTAINed FROM (see below), so they
	won't be executed.
	</P>

	<P>
	The following statement is initially ABSTAINed FROM (because of the word
	"NOT" as a prefix of "NOTE"):
<PRE>
    PLEASE NOTE THAT WE DO NOT KNOW WHAT WE ARE TALKING ABOUT
</PRE>
	(in fact, this example contains two statements, but this is OK as they
	are both ABSTAINed FROM).
	</P>

	<P>
	If a comment is executed, it is printed as an error message. For example,
<PRE>
    DO YOU REALISE THAT USING INTERCAL IS BAD FOR YOUR SANITY?
    PLEASE DO SOMETHING ELSE.
</PRE>
	would print the first line and terminate the program (the second
	line is understood by the compiler as a separate statement,
	which does not get executed because the first line terminates
	the program).
	</P>

	<P>
	Comments usually correspond to a splat code 0. Other error codes are
	listed in <A HREF="errors.html">the chapter about Errors</A>.
	</P>

	<H2><A NAME="calculate">Calculate</A></H2>

	<P>
	This statement has the form of a register name, a left arrow
	(<CODE>&lt;-</CODE>) and an expression. The effect is to assign the value
	of the expression to the register.
	</P>

	<P>
	Examples:<BR>
	<CODE>DO .1 &lt;- #3</CODE><BR>
	<CODE>DO ,1 SUB .1 SUB .2 &lt;- .3~#3</CODE>
	</P>

	<P>
	If the left-hand side contains an array without subscripts, this statement
	will dimension the array (or redimension it, throwing away the old contents).
	In this case, it is possible to specify multidimensional arrays by including
	more than one expression, separated by the keyword "BY".
	</P>

	<P>
	Example:<BR>
	<CODE>DO ,1 &lt;- #3 BY #4 BY .1</CODE><BR>
	CLC-INTERCAL 1.-94.-4 and newer allows to assign to constants,
	or indeed to any expression (when the compiler is sick). This
	result has always been possible using overloading, but it is now
	easier to achieve.
	</P>

	<P>
	Examples:<BR>
	<CODE>DO #1 &lt;- #3</CODE><BR>
	<CODE>DO .1 &lt;- #4</CODE><BR>
	assigns #3 to #1 and then assigns #4 to .3
	(because the value of the "1" in .1 is now 3).
	</P>

	<P>
	Examples:<BR>
	<CODE>DO .2 &lt;- #1</CODE><BR>
	<CODE>DO #1 &lt;- #3</CODE><BR>
	<CODE>DO #3 &lt;- .1</CODE><BR>
	swaps the values of #1 and #3.
	</P>

	<P>
	Quantum INTERCAL allows the programmer to do and not-do the
	assignment at the same time using syntax <CODE>DO .1 &lt;- #2 WHILE NOT
	ASSIGNING TO IT</CODE>. This is described in more detail in
	<A HREF="quantum.html">the chapter about Quantum INTERCAL</A>.
	</P>

	<H2><A NAME="ignore">IGNORE</A></H2>

	<P>
	The keyword "IGNORE" is followed by a list of registers,
	separated by intersection (<CODE>+</CODE>). After this, any
	attempt to modify the values of the registers will be silengly
	ignored, but any side effect will still happen, so if you try to
	WRITE IN an ignored register you discard some input, and if you
	assign an expression containing overloading you still execute the
	overloading; however, if you try to overload in IGNOREd register,
	this overloading won't be applied.
	</P>

	<P>
	Note that you can IGNORE whole arrays, but not single subscripts.
	</P>

	<P>
	The effect of IGNORE ceases when a REMEMBER lists the same registers.
	</P>

	<P>
	Examples:<BR>
	<CODE>IGNORE .1 + ,1 + :3</CODE><BR>
	<CODE>IGNORE $49.99</CODE>
	<P>

	<P>
	Quantum INTERCAL allows the programmer to set the "ignore" state of a
	variable to both true and false symultaneously, for example:<BR>
	<CODE>IGNORE .1 + ,1 + :3 WHILE REMEMBERING THEM</CODE><BR>
	<CODE>IGNORE $49.99 WHILE REMEMBERING IT</CODE><BR>
	This is described in more detail in <A HREF="quantum.html">the
	chapter about Quantum INTERCAL</A>.
	</P>

	<H2><A NAME="remember">REMEMBER</A></H2>

	<P>
	The keyword is followed by a list of registers, separated by intersection
	(<CODE>+</CODE>). It undoes the effect of an IGNORE on those registers, so
	subsequent changes will affect them. It is not an error to REMEMBER a
	register which had not been IGNOREd. It is possible to follow the list
	with <CODE>WHILE IGNORING THEM</CODE> to produce a program which
	simultaneously remembers and ignores the registers: see
	<A HREF="quantum.html">the chapter about Quantum INTERCAL</A>.
	</P>

	<H2><A NAME="abstain_from">ABSTAIN FROM</A></H2>

	<P>
	This is followed by either a label or a list of gerunds separated by
	intersection (<CODE>+</CODE>). The statement corresponding to that label,
	or all statements corresponding to the gerunds, will not be executed from
	now on (until a REINSTATE is executed).
	</P>

	<P>
	It is not possible to ABSTAIN FROM GIVING UP. If you ABSTAIN FROM a label,
	and that happens to be a GIVE UP statement, this is silently ignored.
	</P>

	<P>
	For example, the following program will assign 12 to register <CODE>.1</CODE>
<PRE>
    PLEASE ABSTAIN FROM (1)
(1) DO ABSTAIN FROM CALCULATING + ABSTAINING
    DO .1 &lt;- #12
    DO ABSTAIN FROM (2)
(2) DO .1 &lt;- #4
    PLEASE GIVE UP
</PRE>
	</P>

	<P>
	It is possible to ABSTAIN FROM ABSTAINING. It is also possible to ABSTAIN
	FROM REINSTATING, although we do not recommend it.
	</P>

	<P>
	The presence of a negative (<CODE>NOT</CODE>, <CODE>N'T</CODE> or
	<CODE>&#172;</CODE>) before a statement will cause it to be initially
	ABSTAINED FROM, so the above program is equivalent to:
<PRE>
    DO NOT ABSTAIN FROM CALCULATING + ABSTAINING
    DO .1 &lt;- #12
    DO NOT .1 &lt;- #4
    PLEASE GIVE UP
</PRE>
	</P>

	<P>
	Which in turn is the same as:
<PRE>
    DO .1 &lt;- #12
    PLEASE GIVE UP
</PRE>
	</P>

	<P>
	CLC-INTERCAL 1.-94 introduced ABSTAIN FROM COMMENTING, which ABSTAINs from
	anything the compiler finds unparseable. THere is a corresponding
	REINSTATE COMMENTING.
	</P>

	<P>
	If you have a quantum computer, you can simultaneously ABSTAIN
	and REINSTATE a statement or a list of gerunds:
<PRE>
    PLEASE ABSTAIN FROM (1) WHILE REINSTATING IT
(1) DO ABSTAIN FROM CALCULATING + ABSTAINING WHILE REINSTATING THEM
    DO ABSTAIN FROM CALCULATING WHILE REINSTATING IT
    PLEASE GIVE UP
</PRE>
	This is described in more detail in <A HREF="quantum.html">the
	chapter about Quantum INTERCAL</A>.
	</P>

	<P>
	A recent improvement to the Quantum INTERCAL engine allows to
	ABSTAIN FROM QUANTUM COMPUTING, which would make all quantum
	statement behave like classical ones, and the corresponding
	REINSTATE QUANTUM COMPUTING. And of course, one can ABSTAIN FROM
	QUANTUM COMPUTING WHILE REINSTATING IT.
	</P>

	<P>
	One last extension (in CLC-INTERCAL 0.05) allows to specify an expression
	instead of a label; and a statement template instead of a gerund. For example:
<PRE>
    DO ABSTAIN FROM REGISTER &lt;- EXPRESSION
                  + REMEMBER REGISTER LIST
		  + IGNORE REGISTER LIST
</PRE>
	is equivalent to:
<PRE>
    DO ABSTAIN FROM CALCULATING + REMEMBERING + IGNORING
</PRE>
	</P>

	<P>
	However, statement templates give finer control than gerunds. For example,
	after:
<PRE>
    DO ABSTAIN FROM ABSTAIN FROM LABEL + REINSTATE GERUND LIST
</PRE>
	an "ABSTAIN FROM (2)" or "REINSTATE ABSTAINING" would be ignored, but
	"ABSTAIN FROM REINSTATING" and "REINSTATE (3)" would be still executed.
	</P>

	<H2><A NAME="reinstate">REINSTATE</A></H2>

	<P>
	Followed by the same kind of things you can say after
	"ABSTAIN FROM", undoes the effects of ABSTAINING FROM these
	things. CLC-INTERCAL 0.05 or later allows an expression instead
	of a label, and a statement template instead of a gerund.
	</P>

	<P>
	You can REINSTATE REINSTATING, and it does make sense - maybe you want to
	make sure that any REINSTATE which was ABSTAINED FROM by label is
	REINSTATEd. You cannot REINSTATE GIVING UP, not even by label.
	</P>

	<P>
	Quantum program might wish to add <CODE>WHILE ABSTAINING FROM IT</CODE>
	(or <CODE>WHILE ABSTAINING FROM THEM</CODE>). See <A HREF="quantum.html">the
	chapter about Quantum INTERCAL</A>.
	</P>

	<P>
	CLC-INTERCAL 0.05 and newer allows to REINSTATE templates, with a syntax
	similar to ABSTAIN FROM templates.
	</P>

	<P>
	CLC-INTERCAL 1.-94 allows to REINSTATE COMMENTING. You probably don't want
	to do that, but it's there if you need it.
	Note that there is no template corresponding to this gerund.
	</P>

	<H2><A NAME="come_from">COME FROM</A></H2>

	<P>
	This is the main program control statement in CLC-INTERCAL. It is followed by
	either a label or an expression. When the execution reaches the label (or
	a label with the same value as the expression), it will run the current
	statement and then jump to the COME FROM. For example, this is a subroutine
	call, in which register <CODE>.1</CODE> is used to hold the "return address"
	and register <CODE>.2</CODE> to hold the "subroutine address":
<PRE>
        DO .1 &lt;- #1000
(100)   DO .2 &lt;- #100
        PLEASE COME FROM .1
        DO .1 &lt;- #0

...

        PLEASE COME FROM .2
        DO .2 &lt;- #0
...
(1000)  DON'T PANIC
</PRE>
	</P>

	<P>
	The assignment of <CODE>#100</CODE> to <CODE>.2</CODE> causes an immediate
	jump to the subroutine. At the end of the subroutine, after the
	no-op (DON'T PANIC does nothing because it is ABSTAINed FROM), the program
	jumps back to the COME FROM <CODE>.1</CODE>. We assign zero to the pointers
	just after use to avoid problems when the subroutine is called in more than
	one place.
	</P>

	<P>
	It is an error to have multiple COME FROMs pointing at the same label (unless the
	<I>thick</I> compiler option is in operation). However,
	if all except one are ABSTAINed FROM, this is not a problem. So the above
	program can be rewritten as:
<PRE>
        DO REINSTATE (101)
(100)   DO .2 &lt;- #100
(101)   PLEASE DON'T COME FROM (1000)
        DO ABSTAIN FROM (101)

...

        PLEASE COME FROM .2
        DO .2 &lt;- #0
...
(1000)  DON'T PANIC
</PRE>
	or even without computed COME FROMs (although this requires to change the
	subroutine every time you add a call - this way of removing computed COME
	FROMs is best left to the optimiser):
<PRE>
        DO REINSTATE (1001)
(100)   DO REINSTATE (101)
(101)   PLEASE DON'T COME FROM (1000)
        DO ABSTAIN FROM (101)
        DO ABSTAIN FROM (1001)

...

(1001)  PLEASE DO NOT COME FROM (100)
...
(1000)  DON'T PANIC
</PRE>
	</P>

	<P>
	The simple program to implement a stack and allow recursive subroutines using
	this technique is left as an exorcism (sic) to the reader.
	</P>

	<P>
	CLC-INTERCAL 1.-94 introduces COME FROM GERUND (and NEXT FROM GERUND): for
	example:
<PRE>
        PLEASE COME FROM COMING FROM
</PRE>
	causes an infinite loop because the statement keeps reexecuting (and COMING
	FROM itself!). Since there are runtime overheads associated with COME FROM
	GERUND, it must be requested by the compiler option <I>come-from-gerund</I>. And of
	course, templates can be used instead of gerunds, just like the ABSTAIN FROM and REINSTATE statements.
	</P>

	<P>
	When the <I>thick</I> compiler option is in operation, multiple COME FROMs
	all pointing at the same label will cause the program to start as many
	threads as necessary so it gan go to all those places.
	</P>
	       
	<P>
	When using computed COME FROMs or computed labels, please
	remember that if any of the expressions have side effects
	(e.g. overloading), these side effects can appear in the most
	unexpected places. See for example the
	<A HREF="../examples/hello.i">Hello, World</A> program,
	which works by having each of the computed COME FROM setting
	up an overload to modify the way the other computed COME FROMs
	behave. It is slightly confusing.
	</P>

	<P>
	The Quantum variant of COME FROM adds a "WHILE NOT COMING FROM
	THERE" at the end of the statement.
	</P>

	<H2><A NAME="next">NEXT</A></H2>

	<P>
	The keyword must be <EM>preceded</EM> by a label. It serves the function
	of the GO TO statement of other languages, and can also be used for subroutine
	calls. For this reason, it allow to write programs which look just like any
	other language, and this is a Bad Idea. CLC-INTERCAL considers any programs
	which use NEXT, FORGET or RESUME as obsolete, and will only run them if you
	use the <I>next</I> option, or the <I>ick</I> or <I>1972</I> compiler.
	</P>

	<P>
	Beginning with CLC-INTERCAL 0.05, the label preceding "NEXT" can be replaced
	by an expression.
	</P>

	<P>
	The effect of NEXT is to transfer control to the stated label, and also to
	save a return address in an internal stack. See FORGET and RESUME below for
	the rest of the story.
	</P>

	<P>
	This is an example of subroutine call:
<PRE>
        DO (1000) NEXT
...
(1000)  DO ....
        PLEASE RESUME #1
</PRE>
	</P>

	<P>
	The Quantum version of NEXT adds "WHILE NOT NEXTING" at the end of the statement.
	</P>

	<H2><A NAME="forget">FORGET</A></H2>

	<P>
	Followed by an expression. It evaluates the expression, then removes that
	many return addresses from the stack managed by NEXT and RESUME. These
	addresses are simply discarded. If you want to use NEXT as a GO TO, you
	should FORGET #1 just afterwards so the stack does not overflow.
	</P>

	<P>
	The Quantum version of FORGET adds "WHILE REMEMBERING" at the end of
	the statement; for compatibility with previous versions of CLC-INTECAL,
	"WHILE NOT FORGETTING" can also be used.
	</P>

	<H2><A NAME="resume">RESUME</A></H2>

	<P>
	Followed by an expression. It evaluates the expression, then removes that
	many return addresses from the stack managed by NEXT and FORGET. After that,
	it jumps to the last return address it removed. So RESUME #1 is a normal
	return from subroutine, while RESUME #3 is equivalent to FORGET #2 followed
	by RESUME #1.
	</P>

	<P>
	The Quantum version of RESUME adds "WHILE NOT RESUMING" at the end of the statement.
	</P>

	<H2><A NAME="next_from">NEXT FROM</A></H2>

	<P>
	Like <CODE>COME FROM</CODE>, but it saves the return address, as a
	<CODE>NEXT</CODE> would do. It has the same syntax as <CODE>COME FROM</CODE>:
<PRE>
    PLEASE NEXT FROM (666)
    ...
    DO RESUME #1
</PRE>
	</P>

	<P>
	Just after executing the statement with label (666) the program jumps to the
	above fragment: at the end, it returns to the statement after the one with
	the label (666).
	</P>

	<P>
	The Quantum version of NEXT FROM uses the syntax "WHILE NOT NEXTING FROM THERE"
	</P>

	<H2><A NAME="stash">STASH</A></H2>

	<P>
	Followed by a list of registers, it copies them to some secret place for
	safekeeping. You can stash whole arrays, but not single elements (well,
	you can always assign the element to a register and then STASH that).
	Note that not just the values are saved: the current BELONGS TO relation,
	the current overloading, and the current IGNORE/REMEMBER state are also
	saved. See RETRIEVE for the second half of the story.
	</P>

	<H2><A NAME="retrieve">RETRIEVE</A></H2>

	<P>
	Followed by a list of registers, it rummages through the STASH until it
	finds the most recent saved values of these registers, and restores them.
	These values are removed from the STASH, which effectively acts like a stack
	(yet another normal programming concept which has managed to creep into
	INTERCAL, sigh). After RETRIEVE, the register's value, BELONGS TO relation,
	overloading, and IGNORE/REMEMBER state are restored as they were before the
	corresponding STASH.
	</P>

	<P>
	For example, the following program leaves <CODE>.1</CODE>, <CODE>;1</CODE> and
	<CODE>,1 SUB #1</CODE> unchanged:
<PRE>
        PLEASE STASH .1 + ;1
        DO .1 &lt;- ,1 SUB #1
        DO STASH .1
        DO ,1 SUB #1 &lt;- #0
        DO ;1 SUB .1 &lt;- #1
...
        PLEASE RETRIEVE .1
        DO ,1 SUB #1 &lt;- .1
        DO RETRIEVE .1 + ;1
</PRE>
	</P>

	<P>
	Quantum version of STASH and RETRIEVE are of course available, by appending
	"WHILE NOT STASHING THEM" or "WHILE NOT RETRIEVING THEM".
	</P>

	<H2><A NAME="give_up">GIVE UP</A></H2>

	<P>
	Finishes executing the program, presumably returning to saner things like a
	shell or perhaps JCL.
	</P>

	<P>
	ABSTAIN FROM and REINSTATE do not have any effect on GIVE UP. This means that
	you can always GIVE UP, no matter how badly you've managed to screw up your
	program. Also, it means that DON'T GIVE UP is guaranteed to be a no-op.
	</P>

	<P>
	The quantum version of GIVE UP appends "WHILE CONTINUING TO RUN"
	to the statement. What happens is that the program continues
	to run, the fact it also stops at the same time is irrelevant
	because it is not observable.
	</P>

	<P>
	An interesting side-effect of the Quantum version is that if you
	ABSTAIN FROM QUANTUM COMPUTING and then GIVE UP WHILE CONTINUING
	TO RUN, you effectively GIVE UP; however if you REINSTATE QUANTUM
	COMPUTING then the above Quantum GIVE UP is a no-op. In other
	words, you can abstain from giving up, using this trick, by
	calling it REINSTATE QUANTUM COMPUTING.
	</P>

	<H2><A NAME="read_out">READ OUT</A></H2>

	<P>
	Followed by a register list (arrays can be with or without subscripts),
	will read the contents of the register to the standard output. See
	<A HREF="input_output.html">the chapter on Input/Output</A>.
	</P>

	<P>
	There is no Quantum READ OUT. Either you do it, or you don't.
	</P>

	<H2><A NAME="write_in">WRITE IN</A></H2>

	<P>
	Followed by a register list (arrays can be with or without subscripts),
	will write into the register from the standard input. See
	<A HREF="input_output.html">the chapter on Input/Output</A>.
	</P>

	<P>
	The quantum WRITE IN (which appends "WHILE NOT WRITING THEM" to
	the statement) always consumes some input, except that it assigns
	it to variables while at the same time not assigning it. This is
	not the same as executing the WRITE IN while not executing it,
	which would require the input to be consumed while at the same
	time not being consumed, which would be impossible as the internal
	quantum state could be observed.
	</P>

	<H2><A NAME="enslave">ENSLAVE</A></H2>

	<P>
	Followed by two registers (without subscripts, if arrays), using the form:
<PRE>
    DO ENSLAVE .1 TO ,1
</PRE>
	it sets the BELONGS TO relation between the first and the second. It is
	not an error if the first register is already a slave, although it can
	be confusing. See <A HREF="belongs.html">the chapter on Belongs TO</A>.
	</P>

	<P>
	The Quantum version of this statement appends "WHILE LEAVING IT FREE"
	</P>

	<H2><A NAME="free">FREE</A></H2>

	<P>
	Followed by two registers (without subscripts, if arrays), using the form:
<PRE>
    DO FREE .1 FROM ,1
</PRE>
	it removes the BELONGS TO relation between the first and the second. It is
	an error if the first register was not a slave of the second. If the first
	register BELONGed TO more than one register, the other owners remain
	unchnanged. See <A HREF="belongs.html">the chapter on Belongs TO</A>.
	</P>

	<P>
	The Quantum version of this statement appends "WHILE LEAVING IT IN SLAVERY"
	</P>

	<H2><A NAME="study">STUDY</A></H2>

	<P>
	Followed by a subject number, a lecture label, and a class name, using a
	format like:
<PRE>
    DO STUDY #2 AT (1030) IN CLASS @4
</PRE>
	It advertise that the lecture is available. See
	<A HREF="lectures.html">the chapter on Classes and Lectures</A>.
	</P>

	<P>
	Beginning with CLC-INTERCAL 0.05, the subject number and the label can
	be replaced by expressions.
	</P>

	<P>
	The Quantum version of this statement appends "WHILE NOT STUDYING IT"
	</P>

	<H2><A NAME="enrol">ENROL</A></H2>

	<P>
	Followed by a register (without subscripts, if an array) and a list of
	subjects, using a format like:
<PRE>
    DO ENROL .2 TO LEARN #1 + #4 + #5
</PRE>
	</P>

	<P>
	It looks for a class where these subjects are taught, and makes a note that
	the register is not a student there. It is an error if no class is found
	which teaches these subjects, or if there is more than one eligible class.
	The latter case results in a CLASS WAR error. See
	<A HREF="lectures.html">the chapter on Classes and Lectures</A>.
	</P>

	<P>
	Beginning with CLC-INTERCAL 0.05, the subject numbers can be specified
	as expressions and need not be constant.
	</P>

	<P>
	The Quantum version of this statement appends "WHILE NOT ENROLLING"
	</P>

	<H2><A NAME="learns">LEARNS</A></H2>

	<P>
	Preceded by a register (without subscripts, if an array) and followed by
	a subject number, as in:
<PRE>
    DO .2 LEARNS #4
</PRE>
	</P>

	<P>
	The register must have ENROLled in a class which teaches that subject. The
	effect is to go to the lecture. The class will be temporarily ENSLAVed to
	the register. This can be used to replace what other languages call "self"
	or "this". See
	<A HREF="lectures.html">the chapter on Classes and Lectures</A>.
	</P>

	<P>
	Beginning with CLC-INTERCAL 0.05, the subject number can be specified
	as an expression.
	</P>

	<P>
	The Quantum version of this statement is specified with "WHILE NOT LEARNING IT"
	</P>

	<H2><A NAME="finish_lecture">FINISH LECTURE</A></H2>

	<P>
	Used in lectures to return to the statement following the last LEARNS. See
	<A HREF="lectures.html">the chapter on Classes and Lectures</A>.
	</P>

	<P>
	The Quantum version of this statement is specified with "WHILE CONTINUING IT"
	</P>

	<H2><A NAME="graduates">GRADUATES</A></H2>

	<P>
	Preceded by a register (if an array, without subscripts), it removes it
	from the list of students of all classes. The effect is that the register
	cannot LEARN anything after that, unless he ENROLs again. See
	<A HREF="lectures.html">the chapter on Classes and Lectures</A>.
	</P>

	<P>
	The Quantum version of this statement is specified with "WHILE REMAINING A STUDENT"
	</P>

	<H2><A NAME="convert">CONVERT</A></H2>

	<P>
	Followed by one statement template, the keyword "TO", and another statement
	template. At runtime, the meaning of the first statement is changed into
	the meaning of the second. In most back ends, this will be implemented by
	keeping a list of code refences (or pointer to functions or whatever),
	and changing them as needed. The statements must be "compatible", i.e.
	their syntactic definition must use the same terminals. For example,
	the statement ABSTAIN FROM can contain wither a single LABEL or a
	GERUND LIST. In the latter form, can only be converted to a REINSTATE.
	In the form with LABEL, it can be converted to COME FROM, NEXT, or REINSTATE.
	The statements to do all these conversions are:
<PRE>
    DO CONVERT ABSTAIN FROM GERUND LIST TO REINSTATE GERUND LIST
    DO CONVERT ABSTAIN FROM LABEL TO COME FROM LABEL
    DO CONVERT ABSTAIN FROM LABEL TO LABEL NEXT
    DO CONVERT ABSTAIN FROM LABEL TO REINSTATE LABEL
</PRE>
	</P>

	<P>
	There is a quantum version of this statement, obtained adding the
	string "WHILE LEAVING IT UNCHANGED" at the end. This has the effect
	of doing the conversion but at the same time not doing it.
	This is described in more detail in <A HREF="quantum.html">the
	chapter about Quantum INTERCAL</A>.
	</P>

	<P>
	This statement was introduced in CLC-INTERCAL 0.05.
	</P>

	<H2><A NAME="swap">SWAP</A></H2>

	<P>
	Followed by one statement template, the keyword "AND", and another statement
	template. At runtime, the meaning of the first statement is changed into
	the meaning of the second, and vice versa. In most back ends, this will
	be implemented by keeping a list of code refences (or pointer to functions
	or whatever), and changing them as needed. The statements must be
	"compatible", i.e. their syntactic definition must use the same terminals.
	For example, "CALCULATE" has two terminals, a REGISTER and an EXPRESSION.
	The other statement which has the same terminals is LEARNS. Therefore, they
	can be swapped. The two following statements both do the same (and undo
	each other):
<PRE>
     DO SWAP REGISTER &lt;- EXPRESSION AND REGISTER LEARNS EXPRESSION
     DO SWAP REGISTER LEARNS EXPRESSION AND REGISTER &lt;- EXPRESSION
</PRE>
	</P>

	<P>
	There is a quantum version of this statement, obtained adding the
	string "WHILE LEAVING THEM UNCHANGED" at the end. This has the effect
	of doing the swapping but at the same time not doing it.
	This is described in more detail in <A HREF="quantum.html">the
	chapter about Quantum INTERCAL</A>.
	</P>

	<P>
	This statement was introduced in CLC-INTERCAL 0.05
	</P>

	<H2><A NAME="create">CREATE</A></H2>

	<P>
	This is the most powerful statement of CLC-INTERCAL, and, by necessity, the
	most complex. The syntax is described in detail in <A HREF="parsers.html">the
	chapter about parsers</A>. It extends the C-unlike postprocessor (see the
	<A HREF="#convert">convert</A> and <A HREF="#swap">swap</A> statements) in
	such a way that a complete compiler can be written out of <CODE>CREATE</CODE>
	statements. In fact, CLC-INTERCAL 1.-94 and newer are written this way.
	</P>

	<P>
	This statement was introduced in CLC-INTERCAL 1.-94.
	</P>

	<P>
	The Quantum version of this statement appends "WHILE NOT CREATING IT"
	</P>

	<H2><A NAME="destroy">DESTROY</A></H2>

	<P>
	This statement undoes the effect of a CREATE. Note that since
	the compiler itself is just a big list of CREATE statement you
	can also remove bits of the compiler you don't like. The syntax
	is described in detail in <A HREF="parsers.html">the chapter
	about parsers</A>.
	</P>

	<P>
	This statement was introduced in CLC-INTERCAL 1.-94.
	</P>

	<P>
	The Quantum version of this statement appends "WHILE NOT DESTROYING IT"
	</P>

	<H2><A NAME="while">WHILE</A></H2>

	<P>
	Preceded by a statement, and followed by another one, executes the two
	simultaneously. The first statement acts as a "loop control" for the
	second, which is repeated as many times as needed. For example:
<PRE>
    PLEASE STUDY #1 AT (1000) IN CLASS @1
    DO ENROL .1 TO LEARN #1
    DO .1 LEARNS #1 WHILE READ OUT .1
</PRE>
	</P>

	<P>
	Would keep reading out the value of .1 until the lecture is finished. This
	might or might not cause disruption to the lecture.
	</P>

	<P>
	The first statement can be replaced by an expression, in which case the
	WHILE statement is called "event statement". If the expression can be
	evaluated, the statement is executed and the program continues as normal.
	If the expression produces an error, the WHILE is kept in suspended animation
	until it is possible to execute it. For example:
<PRE>
    DO ,1 &lt;- #2
    PLEASE DO ,1 SUB #1 #1 WHILE ,1 SUB #1 #1 &lt;- #5
    DO ,1 SUB #1 &lt;- #2
    DO ,1 &lt;- #2 BY #2
    DO .1 &lt;- ,1 SUB #1 #1
    DO READ OUT .1
</PRE>
	</P>

	<P>
	Will read "V". This is because the ",1 SUB #1 #1" produces an error (too
	many subscripts), but is retried as soon as ,1 is redimensioned, and causes
	#5 to be assigned to ",1 SUB #1 #1" after dimensioning but before assigning
	to .1
	</P>

	<P>
	This statement was introduced in CLC-INTERCAL 0.05.
	</P>

	<P>
	Note that there isn't a Quantum version of this statement, although
	its two sub-statements can be quantum, for example:
<PRE>
    DO ABSTAIN FROM (1) WHILE REINSTATING IT
       WHILE
       COME FROM (2) WHILE NOT COMING FROM THERE
</PRE>
	</P>

	<H2><A NAME="steal">STEAL and SMUGGLE</A></H2>

	<P>
	This statement is only available when the internet option is
	in force. Since CLC-INTERCAL 1.-94.-2 this also requires the
	optional package CLC-INTERCAL-INET to be installed.
	</P>

	<P>
	The statement is followed by a list of variables,
	optionally ON and a Process ID and optionally FROM and an IP
	address. For example:
<PRE>
    DO STEAL .1 ON #1234 FROM :1
    DO STEAL .1 ON #1234
    DO STEAL .1 FROM :1
    DO STEAL .1
</PRE>
	</P>

	<P>
	The first statement connects to a computer with IP address :1
	(a 32 bit number interpreted as an IP address), and locates the
	INTERCAL program with Process ID #1234. If that can be found, its
	.1 variable is stolen (see below). The second statement is similar,
	but it connects to a random IP address obtained by broadcasting
	on the local network. The third statement specifies an IP address
	but not a Process ID: the remote computer is asked to provide
	a random one. Finally, the last statement broadcasts for an IP
	address, then asks the computer to select a random process.
	</P>

	<P>
	Stealing a variable means doing a destructive copy, so that the
	vistim can no longer use it, while the thief gets the original
	value. For example, suppose the following program runs on Process
	ID #666 on IP address 10.0.0.1:
<PRE>
    DO .1 &lt;- #2
(2) PLEASE COME FROM (.1)
    DO READ OUT .1
    DO GIVE UP
</PRE>
	(by the way, the second statement is recognised by the optimiser,
	which will cause the program to wait for a network connection
	instead of performing a busy wait, so this program will use very
	little CPU time).
	</P>

	<P>
	Now consider the following program running on some other computer:
<PRE>
    DO STEAL .1 ON #666 FROM #12288 &cent; #1
    PLEASE READ OUT .1
    DO GIVE UP
</PRE>
	</P>

	<P>
	This produces "II", because it goes to get the variable .1 from
	the previous program (#12288 &cent; #1 is 10.0.0.1; do the calculation
	if you don't believe me).
	</P>

	<P>
	Meanwhile, the first program produces NIHIL and terminates: this
	is because variable .1 has been stolen, so it's now reset to its
	initial value (#0). This causes the COME FROM to stop executing,
	and the READ OUT to produce NIHIL.
	</P>

	<P>
	If a register is IGNOREd by the victim it cannot be stolen. This
	is because stealing a register modifies it. However, the SMUGGLE
	statement, which has identical syntax, allows to copy an IGNOREd
	register, of course without modifying it. It is a runtime error to
	STEAL an IGNOREd register, or to SMUGGLE one which is not IGNOREd.
	</P>

	<P>
	Note that the thief is free to IGNORE or REMEMBER a register
	before stealing or smuggling it: the theft will always succeed,
	but the subsequent assignment of the value to the thief's variables
	is controlled by the thief's IGNORE state for the register.
	</P>

	<P>
	STEAL and SMUGGLE have Quantum counterparts, which are specified
	with "WHILE NOT STEALING IT" and "WHILE NOT SMUGGLING IT". Like
	Quantum WRITE IN, the theft always happens, but the assignment
	of the result happens while not happening.
	</P>

	<P>
	The next section suggests a way to obtain IP addresses and process IDs
	</P>

	<H2><A NAME="case">CASE</A></H2>

	<P>
	This statement is only available if the internet option is in
	effect. Followed by an expression, IN and a list of case elements
	(with the form variable THEN statement), executes a generic network
	look-up and assigns the results to the variables indicated in
	the case elements; after that, it executes all the statements in
	sequence. If there are multiple case elements, they are separated
	by the keyword OR.
	</P>

	<P>
	The network look-up performed depends on the type of the
	expression. If it is an array, it is converted to characters (as
	if you READ it OUT) and used as a name to perform a DNS look-up;
	if it is a number, it is interpreted as an IP address; if it
	happens to be a broadcast address, the corresponding broadcast
	is executed to return a list of IP addresses of computers running
	INTERCAL programs; if it is a unicast address, the corresponding
	computer is queried for the list of Process IDs running on it
	(only Process IDs of INTERCAL programs with the internet option
	are returned by this query).
	</P>

	<P>
	A network look-up returns a list of values: in the DNS or broadcast
	case, a list of IP addresses, in the unicase case, a list of
	process IDs. The list elements are assigned to the registers
	specified in the case elements. If there are more elements than
	registers, a random selection is used; if there are more registers
	than elements, the elements are duplicated to get the right number.
	</P>

	<P>
	Consider the statement:
<PRE>
    DO CASE #0 IN
       :1 THEN CASE :1 IN
          .1 THEN STEAL ,1 ON .1 FROM :1
</PRE>
	</P>

	<P>
	This is the internal implementation of DO STEAL ,1 - first,
	it broadcasts on all local network interfaces to get a list of
	IP addresses (#0 is considered a broadcast address by the CASE
	statement). Then a random one is selected (because there is only
	one case element) and assigned to :1. Then the statement inside
	the CASE is executed - this is another CASE, his time using the
	IP address returned by the first one to get a list of Process
	IDs. Again, there is only one element, so a random one is selected
	and assigned to .1 - finally, the STEAL statement uses the IP
	address and Process ID. The only real difference between this
	example and a simple DO STEAL .1 is that this example also keeps
	the random IP and PId used, which may be used by the program to
	do something else, while the implicit CASE executed by STEAL when
	ON or FROM are not specified does not save these numbers.
	</P>

	<P>
	It goes without saying that there is a Quantum CASE statement;
	the syntax is slightly unusual: DO CASE expression WHILE NOT
	CASING IT IN register THEN statement OR register THEN statement
	</P>

	<P>
	To improve the program's legibility when a CASE statement is
	nested inside another, it is possible to terminate the list of
	case elements with the keyword ESAC. This closes the innermost
	CASE. For example:
<PRE>
    DO CASE #0 IN
       :1 THEN CASE :1 IN
          .1 THEN STEAL ,1 ON .1 FROM :1
          OR
          .2 THEN READ OUT .2
          ESAC
       OR
       :2 THEN WRITE IN :3
       ESAC
</PRE>
	</P>

	<P>
	(And, yes, it's a rather meaningless program, but it shows
	the syntax)
	</P>

    </BODY>
</HTML>