const string (1) SNL ="
"
begin
   const integer TRUE = 1, FALSE = 0
   constant integer  A stream = 1, B stream = 2
   ownstring (255) A file, B file, pr, left, right
   ownstring (255) array File('A':'B')
   owninteger array Base('A':'B')
   owninteger A count, B count
   owninteger A num, B num

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

   integerfn  input ended
      integer ch
      on event 9 start
         result = TRUE
      finish
      ch = next symbol
      result = 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.tostring(ch)
      repeat
   end

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

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

   routine  refill (byte integer 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=TRUE
            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=TRUE
            Read symbol (ch)
         repeat
         x (i, j) = nl
         count = count + 1
      repeat
   end

   routine  print (byte integer 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

   integerfn  lines match (integer A line, B line)

      integer j
      if A line > A count or B line > B count start
         result = TRUE if A line > A count and B line > B count
         result = FALSE
      finish
      for j = 1, 1, Max Line Width cycle
         result = FALSE if A (A line, j) # B (B line, j)
         result = TRUE if A (A line, j) = nl
      repeat
      result = 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)=TRUE
         if i > 1 start
            for j = 1, 1, I - 1 cycle
               AL = i and BL = j and return if lines match (i, j)=TRUE
               AL = j and BL = i and return if lines match (j, i)=TRUE
            repeat
         finish
      repeat
      AL = Max Lines+1; BL = Max Lines+1
   end


integer fname len; 

A num = Max Lines; B num = Max Lines
Base('A') = 0; Base('B') = 0
A count = 0; B count = 0

if cli param -> ("-h") start
  print string("Syntax: compare oldfile newfile".snl)
  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

File('A') = A file; File('B') = B file

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

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("---------------------".snl)
      if A num > Max Lines start
         Print string ("*** Mismatch too large")
         Newline
         stop
      finish
   finish
   Base('A') = Base('A') + A num
   Base('B') = Base('B') + B num
   A count = A count - A num
   B count = B count - B num
repeat

end of program