Next: READ OUT and WRITE IN, Previous: IGNORE and REMEMBER, Up: Statements [Index]
INTERCAL-72 | C-INTERCAL | CLC-INTERCAL | J-INTERCAL |
---|---|---|---|
yes | all versions | all versions | all versions |
The statement identifier of a statement determines whether it’s
in an abstained or reinstated state at the start of a program; these
states determine whether the statement runs at all when it’s
encountered. It is, however, possible to change this state dynamically
during a program’s execution, and the statements to do this are
rather appropriately named ABSTAIN
and
REINSTATE
. There are two forms of each, one which takes a
single line label (which must be constant in most compilers, but can
instead be an expression in recent CLC-INTERCAL versions),
and one which takes an intersection-delimited list of gerunds. They
look like this:
DO ABSTAIN FROM ABSTAINING + REINSTATING DO ABSTAIN FROM (10) DO REINSTATE CALCULATING DO REINSTATE (22)
(This also illustrates the gerunds used for these commands; note that
ABSTAINING
from REINSTATING
is generally a
bad idea!) The line referenced, or every command represented by any
gerund referenced, are reinstated or abstained as appropriate
(effectively changing the DO to DON’T (or PLEASE to PLEASE
DON’T, etc.), or vice versa). Using these forms of
ABSTAIN
and/or REINSTATE
won’t abstain
from a command that’s already abstained, or reinstate a command
that’s already reinstated.
There is a strange set of restrictions on ABSTAIN
and
REINSTATE
that has existed since INTERCAL-72;
historically such restrictions have not always been implemented, or
have not been implemented properly. They together define an unusual
interaction of ABSTAIN
and GIVE UP
(note, for
instance, that there isn’t a gerund for GIVE UP
).
The wording used in the INTERCAL-72 manual is:
[...] the statement DO ABSTAIN FROM GIVING UP is not accepted, even though DON’T GIVE UP is. [...] DO REINSTATE GIVING UP is invalid, and attempting to REINSTATE a GIVE UP statement by line label will have no effect. Note that this insures that DON’T GIVE UP will always be a "do-nothing" statement.
This restriction was not implemented at all in the only
CLC-INTERCAL version before 0.02 (i.e. version 0.01), or
in C-INTERCAL versions before 1.26. The restriction was
implemented in C-INTERCAL version 1.26 and
CLC-INTERCAL versions 0.02 and later as “GIVE
UP
cannot be REINSTATED
or ABSTAINED
FROM
”; however, this is not strictly the same as the
definition used by INTERCAL-72 (C-INTERCAL
still uses this definition in CLC-INTERCAL compatibility
mode). The J-INTERCAL implementation of this restriction
is to make REINSTATING
or ABSTAINING
from a
line label that refers to a GIVE UP
statement a
compile-time error, but this does not fit the INTERCAL-72
definition either. The definition adopted with version 0.27 and later
of C-INTERCAL, which is hopefully correct, is to allow
abstaining from a GIVE UP
statement by line number but to
rule out the other three cases (reinstating by line number silently
fails, reinstating or abstaining by gerund is impossible because there
is no gerund).
As well as CLC-INTERCAL’s extension to
abstain/reinstate by computed line number, there is also (since version
0.25) a C-INTERCAL-specific extension to
ABSTAIN
, also known as ‘computed abstain’, but
with a different syntax and different semantics. It’s written
like an ordinary ABSTAIN
, but with an expression between
the words ABSTAIN
and FROM
, for instance:
DO ABSTAIN #1 FROM (1000) DO ABSTAIN .2 FROM WRITING IN
Unlike non-computed ABSTAIN
, this form allows a command to
be abstained from even if it’s already been abstained from; so if
the first example command is run and line (1000) is already abstained,
it becomes ‘double-abstained’. The number of times the
statement is abstained from is equal to the number of times it was
already abstained from, plus the expression (whereas with non-computed
abstain, it ends up abstained once if it wasn’t abstained at all,
and otherwise stays at the same abstention status). Reinstating a
statement always de-abstains it exactly once; so double-abstaining from
a statement, for instance, means it needs to be reinstated twice before
it will actually execute.
There are many uses for ABSTAIN
(both the computed and
non-computed versions) and REINSTATE
, especially when
interacting with ONCE
and AGAIN
(see ONCE and AGAIN); the computed
version, in particular, is a major part of a particular concise way to
write conditionals and certain kinds of loops. They also play an
important role in multithreaded programs.
Next: READ OUT and WRITE IN, Previous: IGNORE and REMEMBER, Up: Statements [Index]