DataMuseum.dk

Presents historical artifacts from the history of:

RC4000/8000/9000

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about RC4000/8000/9000

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download

⟦e59000f08⟧ TextFile

    Length: 35328 (0x8a00)
    Types: TextFile
    Names: »xfortran4tx «

Derivation

└─⟦01e83a425⟧ Bits:30008166 Bånd med SW8010 og SW8500 source code
    └─⟦75ff9bef3⟧ 
        └─⟦this⟧ »xfortran4tx « 

TextFile

xfortran = algol index.no
begin
<*     bobs-system parser     *>
<*     algol6 - version       *>
<*     rewritten from pascal  *>
<*           october 76       *>

message version id: 88 10 10, 4;

  integer
   linemax,          <* max line length *>
   stackmax,         <* parse stack size *>
   bufmax,           <* max no of chars in name and consts *>
   lrmax,            <* size of lr-tables *>
   lxmax,            <* size of lexical tables *>
   errorval,         <*     *>
   nameval,          <* internal value of name *>
   constval,         <*    -        -   - const *>
   stringval,        <*    -        -   - string *>
   stringch,         <* stringescape char *>
   curchclass,       <* class of curch *>
   filemax,          <* max no of files allowed to be defined *>
   fpmax,            <* max size of call of compiler *>
   errormax;         <* max no of marked errors*>
   zone productions(128,1,stderror);
   zone parsetables(128,1,stderror);
   zone xref(128,1,stderror);
   integer field f2,f4,f6,f8,f10,f12,f14,f16,f18;

  f2:=2; f4:=4; f6:=6; f8:=8; f10:=10; f12:=12; f14:=14; f16:=16; f18:=18;
  linemax := 150; fpmax:=60; stackmax := 60; 
  bufmax := 12; errormax := 10; filemax := 5;
  open(productions,4,<:productions:>,0);
  open(parsetables,4,<:parsetables:>,0);
  inrec6(parsetables,18);
  lrmax:=parsetables.f6; lxmax:=parsetables.f8;
  errorval:=parsetables.f10; nameval:=parsetables.f12;
  constval:=parsetables.f14; stringval:=parsetables.f16;
  stringch:=parsetables.f18;

  begin
    integer array lrchain,lrnext,lr(0:lrmax);
            <* lr(.) bit 0 - 2 kind
                     bit 3 - 11 symb/rs
                     bit 12 - 23 lb/prd (if kind=5 then this field is 0)
             *>
    integer  kind, symb;
    integer startinx;                           <* start of current state in lr *>
    integer array stack(0:stackmax);            <* parse stack *>
    integer stacktop, newtop;
    integer array entry(1:4,32:127);
                  <* entry(1,.) - np (0:lxmax)
                     entry(2,.) - hp (    -   )
                     entry(3,.) - tv (0:symbmax)
                     entry(4,.) - ch4 ( charvalue )
                  *>
    integer np,tv,hp,ch4;
    integer array lx(1:4,0:lxmax);     <* lexical tables *>
                                       <* the entries are as above *>
    integer
     newsymb,                          <* current terminal symbol *>
     curch;                            <* current char *>
    integer array
     name(1:bufmax),                   <* current name in chars *>
     konst,konstbuf(0:bufmax);         <* current const in chars *>
    integer nameno,  konstno;
        
    integer
     stringescape,
     lineinx;                          <* pos in line of current char *>
    boolean
     letterordigit,                    <* true if current char is letter or digit *>
     ok,                               <* false when parsing has to be stopped *>
     moreinput;                        <* false when input is exhausted *>
    integer array errormark(1:2,0:errormax);
                                        <* errormark(1,.) - errornous lineno
                                               -    (2,.) - errornous char pos.
                                        *>
    integer array line1,line2,ltype1,ltype2(0:linemax); <* line buffer and type *>
    integer errorcount,linecount1,linecount2,lineno ; <* index to line *>
    integer linecount3;
    boolean newline,                    <* newline char (local) *>
            firsttime ,                 <* used to handle output *>
            more,                       <* true as long as more input in buffer2 *>
            anything_left,
            commentline;                <* false when input line is skipped *>
    integer startexp,konstlimit,s1,new1,i,j;
    boolean readexp;                    <* true if read statement *>
    integer endexp,                     <* pointer to exp in special read-write *>
            startio,                    <* start of io list *>
           fileinx;                     <* no of defined files *>
    boolean firstdefine ,format;
    integer array unit(1:2,1:filemax),     <* unit no in define file *>
                  assvar(1:6,1:filemax),   <* the associated variable *>
                  conv(0:225) ,            <* converted prod number *>
                  recsize(1:filemax),      <* the recordsize *>
                  cheat(1:3),tcheat(1:3);  <* used to avoid parsing formats *>
    zone outfile(128,1,stderror);          <* the zone name used to outputfile *>
    integer array tail(1:20),fp(1:fpmax);  <* tail of entry, fp-stack *>
    real array workfile,fpparam(1:2);   <* parameters to system-procedure *>
    real array sourcename(1:2);      <* filename for input to normal fortran *>
    integer fpinx,sourceinx,paramno;
    integer array rem(1:20),            <* array to remember pos of dots *>
                  testword(1:10);       <* contains some operators *>
    integer reminx;                     <* index to rem *>
    boolean dot,                        <* true if dots in line *>
            random1,                    <* true if random access *>
            xfortrantest,               <* true if test-output *>
            crossref;                   <* true if crossref of prg *>


    procedure outfilno(inx);
    value inx; integer inx;
    begin integer i;
      for i:=1,2 do
        if unit(i,inx)=32 then i := 10000
        else outchar(outfile, unit(i,inx));
    end;


    procedure outassvar(inx);
    value inx; integer inx;
    begin integer i;
      for i:=1 step 1 until 6 do
        if assvar(i,inx)=32 then i := 10000
        else outchar(outfile,assvar(i,inx));
    end;


    procedure outfiledef(inx);
    value inx; integer inx;
    begin integer i;
      if firstdefine then
        begin
        firstdefine := false;
        lineno := lineno+1;
        write(outfile, <:      logical setposition:>, newline, 1);
        end;
      write(outfile, <:      zone fil:>); outfilno(inx);
      write(outfile, <:(:>, <<ddd>, 128*recsize(inx), <:, 1, stderror):>,
            newline, 1, <:      integer :>); outassvar(inx);
      write(outfile, newline, 1);
      lineno := lineno + 2;
      write(outfile, <:      common/comfil:>); outfilno(inx);
      write(outfile, <:/fil:>);                outfilno(inx);
      write(outfile, <:/comass:>);             outfilno(inx);
      write(outfile, <:/:>);                   outassvar(inx);
      write(outfile, newline, 1);
      lineno := lineno + 1;
    end;


    procedure code(prodno);
    value prodno; integer prodno;
    begin integer ii;
      if xfortrantest then write(productions,<<dddd>,prodno);
      if conv(prodno)=0 then goto exitcode;
      case conv(prodno) of
      begin
 
       <* -1- <simple statement> ::= <rewind> konst / <endfile> konst *>
       begin 
         lineno:=lineno+1; 
         for i:=1 step 1 until 6 do outchar(outfile,line1(i));
         if prodno=130 then
         begin <* rewind *>
           write(outfile,<:call setposition(fil:>);
           for i:=1 step 1 until konstno do outchar(outfile,konst(i));
           write(outfile,<:, 0, 0):>,newline,1);
         end
        else
         begin <* endfile *>
           write(outfile,<:call close(fil:>);
           for i:=1 step 1 until konstno do outchar(outfile,konst(i));
           write(outfile,<:, .true.):>,newline,1);
         end
       end;
 
       <* -2- <rewind> ::= rewind
              <endfile>::= endfile
       *>
       commentline := true;
 
       <* -3-     <special read statem> ::= read ( <fileno> ' 
                  <special write statem>::= write ( <fileno> '
       *>
       begin
         if prodno = 174 then readexp:=true else readexp:=false;
         commentline := true;
       end;
     
       <* -4-     <special read write> ::= <special read statem> <expr> )
                                        / <special write statem> <expr> )
       *>
       begin
         for ii:=1 step 1 until fileinx do
           if unit(1,ii)=konstbuf(1) and
              unit(2,ii)=konstbuf(2) then goto found;
          markerror; ii:=1;
         found :
          if random1 then <* random access *>
          begin lineno:=lineno+1;
            write(outfile,<:      call setposition(fil:>);
            outchar(outfile,konstbuf(1)); outchar(outfile,konstbuf(2));
            write(outfile,<:, 0, (:>);
            for i:=1 step 1 until endexp do outchar(outfile,rem(i));
            write(outfile,<: - 1)*:>,<<ddd>,recsize(ii),<:):>,newline,1);
          end;
         lineno:=lineno+1;
         write(outfile,<:      :>,if readexp then <:read:> else <:write:>,
                       <:(fil:>);
         for i:=1 step 1 until konstlimit do outchar(outfile,konstbuf(i));
         write(outfile,<:) :>);
         for i:=startio step 1 until linecount1-1 do outchar(outfile,line1(i));
         <* associated variable *>
         write(outfile,newline,1);
         lineno:=lineno+1;
         for i:=1 step 1 until 6 do outchar(outfile,line1(i));
         outassvar(ii);
         write(outfile,<: = 1 + :>);
         for i:=1 step 1 until endexp do outchar(outfile,rem(i));
         write(outfile,newline,1);
         startexp:=0;
       end;
 
       <* -5-      <expr> ::=  <prim5>  *>
       if startexp>0 then
       begin  startio:=lineinx;
         if line1(startexp)<48 then startexp:=startexp+1;
         for i:=startexp step 1 until lineinx-2 do rem(i-startexp+1):=line1(i);
         endexp:=lineinx-1-startexp;
       end;
 
       <* -6-  <unit> ::= konst *>
       begin commentline := true;
         if fileinx < filemax then fileinx := fileinx+1 else stop(4);
         unit(1,fileinx) := konst(1);
         unit(2,fileinx) := if konstno=1 then 32 else konst(2);
       end;
 
       <* -7- <noofrec> ::= konst *>
       begin <* this is not used in this version *>
       end;
 
       <* -8-  <max> ::= konst *>
       begin j:=0;
         for i:=1 step 1 until konstno do j:=j*10+konst(i)-48;
         recsize(fileinx):=if j mod 256=0 then j/256 else j/256+1;;
       end;
