begin 
   constant  integer   A stream = 1, B stream = 2
   string  (255) A file, B file, pr, left, right
   string  (255) name  array  File('A':'B')
                              File('A') == A file; File('B') == B file
   integer  A base, B base
   integer  name  array  Base('A':'B')
                         Base('A') == A base; Base('B') == B base
   integer  A count, B count
   integer  A num, B num

   const  integer  Max Lines = 512, Max Line Width = 128
   byte  array  AA, BB (1:Max Lines*Max Line Width)

   predicate   input ended
      integer  ch
      on  event  9 start 
         true 
      finish 
      ch = next symbol
      false 
   end 

   routine   Rd line (string  (*) name  s)
      integer  ch
      s = ""
      cycle 
         read symbol (ch)
         exit  if  ch = nl or  LENGTH(s) = Max Line Width
         s = s.ch
      repeat 
   end 

   byte  map   A (integer  i, j)
      result  == AA (((A base + i)&(Max Lines-1))*Max Line Width + j)
   end 

   byte  map   B (integer  i, j)
      result  == BB (((B base + i)&(Max Lines-1))*Max Line Width + j)
   end 

   routine   refill (byte  map  x (integer  i, j),
                     integer  n,
                     integer  name  count)

      integer  i, j, ch
      for  i = Max Lines+1-n, 1, Max Lines cycle 
         cycle 
            return  if  input ended
            Read symbol (ch)
         repeat  until  ch # nl
         for  j = 1, 1, Max Line Width-1 cycle 
            exit  if  ch = nl OR  CH<32
            x (i, j) = ch
            return  if  input ended
            Read symbol (ch)
         repeat 
         x (i, j) = nl
         count = count + 1
      repeat 
   end 

   routine   print (byte  map  x (integer  i, j),
                    integer  n,
                             flag)

      integer  i, j
      for  i = 1, 1, n cycle 
         Print string ("""".File(flag).""",")
         Write (Base(flag)+i+1, 5)
         Print string (": ")
         j = 0
         cycle 
           j = j + 1
           exit  if  x (i, j) = nl
           Print symbol (x (i, j))
           if  j=57 then  newline and  spaces(20) and  printsymbol(':')
         repeat 
         newline
      repeat 
   end 

   predicate   lines match (integer  A line, B line)

      integer  j
      if  A line > A count or  B line > B count start 
         true  if  A line > A count and  B line > B count
         false 
      finish 
      for  j = 1, 1, Max Line Width cycle 
         false  if  A (A line, j) # B (B line, j)
         true  if  A (A line, j) = nl
      repeat 
      true 
   end 

   routine   find match (integer  name  AL, BL)

      integer  i, j
      for  i = 1, 1, Max Lines cycle 
         AL = i and  BL = i and  return  if  lines match (i, i)
         if  i > 1 start 
            for  j = 1, 1, I - 1 cycle 
               AL = i and  BL = j and  return  if  lines match (i, j)
               AL = j and  BL = i and  return  if  lines match (j, i)
            repeat 
         finish 
      repeat 
      AL = Max Lines+1; BL = Max Lines+1
   end 

A num = Max Lines; B num = Max Lines
A base = 0; B base = 0
A count = 0; B count = 0

if  cli param -> ("-h") start 
  print string("Syntax: compare oldfile newfile".nl)
  stop 
finish 

pr = "New file: "

unless  cli param -> A file.(" ").B file start 
  A file = cli param
  if  A file # "" start 
   B file = ""; pr = "Against:  "
  else 
   A file = ""
   B file = ""
  finish 
finish 

A file <- left.right while  A file -> left.(" ").right
B file <- left.right while  B file -> left.(" ").right

Prompt ("Old file: ")
Rd line (A file) while  A file = ""
Prompt (pr)
Rd line (B file) while  B file = ""

integer  fname len = LENGTH(A file)
if  fname len < LENGTH(B file) then  fname len = LENGTH(B file)
if  fname len > 11 then  fname len = 11

Open input (A stream, A file)
Open input (B stream, B file)

A file = "           ".A file
B file = "           ".B file
A file = SUBSTRING(A file, LENGTH(A file)-10, LENGTH(A file))
B file = SUBSTRING(B file, LENGTH(B file)-10, LENGTH(B file))

cycle 
   select input (A stream)
   refill (A, A num, A count)
   select input (B stream)
   refill (B, B num, B count)
   exit  if  A count <= 0 and  B count <= 0
   find match (A num, B num)
   if  A num # 1 or  B num # 1 start 
      print (A, A num-1, 'A')
      print (B, B num-1, 'B')
      Print string("---------------------".nl)
      if  A num > Max Lines start 
         Print string ("*** Mismatch too large")
         Newline
         stop 
      finish 
   finish 
   A base = A base + A num
   B base = B base + B num
   A count = A count - A num
   B count = B count - B num
repeat 
end  of  programme