#include <perms.h>
// Edinburgh IMP77 Compiler - Version 8.4
//
// 1 %const %string (1) SNL ="
const _imp_string1 SNL = _imp_str_init("\n");
// 2+ "
// 3 %begin
int main(int argc, char **argv) { /*%begin*/
_imp_initialise(argc, argv);
// 4 %const %integer TRUE = 1, FALSE = 0
// 5 %constant %integer A stream = 1, B stream = 2
// 6 %ownstring (255) A file, B file, pr, left, right
static _imp_string255 AFILE;
static _imp_string255 BFILE;
static _imp_string255 PR;
static _imp_string255 LEFT;
static _imp_string255 RIGHT;
// 7 %ownstring (255) %array File('A':'B')
static _imp_string255 FILE[2];
// 8 %owninteger %array Base('A':'B')
static int BASE[2];
// 9 %owninteger A count, B count
static int ACOUNT;
static int BCOUNT;
// 10 %owninteger A num, B num
static int ANUM;
static int BNUM;
// 11
// 12 %const %integer Max Lines = 512, Max Line Width = 128
// 13 %byte %integer %array AA, BB (1:Max Lines*Max Line Width)
unsigned char AA[512 * 128 - 1 + 1];
unsigned char BB[512 * 128 - 1 + 1];
// 14
// 15 %integer%fn input ended
int INPUTENDED(void) {
// 16 %integer ch
int CH;
// 17 %on %event 9 %start
if (!_imp_on_event(9)) goto L_0001;
// 18 %result = TRUE
return 1;
// 19 %finish
L_0001:;
// 20 ch = next symbol
CH = _imp_NEXTSYMBOL();
// 21 %result = FALSE
return 0;
// 22 %end
} /* end of INPUTENDED */
// 23
// 24 %routine Rd line (%string (*) %name s)
void RDLINE(_imp_string * S) {
// 25 %integer ch
int CH;
// 26 s = ""
*S = _imp_str_literal("");
// 27 %cycle
L_0002:;
// 28 read symbol (ch)
_imp_READSYMBOL(/*?*/ &CH);
// 29 %exit %if ch = nl %or LENGTH(s) = Max Line Width
if (CH == 10) goto L_0003;
if (*_imp_LENGTH((_imp_string255 *)/*p*/ S) != 128) goto L_0004;
L_0003:;
goto L_0005;
L_0004:;
// 30 s = s.tostring(ch)
*S = *
*({
_imp_string255 tmp = _imp_join(({
__typeof__(_imp_string255) tmp; /*D*/
tmp = *S;
(void *)&tmp;
}),
({
__typeof__(_imp_string1) tmp; /*E*/
tmp = _imp_TOSTRING(CH);
(void *)&tmp;
}));
(_imp_string255 *)&tmp;
})
;
// 31 %repeat
goto L_0002;
L_0005:;
// 32 %end
return;
} /* end of RDLINE */
// 33
// 34 %byte %integer %map A (%integer i, j)
unsigned char *A(int I, int J)
{
// 35 %result == AA (((Base('A') + i)&(Max Lines-1))*Max Line Width + j)
return /*?*/ &AA[(BASE[0] + I & 512 - 1) * 128 + J - 1];
// 36 %end
} /* end of A */
// 37
// 38 %byte %integer %map B (%integer i, j)
unsigned char *B(int I, int J)
{
// 39 %result == BB (((Base('B') + i)&(Max Lines-1))*Max Line Width + j)
return /*?*/ &BB[(BASE[1] + I & 512 - 1) * 128 + J - 1];
// 40 %end
} /* end of B */
// 41
// 42 %routine refill (%byte %integer %map x (%integer i, j),
void REFILL(unsigned char *(*X)(int I, int J), int N, int *COUNT) {
// 43+ %integer n,
// 44+ %integer %name count)
// 45
// 46 %integer i, j, ch
int I;
int J;
int CH;
// 47 %for i = Max Lines+1-n, 1, Max Lines %cycle
// %for I = 512 + 1 - N, 1, 512 %cycle
{
int _initial = 512 + 1 - N;
if (invalid_for_loop(_initial, 1, 512)) _imp_signal(5, 1, 0, "Illegal cycle I = 512 + 1 - N, 1, 512");
I = _initial - (1);
L_0006:
if (I == 512) goto L_0007;
I += 1;
// 48 %cycle
L_0009:;
// 49 %return %if input ended=TRUE
if (INPUTENDED() != 1) goto L_000A;
return;
L_000A:;
// 50 Read symbol (ch)
_imp_READSYMBOL(/*?*/ &CH);
// 51 %repeat %until ch # nl
if (CH != 10) goto L_000B;
goto L_0009;
L_000B:;
// 52 %for j = 1, 1, Max Line Width-1 %cycle
// %for J = 1, 1, 128 - 1 %cycle
{
int _final = 128 - 1;
if (invalid_for_loop(1, 1, _final)) _imp_signal(5, 1, 0, "Illegal cycle J = 1, 1, 128 - 1");
J = 0;
L_000C:
if (J == _final) goto L_000D;
J += 1;
// 53 %exit %if ch = nl %OR CH<32
if (CH == 10) goto L_000F;
if (CH >= 32) goto L_0010;
L_000F:;
goto L_000D;
L_0010:;
// 54 x (i, j) = ch
*X(I, J) = CH;
// 55 %return %if input ended=TRUE
if (INPUTENDED() != 1) goto L_0011;
return;
L_0011:;
// 56 Read symbol (ch)
_imp_READSYMBOL(/*?*/ &CH);
// 57 %repeat
goto L_000C;
}
L_000D:;
// 58 x (i, j) = nl
*X(I, J) = 10;
// 59 count = count + 1
*COUNT = *COUNT + 1;
// 60 %repeat
goto L_0006;
}
L_0007:;
// 61 %end
return;
} /* end of REFILL */
// 62
// 63 %routine print (%byte %integer %map x (%integer i, j),
void PRINT(unsigned char *(*X)(int I, int J), int N, int FLAG) {
// 64+ %integer n,
// 65+ flag)
// 66
// 67 %integer i, j
int I;
int J;
// 68 %for i = 1, 1, n %cycle
// %for I = 1, 1, N %cycle
{
int _final = N;
if (invalid_for_loop(1, 1, _final)) _imp_signal(5, 1, 0, "Illegal cycle I = 1, 1, N");
I = 0;
L_0012:
if (I == _final) goto L_0013;
I += 1;
// 69 Print string ("""".File(flag).""",")
_imp_PRINTSTRING(
*({
__typeof__(_imp_string255) tmp = *({
_imp_string255 tmp = _imp_join((_imp_string *)/*?*/ &*({
_imp_string255 tmp =
_imp_join((_imp_string *)/*?*/ _imp_str_literal_ptr("\""),
(_imp_string *)/*?*/ &FILE[FLAG - 65]);
(_imp_string255 *)&tmp;
}),
(_imp_string *)/*?*/ _imp_str_literal_ptr("\","));
(_imp_string255 *)&tmp;
}) /*q*/;
(_imp_string255 *)&tmp;
})
);
// 70 Write (Base(flag)+i+1, 5)
_imp_WRITE(BASE[FLAG - 65] + I + 1, 5);
// 71 Print string (": ")
_imp_PRINTSTRING(_imp_str_literal(": "));
// 72 j = 0
J = 0;
// 73 %cycle
L_0014:;
// 74 j = j + 1
J = J + 1;
// 75 %exit %if x (i, j) = nl
if (*X(I, J) != 10) goto L_0015;
goto L_0016;
L_0015:;
// 76 Print symbol (x (i, j))
_imp_PRINTSYMBOL(*X(I, J));
// 77 %if j=57 %then newline %and spaces(20) %and printsymbol(':')
if (J != 57) goto L_0017;
_imp_NEWLINE();
_imp_SPACES(20);
_imp_PRINTSYMBOL(58);
L_0017:;
// 78 %repeat
goto L_0014;
L_0016:;
// 79 newline
_imp_NEWLINE();
// 80 %repeat
goto L_0012;
}
L_0013:;
// 81 %end
return;
} /* end of PRINT */
// 82
// 83 %integer%fn lines match (%integer A line, B line)
int LINESMATCH(int ALINE, int BLINE) {
// 84
// 85 %integer j
int J;
// 86 %if A line > A count %or B line > B count %start
if (ALINE > ACOUNT) goto L_0008;
if (BLINE <= BCOUNT) goto L_0018;
L_0008:;
// 87 %result = TRUE %if A line > A count %and B line > B count
if (ALINE <= ACOUNT) goto L_0019;
if (BLINE <= BCOUNT) goto L_0019;
return 1;
L_0019:;
// 88 %result = FALSE
return 0;
// 89 %finish
L_0018:;
// 90 %for j = 1, 1, Max Line Width %cycle
// %for J = 1, 1, 128 %cycle
{
J = 0;
L_001A:
if (J == 128) goto L_001B;
J += 1;
// 91 %result = FALSE %if A (A line, j) # B (B line, j)
if (*A(ALINE, J) == *B(BLINE, J)) goto L_001D;
return 0;
L_001D:;
// 92 %result = TRUE %if A (A line, j) = nl
if (*A(ALINE, J) != 10) goto L_001E;
return 1;
L_001E:;
// 93 %repeat
goto L_001A;
}
L_001B:;
// 94 %result = TRUE
return 1;
// 95 %end
} /* end of LINESMATCH */
// 96
// 97 %routine find match (%integer %name AL, BL)
void FINDMATCH(int *AL, int *BL) {
// 98
// 99 %integer i, j
int I;
int J;
// 100 %for i = 1, 1, Max Lines %cycle
// %for I = 1, 1, 512 %cycle
{
I = 0;
L_001F:
if (I == 512) goto L_0020;
I += 1;
// 101 AL = i %and BL = i %and %return %if lines match (i, i)=TRUE
if (LINESMATCH(I, I) != 1) goto L_0021;
*AL = I;
*BL = I;
return;
L_0021:;
// 102 %if i > 1 %start
if (I <= 1) goto L_0022;
// 103 %for j = 1, 1, I - 1 %cycle
// %for J = 1, 1, I - 1 %cycle
{
int _final = I - 1;
if (invalid_for_loop(1, 1, _final)) _imp_signal(5, 1, 0, "Illegal cycle J = 1, 1, I - 1");
J = 0;
L_0023:
if (J == _final) goto L_0024;
J += 1;
// 104 AL = i %and BL = j %and %return %if lines match (i, j)=TRUE
if (LINESMATCH(I, J) != 1) goto L_0026;
*AL = I;
*BL = J;
return;
L_0026:;
// 105 AL = j %and BL = i %and %return %if lines match (j, i)=TRUE
if (LINESMATCH(J, I) != 1) goto L_0027;
*AL = J;
*BL = I;
return;
L_0027:;
// 106 %repeat
goto L_0023;
}
L_0024:;
// 107 %finish
L_0022:;
// 108 %repeat
goto L_001F;
}
L_0020:;
// 109 AL = Max Lines+1; BL = Max Lines+1
*AL = 512 + 1;
*BL = 512 + 1;
// 110 %end
return;
} /* end of FINDMATCH */
// 111
// 112
// 113 %integer fname len;
int FNAMELEN;
// 114
// 115 A num = Max Lines; B num = Max Lines
ANUM = 512;
BNUM = 512;
// 116 Base('A') = 0; Base('B') = 0
BASE[0] = 0;
BASE[1] = 0;
// 117 A count = 0; B count = 0
ACOUNT = 0;
BCOUNT = 0;
// 118
// 119 %if cli param -> ("-h") %start
if (!(_imp_resolve(*({
_imp_string255 tmp = _imp_CLIPARAM();
(_imp_string255 *)&tmp;
}),
0 /*NULL*/, *({
_imp_string tmp = _imp_str_literal("-h");
(_imp_string255 *)&tmp;
}),
0 /*NULL*/)))
goto L_0028;
// 120 print string("Syntax: compare oldfile newfile".snl)
_imp_PRINTSTRING(
*({
__typeof__(_imp_string255) tmp = *({
_imp_string255 tmp = _imp_join((_imp_string *)/*?*/ _imp_str_literal_ptr("Syntax: compare oldfile newfile"),
(_imp_string *)/*?*/ &SNL);
(_imp_string255 *)&tmp;
}) /*q*/;
(_imp_string255 *)&tmp;
})
);
// 121 %stop
_imp_stop(0);
// 122 %finish
L_0028:;
// 123
// 124 pr = "New file: "
_imp_strncpy(/*?*/ &PR, ({
__typeof__(_imp_string255) tmp; /*B*/
tmp = _imp_str_literal("New file: ");
(void *)&tmp;
}),
/*max:*/ 255);
// 125
// 126 %unless cli param -> A file.(" ").B file %start
if (_imp_resolve(*({
_imp_string255 tmp = _imp_CLIPARAM();
(_imp_string255 *)&tmp;
}),
(_imp_string255 *)/*?*/ &AFILE, *({
_imp_string tmp = _imp_str_literal(" ");
(_imp_string255 *)&tmp;
}),
(_imp_string255 *)/*?*/ &BFILE))
goto L_0029;
// 127 A file = cli param
_imp_strncpy(/*?*/ &AFILE, ({
__typeof__(_imp_string255) tmp; /*B*/
tmp = _imp_CLIPARAM();
(void *)&tmp;
}),
/*max:*/ 255);
// 128 %if A file # "" %start
if (_imp_strcmp((_imp_string *)/*?*/ &AFILE, (_imp_string *)/*?*/ _imp_str_literal_ptr("")) == 0) goto L_002A;
// 129 B file = ""; pr = "Against: "
_imp_strncpy(/*?*/ &BFILE, ({
__typeof__(_imp_string255) tmp; /*B*/
tmp = _imp_str_literal("");
(void *)&tmp;
}),
/*max:*/ 255);
_imp_strncpy(/*?*/ &PR, ({
__typeof__(_imp_string255) tmp; /*B*/
tmp = _imp_str_literal("Against: ");
(void *)&tmp;
}),
/*max:*/ 255);
// 130 %else
goto L_002B;
L_002A:;
// 131 A file = ""
_imp_strncpy(/*?*/ &AFILE, ({
__typeof__(_imp_string255) tmp; /*B*/
tmp = _imp_str_literal("");
(void *)&tmp;
}),
/*max:*/ 255);
// 132 B file = ""
_imp_strncpy(/*?*/ &BFILE, ({
__typeof__(_imp_string255) tmp; /*B*/
tmp = _imp_str_literal("");
(void *)&tmp;
}),
/*max:*/ 255);
// 133 %finish
L_002B:;
// 134 %finish
L_0029:;
// 135
// 136 A file <- left.right %while A file -> left.(" ").right
L_002C:;
if (!(_imp_resolve(*({
_imp_string255 tmp = AFILE;
(_imp_string255 *)&tmp;
}),
(_imp_string255 *)/*?*/ &LEFT, *({
_imp_string tmp = _imp_str_literal(" ");
(_imp_string255 *)&tmp;
}),
(_imp_string255 *)/*?*/ &RIGHT)))
goto L_002D;
_imp_strncpy(/*?*/ &AFILE, ({
__typeof__(_imp_string255) tmp; /*C*/
tmp = *({
_imp_string255 tmp = _imp_join((_imp_string *)/*?*/ &LEFT, (_imp_string *)/*?*/ &RIGHT);
(_imp_string255 *)&tmp;
});
(void *)&tmp;
}),
/*max:*/ 255);
goto L_002C;
L_002D:;
// 137 B file <- left.right %while B file -> left.(" ").right
L_002E:;
if (!(_imp_resolve(*({
_imp_string255 tmp = BFILE;
(_imp_string255 *)&tmp;
}),
(_imp_string255 *)/*?*/ &LEFT, *({
_imp_string tmp = _imp_str_literal(" ");
(_imp_string255 *)&tmp;
}),
(_imp_string255 *)/*?*/ &RIGHT)))
goto L_002F;
_imp_strncpy(/*?*/ &BFILE, ({
__typeof__(_imp_string255) tmp; /*C*/
tmp = *({
_imp_string255 tmp = _imp_join((_imp_string *)/*?*/ &LEFT, (_imp_string *)/*?*/ &RIGHT);
(_imp_string255 *)&tmp;
});
(void *)&tmp;
}),
/*max:*/ 255);
goto L_002E;
L_002F:;
// 138
// 139 File('A') = A file; File('B') = B file
_imp_strncpy(/*?*/ &FILE[0], ({
__typeof__(_imp_string255) tmp; /*B*/
tmp = AFILE;
(void *)&tmp;
}),
/*max:*/ 255);
_imp_strncpy(/*?*/ &FILE[1], ({
__typeof__(_imp_string255) tmp; /*B*/
tmp = BFILE;
(void *)&tmp;
}),
/*max:*/ 255);
// 140
// 141 Prompt ("Old file: ")
_imp_PROMPT(_imp_str_literal_size(15, "Old file: "));
// 142 Rd line (A file) %while A file = ""
L_0030:;
if (_imp_strcmp((_imp_string *)/*?*/ &AFILE, (_imp_string *)/*?*/ _imp_str_literal_ptr("")) != 0) goto L_0031;
RDLINE((_imp_string255 *)/*p*/ /*?*/ &AFILE);
goto L_0030;
L_0031:;
// 143 Prompt (pr)
_imp_PROMPT(
*({
__typeof__(_imp_string255) tmp = PR /*q*/;
(_imp_string15 *)&tmp;
})
);
// 144 Rd line (B file) %while B file = ""
L_0032:;
if (_imp_strcmp((_imp_string *)/*?*/ &BFILE, (_imp_string *)/*?*/ _imp_str_literal_ptr("")) != 0) goto L_0033;
RDLINE((_imp_string255 *)/*p*/ /*?*/ &BFILE);
goto L_0032;
L_0033:;
// 145
// 146 fname len = LENGTH(A file)
FNAMELEN = *_imp_LENGTH((_imp_string255 *)/*p*/ /*?*/ &AFILE);
// 147 %if fname len < LENGTH(B file) %then fname len = LENGTH(B file)
if (FNAMELEN >= *_imp_LENGTH((_imp_string255 *)/*p*/ /*?*/ &BFILE)) goto L_0034;
FNAMELEN = *_imp_LENGTH((_imp_string255 *)/*p*/ /*?*/ &BFILE);
L_0034:;
// 148 %if fname len > 11 %then fname len = 11
if (FNAMELEN <= 11) goto L_0035;
FNAMELEN = 11;
L_0035:;
// 149
// 150 open input (A stream, A file)
_imp_OPENINPUT(1,
*({
__typeof__(_imp_string255) tmp = AFILE /*q*/;
(_imp_string255 *)&tmp;
})
);
// 151 open input (B stream, B file)
_imp_OPENINPUT(2,
*({
__typeof__(_imp_string255) tmp = BFILE /*q*/;
(_imp_string255 *)&tmp;
})
);
// 152
// 153 A file = " ".A file
_imp_strncpy(/*?*/ &AFILE, ({
__typeof__(_imp_string255) tmp; /*B*/
tmp = *({
_imp_string255 tmp =
_imp_join((_imp_string *)/*?*/ _imp_str_literal_ptr(" "), (_imp_string *)/*?*/ &AFILE);
(_imp_string255 *)&tmp;
});
(void *)&tmp;
}),
/*max:*/ 255);
// 154 B file = " ".B file
_imp_strncpy(/*?*/ &BFILE, ({
__typeof__(_imp_string255) tmp; /*B*/
tmp = *({
_imp_string255 tmp =
_imp_join((_imp_string *)/*?*/ _imp_str_literal_ptr(" "), (_imp_string *)/*?*/ &BFILE);
(_imp_string255 *)&tmp;
});
(void *)&tmp;
}),
/*max:*/ 255);
// 155 A file = SUBSTRING(A file, LENGTH(A file)-10, LENGTH(A file))
_imp_strncpy(/*?*/ &AFILE, ({
__typeof__(_imp_string255) tmp; /*B*/
tmp = _imp_SUBSTRING((_imp_string255 *)/*p*/ /*?*/ &AFILE,
*_imp_LENGTH((_imp_string255 *)/*p*/ /*?*/ &AFILE) - 10,
*_imp_LENGTH((_imp_string255 *)/*p*/ /*?*/ &AFILE));
(void *)&tmp;
}),
/*max:*/ 255);
// 156 B file = SUBSTRING(B file, LENGTH(B file)-10, LENGTH(B file))
_imp_strncpy(/*?*/ &BFILE, ({
__typeof__(_imp_string255) tmp; /*B*/
tmp = _imp_SUBSTRING((_imp_string255 *)/*p*/ /*?*/ &BFILE,
*_imp_LENGTH((_imp_string255 *)/*p*/ /*?*/ &BFILE) - 10,
*_imp_LENGTH((_imp_string255 *)/*p*/ /*?*/ &BFILE));
(void *)&tmp;
}),
/*max:*/ 255);
// 157
// 158 %cycle
L_0036:;
// 159 select input (A stream)
_imp_SELECTINPUT(1);
// 160 refill (A, A num, A count)
REFILL(A, ANUM, /*?*/ &ACOUNT);
// 161 select input (B stream)
_imp_SELECTINPUT(2);
// 162 refill (B, B num, B count)
REFILL(B, BNUM, /*?*/ &BCOUNT);
// 163 %exit %if A count <= 0 %and B count <= 0
if (ACOUNT > 0) goto L_0037;
if (BCOUNT > 0) goto L_0037;
goto L_0038;
L_0037:;
// 164 find match (A num, B num)
FINDMATCH(/*?*/ &ANUM, /*?*/ &BNUM);
// 165 %if A num # 1 %or B num # 1 %start
if (ANUM != 1) goto L_000E;
if (BNUM == 1) goto L_0039;
L_000E:;
// 166 print (A, A num-1, 'A')
PRINT(A, ANUM - 1, 65);
// 167 print (B, B num-1, 'B')
PRINT(B, BNUM - 1, 66);
// 168 Print string("---------------------".snl)
_imp_PRINTSTRING(
*({
__typeof__(_imp_string255) tmp = *({
_imp_string255 tmp =
_imp_join((_imp_string *)/*?*/ _imp_str_literal_ptr("---------------------"), (_imp_string *)/*?*/ &SNL);
(_imp_string255 *)&tmp;
}) /*q*/;
(_imp_string255 *)&tmp;
})
);
// 169 %if A num > Max Lines %start
if (ANUM <= 512) goto L_003A;
// 170 Print string ("*** Mismatch too large")
_imp_PRINTSTRING(_imp_str_literal("*** Mismatch too large"));
// 171 Newline
_imp_NEWLINE();
// 172 %stop
_imp_stop(0);
// 173 %finish
L_003A:;
// 174 %finish
L_0039:;
// 175 Base('A') = Base('A') + A num
BASE[0] = BASE[0] + ANUM;
// 176 Base('B') = Base('B') + B num
BASE[1] = BASE[1] + BNUM;
// 177 A count = A count - A num
ACOUNT = ACOUNT - ANUM;
// 178 B count = B count - B num
BCOUNT = BCOUNT - BNUM;
// 179 %repeat
goto L_0036;
L_0038:;
// 180
// 181 %end %of %program
_imp_stop(0);
return 0;
end_0:;
}