         Edinburgh IMP77 Compiler - Version 8.4

    1  %begin
    2     %const %integer TRUE = 1, FALSE = 0
    3     %constant %integer  A stream = 1, B stream = 2
    4     %ownstring (255) A file, B file, pr, left, right
    5     %ownstring (255) %array File('A':'B')
    6     %owninteger %array Base('A':'B')
    7     %owninteger A count, B count
    8     %owninteger A num, B num
    9  
   10     %const %integer Max Lines = 512, Max Line Width = 128
   11     %byte %integer %array AA, BB (1:Max Lines*Max Line Width)
   12  
   13     %integer%fn  input ended
   14        %integer ch
   15        %on %event 9 %start
   16           %result = TRUE
   17        %finish
   18        ch = next symbol
   19        %result = FALSE
   20     %end
   21  
   22     %routine  Rd line (%string (*) %name s)
   23        %integer ch
   24        s = ""
   25        %cycle
   26           read symbol (ch)
   27           %exit %if ch = nl %or LENGTH(s) = Max Line Width
   28           s = s.tostring(ch)
   29        %repeat
   30     %end
   31  
   32     %byte %integer %map  A (%integer i, j)
   33        %result == AA (((Base('A') + i)&(Max Lines-1))*Max Line Width + j)
   34     %end
   35  
   36     %byte %integer %map  B (%integer i, j)
   37        %result == BB (((Base('B') + i)&(Max Lines-1))*Max Line Width + j)
   38     %end
   39  
   40     %routine  refill (%byte %integer %map x (%integer i, j),
   41+                      %integer n,
   42+                      %integer %name count)
   43  
   44        %integer i, j, ch
   45        %for i = Max Lines+1-n, 1, Max Lines %cycle
   46           %cycle
   47              %return %if input ended=TRUE
   48              Read symbol (ch)
   49           %repeat %until ch # nl
   50           %for j = 1, 1, Max Line Width-1 %cycle
   51              %exit %if ch = nl %OR CH<32
   52              x (i, j) = ch
   53              %return %if input ended=TRUE
   54              Read symbol (ch)
   55           %repeat
   56           x (i, j) = nl
   57           count = count + 1
   58        %repeat
   59     %end
   60  
   61     %routine  print (%byte %integer %map x (%integer i, j),
   62+                     %integer n,
   63+                              flag)
   64  
   65        %integer i, j
   66        %for i = 1, 1, n %cycle
   67           Print string ("""".File(flag).""",")
   68           Write (Base(flag)+i+1, 5)
   69           Print string (": ")
   70           j = 0
   71           %cycle
   72             j = j + 1
   73             %exit %if x (i, j) = nl
   74             Print symbol (x (i, j))
   75             %if j=57 %then newline %and spaces(20) %and printsymbol(':')
   76           %repeat
   77           newline
   78        %repeat
   79     %end
   80  
   81     %integer%fn  lines match (%integer A line, B line)
   82  
   83        %integer j
   84        %if A line > A count %or B line > B count %start
   85           %result = TRUE %if A line > A count %and B line > B count
   86           %result = FALSE
   87        %finish
   88        %for j = 1, 1, Max Line Width %cycle
   89           %result = FALSE %if A (A line, j) # B (B line, j)
   90           %result = TRUE %if A (A line, j) = nl
   91        %repeat
   92        %result = TRUE
   93     %end
   94  
   95     %routine  find match (%integer %name AL, BL)
   96  
   97        %integer i, j
   98        %for i = 1, 1, Max Lines %cycle
   99           AL = i %and BL = i %and %return %if lines match (i, i)=TRUE
  100           %if i > 1 %start
  101              %for j = 1, 1, I - 1 %cycle
  102                 AL = i %and BL = j %and %return %if lines match (i, j)=TRUE
  103                 AL = j %and BL = i %and %return %if lines match (j, i)=TRUE
  104              %repeat
  105           %finish
  106        %repeat
  107        AL = Max Lines+1; BL = Max Lines+1
  108     %end
  109  
  110  
  111  %integer fname len; 
  112  
  113  A num = Max Lines; B num = Max Lines
  114  Base('A') = 0; Base('B') = 0
  115  A count = 0; B count = 0
  116  
  117  %if cli param -> ("-h") %start
  118    print string("Syntax: compare oldfile newfile".snl)
  119    %stop
  120  %finish
  121  
  122  pr = "New file: "
  123  
  124  %unless cli param -> A file.(" ").B file %start
  125    A file = cli param
  126    %if A file # "" %start
  127     B file = ""; pr = "Against:  "
  128    %else
  129     A file = ""
  130     B file = ""
  131    %finish
  132  %finish
  133  
  134  A file <- left.right %while A file -> left.(" ").right
  135  B file <- left.right %while B file -> left.(" ").right
  136  
  137  File('A') = A file; File('B') = B file
  138  
  139  Prompt ("Old file: ")
  140  Rd line (A file) %while A file = ""
  141  Prompt (pr)
  142  Rd line (B file) %while B file = ""
  143  
  144  fname len = LENGTH(A file)
  145  %if fname len < LENGTH(B file) %then fname len = LENGTH(B file)
  146  %if fname len > 11 %then fname len = 11
  147  
  148  open input (A stream, A file)
  149  open input (B stream, B file)
  150  
  151  A file = "           ".A file
  152  B file = "           ".B file
  153  A file = SUBSTRING(A file, LENGTH(A file)-10, LENGTH(A file))
  154  B file = SUBSTRING(B file, LENGTH(B file)-10, LENGTH(B file))
  155  
  156  %cycle
  157     select input (A stream)
  158     refill (A, A num, A count)
  159     select input (B stream)
  160     refill (B, B num, B count)
  161     %exit %if A count <= 0 %and B count <= 0
  162     find match (A num, B num)
  163     %if A num # 1 %or B num # 1 %start
  164        print (A, A num-1, 'A')
  165        print (B, B num-1, 'B')
  166        Print string("---------------------".snl)
  167        %if A num > Max Lines %start
  168           Print string ("*** Mismatch too large")
  169           Newline
  170           %stop
  171        %finish
  172     %finish
  173     Base('A') = Base('A') + A num
  174     Base('B') = Base('B') + B num
  175     A count = A count - A num
  176     B count = B count - B num
  177  %repeat
  178  
  179  %end %of %program

  154 Statements compiled
