Next: PIC-INTERCAL, Previous: Multithreading and Backtracking, Up: Top [Index]
INTERCAL-72 | C-INTERCAL | CLC-INTERCAL | J-INTERCAL |
---|---|---|---|
no | version 0.26+ | version 0.05+ | no |
(Operand overloading in C-INTERCAL is nowhere near as advanced as it is in CLC-INTERCAL. This chapter only explains the partial implementation used by C-INTERCAL; for a full implementation, see CLC-INTERCAL and its documentation.)
Operand overloading is a method of using a onespot or twospot variable as a substitute for an expression. When a variable is overloaded to an expression (which could be another variable, or something more complex), any uses of that variable cause the expression to be substituted instead.
At the beginning of the program, all variables stand for themselves; so
.1
really does mean .1
, for instance. The
meaning of a variable can be overloaded using the slat operator
(/
), which is the same in both Princeton and Atari syntax:
it is a binary operator whose left argument must be a onespot or
twospot variable and whose right argument can be any expression. The
slat operator returns the true value of its left argument, but as a
side effect, changes the meaning of its left argument to be its right
argument. Here is an example:
DO .1 <- .2/'.3~.4'
The example causes .2
’s true value to be assigned to
.1
(unless of course .1
is read-only), but
also causes .2
from then on to actually mean
'.3~.4'
, except when it’s the left operand of a slat
operator. So for instance, DO .1 <- .2
would actually
assign '.3~.4'
to .1
. Somewhat confusingly,
this also works in the other direction; DO .2 <- .1
would assign .1
to '.3~.4'
, which would have
the effect of changing the values of .3
and
.4
so that '.3~.4'
had the correct value, or
throw an error if it couldn’t manage this. (The general rule in
this case is that any variable or constant in the expression that
overloads the variable is at risk of being changed; this is known as a
‘reverse assignment’. Code like DO .1 <-
.1/#1
is entirely capable of changing the value of
#1
, although to protect new INTERCAL
users C-INTERCAL will refuse to carry out operations that
change the value of constants unless a command-line switch (see
-v) is used to give it permission.
In C-INTERCAL, changing the value of a constant only
changes meshes with that value, but in CLC-INTERCAL it can
also change non-mesh uses of that constant, so doing so is not portable
anyway.)
When multiple overloading rules are in effect, they are all applied;
overloading .1
to '.2~.3'
and .2
to '.3$.4'
will cause .1
to refer to
''.3$.4'~.3'
. However, this expansion stops if this would
cause a loop; to be precise, overloading is not expanded if the
expansion is nested within the same expansion at a higher level (so
.1/.2
and .2/.1
together cause
.1
to expand to .2
, which expands to
.1
, which cannot expand any further). In
C-INTERCAL, the expression on the right hand side of a
slat is not evaluated and not expanded by operand overloading.
STASHING
a variable causes its overloading information to
be stashed too; RETRIEVING
it causes its overload rule to
also be retrieved from the stash (or any overload rule on the variable
to be removed if there wasn’t one when the variable was stashed).
Overloading a onespot variable to a twospot variable or vice versa is possible, but the results are unlikely to be predictable, especially if a onespot variable is used to handle a twospot value. Possible outcomes include truncating the value down to the right bitwidth, throwing an error if a value outside the onespot range is used, and even temporarily handling the entire twospot value as long as it doesn’t end up eventually being assigned a value greater than twospot.
Note that reverse assignments can cause unpredictable behaviour if an
attempt is made to reverse-assign the same variable twice in the same
expression. In particular, sequences of commands like DO .1 <-
.2/'.3$.3' DO .2 <- #6
are liable to succeed assigning
garbage to .3
rather than failing as they ought to do, and
likewise any situation where a variable is reverse-assigned twice in
the same expression may assign garbage to it. This behaviour is seen as
unsatisfactory, though, and plans exist to improve it for future
versions.
Next: PIC-INTERCAL, Previous: Multithreading and Backtracking, Up: Top [Index]