Next: Operators, Previous: Constants and Variables, Up: Expressions [Index]
Because there are no operator precedences in INTERCAL, there are various solutions to specifying what precedences actually are.
All known versions of INTERCAL accept the
INTERCAL-72 grouping rules. These state that
it’s possible to specify that an operator takes precedence by
grouping it inside sparks ('
) or rabbit-ears
("
), the same way as wax/wane pairs (parentheses) are
used in other programming languages. INTERCAL-72 and
earlier C-INTERCAL versions demanded that expressions
were grouped fully like this, and this practice is still
recommended because it leads to portable programs and is easier to
understand. Whether sparks or rabbit-ears (often called just
‘ears’ for short) are used normally doesn’t
matter, and programmers can use one or the other for clarity or for
aesthetic appeal. (One common technique is to use just sparks at
the outermost level of grouping, just ears at the next level, just
sparks at the next level, and so on; but expressions like
''#1~#2'~"#3~#4"'~#5
are completely unambiguous, at
least to the compiler.)
There are, however, some complicated situations involving array subscripting where it is necessary to use sparks and ears at alternate levels, if you want to write a portable program. This limitation is in C-INTERCAL to simplify the parsing process; INTERCAL-72 has the same limitation, probably for the same reason. Compare these two statements:
DO .1 <- ,3SUB",2SUB.1".2 DO .1 <- ,3SUB",2SUB.1".2~.3"".4
The problem is that in the first statement, the ears close a group, and in the second statement, the ears open a group, and it’s impossible to tell the difference without unlimited lookahead in the expression. Therefore, in similar situations (to be precise, in situations where a group is opened inside an array subscript), it’s necessary to use the other grouping character to the one that opened the current group if you want a portable program.
One final comment about sparks and rabbit-ears; if the next
character in the program is a spot, as often happens because
onespot variables are common choices for operands, a spark and the
following spot can be combined into a wow (!
).
Unfortunately, the rabbit-ear/spot combination has no one-character
equivalent in any of the character sets that
C-INTERCAL accepts as input (UTF-8, Latin-1, and
ASCII-7) as none of these contain the rabbit character, although
the Hollerith input format that CLC-INTERCAL can use
does.
The precedence rules used by CLC-INTERCAL for grouping
when full grouping isn’t used are simple to explain: the
largest part of the input that looks like an expression is taken to
be that expression. The main practical upshot of this is that
binary operators right-associate; that is, .1~.2~.3
is
equivalent to .1~'.2~.3'
. C-INTERCAL
versions 0.26 and later also right-associate binary operators so as
to produce the same results as CLC-INTERCAL rules in
this situation, but as nobody has yet tried to work out what the
other implications of CLC-INTERCAL rules are they are
not emulated in C-INTERCAL, except possibly by chance.
In INTERCAL-72 and versions of C-INTERCAL
before 0.26, unary operators were always in the ‘infix’
position. (If you’re confused about how you can have an infix
unary operator: they go one character inside a group that they
apply to, or one character after the start of a constant or
variable representation; so for instance, to portably apply the
unary operator &
to the variable :1
,
write :&1
, and to portably apply it to the
expression '.1~.2'
, write '&.1~.2'
.)
CLC-INTERCAL, and versions of C-INTERCAL
from 0.26 onwards, allow the ‘prefix’ position of a
unary operator, which is just before whatever it applies to (as in
&:1
). This leads to ambiguities as to whether an
operator is prefix or infix. The portable solution is, of course,
to use only infix operators and fully group everything, but when
writing for recent versions of C-INTERCAL, it’s
possible to rely on its grouping rule, which is: unary operators
are interpreted as infix where possible, but at most one infix
operator is allowed to apply to each variable, constant, or group,
and infix operators can’t apply to anything else. So for
instance, the C-INTERCAL
'&&&.1~.2'
is equivalent to the portable
'&"&.&1"~.2'
(or the more readable version
of this, "&'"&.&1"~.2'"
, which is also
portable). If these rules are counter-intuitive to you, remember
that this is INTERCAL we’re talking about;
note also that this rule is unique to C-INTERCAL, at
least at the time of writing, and in particular
CLC-INTERCAL is likely to interpret this expression
differently.
Next: Operators, Previous: Constants and Variables, Up: Expressions [Index]