Next: , Previous: , Up: Expressions   [Index]


6.2 Grouping Rules

Because there are no operator precedences in INTERCAL, there are various solutions to specifying what precedences actually are.

The portable solution

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.

Positional precedences: CLC-INTERCAL rules

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.

Prefix and infix unary operators

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: , Previous: , Up: Expressions   [Index]