home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / TURBOPAS / RNF-PAS.LBR / RNF2.PQS / RNF2.PAS
Pascal/Delphi Source File  |  2000-06-30  |  33KB  |  1,199 lines

  1. (*  ---  rnf2 --- *)
  2.  
  3. procedure GetNum(var SignValue: sign; var NumberValue: integer);
  4.  
  5.   const
  6.     SMnestMax = 5;
  7.     
  8.   var
  9.     EndOfSyl: boolean;
  10.     SylCharIndex: integer;
  11.     CurChar,
  12.     LookAheadChar: char;
  13.     SubMacStackIndx: integer;
  14.     SMstack: array [1 .. SMnestMax] of
  15.                record
  16.                  TextPtr: integer;
  17.                  SMmac: pmac;
  18.                end;
  19.     
  20.  
  21.   PROCEDURE NextChar;
  22.    
  23.     BEGIN
  24.       CurChar := ' ';
  25.       if SubMacStackIndx = 0 then
  26.         with syl do
  27.           begin
  28.             ExprErr := ExprErr or EndOfSyl;
  29.             IF SylCharIndex <= LEN THEN
  30.               begin
  31.                 CurChar := LIN[SylCharIndex];
  32.                 SylCharIndex := SylCharIndex + 1;   
  33.               end
  34.             ELSE
  35.               EndOfSyl := true;
  36.           end
  37.       else
  38.         begin
  39.           with SMstack[SubMacStackIndx] do
  40.             with SMmac^ do
  41.               begin
  42.                 if TextPtr <= MacroEnd then
  43.                   begin
  44.                     CurChar := StgTable[TextPtr];
  45.                     TextPtr := TextPtr + 1
  46.                   end;
  47.               end;
  48.         end;
  49.     END (*NextChar*);
  50.   
  51.   
  52.   FUNCTION Expression: INTEGER;
  53.    
  54.     VAR
  55.                 EXPR1,
  56.                 EXPR2: integer;
  57.                 EXPR3: boolean;
  58.                EXPROP: RELOPR;
  59.    
  60.   function number: integer;
  61.   
  62.     var 
  63.       ival: integer;
  64.       
  65.     begin
  66.       ival := 0;
  67.       while (CurChar in ['0' .. '9']) and (ival < DangerPoint) do
  68.         begin
  69.           ival := ival * 10 + (ord(CurChar) - ord('0'));
  70.           NextChar
  71.         end;
  72.       if CurChar in ['0' .. '9'] then
  73.         if (ord(CurChar) - ord('0')) > maxint mod 10 then
  74.           error(58) (* number too big *)
  75.         else
  76.           begin
  77.             ival := ival * 10 + (ord(CurChar) - ord('0'));
  78.             NextChar;
  79.             if CurChar in ['0' .. '9'] then
  80.               error(58) (* number too big *);
  81.           end;
  82.       while CurChar in ['0' .. '9'] do NextChar;
  83.       number := ival;
  84.     end;
  85.     
  86.   function character: integer;
  87.   
  88.     var
  89.       cval: char;
  90.       
  91.     begin
  92.       NextChar  (* skip quote *);
  93.       cval := CurChar;
  94.       ExprErr := false;
  95.       if CurChar = '''' then
  96.         begin (* handle quotes as characters *)
  97.           NextChar;
  98.           ExprErr := CurChar <> '''';
  99.         end;
  100.       NextChar;
  101.       ExprErr := ExprErr or (CurChar <> '''');
  102.       NextChar;
  103.       if ExprErr then
  104.         begin
  105.           error(59)  (* bad character constant *);
  106.           cval := '?';
  107.           ExprErr := false;
  108.         end;
  109.       character := ord(cval);
  110.     end;
  111.     
  112.   FUNCTION TERM: INTEGER;
  113.     
  114.     var
  115.       term1, term2: integer;
  116.       tch: char;
  117.       
  118.     function item: integer;
  119.     
  120.       var
  121.         ItemSign: (none, negative, positive, LogicalNot);
  122.         item1: integer;
  123.       
  124.       FUNCTION VARIABLE: INTEGER;
  125.        
  126.         VAR
  127.                         V: ALFA;
  128.                         I: INTEGER;
  129.                     VNDX1,
  130.                     VNDX2: 0 .. VARMAX;
  131.                      VAR1: INTEGER;
  132.        
  133.         BEGIN
  134.           NextChar;   V := AlfaBlanks;   I := 0;
  135.           WHILE ForceUpperCase(CurChar) IN ['A' .. 'Z', '$', '0' .. '9'] DO
  136.             BEGIN I := I + 1;   
  137.               IF I <= AlfaLen THEN V[I] := ForceUpperCase(CurChar);   
  138.               NextChar; 
  139.             END;
  140.           VAR1 := 0;
  141.           IF I = 0   THEN ExprErr := TRUE
  142.           ELSE
  143.             BEGIN
  144.               VID[TV] := V;   VNDX1 := 1;   VNDX2 := 0;
  145.               WHILE VID[VNDX1] <> V DO VNDX1 := VNDX1 + 1;
  146.               IF VNDX1 <> TV
  147.               THEN
  148.                 BEGIN
  149.                   IF (VTY[VNDX1] = VARRAY) AND (CurChar = '[')
  150.                   THEN
  151.                     BEGIN
  152.                       NextChar;   VNDX2 := TERM;
  153.                       IF CurChar <> ']'   THEN ExprErr := TRUE   ELSE NextChar;
  154.                       IF (VNDX2 < 0) OR (VNDX2 > VUP[VNDX1]) THEN
  155.                         BEGIN
  156.                           Error(4)    (* Error - ARRAY INDEX OUT OF BOUNDS *);
  157.                           VNDX2 := 0
  158.                         END;
  159.                     END;
  160.                   IF CurChar = '='
  161.                   THEN BEGIN NextChar;   VAL[VNDX1 + VNDX2] := TERM; END;
  162.                   VAR1 := VAL[VNDX1 + VNDX2];
  163.                 END
  164.               ELSE 
  165.                 begin  
  166.                   VarName := V;  Error(55)   (* UNDEFINED VARIABLE: $V*);
  167.                 end;
  168.             END;
  169.           VARIABLE := VAR1;
  170.         END (*VARIABLE*);
  171.  
  172.  
  173.       FUNCTION SUBMACRO: INTEGER;
  174.        
  175.         VAR
  176.               SaveCurChar: char;
  177.                    SUBMAC: PMAC;
  178.                   MACNAME: alfa;
  179.                   NAMINDX: integer;
  180.                  EXITFLAG: BOOLEAN;
  181.        
  182.         BEGIN
  183.           MACNAME := AlfaBlanks;   NextChar;   
  184.           
  185.           NAMINDX := 0;
  186.           while CurChar = macchr do
  187.             begin  (* pick up leading macchrs *)
  188.               namindx := namindx + 1;
  189.               if namindx <= alfalen then macname[namindx] := CurChar;
  190.               NextChar;
  191.             end;
  192.           while CurChar in ['A' .. 'Z', 'a' .. 'z', '0' .. '9'] do
  193.             begin
  194.               namindx := namindx + 1;
  195.               if namindx <= alfalen then 
  196.                 macname[namindx] := ForceUpperCase(CurChar);
  197.               NextChar;
  198.             end;
  199.           
  200.           SUBMAC := MACLSTP;   EXITFLAG := FALSE;
  201.           REPEAT
  202.             IF SUBMAC = NIL   THEN EXITFLAG := TRUE
  203.             ELSE
  204.               IF SUBMAC ^.NM = MACNAME   THEN EXITFLAG := TRUE
  205.               ELSE SUBMAC := SUBMAC ^.MA;
  206.           UNTIL EXITFLAG;
  207.           
  208.           IF TestOk((SUBMAC <> NIL), 1) 
  209.                                      (* Error - UNRECOGNIZED SUB-MACRO NAME *)
  210.           THEN
  211.             if TestOk(not submac^.on, 2) (* Error - recursive sub-macro *)
  212.             then
  213.               if SubMacStackIndx < SMnestMax then
  214.                 begin
  215.                   SaveCurChar := CurChar;
  216.                   SubMacStackIndx := SubMacStackIndx + 1;
  217.                   with SMstack[SubMacStackIndx], submac^ do
  218.                     begin (* stack SUB-MACRO VALUE *)
  219.                       on := true;
  220.                       SMmac := submac;
  221.                       TextPtr := MacroBegin;
  222.                       NextChar;
  223.                       LookAheadChar := StgTable[TextPtr];
  224.                       submacro := Expression;
  225.                       on := false;
  226.                     end;
  227.                   SubMacStackIndx := SubMacStackIndx - 1;
  228.                   CurChar := SaveCurChar;
  229.                 END;
  230.         END (* SUBMACRO *);
  231.       
  232.       
  233.         BEGIN (* item *)
  234.           ItemSign := none;
  235.           IF CurChar = '-'   THEN ItemSign := negative
  236.           ELSE
  237.             IF CurChar = '#'   THEN ItemSign := LogicalNot
  238.             ELSE
  239.               IF CurChar = '+'   THEN ItemSign := positive;
  240.  
  241.           if ItemSign <> none then
  242.             NextChar;
  243.           
  244.           ITEM1 := 0;
  245.           IF CurChar = varchr  THEN ITEM1 := VARIABLE
  246.           ELSE
  247.             IF CurChar = macchr  THEN ITEM1 := SUBMACRO
  248.             ELSE
  249.               IF CurChar IN ['0' .. '9'] THEN  item1 := number
  250.               else
  251.                 if CurChar = '''' then item1 := character
  252.                 ELSE ExprErr := TRUE;
  253.           
  254.           CASE ItemSign OF
  255.             none,
  256.             positive:;
  257.             negative: ITEM1 := - ITEM1;
  258.             LogicalNot: item1 := BoolOrd(item1 = 0)
  259.           END;
  260.           ITEM := ITEM1;
  261.         END (*ITEM*);
  262.      
  263.      
  264.       BEGIN (* term *)
  265.         TERM1 := 0;
  266.         IF CurChar = '('
  267.         THEN
  268.           BEGIN
  269.             NextChar;   TERM1 := TERM;
  270.             IF CurChar <> ')'   THEN ExprErr := TRUE   ELSE NextChar;
  271.           END
  272.         ELSE
  273.           IF CurChar IN ITEMSET
  274.           THEN
  275.             BEGIN
  276.               TERM1 := ITEM;
  277.               WHILE CurChar IN ['+', '-'] DO
  278.                 BEGIN
  279.                   TCH := CurChar;   NextChar;   TERM2 := 0;
  280.                   IF CurChar IN ITEMSET   THEN TERM2 := ITEM
  281.                   ELSE IF CurChar = '('   THEN TERM2 := TERM;
  282.                   IF TCH = '+'   
  283.                   THEN TERM1 := TERM1 + TERM2
  284.                   ELSE TERM1 := TERM1 - TERM2;
  285.                 END;
  286.             END;
  287.         TERM := TERM1;
  288.       END (*TERM*);
  289.  
  290.  
  291.     FUNCTION RELOP: RELOPR;
  292.      
  293.       VAR
  294.                      OP: ALFA;
  295.                     ROP: RELOPR;
  296.      
  297.       BEGIN
  298.         OP := AlfaBlanks;   
  299.         
  300.         NextChar;   OP[1] := ForceUpperCase(CurChar);   
  301.         NextChar;   OP[2] := ForceUpperCase(CurChar);   
  302.         NextChar;   IF CurChar = '.'   THEN NextChar;
  303.         
  304.         ARELOPR[BADRELOP] := OP;   ROP := EQ;
  305.         WHILE (ARELOPR[ROP] <> OP) DO ROP := SUCC(ROP);
  306.         IF (ROP = BADRELOP) THEN
  307.           Error(5)  (* UNRECOGNIZED RELATIONAL OPERATOR *);
  308.         RELOP := ROP;
  309.       END (*RELOP*);
  310.  
  311.  
  312.     BEGIN  (* expression *)
  313.       EXPR1 := 0;   
  314.       IF (CurChar = varchr) AND (LookAheadChar = '(')   THEN
  315.         NextChar;
  316.       IF CurChar IN TERMSET
  317.       THEN
  318.         BEGIN
  319.           EXPR1 := TERM;
  320.           IF CurChar = '.'
  321.           THEN
  322.             BEGIN
  323.               EXPROP := RELOP;   EXPR2 := 0;
  324.               IF CurChar IN TERMSET   THEN EXPR2 := TERM;   
  325.               CASE EXPROP OF
  326.                 EQ: expr3 := EXPR1 = EXPR2;
  327.                 GT: expr3 := EXPR1 > EXPR2;
  328.                 LT: expr3 := EXPR1 < EXPR2;
  329.                 NE: expr3 := EXPR1 <> EXPR2;
  330.                 GE: expr3 := EXPR1 >= EXPR2;
  331.                 LE: expr3 := EXPR1 <= EXPR2;
  332.                 BADRELOP: EXPR3 := false;
  333.               END;
  334.               EXPR1 := BoolOrd(EXPR3);
  335.             END
  336.         end;
  337.       Expression := EXPR1;
  338.     END (*Expression*);
  339.   
  340.  
  341.   BEGIN (* GetNum *)
  342.     SubMacStackIndx := 0;
  343.     
  344.     EndOfSyl := false;
  345.     SylCharIndex := 1;
  346.     NextChar;
  347.     
  348.     IF CurChar = '+'   THEN SignValue := plus
  349.     ELSE
  350.       IF CurChar = '-'   THEN SignValue := minus
  351.       ELSE SignValue := UnSigned;
  352.     
  353.     if SignValue <> UnSigned then
  354.       NextChar;
  355.       
  356.     LookAheadChar := Syl.LIN[SylCharIndex]; 
  357.     
  358.     ExprErr := false;
  359.     
  360.     NumberValue := Expression;
  361.     
  362.     if CurChar = ';' then
  363.       begin
  364.         ShowExpr := false;
  365.         NextChar;
  366.       end
  367.     else
  368.       ShowExpr := true;
  369.     
  370.     while (CurChar = ' ') and not EndOfSyl do
  371.       NextChar;
  372.       
  373.     IF ExprErr or not EndOfSyl then
  374.       begin
  375.         SignValue := invalid;
  376.         Error(6)  (* ERROR IN EXPRESSION *);
  377.       end;
  378.   END (*GetNum*);
  379.  
  380.  
  381.  
  382.  
  383. PROCEDURE PSHENV;
  384.  
  385.   BEGIN
  386.     SAVENV(ENSTK[ENP]);
  387.     ENP := ENP + BoolOrd(TestOk((ENP <> MAXENP), 7));
  388.                     (* Error - TOO MANY P OR LIST LEVELS *)
  389.   END (*PSHENV*);
  390.  
  391.  
  392. PROCEDURE POPENV;
  393.  
  394.   BEGIN
  395.     ENP := ENP - BoolOrd(TestOk((ENP <> 0), 8));
  396.                     (* Error - TOO MANY POPS *)
  397.     RESENV(ENSTK[ENP]);
  398.   END (*POPENV*);
  399.  
  400. PROCEDURE DOJUST(VAR L: LINE; VAR F: JUSLIN; RIGHT: BOOLEAN);
  401.  
  402.   VAR
  403.           LineIndex: integer;
  404.                   I,
  405.                   J,
  406.                   K,
  407.                   N,
  408.                   M: LLEN;
  409.  
  410.   BEGIN
  411.     WITH L, F DO
  412.       BEGIN
  413.         IF LEN > 2   THEN IF XTRABL   THEN BEGIN LEN := LEN - 1 END;
  414.         IF (NOT CENTER) AND (NDX > 1) AND (LEN <= VAL[VRM] + 1)
  415.         THEN
  416.           BEGIN
  417.             I := NDX;   J := VAL[VRM];
  418.             N := (VAL[VRM] - LEN + 1) DIV (NDX - 1);
  419.             M := (VAL[VRM] - LEN + 1) MOD (NDX - 1);   LEN := J + 1;
  420.             FOR K := NDX DOWNTO 2 DO
  421.               BEGIN
  422.                 FOR LineIndex := POS[K] DOWNTO POS[K - 1] + 1 DO
  423.                   BEGIN
  424.                     LIN[J] := LIN[LineIndex];   
  425.                     OverLin[J] := OverLin[LineIndex];
  426.                     BoldFlag[j] := BoldFlag[LineIndex];
  427.                     USflag[j] := USflag[LineIndex];
  428.                     J := J - 1
  429.                   END; 
  430.                 FOR LineIndex := 1 TO N DO
  431.                   BEGIN
  432.                     LIN[J] := ' ';   OverLin[J] := ' ';
  433.                     BoldFlag[j] := false;   USflag[j] := false;
  434.                     J := J - 1
  435.                   END;
  436.                 IF RIGHT
  437.                 THEN
  438.                   BEGIN
  439.                     IF (NDX - K) <= M THEN
  440.                       BEGIN
  441.                         LIN[J] := ' ';   OverLin[J] := ' ';
  442.                         BoldFlag[j] := false;   USflag[j] := false;
  443.                         J := J - 1
  444.                       END
  445.                   END
  446.                 ELSE
  447.                   IF (K - 2) <= M THEN
  448.                     BEGIN
  449.                       LIN[J] := ' ';   OverLin[J] := ' ';
  450.                       BoldFlag[j] := false;   USflag[j] := false;
  451.                       J := J - 1
  452.                     END
  453.               END
  454.           END
  455.       END
  456.   END (*DOJUST*);
  457.  
  458.  
  459. PROCEDURE STARTLINE;
  460.    BEGIN
  461.     if RightSpace > 0 then
  462.       write(outfile,' ':RightSpace);
  463.     if bar then
  464.       if otl.bbar then 
  465.         write(outfile, '|  ')  
  466.       else 
  467.         write(outfile,' ':3);
  468.  
  469.   END (*STARTLINE*);
  470.  
  471.  
  472. PROCEDURE DOTOP;
  473.  
  474.   var
  475.     i: integer;
  476.     
  477.   BEGIN
  478.     if HandFeed then
  479.       begin
  480.         write(' Type return when paper is ready >');
  481.         readln;
  482.       end
  483.     else
  484.      if InitialPageEject then
  485.       IF NOPAGE   THEN
  486.         FOR i := VAL[VOLNO] TO OEPAG DO
  487.           writeln(outfile)
  488.       ELSE
  489.         PAGE(OUTFILE);
  490.     InitialPageEject := true; { subsequent pages always eject }
  491.     VAL[VOLNO] := 1;   STARTLINE;   OVETXT := OETXT - 1;   OVBTXT := 0;
  492.     IF NOT HOLDBB   THEN BEGIN HOLDBB := BB;   BB := FALSE; END;
  493.   END (*DOTOP*);
  494.  
  495.  
  496. PROCEDURE DOBOT;
  497.  
  498.   var
  499.     i: integer;
  500.     
  501.   BEGIN
  502.     FOR i := VAL[VOLNO] TO OETXT DO
  503.       writeln(outfile);
  504.     VAL[VOLNO] := OETXT + 1;   OVETXT := 32000;   HOLDBB := BB;
  505.   END (*DOBOT*);
  506.  
  507.  
  508. PROCEDURE PUTBLANK(count: integer);
  509.  
  510.   var
  511.     i: integer;
  512.   
  513.   BEGIN
  514.     IF VAL[VOLNO] > OVBTXT THEN
  515.       for i := 1 to count do
  516.         IF VAL[VOLNO] <= OVETXT + 1 THEN
  517.           BEGIN 
  518.             VAL[VOLNO] := VAL[VOLNO] + 1;   
  519.             if Bar then
  520.               if Otl.BBar then
  521.                 begin
  522.                   if RightSpace > 0 then
  523.                     write(outfile,' ':Rightspace);
  524.                   write(outfile, '|  ');
  525.                 end;
  526.             writeln(outfile);
  527.           END;
  528.   END (*PUTBLANK*);
  529.  
  530.  
  531. PROCEDURE WRITEOTL;
  532.  
  533.   VAR
  534.       i,  LineIndex: integer;
  535.             LastPos,
  536.               CENTS: INTEGER;
  537.       BoldStarted, UscoreStarted : Boolean;
  538.  
  539.   BEGIN (*WRITEOTL*)
  540.     WITH OTL DO
  541.       BEGIN
  542.         LEN := LEN - BoolOrd(Len > 0);
  543.         if center then
  544.           CENTS := ((VAL[VRM] - VAL[VLM]) DIV 2) - ((LEN - VAL[VLM]) DIV 2)
  545.         else
  546.           cents := 0;
  547.  
  548.  
  549.         IF NOT UL THEN
  550.           FOR LineIndex := 1 TO LEN DO
  551.             BEGIN
  552.               LIN[LineIndex] := ForceUpperCase(LIN[LineIndex]);
  553.               OverLin[LineIndex] := MakeUpper[OverLin[LineIndex]];
  554.             END;
  555.  
  556.         STARTLINE;
  557.         if cents > 0 then
  558.           write(outfile,' ':cents);
  559.         LastPos := len;
  560.         while (LastPos > 1) and (Lin[LastPos] = ' ') do
  561.           LastPos := LastPos - 1;
  562.         if val[VANSI] = 1 then
  563.           begin
  564.             { This code is for any ANSI output device }
  565.             { it can be used for screen previews of underlining and bold }
  566.             {     on VT100 or on the IBM-PC if the ANSI driver is loaded. }
  567.             { To enable it, put  $$ANSI=1 in your input text file. }
  568.             BoldStarted := false;
  569.             UScoreStarted := false;
  570.             for i := 1 to Lastpos do
  571.               begin
  572.                 if UScoreStarted and (not USFlag[i])  or
  573.                    BoldStarted and (not BoldFlag[i]) then
  574.                   begin
  575.                     { ANSI turns off both at once }
  576.                     write (outfile, chr(27),'[0m');
  577.                     UScoreStarted := false;
  578.                     BoldStarted := false;
  579.                   end;
  580.                 if (not BoldStarted) and BoldFlag[i] then
  581.                   begin
  582.                     write (outfile, chr(27),'[1m');{ turn on bold mode }
  583.                     BoldStarted := true;
  584.                   end;
  585.                 if (not UScoreStarted) and USFlag[i] then
  586.                   begin
  587.                     write (outfile, chr(27),'[4m');
  588.                     UScorestarted := true;
  589.                   end;
  590.                 write (outfile, lin[i]); { now write the character }
  591.               end;
  592.             { finished with character writing, turn off attributes }
  593.             if UScoreStarted or BoldStarted then
  594.               begin
  595.                 write (outfile, chr(27),'[0m');
  596.                 UScoreStarted := false;
  597.                 BoldStarted := false;
  598.               end;
  599.           end
  600.  
  601.         else
  602.         begin
  603.           { non-ANSI device, overprint for bold and underline }
  604.           WritePAOC(Lin, Lastpos);
  605.         if HasBoldPrinting then
  606.           begin
  607.             for LineIndex := 1 to len do
  608.               if BoldFlag[LineIndex] then
  609.                 LastPos := LineIndex
  610.               else
  611.                 Lin[LineIndex] := ' ';
  612.             for i := 1 to 2 {number of overwrites} do
  613.             begin
  614.               write(outfile, chr(val[vcr]));
  615.               STARTLINE;
  616.               if cents > 0 then
  617.                 write(outfile,' ':cents);
  618.               WritePAOC( Lin, LastPos);
  619.             end;
  620.           end;
  621.  
  622.         if HasOverPrinting then
  623.           begin
  624.             write(outfile, chr(val[vcr]));
  625.             STARTLINE;
  626.             if cents > 0 then
  627.               write(outfile,' ':cents);
  628.             LastPos := len;
  629.             while (LastPos > 1) and (OverLin[LastPos] = ' ') do
  630.               LastPos := LastPos - 1;
  631.             WritePAOC( OverLin, Lastpos);
  632.           end;
  633.  
  634.         if HasUnderScore then
  635.           begin
  636.             write(outfile, chr(val[vcr]));
  637.             STARTLINE;
  638.             if cents > 0 then
  639.               write(outfile,' ':cents);
  640.             for LineIndex := 1 to len do
  641.               if USflag[LineIndex] then
  642.                 begin
  643.                   Lin[LineIndex] := '_';
  644.                   LastPos := LineIndex;
  645.                 end
  646.               else
  647.                 Lin[LineIndex] := ' ';
  648.             WritePAOC( Lin, LastPos);
  649.           end;
  650.         end;
  651.         writeln(outfile); { finished with complete line }
  652.       END
  653.   END (*WRITEOTL*); 
  654.  
  655.  
  656. PROCEDURE DOMID;
  657.  
  658.   VAR
  659.                   i: integer;
  660.               DOFIG: BOOLEAN;
  661.  
  662.   PROCEDURE MIDRESTORE;
  663.    
  664.     BEGIN
  665.       CLRLINE;
  666.       IF PAGOTL THEN
  667.         BEGIN
  668.           OTL := PAGSAV;   WRITEOTL;   VAL[VOLNO] := VAL[VOLNO] + 1;
  669.           PAGOTL := FALSE;   CLRLINE;
  670.         END;
  671.       BB := HOLDBB;   HOLDBB := FALSE;
  672.     END (*MIDRESTORE*);
  673.  
  674.   BEGIN
  675.     OVBTXT := VAL[VOLNO];   DOFIG := TRUE;
  676.     IF FIGP > 0
  677.     THEN
  678.       WHILE DOFIG DO
  679.         IF FIGN[FIGP] <= OVETXT - OVBTXT + 1
  680.         THEN
  681.           BEGIN
  682.             FOR i := 1 TO FIGN[FIGP] DO
  683.               BEGIN 
  684.                 writeln(outfile);   
  685.                 VAL[VOLNO] := VAL[VOLNO] + 1; 
  686.               END;
  687.             FIGP := FIGP - 1;   IF FIGP = 0   THEN DOFIG := FALSE;
  688.           END
  689.         ELSE DOFIG := FALSE;
  690.     MIDRESTORE;
  691.   END (*DOMID*);
  692.  
  693.  
  694. PROCEDURE PUTLINE;
  695.  
  696.   BEGIN
  697.     IF (NOT SUP) AND (NOT EMPTY)
  698.     THEN
  699.       BEGIN
  700.         IF (VAL[VOLNO] + BoolOrd(pushed) > OVETXT + 1) THEN
  701.           BEGIN
  702.             PAGSAV := OTL;   PAGOTL := TRUE;   PushText(DefrFrcPgMacP);
  703.           END
  704.         ELSE
  705.           BEGIN
  706.             PUSHED := FALSE (* NO PAGE THROW *);
  707.             VAL[VOLNO] := VAL[VOLNO] + 1;
  708.             RIGHT := NOT RIGHT;   
  709.             WRITEOTL; 
  710.           END 
  711.       END;
  712.     PUTBLANK(DEFRB);   CLRLINE;
  713.   END (*PUTLINE*);
  714.  
  715.  
  716. PROCEDURE PUSHSYL(VAR Asyl: LINE);
  717.   FORWARD;
  718.  
  719.  
  720. PROCEDURE TESTPAGE(N: INTEGER; SaveSyl: boolean);
  721.  
  722.   BEGIN
  723.     IF (N * VAL[VSP]) - 1 > (OVETXT - VAL[VOLNO] + 1) THEN 
  724.       BEGIN 
  725.         if SaveSyl then
  726.           PushSyl(Syl);
  727.         PushText(DefrFrcPgMacP);  
  728.       END;
  729.   END (*TESTPAGE*);
  730.  
  731.  
  732. PROCEDURE PARAGRAPH;
  733.  
  734.   var
  735.     indent: integer;
  736.     
  737.   BEGIN
  738.     RIGHT := TRUE (* RESET ALTERNATING FILL *);
  739.     PUTBLANK(PARSPACE * VAL[VSP]);
  740.     WITH OTL DO
  741.       BEGIN
  742.         IF PREL
  743.         THEN
  744.           IF VAL[VLM] + PMAR > 0   THEN indent := VAL[VLM] + PMAR
  745.           ELSE indent := 1
  746.         ELSE indent := PMAR;
  747.         LEN := indent;   
  748. {}      if len = 0 then len := 1;
  749.         FOR indent := 1 TO LEN DO LIN[indent] := ' ';
  750.       END;
  751.     RIGHT := TRUE;   TESTPAGE(PARTEST, true);
  752.   END (*PARAGRAPH*);
  753.  
  754. PROCEDURE MARKJUST(N: LLEN);
  755.  
  756.   BEGIN WITH JUST DO BEGIN NDX := NDX + 1;   POS[NDX] := N END
  757.   END (*MARKJUST*);
  758.  
  759.  
  760. PROCEDURE ADDWORD;
  761.  
  762.   VAR
  763.                  TAB, J, LineIndex: INTEGER;
  764.  
  765.   procedure CopyDown(OffSet: integer);
  766.   
  767.     var
  768.       i, indx: integer;
  769.       
  770.     begin 
  771.       with tmpl do
  772.         FOR i := LEN DOWNTO 1 DO
  773.           BEGIN
  774.             indx := i + OffSet;
  775.             LIN[indx] := LIN[i];
  776.             OverLin[indx] := OverLin[i];
  777.             USflag[indx] := USflag[i];
  778.             BoldFlag[indx] := BoldFlag[i];
  779.           END;
  780.     end;
  781.  
  782.   FUNCTION GETTAB(X: INTEGER): INTEGER;
  783.    
  784.     var
  785.       TabLoc: integer;
  786.       
  787.     BEGIN
  788.       TabLoc := 1;   TABS[TABMAX] := X;   
  789.       WHILE TABS[TabLoc] < X DO TabLoc := TabLoc + 1;
  790.       JUST.NDX := 0;   RT := FALSE;   T := FALSE;   GETTAB := TABS[TabLoc];
  791.     END (*GETTAB*);
  792.  
  793.  
  794.   BEGIN
  795.     WITH OTL DO
  796.       BEGIN
  797.         IF (XTEND) AND (JUST.NDX > 0)
  798.         THEN
  799.           BEGIN
  800.             JUST.NDX := JUST.NDX - 1;
  801.             CopyDown(LASTSLEN);
  802.             FOR LineIndex := 1 TO LASTSLEN DO
  803.               BEGIN
  804.                 J := LineIndex + LASTLEN - 1;
  805.                 TMPL.LIN[LineIndex] := LIN[J];
  806.                 TMPL.OverLin[LineIndex] := OverLin[J];
  807.                 TMPL.USflag[LineIndex] := USflag[J];
  808.                 tmpl.BoldFlag[LineIndex] := BoldFlag[J];
  809.               END;
  810.             TMPL.LEN := TMPL.LEN + LASTSLEN;   LEN := LASTLEN;
  811.             FOR LineIndex := 1 TO SYL.LEN DO
  812.               ADDSYL.LIN[LineIndex + ADDSYL.LEN] := SYL.LIN[LineIndex];
  813.             ADDSYL.LEN := ADDSYL.LEN + SYL.LEN 
  814.           END
  815.         ELSE ADDSYL := SYL;
  816.         XTEND := FALSE;   
  817.         
  818.         TAB := 0;
  819.         IF RT   THEN TAB := GETTAB(LEN + TMPL.LEN - 1) - TMPL.LEN + 1
  820.         ELSE IF T   THEN TAB := GETTAB(LEN);
  821.         WHILE LEN < TAB DO
  822.           BEGIN
  823.             IF DOT AND (NOT (LEN = TAB - 1))   THEN LIN[LEN] := '.'
  824.             ELSE LIN[LEN] := ' ';
  825.             OverLin[LEN] := ' ';   LEN := LEN + 1;
  826.           END;
  827.         
  828.         IF (LEN + TMPL.LEN - 1 > VAL[VRM]) AND (NOT EMPTY)
  829.         THEN
  830.           BEGIN
  831.             IF JUSTIT   THEN DOJUST(OTL, JUST, RIGHT);
  832.             
  833.             PUSHED := TRUE;
  834.             PUSHSYL(ADDSYL)               (* SAVE THE CURRENT SYMBOL *);
  835.             PushText(CarRtnMacP)          (* AND FORCE THE END OF LINE*);
  836.             PUTLINE;
  837.             PUSHED := FALSE;
  838.           END
  839.         ELSE
  840.           BEGIN
  841.             EMPTY := FALSE;
  842.  
  843.             FOR LineIndex := 1 TO TMPL.LEN DO
  844.               LIN[LEN + LineIndex - 1] := TMPL.LIN[LineIndex];
  845.             
  846.             HasOverPrinting := tmpl.HasOverPrinting or HasOverPrinting;
  847.             if tmpl.HasOverPrinting then
  848.               for LineIndex := 1 to tmpl.len do
  849.                 OverLin[LEN + LineIndex - 1] := tmpl.OverLin[LineIndex];
  850.             
  851.             HasUnderScore := tmpl.HasUnderScore or HasUnderscore;
  852.             if tmpl.HasUnderScore then
  853.               for LineIndex := 1 to tmpl.len do
  854.                 USflag[Len + LineIndex - 1] := tmpl.USflag[LineIndex];
  855.             
  856.             HasBoldPrinting := tmpl.HasBoldPrinting or HasBoldPrinting;
  857.             if tmpl.HasBoldPrinting then
  858.               for LineIndex := 1 to tmpl.len do
  859.                 BoldFlag[Len + LineIndex - 1] := tmpl.BoldFlag[LineIndex];
  860.             
  861.             LASTLEN := LEN;
  862.             LASTSLEN := TMPL.LEN;   LEN := LEN + TMPL.LEN;
  863.             MARKJUST(LEN - 1);
  864.             IF NOT SIGBL
  865.             THEN
  866.               BEGIN
  867.                 LIN[LEN] := ' ';
  868.                 LEN := LEN + 1;
  869.                 IF PQEND THEN
  870.                   BEGIN
  871.                     LIN[LEN] := ' ';
  872.                     LEN := LEN + 1
  873.                   END;
  874.                 XTRABL := PQEND
  875.               END;
  876.           END;
  877.       END;
  878.   END (*ADDWORD*);
  879.  
  880.  
  881. PROCEDURE ADDCHR(C: CHAR);
  882.  
  883.   BEGIN
  884.     WITH OTL DO
  885.       BEGIN
  886.         LIN[LEN] := C;  LEN := LEN + 1;
  887.       END;
  888.   END (*ADDCHR*);
  889.  
  890.  
  891. PROCEDURE ADDNUM(N: INTEGER; VAR LocOTL: LINE);
  892.  
  893.   PROCEDURE ADDCHROTL(C: CHAR);
  894.  
  895.     BEGIN
  896.       WITH LocOTL DO
  897.         BEGIN
  898.           LIN[LEN] := C;   LEN := LEN + 1;  
  899.         END;
  900.     END (*ADDCHR*);
  901.  
  902.  
  903.   PROCEDURE ADDN(N: INTEGER);
  904.    
  905.     BEGIN
  906.       IF N >= 10   THEN ADDN(N DIV 10);
  907.       ADDCHROTL(CHR((N MOD 10) + ORD('0')));
  908.     END (*ADDN*);
  909.  
  910.   BEGIN
  911.     IF N < 0
  912.     THEN 
  913.       BEGIN
  914.         ADDCHROTL('-');
  915.         ADDN(- N)
  916.       END
  917.     ELSE ADDN(N);
  918.   END (*ADDNUM*);
  919.  
  920.  
  921. PROCEDURE UNFLAG(VAR L: LINE; LOWER: BOOLEAN);
  922.  
  923.   VAR
  924.           LineIndex: integer;
  925.                 FUP: 0 .. 3;
  926.                RCHN: LLEN;
  927.                OVER: BOOLEAN;
  928.  
  929.   PROCEDURE OUT(C: CHAR);
  930.  
  931.     BEGIN
  932.       RCHN := RCHN + 1;   
  933.       with tmpl do
  934.         begin
  935.           LIN[RCHN] := C;
  936.           OverLin[RCHN] := ' ';
  937.           if UNDL then
  938.             begin
  939.               HasUnderScore := true;
  940.               USflag[RCHN] := true;
  941.             end;
  942.           if bold then
  943.             if c <> ' ' then
  944.               begin
  945.                 HasBoldPrinting := true;
  946.                 BoldFlag[RCHN] := true;
  947.               end;
  948.         end;
  949.       LineIndex := LineIndex + 1;
  950.     END (*OUT*);
  951.   
  952.   
  953.   BEGIN (*UNFLAG*)
  954.     RCHN := 0;
  955.     with tmpl do
  956.       begin
  957.         HasBoldPrinting := false;
  958.         HasOverPrinting := false;
  959.         HasUnderScore := false;
  960.         BoldFlag := EmptyFlags;
  961.         USflag := EmptyFlags;
  962.       end;
  963.     WITH L DO
  964.       BEGIN
  965.         FUP := 0 (* NO CASE FORCING *);   
  966.         LineIndex := 1;   PQEND := FALSE;
  967.         if len < linlen then
  968.           lin[len+1] := ' ';
  969.         WHILE LineIndex <= LEN DO
  970.           BEGIN
  971.             IF NOT (LIN[LineIndex] IN ['''', '"', ')'])   THEN PQEND := FALSE;
  972.             CASE CharCategory[LIN[LineIndex]] OF 
  973.               UpArrow:
  974.                 BEGIN
  975.                   IF FLAG AND (LineIndex < LEN) THEN
  976.                     IF CharCategory[LIN[LineIndex + 1]] IN [ucLetter, lcLetter]
  977.                     THEN
  978.                       BEGIN
  979.                         LineIndex := LineIndex + 1;
  980.                         CASE FUP OF
  981.                           0, 
  982.                           1: LIN[LineIndex] := MAKEUPPER[LIN[LineIndex]];
  983.                           2: LIN[LineIndex] := MAKELOWER[LIN[LineIndex]]
  984.                         END
  985.                       END;
  986.                   OUT(LIN[LineIndex]);
  987.                 END;
  988.               ucLetter:
  989.                 begin
  990.                   if (FUP = 2) or ((FUP = 0) and LOWER) then
  991.                     repeat
  992.                       lin[LineIndex] := MakeLower[LIN[LineIndex]];
  993.                       out(lin[LineIndex])
  994.                     until not (CharCategory[LIN[LineIndex]] 
  995.                                                        in [ucLetter, lcLetter])
  996.                   else
  997.                     repeat
  998.                       out(lin[LineIndex])
  999.                     until (CharCategory[LIN[LineIndex]] <> ucLetter);
  1000.                 end;
  1001.               lcLetter:
  1002.                 begin
  1003.                   if (FUP = 1) or ((FUP = 0) and NOT LOWER) then
  1004.                     repeat
  1005.                       lin[LineIndex] := MakeUpper[LIN[LineIndex]];
  1006.                       out(lin[LineIndex])
  1007.                     until not (CharCategory[LIN[LineIndex]] 
  1008.                                                       in [ucLetter, lcLetter])
  1009.                   else
  1010.                     repeat
  1011.                       out(lin[LineIndex])
  1012.                     until (CharCategory[LIN[LineIndex]] <> lcLetter); 
  1013.                 end;
  1014.               LeftAngle:
  1015.                 begin
  1016.                   IF FLAGCAPS THEN 
  1017.                     BEGIN
  1018.                       FUP := FUP + 1; 
  1019.                       IF FUP = 3 THEN FUP := 1;
  1020.                       LineIndex := LineIndex + 1;
  1021.                     END
  1022.                   else
  1023.                     out(lin[LineIndex]);
  1024.                 end;
  1025.               EndSentence:
  1026.                 begin
  1027.                   IF PERIOD   THEN PQEND := TRUE;
  1028.                   OUT(LIN[LineIndex]);
  1029.                 end;
  1030.               UnderScore:
  1031.                 begin
  1032.                   LineIndex := LineIndex + BoolOrd(ESCCHR);
  1033.                   OUT(LIN[LineIndex]);
  1034.                 end;
  1035.               NumberSign:
  1036.                 begin
  1037.                   IF FLAGSIG THEN
  1038.                     BEGIN
  1039.                       OVER := UNDL;
  1040.                       UNDL := UNDL AND USB;
  1041.                       OUT(' ');
  1042.                       UNDL := OVER;
  1043.                     END
  1044.                   else
  1045.                     out(lin[LineIndex]);
  1046.                 end;
  1047.               BackSlash:
  1048.                 begin
  1049.                   IF FLAGOVER THEN
  1050.                     BEGIN 
  1051.                       LineIndex := LineIndex + 1;   
  1052.                       tmpl.HasOverPrinting := true;
  1053.                       tmpl.OverLin[rchn] := Lin[LineIndex];
  1054.                       LineIndex := LineIndex + 1;
  1055.                     END
  1056.                   else
  1057.                     OUT(LIN[LineIndex]);
  1058.                 end;
  1059.               MiscChar:
  1060.                 begin
  1061.                   IF NOT (UL OR LOWER)
  1062.                   THEN LIN[LineIndex] := MAKEUPPER[LIN[LineIndex]];
  1063.                   OUT(LIN[LineIndex]);
  1064.                 end;
  1065.               ArithChar:
  1066.                 OUT(LIN[LineIndex]);
  1067.               OtherChar:
  1068.                 LineIndex := LineIndex + 1
  1069.             END;
  1070.           END;
  1071.         TMPL.LEN := RCHN; 
  1072.       END;
  1073.   END (*UNFLAG*);
  1074.  
  1075.  
  1076. PROCEDURE ROMAN(N: INTEGER);
  1077.  
  1078.   var
  1079.     i, j: integer;
  1080.     
  1081.   BEGIN
  1082.     j := 1;
  1083.     if n <= 10000 then
  1084.       for i := 1 to 13 do
  1085.         begin
  1086.           while n >= RomanValue[i] do
  1087.             with syl do
  1088.               begin
  1089.                 len := len + 1;
  1090.                 lin[len] := RomanChars[j];
  1091.                 lin[len+1] := RomanChars[j+1];
  1092.                 len := len + BoolOrd(RomanChars[j+1] <> ' ');
  1093.                 n := n - RomanValue[i];
  1094.               end;
  1095.           j := j + 2;
  1096.         end;
  1097.   END (*ROMAN*);
  1098.  
  1099.  
  1100. PROCEDURE DOFMT(F, N: INTEGER);
  1101.  
  1102.   var
  1103.     savesc: boolean;
  1104.     
  1105.   BEGIN
  1106.     SYL.LEN := 0;
  1107.     savesc := escchr;
  1108.     escchr := true;
  1109.     IF (F >= 0) AND (F <= 4)
  1110.     THEN
  1111.       CASE F OF
  1112.         0:
  1113.           BEGIN
  1114.             SYL.LEN := 1;   ADDNUM(N, SYL);   SYL.LEN := SYL.LEN - 1;
  1115.             UNFLAG(SYL, FALSE);   
  1116.           END;
  1117.         1: 
  1118.           BEGIN 
  1119.              SYL.LEN := 2;
  1120.              SYL.LIN[1] := '_';
  1121.              SYL.LIN[2] := chr(N) ;  { Cyber was  CHR(N MOD CHRMOD)  }
  1122.            END;
  1123.         2:
  1124.            BEGIN
  1125.              SYL.LEN := 2;
  1126.              SYL.LIN[1] := '_';
  1127.              SYL.LIN[2] := chr(N) ;  { Cyber did lower case shift }
  1128.            END;
  1129.  
  1130.         3, 4: ROMAN(N);
  1131.       END;
  1132.     IF SYL.LEN > 0   THEN begin UNFLAG(SYL, (F = 4));  ADDWORD;  end;
  1133.     escchr := savesc;
  1134.   END (*DOFMT*);
  1135.  
  1136.  
  1137. PROCEDURE BREAK;
  1138.  
  1139.   BEGIN PUTLINE; END (*BREAK*);
  1140.  
  1141.  
  1142. PROCEDURE CR; 
  1143.  
  1144.   BEGIN PUTBLANK(VAL[VSP] - 1) END (*CR*);
  1145.  
  1146.  
  1147. PROCEDURE ENDPARA;
  1148.  
  1149.   BEGIN BREAK;   CR; END (*ENDPARA*);
  1150.  
  1151.  
  1152. PROCEDURE BLANKLINE;
  1153.  
  1154.   BEGIN
  1155.     IF (NOT AP)   THEN BEGIN ENDPARA;   PUTBLANK(1)  END
  1156.     ELSE PushText(ParagMacP);
  1157.   END (*BLANKLINE*);
  1158.  
  1159.  
  1160. PROCEDURE ENDLINE;
  1161.  
  1162.   BEGIN
  1163.     IF SUP   THEN CLRLINE;
  1164.     IF FORCE OR (NOT FILL) OR OTL.CENTER   THEN ENDPARA;
  1165.   END (*ENDLINE*);
  1166.  
  1167.  
  1168. PROCEDURE FIN;
  1169.  
  1170.   BEGIN PUTLINE;   DOTOP; END (*FIN*);
  1171.  
  1172.  
  1173. PROCEDURE PUTWORD;
  1174.  
  1175.   BEGIN UNFLAG(SYL, LOWER);   ADDWORD; END (*PUTWORD*);
  1176.  
  1177.  
  1178. PROCEDURE PUTVAR;
  1179.  
  1180.   VAR
  1181.                   N: INTEGER;
  1182.                   S: SIGN;
  1183.  
  1184.   BEGIN
  1185.     GETNUM(S, N);
  1186.     IF S <> INVALID
  1187.     THEN
  1188.       BEGIN
  1189.         IF SHOWEXPR THEN
  1190.           BEGIN
  1191.             SYL.LEN := 1;   ADDNUM(N, SYL);
  1192.             SYL.LEN := SYL.LEN - 1;
  1193.             PUTWORD;
  1194.           END
  1195.       END
  1196.     ELSE PUTWORD;
  1197.   END (*PUTVAR*);
  1198.     
  1199.