#include <perms.h>
// Edinburgh IMP77 Compiler - Version 8.4
//
// 1 %begin
int main(int argc, char **argv) { /*%begin*/
_imp_initialise(argc, argv);
// 2
// 3 !
// 4 ! Precedence of operators
// 5 !
// 6 ! Highest: 1. \ (complement, unary not)
// 7 ! 2. \, \\, <<, >>
// 8 ! 3. *, /, //, &
// 9 ! Lowest: 4. +, - (unary and binary), !, !!
// 10 !
// 11 ! In general, sub-expressions with operators of equal precedence are evaluated from left to right.
// 12 !
// 13 ! The one exception to the left-hand precedence rule is that consecutive
// 14 ! exponentiations are evaluated from right to left; thus A**B**C is
// 15 ! evaluated as A**(B**C), not as (A**B)**C. (Imp80 documentation)
// 16
// 17 ! Arithmetic operators:
// 18
// 19 ! |...| modulus also: !...! (deprecated some time ago)
// 20
// 21 ! ! inclusive or
// 22 ! !! exclusive or
// 23 ! & and
// 24
// 25 ! \ real exponentiation also: ^ (Imp77) or ** (ERCC compilers)
// 26 ! \\ integer exponentiation also: ^^ (Imp77) or ****
// 27
// 28 ! * multiply
// 29 ! / real division
// 30 ! // integer division
// 31
// 32 ! << left shift
// 33 ! >> right shift
// 34
// 35 ! + plus
// 36 ! - minus
// 37
// 38 ! + unary +
// 39 ! - unary -
// 40 ! \ unary not also ~ (can be *displayed* as: ¬ (¬))
// 41
// 42 ! . string concatenation
// 43
// 44 ! Comparison operators:
// 45 ! = eq
// 46 ! # not equals also \= and <> (Imp80 documentation)
// 47 ! == address equals
// 48 ! ## address not equals also \==
// 49 ! -> string resolution (a difficult to classify hybrid of a comparison and an assignment operator)
// 50 ! <= less than or equals
// 51 ! < less than
// 52 ! >= greater than or equals
// 53 ! >
// 54
// 55 ! Assignment operators:
// 56 ! = assignment
// 57 ! == pointer assignment
// 58 ! <- jam transfer
// 59 ! -> string resolution
// 60
// 61 ! Data structure operators:
// 62 ! _ record field
// 63 ! () array indexing
// 64 ! [] pointer increment (a Hamish extension in 68000 Imp only)
// 65
// 66 ! Other:
// 67 ! @ may be considered an operator in %real literals, usually handled by a BIP.
// 68
// 69
// 70 %const %integer a = 19, b = 17, c = 5, d = 3
// 71 %integer x = a * b // c * d
int X;
X = ((long)(19 * 17) / (long)5) * 3;
// 72 print string("Imp77 precedence and associativity test."); newlines(2)
_imp_PRINTSTRING(_imp_str_literal("Imp77 precedence and associativity test."));
_imp_NEWLINES(2);
// 73 %if x = 21 %start
if (X != 21) goto L_0001;
// 74 print string("In a * b // c * d, '*' has higher priority than '/'."); newline
_imp_PRINTSTRING(_imp_str_literal("In a * b // c * d, '*' has higher priority than '/'."));
_imp_NEWLINE();
// 75 print string("A second test with '/' will be needed to determine associativity:"); newline
_imp_PRINTSTRING(_imp_str_literal("A second test with '/' will be needed to determine associativity:"));
_imp_NEWLINE();
// 76 x = a // c // d
X = ((long)(((long)19 / (long)5)) / (long)3);
// 77 %if x = 1 %start
if (X != 1) goto L_0002;
// 78 print string("a // c // d is right associative, i.e. a // (b // c)"); newline
_imp_PRINTSTRING(_imp_str_literal("a // c // d is right associative, i.e. a // (b // c)"));
_imp_NEWLINE();
// 79 %else %if x = 19
goto L_0003;
L_0002:;
if (X != 19) goto L_0004;
// 80 print string("a // c // d is left associative, i.e. (a // b) // c"); newline
_imp_PRINTSTRING(_imp_str_literal("a // c // d is left associative, i.e. (a // b) // c"));
_imp_NEWLINE();
// 81 %else
goto L_0003;
L_0004:;
// 82 print string("a // c // d is something weird! I give up."); newline
_imp_PRINTSTRING(_imp_str_literal("a // c // d is something weird! I give up."));
_imp_NEWLINE();
// 83 %finish
L_0003:;
// 84 %else %if x = 19
goto L_0005;
L_0001:;
if (X != 19) goto L_0006;
// 85 print string("a * b // c * d is right associative and with equal precedence, i.e. a * (b // (c * d))"); newline
_imp_PRINTSTRING(
_imp_str_literal("a * b // c * d is right associative and with equal precedence, i.e. a * (b // (c * d))"));
_imp_NEWLINE();
// 86 newline
_imp_NEWLINE();
// 87 print string("This grammar would support the above:"); newline
_imp_PRINTSTRING(_imp_str_literal("This grammar would support the above:"));
_imp_NEWLINE();
// 88 newline
_imp_NEWLINE();
// 89 print string("P<expr> = <term> <op-term-list> ;"); newline
_imp_PRINTSTRING(_imp_str_literal("P<expr> = <term> <op-term-list> ;"));
_imp_NEWLINE();
// 90 print string("P<op-term-list> = <op-term> <op-term-list> | ;"); newline
_imp_PRINTSTRING(_imp_str_literal("P<op-term-list> = <op-term> <op-term-list> | ;"));
_imp_NEWLINE();
// 91 print string("P<op-term> = <op> <term> ;"); newline
_imp_PRINTSTRING(_imp_str_literal("P<op-term> = <op> <term> ;"));
_imp_NEWLINE();
// 92 %else %if x = 192
goto L_0005;
L_0006:;
if (X != 192) goto L_0007;
// 93 print string("a * b // c * d is left associative and with equal precedence, i.e. ((a * b) // c) * d"); newline
_imp_PRINTSTRING(
_imp_str_literal("a * b // c * d is left associative and with equal precedence, i.e. ((a * b) // c) * d"));
_imp_NEWLINE();
// 94 newline
_imp_NEWLINE();
// 95 print string("This grammar would support the above:"); newline
_imp_PRINTSTRING(_imp_str_literal("This grammar would support the above:"));
_imp_NEWLINE();
// 96 newline
_imp_NEWLINE();
// 97 print string("P<expr> = <term-op-list> <term> ;"); newline
_imp_PRINTSTRING(_imp_str_literal("P<expr> = <term-op-list> <term> ;"));
_imp_NEWLINE();
// 98 print string("P<term-op-list> = <term-op> <term-op-list> | ;"); newline
_imp_PRINTSTRING(_imp_str_literal("P<term-op-list> = <term-op> <term-op-list> | ;"));
_imp_NEWLINE();
// 99 print string("P<term-op> = <term> <op> ;"); newline
_imp_PRINTSTRING(_imp_str_literal("P<term-op> = <term> <op> ;"));
_imp_NEWLINE();
// 100 %else
goto L_0005;
L_0007:;
// 101 print string("a * b // c * d uses some weird non-standard combination of precedence and associativity!"); newline
_imp_PRINTSTRING(
_imp_str_literal("a * b // c * d uses some weird non-standard combination of precedence and associativity!"));
_imp_NEWLINE();
// 102 %finish
L_0005:;
// 103 newline
_imp_NEWLINE();
// 104
// 105
// 106 %const %integer p = 4, q = 3, r = 2
// 107 %integer y
int Y;
// 108
// 109 y = p ^^ q ^^ r
Y = _imp_IEXP(_imp_IEXP(4, 3), 2);
// 110
// 111 %if y = 262144 %start
if (Y != 262144) goto L_0008;
// 112 print string("p ^^ q ^^ r is right associative, i.e. p ^^ (q ^^ r)"); newline
_imp_PRINTSTRING(_imp_str_literal("p ^^ q ^^ r is right associative, i.e. p ^^ (q ^^ r)"));
_imp_NEWLINE();
// 113 newline
_imp_NEWLINE();
// 114 print string("This grammar would support the above:"); newline
_imp_PRINTSTRING(_imp_str_literal("This grammar would support the above:"));
_imp_NEWLINE();
// 115 newline
_imp_NEWLINE();
// 116 print string("P<expr> = <term> <exp-term-list> ;"); newline
_imp_PRINTSTRING(_imp_str_literal("P<expr> = <term> <exp-term-list> ;"));
_imp_NEWLINE();
// 117 print string("P<exp-term-list> = <exp-term> <exp-term-list> | ;"); newline
_imp_PRINTSTRING(_imp_str_literal("P<exp-term-list> = <exp-term> <exp-term-list> | ;"));
_imp_NEWLINE();
// 118 print string("P<exp-term> = ""^^"" <term> ;"); newline
_imp_PRINTSTRING(_imp_str_literal("P<exp-term> = \"^^\" <term> ;"));
_imp_NEWLINE();
// 119 %else %if y = 4096
goto L_0009;
L_0008:;
if (Y != 4096) goto L_000A;
// 120 print string("p ^^ q ^^ r is left associative, i.e. (p ^^ q) ^^ r"); newline
_imp_PRINTSTRING(_imp_str_literal("p ^^ q ^^ r is left associative, i.e. (p ^^ q) ^^ r"));
_imp_NEWLINE();
// 121 newline
_imp_NEWLINE();
// 122 print string("This grammar would support the above:"); newline
_imp_PRINTSTRING(_imp_str_literal("This grammar would support the above:"));
_imp_NEWLINE();
// 123 newline
_imp_NEWLINE();
// 124 print string("P<expr> = <term-exp-list> <term> ;"); newline
_imp_PRINTSTRING(_imp_str_literal("P<expr> = <term-exp-list> <term> ;"));
_imp_NEWLINE();
// 125 print string("P<term-exp-list> = <term-exp> <term-exp-list> | ;"); newline
_imp_PRINTSTRING(_imp_str_literal("P<term-exp-list> = <term-exp> <term-exp-list> | ;"));
_imp_NEWLINE();
// 126 print string("P<term-exp> = <term> ""^^"" ;"); newline
_imp_PRINTSTRING(_imp_str_literal("P<term-exp> = <term> \"^^\" ;"));
_imp_NEWLINE();
// 127 %else
goto L_0009;
L_000A:;
// 128 print string("p ^^ q ^^ r is something weird! ("); write(y, 0); print string(") - I give up."); newline
_imp_PRINTSTRING(_imp_str_literal("p ^^ q ^^ r is something weird! ("));
_imp_WRITE(Y, 0);
_imp_PRINTSTRING(_imp_str_literal(") - I give up."));
_imp_NEWLINE();
// 129 %finish
L_0009:;
// 130 newline
_imp_NEWLINE();
// 131
// 132 ! The remaining issue to be checked is how left/right associativity interact when the precedence is the same,
// 133 ! which is only the case for exponentiation and shifts together, eg
// 134 !
// 135 ! a << b << c ^^ d ^^ e or a ^^ b ^^ c >> d >> e
// 136 !
// 137
// 138 %endofprogram
_imp_stop(0);
return 0;
end_0:;
}