<*  -9-<program start>   ::= <prg> name <sep> <firstpart>
                                    / <prg> name <sep>
       *>
       begin
         for i:=1 step 1 until fileinx do
         begin
           lineno:=lineno+1;
           write(outfile,<:      call open(fil:>);
           outfilno(i);
           write(outfile,<:, 4, 'fil:>);
           outfilno(i);
           write(outfile,<:', 0):>,newline,1,<:      :>);
           lineno:=lineno+1;
           outassvar(i);
           write(outfile,<: = 1 :>,newline,1);
         end;
       end;
 
       <* -10- <filedef> ::=  <unit> ( <noofrec>,<max>,name,name ) *>
       begin
         if nameno>6 then nameno:=6;
         for i:=1 step 1 until nameno do
           assvar(i,fileinx):=name(i);
         for i:=nameno+1 step 1 until 6 do assvar(i,fileinx):=32;
         outfiledef(fileinx);
       end;
       
       <* -11- <f> ::= format / formato *>
       begin format :=true;
         for i := i while true do
         begin
           lineno:=lineno+1;
           j:=if linecount1>=72 then 72 else linecount1-1;
           for i:=1 step 1 until j do outchar(outfile,line1(i));
           write(outfile,newline,1);
           if line1(linecount1)=59 then <* format statement terminated *>
           begin <* copy cheat line into linebuf *>
             j:=if curch=32 then lineinx+1 else lineinx;
             for i:=j step 1 until j+2 do
             begin line1(i):=cheat(i-j+1); ltype1(i):=tcheat(i-j+1);
             end;
             linecount1:=j+2; goto exit;
           end;
           nextline;
         end while;
        exit :
       end;
        
        <* -12- <fileno> ::= konst *>
        begin 
          konstbuf(1):=konst(1);
          konstbuf(2):=if konstno=1 then 32 else konst(2);
          startexp:=lineinx; konstlimit:=konstno;
        end;
        
        <* -13- <statement> ::= <f> ( <format field> ) *>
        format := false;
 
        <* -14- <leftside> ::= <variable> =
                <if>    ::= if
        *>
        begin if reminx=0 then  checkpoint;
          if line1(linecount1)<>59 then dot:=true;
        end;
 
        <* -15- <simple statement> ::= <leftside> <expr>
                <cond statement>   ::= <if> ( <expr> ) <simple statement>
                                     / <if> ( <expr> ) konst, konst, konst
        *>
        begin dot := false; reminx:=0;
        end;
 
        <* -16- <sub-name> ::= name *>
        begin <*used in crossref *>
          i:=-1; write(xref,newline,1,i,nameno,<: :>);
          for i:=1 step 1 until nameno do outchar(xref,name(i));
        end;
 
        <* -17- <prg> ::= program *>
        begin <*used in crossref *>
          i:=-1; j:=4; write(xref,newline,1,i,j,<: main:>);
        end;
 
        <* -18- <pause> ::= pause
                <find> ::= find
        *>
        begin commentline:= true;
          lineno:=lineno+1;
          for i:=1 step 1 until 6 do outchar(outfile,line1(i));
          write(outfile,<:continue:>,newline,1);
        end;
 
        <* -19- <program-unit> ::= <program-start> <statement-part> end
                                /  <     do      > end
                <procedure>    ::= <procedure start> <    do     >  end
                                 / <      do       > end
        *>
       ;  <* empty *>

       <* -20- <proceduredecl> ::= subroutine <sub-name> (separator>
                                 / subroutine <sub-name> ( <formalparameters> )
                                              <separator>
                                 / function <sub-name> ( <formalparameters> )
                                              <separator>
                                 / <type> function <sub-name> ( <formalparameters> )
                                              <separator>
       *>
       begin
       integer fileno;
       firstdefine := true;
       for fileno := 1 step 1 until fileinx do
         outfiledef(fileno);
       end;
 
 
      end case ;
      exitcode :
    end proc code;
 
    procedure checkpoint;
    <* the routine makes some lexical work removing . around
       some relational operators (because of lr-problems)
    *>
    begin integer i,k,t1;
      reminx:=0; i:=7;
      for i:=i while i< linecount1 do
      if line1(i)=46 <* . *> then
      begin k:=i; i:=i+1;
        for i:=i while line1(i)=32 do i:=i+1;
        if (ltype1(i)=6 and ltype1(i+1)=6) then 
        <* . followed by at least two letters *>
        begin t1:= (line1(i) shift 16);
          t1:=t1 add (line1(i+1) shift 8);
          t1:=t1 add (if ltype1(i+2)<>6 then 32 else line1(i+2));
          i:=i+1;
          for j:=1 step 1 until 9 do
          if t1=testword(j) then goto found;
          j:=0;
        found :
          if j<> 0 then
          begin reminx:=reminx+1;
            rem(reminx):=k; line1(k):=32; ltype1(k):=7;
            <* find the belonging . *>
            for i:=i while line1(i)<>46 do i:=i+1;
            reminx:=reminx+1; rem(reminx):=i;
            line1(i):=32; ltype1(i):=7; i:=i+1;
          end;
        end;
     end else i:=i+1;
    end proc checkpoint ;
 
    procedure markerror;
    <* syntax errors are remembered by a call of this routine.
       furthermore if the error recovery algorithm has problems
       with loops this avoided by a call of lexical.
    *>
    begin
      if (new1=newsymb) and (s1=startinx) then lexical;
      new1:=newsymb; s1:=startinx;
      if (errorcount<errormax) and errormark(1,errorcount) <> lineno then
      begin errorcount := errorcount+1;
        errormark(1,errorcount) := lineno;
        errormark(2,errorcount) := lineinx;
      end;
    end proc errormark;
    
    procedure unpackfp;
    begin integer k,l;
      write(productions,newline,2); i:=1;
      for i:=i while i<fpinx do
      begin j:=fp(i) extract 12;
          k:=fp(i) shift (-12);
          write(productions,k,<: shift 12 + :>,j,newline,1);
          if j=0 then goto exit
         else
          if j=4 then
          begin i:=i+1; write(productions,fp(i),newline,1);
          end
         else
          if j=10 then
          begin
            for k:=1 step 1 until 4 do
            for j:=2 step -1 until 0 do
            begin l:=fp(i+k) shift (-8*j); outchar(productions,l);
            end;
            write(productions,newline,1);
            i:=i+4;
          end;
          i:=i+1;
       end;
      exit :
    end unpackfp;
 
    procedure packfp(del);
    <* the fp-stack is changed. repacking is done here *>
    value del; integer del;
    begin integer l, nextdel;
    real array nextparam(1:2);
      l:=del extract 12;
      if l=10 then j:=4 else j:=1;
      if (fpinx+j)>fpmax then stop(5);
      fpinx:=fpinx+1;  fp(fpinx):=del;
      if l=4 then fp(fpinx+1):=fpparam(1) <* integer *>
     else
      begin <* name *>
        nextdel := system(4,paramno+1,nextparam);
    if nextdel=8 shift 12 + 10 and fpparam(1) = real <:xfort:>
       and nextparam(1) = real <:test:> then
    begin
      xfortrantest := true;
      j := -1;
      paramno := paramno + 1;  <* skip the compound parameter *>
    end
   else
        if nextdel=8 shift 12 + 10 and fpparam(1)=real <:xref:> then
        begin <* the param xref.yes or xref.no appear *>
          paramno:=paramno+1; i:=system(4,paramno,fpparam);
          if fpparam(1)=real <:yes:> then crossref:=true;
          j:=-1;
        end
       else
        if nextdel=8 shift 12 + 10 and fpparam(1)= real <:rand:> then
        begin <* the parameter rand.yes or no appear *>
          paramno:=paramno+1; i:=system(4,paramno,fpparam);
          if fpparam(1)=real <:yes:> then random1:=true;
          j:=-1;
        end
       else
        if nextdel=8 shift 12 + 10 and fpparam(1)= real <:text:> then
        begin
          paramno := paramno+1;
          for i:=1,2 do sourcename(i) := nextparam(i);
          j := -1;
        end
       else
        begin <* pack name *>
          l:=1;
          for i:=1,2 do
          begin if i=2 then l:=3;
            fp(fpinx+l):=fpparam(i) shift (-24) extract 24;
            fp(fpinx+l+1):=fpparam(i) extract 24;
          end;
        end;
      end;
      fpinx:=fpinx+j;
    end packfp;
  
    procedure stop(n);
    value n; integer n;
    begin 
      write(out,newline,2);
      case n of
      begin
        write(out,<: *** parse stack overflow (stackmax) :>);
        write(out,<: *** end of file encountered :>);
        begin
          for i:=1 step 1 until errorcount do
          write(out,newline,1,<: syntax in line :>,<<dddd>,errormark(1,i),
                    <: char.no. :>,<<dd>,errormark(2,i));
        end case 3;
        write(out,<: *** too many file definitions (filemax)  :>);
        write(out,<: *** parameter list too small (fpmax) :>);
        write(out,<: *** line too long (linemax) :>);
      end case ;
      if n<>3 then write(out, <:   in line:>, lineno);
      write(out,newline,1);
      if n<>3 then goto exitprg;
    end proc stop;

    procedure initialize;
    <* variables and tables are initialized in this routine *>
    begin
      ok:=moreinput:=firstdefine:=firsttime:=more:=anything_left:=true;
      format:=commentline:=false;
      konstno:=nameno:=stacktop:=lineinx:=errorcount:=fileinx:=linecount1:=linecount2:=0;
      stack(0):=0; curch:=32; lineno:=1;
      startexp:=0;
     
      <* initialization only concerning the algol 6 version : *>
      np := 1; hp := 2; ch4 := 4; tv := 3;
      newline := false add 10;
      conv(0):=0;
      for i:=1 step 1 until 180 do
      conv(i):=case i of
      (0,0,0,0,19,19,0,0,19,19,
       0,0,20,20,20,20,0,0,0,0,
       0,0,0,0,9,9,17,0,0,0,
       0,0,0,0,0,0,0,0,0,0,
       0,0,0,0,0,0,0,0,0,0,
       0,0,0,0,0,0,0,0,0,0,
       0,0,0,0,0,10,6,7,8,0,
       0,0,13,0,0,16,0,0,0,0,
       0,0,0,0,0,0,0,0,0,0,
       0,0,0,0,11,11,0,0,0,0,
       0,0,0,0,0,0,0,0,0,0,
       0,0,0,0,0,0,0,15,0,0,
       0,0,0,0,0,0,0,0,0,1,
       1,0,0,0,15,15,14,0,5,0,
       0,0,0,0,18,0,0,0,2,2,
       2,18,0,0,0,0,0,0,0,0,
       14,0,0,0,0,0,0,0,0,0,
       0,4,4,3,3,12,0,0,0,0);
      for i:=181 step 1 until 225 do conv(i):=0;
      cheat(1):=120; cheat(2):=41; cheat(3):=59;
     tcheat(1):=6;  tcheat(2):=7;  tcheat(3):=7;
      reminx:=0; dot :=false;
      for i:=1 step 1 until 9 do
      testword(i):= long (case i of (<:lt :>,<:ge :>,<:eq :>,<:le :>,
                    <:ne :>,<:gt :>,<:and:>,<:or :>,<:shi:>))
                    shift (-24) extract 24;
 
      for i:=1 step 1 until 63 do
      begin
        inrec6(parsetables,8);
        j:=parsetables.f2; 
        if (j>64) and (j<94) then j:=j+32;
        entry(ch4,j):=j;
        entry(np,j):=parsetables.f4; entry(hp,j):=parsetables.f6;
        entry(tv,j):=parsetables.f8;
      end init entry;

      for i:=0 step 1 until lxmax do
      begin inrec6(parsetables,8);
        j:=parsetables.f2;
        if (j>64) and (j<94) then lx(ch4,i):=j+32 else lx(ch4,i):=j;
        lx(np,i):=parsetables.f4;
        lx(hp,i):=parsetables.f6; lx(tv,i):=parsetables.f8;
      end;

      stringescape:= entry(tv,stringch);

      for i:=0 step 1 until lrmax do
      begin
        inrec6(parsetables,8);
        lrchain(i):=parsetables.f2; lrnext(i):=parsetables.f4;
        kind:=parsetables.f6; symb:=parsetables.f8;
        if kind<>5 then
        begin inrec6(parsetables,2); j:=parsetables.f2;
        end;
        if kind = 5 then lr(i) := (symb shift 3) add 5
                    else lr(i) := (j shift 12) add (symb shift 3) add kind;
      end init lr;
      close(parsetables,true);
    end proc initialize;
 
      procedure readaline(line,ltype,linecount);
      <* the procedure reads the next line, comments  are skipped *>
      integer linecount; integer array line,ltype;
      begin
        linecount := 0;
        more := anything_left;
        if more then
        begin
nextsymbol:
        linecount := linecount + 1;
        if linecount > linemax then stop(6);
        ltype(linecount) := readchar(in,j);
        if 64<j and j<94 then j := j+32;  <* convert to small letters *>
        if j=25 then
          begin <* end medium *>
          repeatchar(in);
          more := false;
          end;
        line(linecount) := j;
        if j <> 10 and j <> 25 then goto nextsymbol;
        if line(1) = 47 then
          begin
          anything_left := false;
          ltype(1) := 6; <* simulate letter *>
          end;
        linecount := linecount - 1;
        end;
      end; <* proc readaline *>
 
      procedure nextline;
      begin
      own integer char73;
        if firsttime then
        begin firsttime := false;
          readaline(line1,ltype1,linecount1);
          readaline(line2,ltype2,linecount2);
        end
       else
        begin
          for i:=1 step 1 until reminx do line1(rem(i)):=46; <* . *>
          if commentline then <* lines which are transformed to comments *> 
          begin if firstdefine or (line2(6)=32) then commentline:=false;
            line1(1):=99; <* c *>
            line1(2):=42; <* * *>
          end;
          if -, format then <* if format the line is written elsewhere *>
          begin
          repline : if line1(linecount3)<>59 then linecount3:=linecount3+1;
            line1(linecount3):=10; line1(73):=char73;
            for i:=1 step 1 until linecount3 do outchar(outfile,line1(i));
            if linecount3>7 then  lineno := lineno+1;
          end;
          for i:=1 step 1 until linecount2 do
          begin line1(i):=line2(i); ltype1(i):=ltype2(i);
          end;
          linecount1:=linecount2;
          readaline(line2,ltype2,linecount2);
          if -, more then <* end of program *>
          begin linecount1:=linecount1+1;
            line1(linecount1):=59; ltype1(linecount1):=7;
            linecount1:=linecount1+1;
            if linecount1<7 then linecount1:=7;
            line1(linecount1):=25; <*em*> ltype1(linecount1):=8;
            linecount1:=linecount1+1;
          end;
        end;

        <* if cardmode (72 signif. chars) *>
        char73 := line1(73);
        linecount3:=linecount1;
        if ltype1(1) = 6 then
          goto repline; <* comment line in source text *>
        if linecount1>72 then linecount1:=72;
        if more and linecount1<=7 then goto repline;
        if dot then checkpoint; <* check points if cont. or if *>
        if more and (ltype2(1)=6 <* commentline *> or line2(6)=32 or linecount2<=6) then
        <* if not continuation line set seperator *>
        begin linecount1:=linecount1+1;
          line1(linecount1):=59; ltype1(linecount1):=7;
        end;
      end proc nextline;
 
 
    procedure lexical;
    <* returns the next terminal in newsymb *>
    begin
      integer bufi, newi, oldch ;
      integer array buf(1:bufmax), lxnode(1:4);
      boolean oldchclass;
  
      procedure inchar;
      <* the procedure reads the next character from the line-
         buffer,if possible, else the linebuffer is changed and 
         the character is read from the new buffer. furthermore
         some lexical work is done here.
      *>
      begin
        if lineinx>= linecount1  and more then
        begin <*change buffer*> nextline; lineinx:=6; 
        end;
        lineinx :=lineinx+1;
        curch := line1(lineinx); curchclass:=ltype1(lineinx);
        if curch=25 then
        begin moreinput:=false;
          line1(linecount1-2):=10;
          if linecount1>9 then
          for i:=1 step 1 until linecount1-2 do outchar(outfile,line1(i));
        end;
        letterordigit := (curchclass=2) or (curchclass=6);
      end; <*proc inchar *>
 

      procedure packname;
      <* the current name (identifier) is packed here *>
      begin
        newsymb := nameval;
        if bufi>bufmax then bufi:=bufmax;
        for i:=1 step 1 until bufi do name(i):=buf(i);
        nameno:=bufi;
if xfortrantest then
begin
write(productions,newline,1,<: name :>);
for i:=1 step 1 until nameno do outchar(productions,name(i));
end;
        write(xref,newline,1,lineno,nameno,<: :>);
        for i:=1 step 1 until nameno do outchar(xref,name(i));
      end proc packname;

      procedure packstring;
      <* the current string is read here *>
      begin 
        for i:=i while true do
        begin
          if curch = stringch then
          begin inchar;
            if curch <> stringch then goto exitloop;
          end;
          inchar;
        end for;
       exitloop:
        newsymb := stringval;
      end proc packstring;

      <* body of lexical *>
      for i:=i while (curch=32) or (curch = 10) do inchar;
      <* spaces and nl's are skipped *>
      if -, moreinput then
      begin
        if newsymb = 0 then <* third *> stop(2)
                       else
        if newsymb = 1 then <* second *> newsymb := 0
                       else <* first  *> newsymb := 1;
      end
     else
      if curchclass = 2 then <* charclass is digit *>
      begin
        for konstno := 1,konstno+1 while letterordigit do
        begin
          if konstno <= bufmax then konst(konstno) := curch;
          inchar;
        end;
        konstno :=konstno-1;
        newsymb := constval;
if xfortrantest then
begin
write(productions,newline,1,<: konst :>);
for i:=1 step 1 until konstno do outchar(productions,konst(i));
end;
      end
     else
      begin <* not constant - search in termtree *>
        bufi := 1; buf(1) := curch;
        for i:= 1 step 1 until 4 do
        lxnode(i):= entry(i,curch);
        newi:= lxnode(hp);
        inchar;
        for i :=i while newi <> 0 do
        begin
          if lx(ch4,newi) = curch then
          begin
            if bufi<bufmax then
            begin bufi:=bufi+1; buf(bufi):=curch;
            end;
            if (bufi=10) and buf(2) =113 then inchar;
            <* if equivalence then skip last e *>
            for i := 1 step 1 until 4 do
            lxnode(i) := lx(i,newi);
            newi := lxnode(hp);
            inchar;
          end
         else newi := lx(np,newi);
        end for i;
        oldch := buf(bufi);
        oldchclass := (oldch>96)and(oldch<=125)or(oldch>47)and(oldch<58);
        if oldchclass and letterordigit then
        begin
          for bufi:=bufi+1,bufi+1 while letterordigit do
          begin
            if bufi<=bufmax then buf(bufi) := curch;
            inchar;
          end;
          bufi:=bufi-1; packname;
        end
       else
        if lxnode(tv)>0 then <* valid terminal *>
        begin
          newsymb := lxnode(tv);
          if newsymb= stringescape then packstring;
        end
       else
        if oldchclass  then packname else markerror;
      end;
if xfortrantest then
write(productions,newline,1,<: newsymb :>,newsymb);
    end proc lexical;


    procedure parse;
    <* the parsing algorithm *>
    begin integer lri,li,si,i;

      procedure syntaxerror;
      begin integer stackp,chainp;
        <* the error is tried to be repaired by a stack-recovery algorithm *>
        markerror;
if xfortrantest then
write(productions,newline,1,<: error :>,startinx,newsymb);
        shiftstack;
        if -, moreinput then ok := false;
        for i:=i while moreinput do
        begin
          stackp := stacktop;
          for i:=i while stackp>0 do
          begin
            chainp := stack(stackp);
            for i:=i while chainp<>0 do
            begin
              if (lr(chainp) shift (-3) extract 9)=errorval then
              begin
                startinx:= stack(stackp);
                stacktop:= stackp-1;
                goto endrecover;
              end;
              chainp := lrchain(chainp);
            end;
            stackp:=stackp-1;
          end stackp>0;
          markerror; lexical;
        end moreinput;
       endrecover:
      end proc syntaxerror;

      procedure shiftstack;
      begin
        stacktop := stacktop+1;
        if stacktop > stackmax then stop(1);
        stack(stacktop) := startinx;
      end proc shiftstack;

      <* body of parse *>
      startinx := 1; lexical;
      for i:=i while ok do
      begin
        lri := startinx;
        i := case lr(lri) extract 3 +1 of (1,2,3,4,3,5,3);
        case i of
        begin
          <* 1 stop *> ok := false;

          <* 2 shift *>
          begin
            for i:=i while (lr(lri) shift (-3)) extract 9 <> newsymb do
            begin li := lrchain(lri);
              if li = 0 then
              begin syntaxerror; goto endshift;
              end;
              lri:=li;
            end for i;
            shiftstack; lexical;
            startinx:=lrnext(lri);
          endshift:
          end shift case2;

          <* 3 shift lookahead or reduce empty *>
          begin
            for i:=i while ((lr(lri) shift (-3)) extract 9)<>newsymb do
            begin li :=lrchain(lri);
              if li=0 then goto exitloop;
              lri := li;
            end;
           exitloop:
            kind := lr(lri) extract 3;
            if kind=2 then
            begin shiftstack; lexical;
            end
           else   
            if kind = 6 then 
            begin shiftstack; newtop := stacktop;
              code(lr(lri) shift (-12));
            end;
            startinx:= lrnext(lri);
          end case 3;

          <* 4 reduce *>
          begin
            newtop := stacktop-(lr(lri) shift (-3) extract 9);
            i :=lr(lri) shift (-12);
    if conv(i) <> 0 then code(i);
            stacktop := newtop;
            startinx := lrnext(lri);
          end;

          <* 5 lookback *>
          begin
            si := stack(stacktop);
            for i:=i while (lr(lri) shift (-3)) <> si do
            begin
              li := lrchain(lri);
              if li = 0 then  goto exlookback;
              lri := li;
            end;
           exlookback:
            startinx := lrnext(lri);
          end
        end case;
      end while;
    end proc parse;
 
    <* m-a-i-n p-r-o-g-r-a-m *>
    <* the most of the following contains code for
       changing the fp-stack.
    *>
    fpinx:=0; random1:=xfortrantest:=crossref:=false; paramno:=1;
    sourcename(1) := real <::>;
    i:=system(4,paramno,fpparam);
    if i=6 shift 12+10 then <*leftside exists *>
    begin i:=system(4,0,fpparam);
      packfp(i); i:=system(4,paramno,fpparam);
    end
   else
    begin <* no leftside *>
      i:=system(4,0,fpparam); paramno:=0;
    end;
    <* the parameter should be xfortran *>
    fpinx:=fpinx+1; fp(fpinx):=i;
    for j:=1 step 1 until 4 do
    fp(fpinx+j) :=long (case j of (<:for:>,<:tra:>,<:n:>,<::>))
                            shift (-24) extract 24;
    fpinx:=fpinx+4; paramno:=paramno+1;
    <* next parameter should be source file if any *>
    fpinx:=fpinx+1; fp(fpinx):=4 shift 12 + 10;
    sourceinx := fpinx;
    fpinx:=fpinx+4;
    i:=system(4,paramno,fpparam);
    j:=system(4,paramno+1,workfile);
    if j shift (-12) <> 4 then packfp(i); <* no source file *>
    paramno:=paramno+1; i:=system(4,paramno,fpparam);
    for i:=i while i<>0 do
    begin packfp(i); paramno:=paramno+1;
      i:=system(4,paramno,fpparam);
    end;

    i:=1; open(outfile, 4, string sourcename(increase(i)), 0);
    if if monitor(52) create area process:(outfile, 0, tail) = 0
     then monitor( 8) reserve process    :(outfile, 0 , tail) <> 0
     else true
    then
      begin <* file did not exist or was not allowed for writing *>
      tail(1) := 42; <* size *> tail(2) := 1; <* disc preferred *>
      for i:=3 step 1 until 10 do tail(i) := 0;
      monitor(40) create entry:(outfile, 0, tail);
      end;

    tail(1):=42; tail(2):=1;
    for i:=3 step 1 until 10 do tail(i):=0;
    open(xref,4,<::>,0);
    monitor(40) create entry:(xref,0,tail);
    getzone6(xref,tail);
    if crossref then
    begin <* make call of crossref program *>
      fpinx:=fpinx+1; fp(fpinx):=2 shift 12 + 10;
      for i:=1 step 1 until 4 do
      fp(fpinx+i):=long (case i of(<:cro:>,<:ssr:>,<:ef:>,<::>))
                              shift (-24) extract 24;
      fpinx:=fpinx+5; fp(fpinx):=4 shift 12 +10;
      for i:=1 step 1 until 4 do
      fp(fpinx+i):=tail(i+1);
      fpinx:=fpinx+4;
    end;
    initialize;
    parse;
    write(outfile,false add 25 ,1);

    getzone6(outfile, tail);
    <* tail 2-5 contains the areaname for input to fortran *>
    for i:= 1 step 1 until 4 do
      fp(sourceinx+i) := tail(i+1);
    close(outfile,true);
    i:=0; write(xref,newline,1,i,i,newline,1);
    close(xref,true);
    if -, crossref then
      monitor(48) remove entry:(xref,0,tail);
    if xfortrantest then
    begin
    unpackfp;
    write(productions,false add 25,1);
    close(productions,true);
    stop(3); <* write out possible errormessages *>
    end;
    fpexecute(fp,fpinx*2);
  exitprg :
  end inner block;
end
▶EOF◀