begin
!
! Precedence of operators
!
! Highest: 1. ¬ (complement, unary not)
! 2. ¬, ¬¬, <<, >>
! 3. *, /, //, &
! Lowest: 4. +, - (unary and binary), !, !!
!
! In general, sub-expressions with operators of equal precedence are evaluated from left to right.
!
! The one exception to the left-hand precedence rule is that consecutive
! exponentiations are evaluated from right to left; thus A**B**C is
! evaluated as A**(B**C), not as (A**B)**C. (Imp80 documentation)
! Arithmetic operators:
! |...| modulus also: !...! (deprecated some time ago)
! ! inclusive or
! !! exclusive or
! & and
! ¬ real exponentiation also: ^ (Imp77) or ** (ERCC compilers)
! ¬¬ integer exponentiation also: ^^ (Imp77) or ****
! * multiply
! / real division
! // integer division
! << left shift
! >> right shift
! + plus
! - minus
! + unary +
! - unary -
! ¬ unary not also ~ (can be *displayed* as: ¬ (¬))
! . string concatenation
! Comparison operators:
! = eq
! # not equals also ¬= and <> (Imp80 documentation)
! == address equals
! ## address not equals also ¬==
! -> string resolution (a difficult to classify hybrid of a comparison and an assignment operator)
! <= less than or equals
! < less than
! >= greater than or equals
! >
! Assignment operators:
! = assignment
! == pointer assignment
! <- jam transfer
! -> string resolution
! Data structure operators:
! _ record field
! () array indexing
! [] pointer increment (a Hamish extension in 68000 Imp only)
! Other:
! @ may be considered an operator in %real literals, usually handled by a BIP.
const integer a = 19, b = 17, c = 5, d = 3
integer x = a * b // c * d
print string("Imp77 precedence and associativity test."); newlines(2)
if x = 21 start
print string("In a * b // c * d, '*' has higher priority than '/'."); newline
print string("A second test with '/' will be needed to determine associativity:"); newline
x = a // c // d
if x = 1 start
print string("a // c // d is right associative, i.e. a // (b // c)"); newline
else if x = 19
print string("a // c // d is left associative, i.e. (a // b) // c"); newline
else
print string("a // c // d is something weird! I give up."); newline
finish
else if x = 19
print string("a * b // c * d is right associative and with equal precedence, i.e. a * (b // (c * d))"); newline
newline
print string("This grammar would support the above:"); newline
newline
print string("P<expr> = <term> <op-term-list> ;"); newline
print string("P<op-term-list> = <op-term> <op-term-list> | ;"); newline
print string("P<op-term> = <op> <term> ;"); newline
else if x = 192
print string("a * b // c * d is left associative and with equal precedence, i.e. ((a * b) // c) * d"); newline
newline
print string("This grammar would support the above:"); newline
newline
print string("P<expr> = <term-op-list> <term> ;"); newline
print string("P<term-op-list> = <term-op> <term-op-list> | ;"); newline
print string("P<term-op> = <term> <op> ;"); newline
else
print string("a * b // c * d uses some weird non-standard combination of precedence and associativity!"); newline
finish
newline
const integer p = 4, q = 3, r = 2
integer y
y = p ^^ q ^^ r
if y = 262144 start
print string("p ^^ q ^^ r is right associative, i.e. p ^^ (q ^^ r)"); newline
newline
print string("This grammar would support the above:"); newline
newline
print string("P<expr> = <term> <exp-term-list> ;"); newline
print string("P<exp-term-list> = <exp-term> <exp-term-list> | ;"); newline
print string("P<exp-term> = ""^^"" <term> ;"); newline
else if y = 4096
print string("p ^^ q ^^ r is left associative, i.e. (p ^^ q) ^^ r"); newline
newline
print string("This grammar would support the above:"); newline
newline
print string("P<expr> = <term-exp-list> <term> ;"); newline
print string("P<term-exp-list> = <term-exp> <term-exp-list> | ;"); newline
print string("P<term-exp> = <term> ""^^"" ;"); newline
else
print string("p ^^ q ^^ r is something weird! ("); write(y, 0); print string(") - I give up."); newline
finish
newline
! The remaining issue to be checked is how left/right associativity interact when the precedence is the same,
! which is only the case for exponentiation and shifts together, eg
!
! a << b << c ^^ d ^^ e or a ^^ b ^^ c >> d >> e
!
endofprogram