home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol162 / compile.pas < prev    next >
Pascal/Delphi Source File  |  1984-04-29  |  34KB  |  1,941 lines

  1. {$S+}  {recursion on}
  2.  
  3. {$K1} {$K2} {$K7} {$K12} {$K13} {$K14}  { reduce symbol table space }
  4.  
  5. module compiler;
  6.  
  7. {$I global.inc}
  8.  
  9. var
  10.    sy:    external symbol;        {last symbol read by insymbol}
  11.    id:    external alfa;            {identifier from insymbol}
  12.    inum: external integer;        {integer from insymbol}
  13.    rnum: external real;            {real number from insymbol}
  14.    sleng: external integer;        {string length}
  15.    ch:  external char;            {last character read from source program}
  16.    line: external array
  17.       [1.. llng] of char;
  18.    cc:    external integer;        {character counter}
  19.    lc:  external integer;        {program location counter}
  20.    ll:    external integer;        {length of current line}
  21.    errs: external set of er;
  22.    errpos: external integer;
  23.    progname: external  alfa;
  24.    skipflag: external  boolean;
  25.    constbegsys, typebegsys, blockbegsys, facbegsys, statbegsys: external symset;
  26.    key: external array
  27.       [1.. nkw] of alfa;
  28.    ksy: external array
  29.       [1.. nkw] of symbol;
  30.    sps: external array
  31.       [char]    of symbol;        {special aymbols}
  32.    t, a, b, sx, c1, c2: external integer;    {indices to tables}
  33.    stantyps: external typset;
  34.    display: external array
  35.       [0.. lmax] of integer;        {identifier table}
  36.    tab: external array
  37.       [0.. tmax] of             {identifier table}
  38.    packed record
  39.           name: alfa;
  40.           link: index;
  41.           obj: object;
  42.           typ: types;
  43.           ref: index;
  44.           normal: boolean;
  45.           lev: 0.. lmax;
  46.           adr: integer;
  47.        end;
  48.    atab: external  array
  49.       [1.. amax] of             {array table}
  50.    packed record
  51.           inxtyp, eltyp: types;
  52.           elref, low, high,    elsize,    size: index;
  53.        end;
  54.    btab: external array
  55.       [1..bmax] of             {block-table}
  56.    packed record
  57.           last, lastpar, psize, vsize: index
  58.        end;
  59.    stab: external  packed array
  60.       [0.. smax] of char;        {string table}
  61.    code: external array
  62.       [0.. cmax] of order;
  63.    tabchar  : char;            {holds tab char for scanner }
  64.  
  65. procedure abort;
  66. { return to CP/M }
  67.  
  68. begin 
  69.   inline("JMP/ $00/ $00)
  70. end;
  71.  
  72. procedure errormsg;
  73.  
  74.    var
  75.       k: er;
  76.       msg: array
  77.       [er] of alfa;
  78.  
  79.    begin
  80.       msg[erid] :=  'identifier';
  81.       msg[ertyp] := 'type      ';
  82.       msg[erkey] := 'keyword   ';
  83.       msg[erpun] := 'punctuatio';
  84.       msg[erpar] := 'parameter ';
  85.       msg[ernf] :=  'not found ';
  86.       msg[erdup] := 'duplicate ';
  87.       msg[erch] :=  'character ';
  88.       msg[ersh] :=  'too short ';
  89.       msg[erln] :=  'too long  ';
  90.       writeln('compilation errors');
  91.       writeln;
  92.       writeln('key words');
  93.       for k :=    erid to    erln do
  94.       if k in errs then
  95.          writeln(ord(k), ' ', msg[k])
  96.    end    {errormsg};
  97.  
  98.  
  99. procedure endskip;
  100.  
  101.    begin {underline skips part of input}
  102.       while errpos < cc do
  103.       begin
  104.          write('-');
  105.          errpos := errpos +    1
  106.       end;
  107.       skipflag    := false
  108.    end    {endskip};
  109.  
  110.  
  111. procedure nextch;
  112.  
  113. {read    next character;    process    line end}
  114.  
  115.    begin
  116.       if cc = ll
  117.       then
  118.       begin
  119.          if    eof(input) then
  120.         begin
  121.            writeln;
  122.            writeln('program incomplete');
  123.            errormsg;
  124.            {goto    99}
  125.            abort;
  126.         end;
  127.          if    errpos <> 0 then
  128.         begin
  129.            if skipflag then
  130.               endskip;
  131.            writeln;
  132.            errpos := 0
  133.         end;
  134.          write(lc: 5, ' ');
  135.          ll    := 0;
  136.           cc    := 0;
  137.          while not eoln(input) do
  138.         begin
  139.            ll := ll + 1;
  140.            read(ch);
  141.            write(ch);
  142.            line[ll] := ch
  143.         end;
  144.          writeln;
  145.          ll    := ll +    1;
  146.          read(line[ll]);
  147.       end;
  148.       cc := cc    + 1;
  149.       ch := line[cc];
  150.    end    {nextch};
  151.  
  152.  
  153. procedure error(n: er);
  154.  
  155.    begin
  156.       if errpos = 0 then
  157.       write('****');
  158.       if cc > errpos then
  159.       begin
  160.          write(' ':    cc - errpos, '^', ord(n): 2);
  161.          errpos := cc + 3;
  162.          errs := errs + [n]
  163.       end
  164.    end    {error};
  165.  
  166.  
  167. procedure fatal(n: integer);
  168.  
  169.    var
  170.       msg: array
  171.       [1..6] of alfa;
  172.  
  173.    begin
  174.       writeln;
  175.       errormsg;
  176.       msg[1]    := 'identifier';
  177.       msg[2]    := 'procedures';
  178.       msg[3]    := 'string    ';
  179.       msg[4]    := 'arrays    ';
  180.       msg[5]    := 'level     ';
  181.       msg[6]    := 'code      ';
  182.       writeln('compiler table for ', msg[n],    ' is too small');
  183.       { goto 99;  terminate compilation}
  184.       abort;
  185.    end    {fatal};
  186.  
  187.  
  188. procedure insymbol;
  189.  
  190. {reads next symbol}
  191.  
  192.    label
  193.       1, 2, 3;
  194.  
  195.    var
  196.       i, j, k,    e: integer;
  197.  
  198.    begin {insymbol}
  199.    1: while ch    in [' ',tabchar] do
  200.       nextch;
  201.       case ch of
  202.        'a', 'b', 'c', 'd', 'e', 'f',    'g', 'h', 'i', 'j', 'k', 'l', 'm'
  203.          , 'n', 'o', 'p', 'q', 'r',    's', 't', 'u', 'v', 'w', 'x', 'y'
  204.          , 'z':
  205.          begin {identifier    or wordsymbol}
  206.         k := 0;
  207.         id := '         ';
  208.         repeat
  209.            if k    < alng then
  210.               begin
  211.              k := k    + 1;
  212.              id[k] := ch
  213.               end;
  214.            nextch
  215.         until not (ch in [
  216.         'a' .. 'z', '0'    .. '9']);
  217.         i := 1;
  218.         j := nkw;        {binary search}
  219.         repeat
  220.            k :=    (i + j)    div 2;
  221.            if id <= key[k] then
  222.               j    := k - 1;
  223.            if id >= key[k] then
  224.               i    := k + 1
  225.         until i    > j;
  226.         if i - 1 > j
  227.         then
  228.            sy := ksy[k]
  229.         else
  230.            sy := ident
  231.          end;
  232.       '0', '1', '2', '3', '4', '5',    '6', '7', '8', '9':
  233.          begin {number}
  234.         k := 0;
  235.         inum :=    0;
  236.         sy := intcon;
  237.         repeat
  238.            inum    := inum    * 10 + ord(ch) - ord('0');
  239.            k :=    k + 1;
  240.            nextch
  241.         until not (ch in [
  242.         '0' .. '9']);
  243.         if (k >    kmax) or (inum > nmax) then
  244.            begin
  245.               error(erln);
  246.               inum := 0;
  247.               k    := 0
  248.            end;
  249.          end;
  250.       ':' {, col}:
  251.          begin
  252.         nextch;        {mod mh}
  253.         if ch =    '='
  254.         then
  255.            begin
  256.               sy := becomes;
  257.               nextch
  258.            end
  259.         else
  260.            sy := colon
  261.          end;
  262.       '<':
  263.          begin
  264.         nextch;
  265.         if ch =    '='
  266.         then
  267.            begin
  268.               sy := leq;
  269.               nextch
  270.            end
  271.         else
  272.            if ch = '>'
  273.            then
  274.               begin
  275.              sy := neq;
  276.              nextch
  277.               end
  278.            else
  279.               sy := lss
  280.          end;
  281.       '>':
  282.          begin
  283.         nextch;
  284.         if ch =    '='
  285.         then
  286.            begin
  287.               sy := geq;
  288.               nextch
  289.            end
  290.         else
  291.            sy := gtr
  292.          end;
  293.       '.':
  294.          begin
  295.         nextch;
  296.         if ch =    '.'
  297.         then
  298.            begin
  299.               sy := colon;
  300.               nextch
  301.            end
  302.         else
  303.            if ch = ')'
  304.            then
  305.               begin
  306.              sy := rbrack;
  307.              nextch
  308.               end
  309.            else
  310.               sy := period
  311.          end;
  312.        '''':
  313.          begin
  314.         k := 0;
  315.          2:    nextch;
  316.         if ch =    '''' then
  317.            begin
  318.               nextch;
  319.               if ch <> '''' then
  320.              goto 3
  321.            end;
  322.         if sx +    k = smax then
  323.            fatal(3);
  324.         stab[sx + k] := ch;
  325.         k := k + 1;
  326.         if cc =    1
  327.         then
  328.            begin {end of line}
  329.               k    := 0;
  330.            end
  331.         else
  332.            goto    2;
  333.          3:    if k = 1
  334.         then
  335.            begin
  336.               sy := charcon;
  337.               inum := ord(stab[sx])
  338.            end
  339.         else
  340.            if k    = 0
  341.            then
  342.               begin
  343.              error(ersh);
  344.              sy := charcon;
  345.              inum := 0
  346.               end
  347.            else
  348.               begin
  349.              sy := string;
  350.              inum := sx;
  351.              sleng := k;
  352.              sx := sx + k
  353.               end
  354.          end;
  355.       '(':
  356.          begin
  357.         nextch;
  358.         if ch =    '.'
  359.         then
  360.            begin
  361.               sy := lbrack;
  362.               nextch
  363.            end
  364.         else
  365.            if ch <> '*'
  366.            then
  367.               sy := lparent
  368.            else
  369.               begin {comment}
  370.              nextch;
  371.              repeat
  372.                 while ch <>    '*' do
  373.                    nextch;
  374.                 nextch
  375.              until ch = ')';
  376.              nextch;
  377.              goto 1
  378.               end
  379.          end;
  380.       '+', '-', '*', ')', '=', ',',    ';','[',']' :
  381.          begin
  382.         sy := sps[ch];
  383.         nextch
  384.          end;
  385.       '$', '!', '@', '^', '?',
  386.      {'""',}
  387.            '&', '/','\' :
  388.          begin
  389.         error(erch);
  390.         nextch;
  391.         goto 1
  392.          end
  393.       end
  394.    end    {insymbol};
  395.  
  396.  
  397. procedure enterstandardids(x0: alfa; x1: object; x2: types; x3: integer);
  398.  
  399.    begin
  400.       t := t +    1;
  401. {enter standard identifier}
  402.       with tab[t] do
  403.       begin
  404.          name := x0;
  405.          link := t - 1;
  406.          obj := x1;
  407.          typ := x2;
  408.          ref := 0;
  409.          normal := true;
  410.          lev := 0;
  411.          adr := x3
  412.       end
  413.    end    {enter};
  414.  
  415.  
  416. procedure enterarray(tp: types; l, h: integer);
  417.  
  418.    begin
  419.       if l > h    then
  420.       error(ertyp);
  421.       if (abs(l) > xmax) or (abs(h) > xmax) then
  422.       begin
  423.          error(ertyp);
  424.          l := 0;
  425.          h := 0;
  426.       end;
  427.       if a = amax
  428.       then
  429.       fatal(4)
  430.       else
  431.       begin
  432.          a := a + 1;
  433.          with atab[a] do
  434.         begin
  435.            inxtyp := tp;
  436.            low := l;
  437.            high    := h
  438.         end
  439.       end {enterarray};
  440.    end    {enterarray};
  441.  
  442. {fix mh}
  443.  
  444.  
  445. procedure enterblock;
  446.  
  447.    begin
  448.       if b = bmax
  449.       then
  450.       fatal(2)
  451.       else
  452.       begin
  453.          b := b + 1;
  454.          btab[b].last := 0;
  455.          btab[b].lastpar := 0
  456.       end
  457.    end    {enterblock};
  458.  
  459.  
  460. procedure emit(fct: integer);
  461.  
  462.    begin
  463.       if lc = cmax then
  464.       fatal(6);
  465.       code[lc].f := fct;
  466.       lc := lc    + 1;
  467.    end    {emit};
  468.  
  469.  
  470. procedure emit1(fct, b: integer);
  471.  
  472.    begin
  473.       if lc = cmax then
  474.       fatal(6);
  475.       with code[lc] do
  476.       begin
  477.          f := fct;
  478.          y := b
  479.       end;
  480.       lc := lc    + 1;
  481.    end    {emit1};
  482.  
  483.  
  484. procedure emit2(fct, a, b: integer);
  485.  
  486.    begin
  487.       if lc = cmax then
  488.       fatal(6);
  489.       with code[lc] do
  490.       begin
  491.          f := fct;
  492.          x := a;
  493.          y := b
  494.       end;
  495.       lc := lc    + 1;
  496.    end    {emit2};
  497.  
  498.  
  499. procedure block(fsys: symset; isfun: boolean; level: integer);
  500.  
  501.    type
  502.       conrec =    record
  503.            tp: types;
  504.            i: integer
  505.         end;
  506.  
  507.    var
  508.       dx: integer;    {data    allocation index}
  509.       prt: integer;    {t-index of this procedure}
  510.       prb: integer;    {b-index of this procedure}
  511.       x: integer;
  512.  
  513.  
  514.    procedure skip(fsys: symset; n: er);
  515.  
  516.       begin
  517.       error(n);
  518.       skipflag := true;
  519.       while    not (sy    in fsys) do
  520.          insymbol;
  521.       if skipflag then
  522.          endskip;
  523.       end {skip};
  524.  
  525.  
  526.    procedure test(s1, s2: symset; n: er);
  527.  
  528.       begin
  529.       if not (sy in    s1) then
  530.          skip(s1 + s2, n)
  531.       end {test};
  532.  
  533.  
  534.    procedure testsemicolon;
  535.  
  536.       begin
  537.       if sy    = semicolon
  538.       then
  539.          insymbol
  540.       else
  541.          error(erpun);
  542.       test([ident] + blockbegsys,    fsys, erkey);
  543.       end {testsemicolon};
  544.  
  545.  
  546.     procedure  enter(id:    alfa; k: object);
  547.  
  548.       var
  549.       j, l:    integer;
  550.  
  551.       begin
  552.       if t = tmax
  553.       then
  554.          fatal(1)
  555.       else
  556.          begin
  557.         tab[0].name := id;
  558.         j := btab[display[level]].last;
  559.         l := j;
  560.         while tab[j].name <> id do
  561.            j :=    tab[j].link;
  562.         if j <>    0
  563.         then
  564.            error(erdup)
  565.         else
  566.            begin
  567.               t    := t + 1;
  568.               with tab[t] do
  569.              begin
  570.                 name := id;
  571.                 link := l;
  572.                 obj    := k;
  573.                 typ    := notyp;
  574.                 ref    := 0;
  575.                 lev    := level;
  576.                 adr    := 0
  577.              end;
  578.               btab[display[level]].last := t
  579.            end
  580.          end
  581.       end {enter};
  582.  
  583.  
  584.    function loc(id: alfa): integer;
  585.  
  586.       var
  587.       i, j:    integer;    {locate id in    table}
  588.  
  589.       begin
  590.       i := level;
  591.       tab[0].name    := id;    {sentinel}
  592.       repeat
  593.          j := btab[display[i]].last;
  594.          while tab[j].name <> id do
  595.         j := tab[j].link;
  596.          i := i - 1;
  597.       until    (i < 0)    or (j <> 0);
  598.       if j = 0 then
  599.          error(ernf);
  600.       loc := j
  601.       end {loc};
  602.  
  603.  
  604.    procedure entervariable;
  605.  
  606.       begin
  607.       if sy    = ident
  608.       then
  609.          begin
  610.         enter(id, variable);
  611.         insymbol
  612.          end
  613.       else
  614.          error(erid)
  615.       end {entervariable};
  616.  
  617.  
  618.    procedure constant(fsys: symset; var c: conrec);
  619.  
  620.       var
  621.       x, sign: integer;
  622.  
  623.       begin
  624.       c.tp := notyp;
  625.       c.i := 0;
  626.       test(constbegsys, fsys, erkey);
  627.       if sy    in constbegsys
  628.       then
  629.          begin
  630.         if sy =    charcon
  631.         then
  632.            begin
  633.               c.tp := chars;
  634.               c.i := inum;
  635.               insymbol
  636.            end
  637.         else
  638.            begin
  639.               sign := 1;
  640.               if sy in [plus, minus] then
  641.              begin
  642.                 if sy = minus then
  643.                    sign := - 1;
  644.                 insymbol
  645.              end;
  646.               if sy = ident
  647.               then
  648.              begin
  649.                 x := loc(id);
  650.                 if x <> 0 then
  651.                    if tab[x].obj <> konstant
  652.                    then
  653.                   error(ertyp)
  654.                    else
  655.                   begin
  656.                      c.tp := tab[x].typ;
  657.                      c.i := sign * tab[x].adr
  658.                   end;
  659.                 insymbol
  660.              end
  661.               else
  662.              if sy = intcon
  663.              then
  664.                 begin
  665.                    c.tp := ints;
  666.                    c.i := sign * inum;
  667.                    insymbol
  668.                 end
  669.              else
  670.                 skip(fsys, erkey)
  671.            end;
  672.         test(fsys, [], erkey);
  673.          end
  674.       end {constant};
  675.  
  676.  
  677.    procedure typ(fsys:    symset;    var tp:    types; var rf, sz: integer);
  678.  
  679.       var
  680.       x: integer;
  681.       eltp:    types;
  682.       elrf:    integer;
  683.       elsz,    offset,    t0, t1:    integer;
  684.  
  685.  
  686.       procedure arraytyp(var aref, arsz: integer);
  687.  
  688.       var
  689.          eltp: types;
  690.          low, high:    conrec;
  691.          elrf, elsz: integer;
  692.  
  693.       begin
  694.          constant([colon, rbrack, ofsy] +    fsys, low);
  695.          if    sy = colon
  696.          then
  697.         insymbol
  698.          else
  699.         error(erpun);
  700.          constant([rbrack,    comma, ofsy] +    fsys, high);
  701.          if    high.tp    <> low.tp then
  702.         begin
  703.            error(ertyp);
  704.            high.i := low.i
  705.         end;
  706.          enterarray(low.tp,    low.i, high.i);
  707.          aref := a;
  708.          if    sy = comma
  709.          then
  710.         begin
  711.            insymbol;
  712.            eltp    := arrays;
  713.            arraytyp(elrf, elsz)
  714.         end
  715.          else
  716.         begin
  717.            if sy = rbrack
  718.            then
  719.               insymbol
  720.            else
  721.               error(erpun);
  722.            if sy = ofsy
  723.            then
  724.               insymbol
  725.            else
  726.               error(erkey);
  727.            typ(fsys, eltp, elrf, elsz)
  728.         end;
  729.          with atab[aref] do
  730.         begin
  731.            arsz    := (high - low + 1) * elsz;
  732.            size    := arsz;
  733.            eltyp := eltp;
  734.            elref := elrf;
  735.            elsize := elsz
  736.         end;
  737.       end {arraytyp};
  738.  
  739.  
  740.       begin {typ}
  741.       tp :=    notyp;
  742.       rf :=    0;
  743.       sz :=    0;
  744.       test(typebegsys, fsys, erid);
  745.       if sy    in typebegsys
  746.       then
  747.          begin
  748.         if sy =    ident
  749.         then
  750.            begin
  751.               x    := loc(id);
  752.               if x <> 0    then
  753.              with tab[x] do
  754.                 if obj <> type1
  755.                 then
  756.                    error(ertyp)
  757.                 else
  758.                    begin
  759.                   tp :=    typ;
  760.                   rf :=    ref;
  761.                   sz :=    adr;
  762.                   if tp    = notyp    then
  763.                      error(ertyp)
  764.                    end;
  765.               insymbol
  766.            end
  767.         else
  768.            if sy = arraysy
  769.            then
  770.               begin
  771.              insymbol;
  772.              if sy = lbrack
  773.              then
  774.                 insymbol
  775.              else
  776.                 error(erpun);
  777.              tp := arrays;
  778.              arraytyp(rf, sz)
  779.               end
  780.            else
  781.               test(fsys, [], erkey);
  782.          end
  783.       end {typ};
  784.  
  785.  
  786.    procedure parameterlist;    {formal parameter list}
  787.  
  788.       var
  789.       tp: types;
  790.       rf, sz, x, t0: integer;
  791.       valpar: boolean;
  792.  
  793.       begin
  794.       insymbol;
  795.       tp :=    notyp;
  796.       rf :=    0;
  797.       sz :=    0;
  798.       test([ident,    varsy], fsys +    [rparent], erpar);
  799.       while    sy in [ident, varsy] do
  800.          begin
  801.         if sy <> varsy
  802.         then
  803.            valpar := true
  804.         else
  805.            begin
  806.               insymbol;
  807.               valpar :=    false
  808.            end;
  809.         t0 := t;
  810.         entervariable;
  811.         while sy = comma do
  812.            begin
  813.               insymbol;
  814.               entervariable;
  815.            end;
  816.         if sy =    colon
  817.         then
  818.            begin
  819.               insymbol;
  820.               if sy <> ident
  821.               then
  822.              error(erid)
  823.               else
  824.              begin
  825.                 x := loc(id);
  826.                 insymbol;
  827.                 if x <> 0 then
  828.                    with tab[x] do
  829.                   if obj <> type1
  830.                   then
  831.                      error(ertyp)
  832.                   else
  833.                      begin
  834.                     tp := typ;
  835.                     rf := ref;
  836.                     if valpar
  837.                     then
  838.                        sz := adr
  839.                     else
  840.                        sz := 1
  841.                      end;
  842.              end;
  843.               test([semicolon,    rparent], [comma, ident] +
  844.              fsys, erpun)
  845.            end
  846.         else
  847.            error(erpun);
  848.         while t0 < t do
  849.            begin
  850.               t0 := t0 + 1;
  851.               with tab[t0] do
  852.              begin
  853.                 typ    := tp;
  854.                 ref    := rf;
  855.                 normal := valpar;
  856.                 adr    := dx;
  857.                 lev    := level;
  858.                 dx := dx + sz
  859.              end
  860.            end;
  861.         if sy <> rparent then
  862.            begin
  863.               if sy = semicolon
  864.               then
  865.              insymbol
  866.               else
  867.              error(erpun);
  868.               test([ident, varsy], [rparent] + fsys, erkey);
  869.            end
  870.          end;
  871.       if sy    = rparent
  872.       then
  873.          begin
  874.         insymbol;
  875.         test([semicolon, colon], fsys, erkey);
  876.          end
  877.       else
  878.          error(erpun)
  879.       end {parameterlist};
  880.  
  881.  
  882.    procedure constdeclaration;
  883.  
  884.       var
  885.       c: conrec;
  886.  
  887.       begin
  888.       insymbol;
  889.       test([ident], blockbegsys, erid);
  890.       while    sy = ident do
  891.          begin
  892.         enter(id, konstant);
  893.         insymbol;
  894.         if sy =    eql
  895.         then
  896.            insymbol
  897.         else
  898.            error(erpun);
  899.         constant([semicolon, comma, ident] + fsys, c);
  900.         tab[t].typ :=    c.tp;
  901.         tab[t].ref :=    0;
  902.         tab[t].adr :=    c.i;
  903.         testsemicolon
  904.          end
  905.       end {constdeclaration};
  906.  
  907.  
  908.    procedure typedeclaration;
  909.  
  910.       var
  911.       tp: types;
  912.       rf, sz, t1: integer;
  913.  
  914.       begin
  915.       insymbol;
  916.       test([ident], blockbegsys, erid);
  917.       while    sy = ident do
  918.          begin
  919.         enter(id, type1);
  920.         t1 := t;
  921.         insymbol;
  922.         if sy =    eql
  923.         then
  924.            insymbol
  925.         else
  926.            error(erpun);
  927.         typ([semicolon, comma,    ident]    + fsys,    tp, rf,    sz);
  928.         with tab[t1] do
  929.            begin
  930.               typ := tp;
  931.               ref := rf;
  932.               adr := sz
  933.            end;
  934.         testsemicolon
  935.          end
  936.       end {typedeclaration};
  937.  
  938.  
  939.    procedure vardeclaration;
  940.  
  941.       var
  942.       t0, t1, rf, sz: integer;
  943.       tp: types;
  944.  
  945.       begin
  946.       insymbol;
  947.       while    sy = ident do
  948.          begin
  949.         t0 := t;
  950.         entervariable;
  951.         while sy = comma do
  952.            begin
  953.               insymbol;
  954.               entervariable;
  955.            end;
  956.         if sy =    colon
  957.         then
  958.            insymbol
  959.         else
  960.            error(erpun);
  961.         t1 := t;
  962.         typ([semicolon, comma,    ident]    + fsys,    tp, rf,    sz);
  963.         while t0 < t1 do
  964.            begin
  965.               t0 := t0 + 1;
  966.               with tab[t0] do
  967.              begin
  968.                 typ    := tp;
  969.                 ref    := rf;
  970.                 lev    := level;
  971.                 adr    := dx;
  972.                 normal := true;
  973.                 dx := dx + sz
  974.              end
  975.            end;
  976.         testsemicolon
  977.          end
  978.       end {variab|edeclaration};
  979.  
  980.  
  981.    procedure procdeclaration;
  982.  
  983.       var
  984.       isfun: boolean;
  985.  
  986.       begin
  987.       isfun    := sy =    functionsy;
  988.       insymbol;
  989.       if sy    <> ident then
  990.          begin
  991.         error(erid);
  992.         id := '         ';
  993.          end;
  994.       if isfun
  995.       then
  996.          enter(id, funktion)
  997.       else
  998.          enter(id, prozedure);
  999.       tab[t].normal := true;
  1000.       insymbol;
  1001.       block([semicolon] +    fsys, isfun, level + 1);
  1002.       if sy    = semicolon
  1003.       then
  1004.          insymbol
  1005.       else
  1006.          error(erpun);
  1007.       emit(32 + ord(isfun))    {exit}
  1008.       end {proceduredeclaration};
  1009.  
  1010.  
  1011.  
  1012.    procedure statement(fsys: symset);
  1013.  
  1014.       var
  1015.       i: integer;
  1016.       x: item;
  1017.  
  1018.  
  1019.       procedure expression(fsys: symset; var x: item);
  1020.       forward;
  1021.  
  1022.  
  1023.       procedure selector(fsys:    symset;    var v: item);
  1024.  
  1025.       var
  1026.          x:    item;
  1027.          a,    j: integer;
  1028.  
  1029.       begin
  1030.          if    sy <> lbrack then
  1031.         error(ertyp);
  1032.          repeat
  1033.         insymbol;
  1034.         expression(fsys    + [comma, rbrack], x);
  1035.         if v.typ <> arrays
  1036.         then
  1037.            error(ertyp)
  1038.         else
  1039.            begin
  1040.               a    := v.ref;
  1041.               if atab[a].inxtyp <> x.typ
  1042.               then
  1043.              error(ertyp)
  1044.               else
  1045.              emit1(21, a);
  1046.               v.typ := atab[a].eltyp;
  1047.               v.ref := atab[a].elref
  1048.            end
  1049.          until sy <> comma;
  1050.          if    sy = rbrack
  1051.          then
  1052.         insymbol
  1053.          else
  1054.         error(erpun);
  1055.          test(fsys,    [], erkey);
  1056.       end {selector};
  1057.  
  1058.  
  1059.       procedure call(fsys: symset; i: integer);
  1060.  
  1061.       var
  1062.          x:    item;
  1063.          lastp, cp,    k: integer;
  1064.  
  1065.       begin
  1066.          emit1(18, i);        {markstack}
  1067.          lastp := btab[tab[i].ref].lastpar;
  1068.          cp    := i;
  1069.          if    sy = lparent
  1070.          then
  1071.         begin             {actual parameter list}
  1072.            repeat
  1073.               insymbol;
  1074.               if cp >= lastp
  1075.               then
  1076.              error(erpar)
  1077.               else
  1078.              begin
  1079.                 cp := cp + 1;
  1080.                 if tab[cp].normal
  1081.                 then
  1082.                    begin     {value parameter}
  1083.                   expression(fsys + [comma, colon,
  1084.                      rparent],    x);
  1085.                   if x.typ = tab[cp].typ
  1086.                   then
  1087.                      begin
  1088.                     if x.ref <> tab[cp].ref
  1089.                     then
  1090.                        error(ertyp)
  1091.                     else
  1092.                        if x.typ = arrays then
  1093.                           emit1(22,    atab[x.ref].
  1094.                          size)
  1095.                      end
  1096.                   else
  1097.                      if    x.typ <> notyp then
  1098.                     error(ertyp);
  1099.                    end
  1100.                 else
  1101.                    begin     {variable    parameter}
  1102.                   if sy    <> ident
  1103.                   then
  1104.                      error(erid)
  1105.                   else
  1106.                      begin
  1107.                     k := loc(id);
  1108.                     insymbol;
  1109.                     if k <>    0
  1110.                     then
  1111.                        begin
  1112.                           if tab[k].obj <> variable
  1113.                           then
  1114.                          error(erpar);
  1115.                           x.typ := tab[k].typ;
  1116.                           x.ref := tab[k].ref;
  1117.                           if tab[k].normal
  1118.                           then
  1119.                          emit2(0, tab[k].lev,
  1120.                             tab[k].adr)
  1121.                           else
  1122.                          emit2(1, tab[k].lev,
  1123.                             tab[k].adr);
  1124.                           if sy = lbrack then
  1125.                          selector(fsys + [comma,
  1126.                             colon, rparent], x);
  1127.                           if (x.typ    <> tab[cp].typ)
  1128.                          or (x.ref <> tab[cp].
  1129.                          ref)
  1130.                           then
  1131.                          error(ertyp)
  1132.                        end
  1133.                      end
  1134.                    end
  1135.              end;
  1136.               test([comma, rparent], fsys, erkey);
  1137.            until sy <> comma;
  1138.            if sy = rparent
  1139.            then
  1140.               insymbol
  1141.            else
  1142.               error(erpun)
  1143.         end;
  1144.          if    cp < lastp then
  1145.         error(erpar);        {too few actual parameters}
  1146.          emit1(19, btab[tab[i].ref].psize - 1);
  1147.          if    tab[i].lev < level then
  1148.         emit2(3, tab[i].lev, level)
  1149.       end {call};
  1150.  
  1151.  
  1152.       function    resulttype(a, b: types): types;
  1153.  
  1154.       begin
  1155.          if    (a > ints) or (b > ints)
  1156.          then
  1157.         begin
  1158.            error(ertyp);
  1159.            resulttype := notyp
  1160.         end
  1161.          else
  1162.         if (a =    notyp) or (b = notyp)
  1163.         then
  1164.            resulttype := notyp
  1165.         else
  1166.            resulttype := ints
  1167.       end {resulttyp};
  1168.  
  1169.  
  1170.       procedure expression;
  1171.  
  1172.       var
  1173.          y:    item;
  1174.          op: symbol;
  1175.  
  1176.  
  1177.       procedure simpleexpression(fsys: symset; var x: item);
  1178.  
  1179.          var
  1180.         y: item;
  1181.         op: symbol;
  1182.  
  1183.  
  1184.          procedure term(fsys: symset; var x: item);
  1185.  
  1186.         var
  1187.            y: item;
  1188.            op: symbol;
  1189.            ts: typset;
  1190.  
  1191.  
  1192.         procedure factor(fsys: symset; var x: item);
  1193.  
  1194.            var
  1195.               i, f: integer;
  1196.  
  1197.            begin {factor}
  1198.               x.typ := notyp;
  1199.               x.ref := 0;
  1200.               test(facbegsys, fsys, erpun);
  1201.               while sy in facbegsys do
  1202.              begin
  1203.                 if sy = ident
  1204.                 then
  1205.                    begin
  1206.                   i := loc(id);
  1207.                   insymbol;
  1208.                   with tab[i]    do
  1209.                      case obj of
  1210.                     konstant:
  1211.                        begin
  1212.                           x.typ := typ;
  1213.                           x.ref := 0;
  1214.                           emit1(24,    adr)
  1215.                        end;
  1216.                     variable:
  1217.                        begin
  1218.                           x.typ := typ;
  1219.                           x.ref := ref;
  1220.                           if sy = lbrack
  1221.                           then
  1222.                          begin
  1223.                             if normal
  1224.                             then
  1225.                                f := 0
  1226.                             else
  1227.                                f := 1;
  1228.                             emit2(f, lev, adr);
  1229.                             selector(fsys, x);
  1230.                             if x.typ in    stantyps
  1231.                             then
  1232.                                emit(34)
  1233.                          end
  1234.                           else
  1235.                          begin
  1236.                             if x.typ in    stantyps
  1237.                             then
  1238.                                if normal
  1239.                                then
  1240.                               f := 1
  1241.                                else
  1242.                               f := 2
  1243.                             else
  1244.                                if normal
  1245.                                then
  1246.                               f := 0
  1247.                                else
  1248.                               f := 1;
  1249.                             emit2(f, lev, adr)
  1250.                          end
  1251.                        end;
  1252.                     type1, prozedure:
  1253.                        error(ertyp);
  1254.                     funktion:
  1255.                        begin
  1256.                           x.typ := typ;
  1257.                           if lev <>    0
  1258.                           then
  1259.                          call(fsys, i)
  1260.                           else
  1261.                          emit1(8, adr)
  1262.                        end
  1263.                      end {case, with}
  1264.                    end
  1265.                 else
  1266.                    if sy in    [charcon, intcon]
  1267.                    then
  1268.                   begin
  1269.                      if    sy = charcon
  1270.                      then
  1271.                     x.typ := chars
  1272.                      else
  1273.                     x.typ := ints;
  1274.                      emit1(24, inum);
  1275.                      x.ref := 0;
  1276.                      insymbol
  1277.                   end
  1278.                    else
  1279.                   if sy    = lparent
  1280.                   then
  1281.                      begin
  1282.                     insymbol;
  1283.                     expression(fsys    + [rparent], x);
  1284.                     if sy =    rparent
  1285.                     then
  1286.                        insymbol
  1287.                     else
  1288.                        error(erpun)
  1289.                      end
  1290.                   else
  1291.                      if    sy = notsy then
  1292.                     begin
  1293.                        insymbol;
  1294.                        factor(fsys,    x);
  1295.                        if x.typ = bools
  1296.                        then
  1297.                           emit(35)
  1298.                        else
  1299.                           if x.typ <> notyp    then
  1300.                          error(ertyp)
  1301.                     end;
  1302.                 test(fsys, facbegsys, erkey);
  1303.              end {while}
  1304.            end {factor};
  1305.  
  1306.  
  1307.         begin {term}
  1308.            factor(fsys + [times, idiv,    imod, andsy], x);
  1309.            while sy in [times,    idiv, imod, andsy] do
  1310.               begin
  1311.              op := sy;
  1312.              insymbol;
  1313.              factor(fsys + [times,    idiv, imod, andsy], y);
  1314.              if op = times
  1315.              then
  1316.                 begin
  1317.                    x.typ :=    resulttype(x.typ, y.typ);
  1318.                    if x.typ    = ints then
  1319.                   emit(57)
  1320.                 end
  1321.              else
  1322.                 if op = andsy
  1323.                 then
  1324.                    begin
  1325.                   if (x.typ = bools) and (y.typ    = bools)
  1326.                   then
  1327.                      emit(56)
  1328.                   else
  1329.                      begin
  1330.                     if (x.typ <> notyp) and    (y.typ <>
  1331.                        notyp)
  1332.                     then
  1333.                        error(ertyp);
  1334.                     x.typ := notyp
  1335.                      end
  1336.                    end
  1337.                 else
  1338.                    begin {op in[idiv, imod]}
  1339.                   if (x.typ = ints) and    (y.typ = ints)
  1340.                   then
  1341.                      if    op = idiv
  1342.                      then
  1343.                     emit(58)
  1344.                      else
  1345.                     emit(59)
  1346.                   else
  1347.                      begin
  1348.                     if (x.typ <> notyp) and    (y.typ <>
  1349.                        notyp)
  1350.                     then
  1351.                        error(ertyp);
  1352.                     x.typ := notyp
  1353.                      end
  1354.                    end
  1355.               end
  1356.         end {term};
  1357.  
  1358.  
  1359.          begin {simpleexpression}
  1360.         if sy in [plus, minus]
  1361.         then
  1362.            begin
  1363.               op := sy;
  1364.               insymbol;
  1365.               term(fsys    + [plus, minus], x);
  1366.               if x.typ > ints
  1367.               then
  1368.              error(ertyp)
  1369.               else
  1370.              if op = minus then
  1371.                 emit(36)
  1372.            end
  1373.         else
  1374.            term(fsys + [plus, minus, orsy], x);
  1375.         while sy in [plus, minus, orsy] do
  1376.            begin
  1377.               op := sy;
  1378.               insymbol;
  1379.               term(fsys    + [plus, minus, orsy], y);
  1380.               if op = orsy
  1381.               then
  1382.              begin
  1383.                 if (x.typ =    bools) and (y.typ = bools)
  1384.                 then
  1385.                    emit(51)
  1386.                 else
  1387.                    begin
  1388.                   if (x.typ <> notyp) and (y.typ <> notyp)
  1389.                   then
  1390.                      error(ertyp);
  1391.                   x.typ    := notyp
  1392.                    end
  1393.              end
  1394.               else
  1395.              begin
  1396.                 x.typ := resulttype(x.typ, y.typ);
  1397.                 if x.typ = ints then
  1398.                    if op = plus
  1399.                    then
  1400.                   emit(52)
  1401.                    else
  1402.                   emit(53)
  1403.              end
  1404.            end
  1405.          end {simpleexpression};
  1406.  
  1407.  
  1408.       begin    {expression};
  1409.          simpleexpression(fsys + [eql, neq, lss, leq, gtr,    geq], x);
  1410.          if    sy in [eql, neq, lss, leq, gtr, geq]
  1411.          then
  1412.         begin
  1413.            op := sy;
  1414.            insymbol;
  1415.            simpleexpression(fsys, y);
  1416.            if (x.typ in    [notyp, ints, bools, chars]) and (x.typ
  1417.               =    y.typ)
  1418.            then
  1419.               case op of
  1420.              eql:
  1421.                 emit(45);
  1422.              neq:
  1423.                 emit(46);
  1424.              lss:
  1425.                 emit(47);
  1426.              leq:
  1427.                 emit(48);
  1428.              gtr:
  1429.                 emit(49);
  1430.              geq:
  1431.                 emit(50);
  1432.               end
  1433.            else
  1434.               error(ertyp);
  1435.            x.typ := bools
  1436.         end
  1437.       end {expression};
  1438.  
  1439.  
  1440.       procedure assignment(lv,    ad: integer);
  1441.  
  1442.       var
  1443.          x,    y: item;
  1444.          f:    integer;        {tab[i]. obj in [variable,prozedure]}
  1445.  
  1446.       begin
  1447.          x.typ := tab[i].typ;
  1448.          x.ref := tab[i].ref;
  1449.          if    tab[i].normal
  1450.          then
  1451.         f := 0
  1452.          else
  1453.         f := 1;
  1454.          emit2(f, lv, ad);
  1455.          if    sy = lbrack then
  1456.         selector([becomes, eql] + fsys, x);
  1457.          if    sy = becomes
  1458.          then
  1459.         insymbol
  1460.          else
  1461.         error(erpun);
  1462.          expression(fsys, y);
  1463.          if    x.typ =    y.typ
  1464.          then
  1465.         if x.typ in stantyps
  1466.         then
  1467.            emit(38)
  1468.         else
  1469.            if x.ref <> y.ref
  1470.            then
  1471.               error(ertyp)
  1472.            else
  1473.               if x.typ = arrays
  1474.               then
  1475.              emit1(23, atab[x.ref].size)
  1476.               else
  1477.              error(ertyp)
  1478.       end {assignment};
  1479.  
  1480.  
  1481.       procedure compoundstatement;
  1482.  
  1483.       begin
  1484.          insymbol;
  1485.          statement([semicolon, endsy] + fsys);
  1486.          while sy in [semicolon] + statbegsys do
  1487.         begin
  1488.            if sy = semicolon
  1489.            then
  1490.               insymbol
  1491.            else
  1492.               error(erpun);
  1493.            statement([semicolon, endsy] + fsys)
  1494.         end;
  1495.          if    sy = endsy
  1496.          then
  1497.         insymbol
  1498.          else
  1499.         error(erkey)
  1500.       end {compoundstatement};
  1501.  
  1502.  
  1503.       procedure ifstatement;
  1504.  
  1505.       var
  1506.          x:    item;
  1507.          lc1, lc2: integer;
  1508.  
  1509.       begin
  1510.          insymbol;
  1511.          expression(fsys + [thensy, dosy], x);
  1512.          if    not (x.typ in [bools, notyp])    then
  1513.         error(ertyp);
  1514.          lc1 := lc;
  1515.          emit(11);        {jmpc}
  1516.          if    sy = thensy
  1517.          then
  1518.         insymbol
  1519.          else
  1520.         error(erkey);
  1521.          statement(fsys + [elsesy]);
  1522.          if    sy = elsesy
  1523.          then
  1524.         begin
  1525.            insymbol;
  1526.            lc2 := lc;
  1527.            emit(10);
  1528.            code[lc1].y := lc;
  1529.            statement(fsys);
  1530.            code[lc2].y := lc
  1531.         end
  1532.          else
  1533.         code[lc1].y := lc
  1534.       end {ifstatement};
  1535.  
  1536.  
  1537.       procedure repeatstatement;
  1538.  
  1539.       var
  1540.          x:    item;
  1541.          lc1: integer;
  1542.  
  1543.       begin
  1544.          lc1 := lc;
  1545.          insymbol;
  1546.          statement([semicolon, untilsy] +    fsys);
  1547.          while sy in [semicolon] + statbegsys do
  1548.         begin
  1549.            if sy = semicolon
  1550.            then
  1551.               insymbol
  1552.            else
  1553.               error(erpun);
  1554.            statement([semicolon, untilsy] + fsys)
  1555.         end;
  1556.          if    sy = untilsy
  1557.          then
  1558.         begin
  1559.            insymbol;
  1560.            expression(fsys, x);
  1561.            if not (x.typ in [bools, notyp]) then
  1562.               error(ertyp);
  1563.            emit1(11, lc1)
  1564.         end
  1565.          else
  1566.         error(erkey)
  1567.       end {repeatstatement};
  1568.  
  1569.  
  1570.       procedure whilestatement;
  1571.  
  1572.       var
  1573.          x:    item;
  1574.          lc1, lc2: integer;
  1575.  
  1576.       begin
  1577.          insymbol;
  1578.          lc1 := lc;
  1579.          expression(fsys + [dosy], x);
  1580.          if    not (x.typ in [bools, notyp])    then
  1581.         error(ertyp);
  1582.          lc2 := lc;
  1583.          emit(11);
  1584.          if    sy = dosy
  1585.          then
  1586.         insymbol
  1587.          else
  1588.         error(erkey);
  1589.          statement(fsys);
  1590.          emit1(10, lc1);
  1591.          code[lc2].y := lc
  1592.       end {whilestatement};
  1593.  
  1594.  
  1595.       procedure forstatement;
  1596.  
  1597.       var
  1598.          cvt: types;
  1599.          x:    item;
  1600.          i,    lc1, lc2: integer;
  1601.  
  1602.       begin
  1603.          insymbol;
  1604.          if    sy = ident
  1605.          then
  1606.         begin
  1607.            i :=    loc(id);
  1608.            insymbol;
  1609.            if i    = 0 then
  1610.               cvt := tab[i].typ;
  1611.            if tab[i].obj = variable
  1612.            then
  1613.               begin
  1614.              cvt :=    tab[i].typ;
  1615.              if not    tab[i].normal
  1616.              then
  1617.                 error(ertyp)
  1618.              else
  1619.                 emit2(0, tab[i].lev, tab[i].adr);
  1620.              if not    (cvt in    [notyp, ints, bools, chars])
  1621.              then
  1622.                 error(ertyp)
  1623.               end
  1624.            else
  1625.               begin
  1626.              error(ertyp);
  1627.              cvt :=    ints
  1628.               end
  1629.         end
  1630.          else
  1631.         skip([becomes,    tosy, dosy] + fsys, erid);
  1632.          if    sy = becomes
  1633.          then
  1634.         begin
  1635.            insymbol;
  1636.            expression([tosy, dosy] + fsys, x);
  1637.            if x.typ <> cvt then
  1638.               error(ertyp);
  1639.         end
  1640.          else
  1641.         skip([tosy, dosy] + fsys, erpun);
  1642.          if    sy = tosy
  1643.          then
  1644.         begin
  1645.            insymbol;
  1646.            expression([dosy] + fsys, x);
  1647.            if x.typ <> cvt then
  1648.               error(ertyp)
  1649.         end
  1650.          else
  1651.         skip([dosy] +    fsys, erkey);
  1652.          lc1 := lc;
  1653.          emit(14);
  1654.          if    sy = dosy
  1655.          then
  1656.         insymbol
  1657.          else
  1658.         error(erkey);
  1659.          lc2 := lc;
  1660.          statement(fsys);
  1661.          emit1(15, lc2);
  1662.          code[lc1].y := lc
  1663.       end {forstatement};
  1664.  
  1665.  
  1666.       procedure standproc(n: integer);
  1667.  
  1668.       var
  1669.          i,    f: integer;
  1670.          x,    y: item;
  1671.  
  1672.       begin
  1673.          case n of
  1674.         1, 2:
  1675.            begin {read}
  1676.               if sy = lparent
  1677.               then
  1678.              begin
  1679.                 repeat
  1680.                    insymbol;
  1681.                    if sy <>    ident
  1682.                    then
  1683.                   error(erid)
  1684.                    else
  1685.                   begin
  1686.                      i := loc(id);
  1687.                      insymbol;
  1688.                      if    i <> 0
  1689.                      then
  1690.                     if tab[i].obj    <> variable
  1691.                     then
  1692.                        error(ertyp)
  1693.                     else
  1694.                        begin
  1695.                           x.typ := tab[i].typ;
  1696.                           x.ref := tab[i].ref;
  1697.                           if tab[i].normal
  1698.                           then
  1699.                          f := 0
  1700.                           else
  1701.                          f := 1;
  1702.                           emit2(f, tab[i].lev,
  1703.                             tab[i].adr);
  1704.                           if sy = lbrack then
  1705.                          selector(fsys + [comma,
  1706.                             rparent], x);
  1707.                           if x.typ in [ints, chars,
  1708.                          notyp]
  1709.                           then
  1710.                          emit1(27, ord(x.typ))
  1711.                           else
  1712.                          error(ertyp)
  1713.                        end
  1714.                   end;
  1715.                    test([comma, rparent],    fsys, erkey)
  1716.                 until sy <>    comma;
  1717.                 if sy = rparent
  1718.                 then
  1719.                    insymbol
  1720.                 else
  1721.                    error(erpun)
  1722.              end;
  1723.               if n = 2 then
  1724.              emit(62)
  1725.            end;
  1726.         3, 4:
  1727.            begin {write}
  1728.               if sy = lparent
  1729.               then
  1730.              begin
  1731.                 repeat
  1732.                    insymbol;
  1733.                    if sy = string
  1734.                    then
  1735.                   begin
  1736.                      emit1(24, sleng);
  1737.                      emit1(28, inum);
  1738.                      insymbol
  1739.                   end
  1740.                    else
  1741.                   begin
  1742.                      expression(fsys + [comma,    colon,
  1743.                     rparent], x);
  1744.                      if    not (x.typ in stantyps)    then
  1745.                     error(ertyp);
  1746.                      emit1(29, ord(x.typ))
  1747.                   end
  1748.                 until sy <>    comma;
  1749.                 if sy = rparent
  1750.                 then
  1751.                    insymbol
  1752.                 else
  1753.                    error(erpun)
  1754.              end;
  1755.               if n = 4 then
  1756.              emit(63)
  1757.            end;
  1758.         5, 6: {wait, signal}
  1759.            if sy <> lparent
  1760.            then
  1761.               error(erpun)
  1762.            else
  1763.               begin
  1764.              insymbol;
  1765.              if sy <> ident
  1766.              then
  1767.                 error(erid)
  1768.              else
  1769.                 begin
  1770.                    i := loc(id);
  1771.                    insymbol;
  1772.                    if i <> 0
  1773.                    then
  1774.                   if tab[i].obj <> variable
  1775.                   then
  1776.                      error(ertyp)
  1777.                   else
  1778.                      begin
  1779.                     x.typ := tab[i].typ;
  1780.                     x.ref := tab[i].ref;
  1781.                     if tab[i].normal
  1782.                     then
  1783.                        f :=    0
  1784.                     else
  1785.                        f :=    1;
  1786.                     emit2(f, tab[i].lev, tab[i].
  1787.                        adr);
  1788.                     if sy =    lbrack then
  1789.                        selector(fsys + [rparent],    x
  1790.                           );
  1791.                     if x.typ = ints
  1792.                     then
  1793.                        emit(n + 1)
  1794.                     else
  1795.                        error(ertyp)
  1796.                      end
  1797.                 end;
  1798.              if sy = rparent
  1799.              then
  1800.                 insymbol
  1801.              else
  1802.                 error(erpun)
  1803.               end;
  1804.          end {case}
  1805.       end {standproc};
  1806.  
  1807.  
  1808.       begin {statement}
  1809.       if sy    in statbegsys +    [ident]
  1810.       then
  1811.          case sy of
  1812.         ident:
  1813.            begin
  1814.               i    := loc(id);
  1815.               insymbol;
  1816.               if i <> 0
  1817.               then
  1818.              case tab[i].obj of
  1819.                 konstant, type1:
  1820.                    error(ertyp);
  1821.                 variable:
  1822.                    assignment(tab[i].lev,    tab[i].adr);
  1823.                 prozedure:
  1824.                    if tab[i].lev <> 0
  1825.                    then
  1826.                   call(fsys, i)
  1827.                    else
  1828.                   standproc(tab[i].adr);
  1829.                 funktion:
  1830.                    if tab[i].ref = display[level]
  1831.                    then
  1832.                   assignment(tab[i].lev + 1, 0)
  1833.                    else
  1834.                   error(ertyp)
  1835.              end
  1836.            end;
  1837.         beginsy:
  1838.            if id = 'cobegin   '
  1839.            then
  1840.               begin
  1841.              emit(4);
  1842.              compoundstatement;
  1843.              emit(5)
  1844.               end
  1845.            else
  1846.               compoundstatement;
  1847.         ifsy:
  1848.            ifstatement;
  1849.         whilesy:
  1850.            whilestatement;
  1851.         repeatsy:
  1852.            repeatstatement;
  1853.         forsy:
  1854.            forstatement;
  1855.          end;
  1856.       test(fsys, [], erpun)
  1857.       end {statement};
  1858.  
  1859.  
  1860.    begin {block}
  1861.       tabchar := chr(9);    
  1862.       dx := 5;
  1863.       prt := t;
  1864.       if level    > lmax then
  1865.       fatal(5);
  1866.       test([lparent, colon, semicolon], fsys, erpun);
  1867.       enterblock;
  1868.       display[level]    := b;
  1869.       prb := b;
  1870.       tab[prt].typ := notyp;
  1871.       tab[prt].ref := prb;
  1872.       if (sy =    lparent) and (level > 1) then
  1873.       parameterlist;
  1874.       btab[prb].lastpar := t;
  1875.       btab[prb].psize := dx;
  1876.       if isfun
  1877.       then
  1878.       if sy    = colon
  1879.       then
  1880.          begin
  1881.         insymbol;    {function type}
  1882.         if sy =    ident
  1883.         then
  1884.            begin
  1885.               x    := loc(id);
  1886.               insymbol;
  1887.               if x <> 0    then
  1888.              if tab[x].obj <> type1
  1889.              then
  1890.                 error(ertyp)
  1891.              else
  1892.                 if tab[x].typ in stantyps
  1893.                 then
  1894.                    tab[prt].typ := tab[x].typ
  1895.                 else
  1896.                    error(ertyp)
  1897.            end
  1898.         else
  1899.            skip([semicolon] +    fsys, erid)
  1900.          end
  1901.       else
  1902.          error(erpun);
  1903.       if sy = semicolon
  1904.       then
  1905.       insymbol
  1906.       else
  1907.       error(erpun);
  1908.       repeat
  1909.       if sy    = constsy then
  1910.          constdeclaration;
  1911.       if sy    = typesy then
  1912.          typedeclaration;
  1913.       if sy    = varsy    then
  1914.          vardeclaration;
  1915.       btab[prb].vsize := dx;
  1916.       while    sy in [proceduresy, functionsy] do
  1917.          procdeclaration;
  1918.       test([beginsy], blockbegsys    + statbegsys, erkey)
  1919.       until sy    in statbegsys;
  1920.       tab[prt].adr := lc;
  1921.       insymbol;
  1922.       statement([semicolon, endsy] +    fsys);
  1923.       while sy    in [semicolon] + statbegsys do
  1924.       begin
  1925.          if    sy = semicolon
  1926.          then
  1927.         insymbol
  1928.          else
  1929.         error(erpun);
  1930.          statement([semicolon, endsy] + fsys)
  1931.       end;
  1932.       if sy = endsy
  1933.       then
  1934.       insymbol
  1935.       else
  1936.       error(erkey);
  1937.       test(fsys + [period], [], erkey);
  1938.    end    {block};
  1939.  
  1940. modend.
  1941.