home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / TURBOPAS / TPF.ZIP / TPFSTM.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1985-05-27  |  12.8 KB  |  556 lines

  1. {[B+]}
  2.  
  3. {*-----------------------------*
  4.  | Parser forward declarations |
  5.  *-----------------------------*}
  6.  
  7.  
  8. procedure Statement;
  9.     forward;
  10.  
  11.  
  12. procedure Expression;
  13.     forward;
  14.  
  15.  
  16. procedure Expr_List(BreakAt: Integer);
  17.     forward;
  18.  
  19.  
  20. procedure Scan_Type;
  21.     forward;
  22.  
  23.  
  24. procedure Do_Block;
  25.     forward;
  26.  
  27.  
  28. procedure Ident_List;
  29. {
  30. ! Scan a list of identifiers separated by commas. Formatting is allowed
  31. ! to continue if a comma is missing 
  32. }
  33.     begin
  34.  
  35.     while Sym = Identifier do
  36.         begin
  37.         Next_Sym;
  38.  
  39.         if Sym = Comma then
  40.             begin
  41.             Next_Sym;
  42.             Set_Symbol_Break(0);
  43.             end;
  44.         end;
  45.  
  46.     end; {Ident_List}
  47.  
  48.  
  49. procedure Constant; {scan a constant}
  50.     begin
  51.     if Sym in [Plus, Minus] then Next_Sym;
  52.     check(Constants - [Plus, Minus]);
  53.     Next_Sym;
  54.     end; {Constant}
  55.  
  56.  
  57. procedure Variable; {scan off a variable, doesn't check much}
  58.     begin
  59.  
  60.     while Sym in [Identifier, Period, Pointer, Open_Brack] do
  61.         begin
  62.         if Sym = Open_Brack then
  63.             begin
  64.             Next_Sym;
  65.             Expr_List(0);
  66.             Check_Sym(Close_Brack);
  67.             end
  68.         else Next_Sym;
  69.         end;
  70.  
  71.     end; {Variable}
  72.  
  73.  
  74. procedure Const_List; {scan a list of constants, as for case labels}
  75.     begin
  76.  
  77.     while Sym in Constants do
  78.         begin
  79.         Constant;
  80.  
  81.         if Sym = Subrange then
  82.             begin
  83.             Next_Sym;
  84.             Constant;
  85.             end;
  86.  
  87.         if Sym = Comma then
  88.             begin
  89.             Next_Sym;
  90.             Set_Symbol_Break(0);
  91.             end;
  92.         end;
  93.  
  94.     end; {Const_List}
  95.  
  96.  
  97. procedure Factor;
  98.     begin {scan a factor in an expression, ignores precedence}
  99.     if Sym = Open_Paren then
  100.         begin
  101.         Next_Sym;
  102.         Expr_List(0); {hack to allow structured constants}
  103.         Check_Sym(Close_Paren);
  104.         if Sym = Comma then Set_Symbol_Break(3);
  105.         end
  106.     else if Sym = Open_Brack then
  107.         begin {set expression}
  108.         Next_Sym;
  109.  
  110.         while Sym in Expr_Beg_Sys do
  111.             begin
  112.             Expr_List(1);
  113.             if Sym = Subrange then Next_Sym;
  114.             end;
  115.         Check_Sym(Close_Brack);
  116.  
  117.         end
  118.     else if Sym = Identifier then
  119.         begin
  120.         Variable;
  121.  
  122.         if Sym = Open_Paren then
  123.             begin
  124.             Put_Sym;
  125.             if Write_Col <= Three_Fourth_Line then
  126.                 Indent_Plus(Write_Col - Indent)
  127.             else Indent_Plus(0);
  128.             Next_Sym;
  129.             Expr_List(3);
  130.             Check_Sym(Close_Paren);
  131.             Undent;
  132.             end
  133.         end
  134.     else Constant;
  135.     end; {Factor}
  136.  
  137.  
  138. procedure Expression; {scan an expression}
  139.     begin
  140.  
  141.     while Sym in Expr_Beg_Sys do
  142.         begin
  143.         if Sym in [Plus, Minus, Not_Sym, Pointer] then Next_Sym;
  144.         Factor;
  145.  
  146.         if Sym in [And_Sym, Or_Sym, Shl_Sym, Shr_Sym, Xor_Sym] then
  147.             begin
  148.             Next_Sym;
  149.             Set_Symbol_Break(3);
  150.             end
  151.         else if Sym in Rel_Ops then
  152.             begin
  153.             Next_Sym;
  154.             Set_Symbol_Break(2);
  155.             end
  156.         else if Sym in Arith_Ops then
  157.             begin
  158.             Next_Sym;
  159.             Set_Symbol_Break(1);
  160.             end;
  161.         end; {while}
  162.     end; {Expression}
  163.  
  164.  
  165. procedure Expr_List {(BreakAt: Integer)} ;
  166.     begin
  167.  
  168.     while Sym in Expr_Beg_Sys + [Comma] do
  169.         begin
  170.         if Sym in Expr_Beg_Sys then Expression;
  171.  
  172.         if (Sym = Comma) or (Sym = Colon) then
  173.             begin
  174.             Next_Sym;
  175.             Set_Symbol_Break(BreakAt);
  176.             end;
  177.         end;
  178.  
  179.     end; {Expr_List}
  180.  
  181.  
  182. procedure Stat_List; {process a list of statements}
  183.  
  184.     var
  185.         Stat_Terms: Set_Of_Syms;
  186.         Stat_Start: Col_Log;
  187.         First_Stat: Boolean;
  188.  
  189.     begin
  190.     Stat_Terms := Stat_Set + [Semicolon];
  191.     First_Stat := true;
  192.  
  193.     repeat
  194.         Log_Symbol_Start(Stat_Start);
  195.         Statement;
  196.  
  197.         {note: may or may not have semicolon}
  198.         Terminal_Semicolon;
  199.         if (Stats_Per_Line > 1) and not First_Stat then
  200.             Bunch_Statement(Stat_Start);
  201.  
  202.         {split like this so following comments don't screw up}
  203.         if Sym = Semicolon then Get_Sym;
  204.         First_Stat := false;
  205.     until not (Sym in Stat_Terms);
  206.  
  207.     end; {State_List}
  208.  
  209.  
  210. procedure Do_Begin(Proc_Block: Boolean);
  211. {
  212. ! Handle a begin - end block, indenting if requested by setting proc_block
  213. ! true
  214. }
  215.     var
  216.     Trim: Integer;            {amount to indent}
  217.  
  218.     begin
  219.     Reset_Char_Count;
  220.     if Proc_Block then Trim := Tab_Spaces else Trim := 0;
  221.     Next_On_New_Line(0, Trim);
  222.     Stat_List;
  223.     Undent;
  224.     Format_Line(Indent);
  225.     Check_Sym(End_Sym);
  226.     end; {Do_Begin}
  227.  
  228.  
  229. procedure Do_Assign_Call; {either assignment or call}
  230.     begin
  231.     Format_Line(Indent);
  232.     Indent_Plus(Continue_Spaces);
  233.     Next_Sym;
  234.  
  235.     if Sym = Colon then
  236.         begin
  237.         Next_Sym;
  238.         Statement;
  239.         end
  240.     else
  241.         begin
  242.         Variable;
  243.  
  244.         if Sym = Becomes then
  245.             begin
  246.             Next_Sym;
  247.  
  248.             if Write_Col < Three_Fourth_Line then
  249.                 Indent_Plus(Write_Col - Indent + 1)
  250.             else
  251.                 begin
  252.                 Indent_Plus(0);
  253.                 Set_Symbol_Break(0);
  254.                 end;
  255.             Expression;
  256.  
  257.             Terminal_Semicolon;
  258.             Undent;
  259.             end
  260.         else if Sym = Open_Paren then
  261.             begin
  262.             Next_Sym;
  263.  
  264.             if Write_Col <= Three_Fourth_Line then
  265.                 Indent_Plus(Write_Col - Indent)
  266.             else Indent_Plus(0);
  267.             Expr_List(3);
  268.  
  269.             Check_Sym(Close_Paren);
  270.             Terminal_Semicolon;
  271.             Undent;
  272.             end
  273.         else Terminal_Semicolon;
  274.  
  275.         Undent;
  276.         end;
  277.     end; {Do_Assign_Call}
  278.  
  279.  
  280. procedure Do_Goto; {goto statement}
  281.     begin
  282.     Format_Line(Indent);
  283.     Next_Sym;
  284.     if Sym in [Number, Identifier] then Next_Sym
  285.     else Abort(Syntax);
  286.     Terminal_Semicolon;
  287.     end; {Do_Goto}
  288.  
  289.  
  290. procedure Do_Inline;
  291.     begin
  292.     Format_Line(Indent);
  293.     Indent_Plus(Continue_Spaces);
  294.     Next_Sym;
  295.     if Sym <> Open_Paren then Abort(Syntax);
  296.  
  297.     repeat
  298.         Next_Sym;
  299.  
  300.         if Sym = Mult then
  301.             begin
  302.             Next_Sym;
  303.             if Sym in Constants then Constant;
  304.             end
  305.         else Constant;
  306.     until Sym <> Divide;
  307.  
  308.     Check_Sym(Close_Paren);
  309.     Terminal_Semicolon;
  310.     Undent;
  311.     end; {Do_Inline}
  312.  
  313.  
  314. procedure Do_While; {while statement}
  315.  
  316.     var
  317.         While_Start: Col_Log;           {start of statement}
  318.         Start_Line, End_Line: Integer;  {statement lines}
  319.         Successful: Boolean;            {bunching went}
  320.  
  321.     begin
  322.     Reset_Char_Count;
  323.     Format_Line(Indent);
  324.     Next_Sym;
  325.  
  326.     if Write_Col < Three_Fourth_Line then Indent_Plus(Write_Col - Indent + 1)
  327.     else Indent_Plus(Continue_Spaces);
  328.  
  329.     Start_Line := Current_Line;
  330.     Expression;
  331.     Check_Sym(Do_Sym);
  332.     Undent;
  333.     Indent_Plus(Tab_Spaces);
  334.     End_Line := Current_Line;
  335.     Log_Symbol_Start(While_Start);
  336.     Stat_Indent := Indent;
  337.     Statement;
  338.     if Bunching and (Start_Line = End_Line) then
  339.         Bunch(While_Start, Successful);
  340.     Undent;
  341.     end; {Do_While}
  342.  
  343.  
  344. procedure Do_With; {with statement}
  345.  
  346.     var
  347.         Start_Line, End_Line: Integer;  {starting and ending lines of heading}
  348.         With_Start: Col_Log;            {start of statement}
  349.         Successful: Boolean;            {bunching went}
  350.  
  351.     begin
  352.     Reset_Char_Count;
  353.     Format_Line(Indent);
  354.     Next_Sym;
  355.  
  356.     if Write_Col < Three_Fourth_Line then Indent_Plus(Write_Col - Indent + 1)
  357.     else Indent_Plus(Continue_Spaces);
  358.  
  359.     Start_Line := Current_Line;
  360.     Expr_List(3);
  361.     Check_Sym(Do_Sym);
  362.     Undent;
  363.     Indent_Plus(Tab_Spaces);
  364.     Stat_Indent := Indent;
  365.     End_Line := Current_Line;
  366.     Log_Symbol_Start(With_Start);
  367.     Statement;
  368.     if Bunching and (Start_Line = End_Line) then
  369.         Bunch(With_Start, Successful);
  370.     Undent;
  371.     Make_White;
  372.     end; {Do_With}
  373.  
  374.  
  375. procedure Do_If(Prev_Else: Boolean {set if previous sym was else} );
  376.  
  377.     var
  378.         If_Start: Col_Log;              {start of if statement}
  379.         Start_Line, End_Line: Integer;  {statement lines}
  380.         Successful: Boolean;            {bunching went}
  381.  
  382.     begin {if statement}
  383.     Reset_Char_Count;
  384.     if not Prev_Else then Format_Line(Indent);
  385.     Next_Sym;
  386.  
  387.     if Write_Col < Three_Fourth_Line then Indent_Plus(Write_Col - Indent + 1)
  388.     else Indent_Plus(Continue_Spaces);
  389.  
  390.     Start_Line := Current_Line;
  391.     Expression;
  392.     Check_Sym(Then_Sym);
  393.     Undent;
  394.     Indent_Plus(Tab_Spaces);
  395.     End_Line := Current_Line;
  396.     Log_Symbol_Start(If_Start);
  397.     Statement;
  398.     if Bunching and (Start_Line = End_Line) then Bunch(If_Start, Successful);
  399.     Undent;
  400.     Stat_Indent := Indent;
  401.  
  402.     if Sym = Else_Sym then
  403.         begin
  404.         Format_Line(Indent);
  405.         Next_Sym;
  406.  
  407.         if Sym = If_Sym then Do_If(true)
  408.         else
  409.             begin
  410.             Indent_Plus(Tab_Spaces);
  411.             Log_Symbol_Start(If_Start);
  412.             Statement;
  413.             if Bunching then Bunch(If_Start, Successful);
  414.             Undent;
  415.             end;
  416.         end;
  417.     end; {Do_If}
  418.  
  419.  
  420. procedure Do_Case;
  421.  
  422.     var
  423.         Case_Start: Col_Log;            {start of case}
  424.         Successful: Boolean;            {bunching successful}
  425.         Lab_Start, LabEnd: Integer;     {label list lines}
  426.  
  427.     begin {case_statement}
  428.     Reset_Char_Count;
  429.     Format_Line(Indent);
  430.     Next_Sym;
  431.  
  432.     if Write_Col < Three_Fourth_Line then Indent_Plus(Write_Col - Indent + 1)
  433.     else Indent_Plus(Continue_Spaces);
  434.  
  435.     Expression;
  436.     Check_Sym(Of_Sym);
  437.     Undent;
  438.     Indent_Plus(Tab_Spaces);
  439.     Stat_Indent := Indent;
  440.  
  441.     while not (Sym in [End_Sym, Else_Sym]) do
  442.         begin
  443.         if Sym in Constants then
  444.             begin
  445.             Format_Line(Indent);
  446.             Lab_Start := Current_Line;
  447.             Const_List;
  448.             Check_Sym(Colon);
  449.             LabEnd := Current_Line;
  450.             Indent_Plus(Tab_Spaces);
  451.             Log_Symbol_Start(Case_Start);
  452.             Statement;
  453.             if Bunching and (Lab_Start = LabEnd) then
  454.                 Bunch(Case_Start, Successful);
  455.             Undent;
  456.             Stat_Indent := Indent;
  457.             end; {if sym in constants}
  458.  
  459.         if Sym = Semicolon then Next_Sym;
  460.         check(Constants + [End_Sym, Semicolon, Else_Sym]);
  461.         end; {while}
  462.  
  463.     if Sym = Else_Sym then
  464.         begin
  465.         Next_On_New_Line(0, Tab_Spaces);
  466.         Log_Symbol_Start(Case_Start);
  467.         Stat_List;
  468.         if Bunching then Bunch(Case_Start, Successful);
  469.         Undent;
  470.         end;
  471.  
  472.     Format_Line(Indent);
  473.     Check_Sym(End_Sym);
  474.     Undent;
  475.     end; {Do_Case}
  476.  
  477.  
  478. procedure Do_Repeat;
  479.     begin {repeat statement}
  480.     Reset_Char_Count;
  481.     Next_On_New_Line(0, Tab_Spaces);
  482.     Stat_List;
  483.     Undent;
  484.     Stat_Indent := Indent;
  485.     Format_Line(Indent);
  486.     Check_Sym(Until_Sym);
  487.  
  488.     if Write_Col < Three_Fourth_Line then Indent_Plus(Write_Col - Indent + 1)
  489.     else Indent_Plus(Continue_Spaces);
  490.  
  491.     Expression;
  492.     Terminal_Semicolon;
  493.     Undent;
  494.     end; {Do_Repeat}
  495.  
  496.  
  497. procedure Do_For;
  498.  
  499.     var
  500.         Start_Line, End_Line: Integer;  {starting and ending lines of header}
  501.         For_Start: Col_Log;             {start of controlled statement}
  502.         Successful: Boolean;            {bunching went}
  503.  
  504.     begin {for statement}
  505.     Reset_Char_Count;
  506.     Next_On_New_Line(0, Continue_Spaces);
  507.     Start_Line := Current_Line;
  508.     Check_Sym(Identifier);
  509.     Check_Sym(Becomes);
  510.     Expression;
  511.     check([To_Sym, Downto_sym]);
  512.     Next_Sym;
  513.     Expression;
  514.     Check_Sym(Do_Sym);
  515.     Undent;
  516.     Indent_Plus(Tab_Spaces);
  517.     End_Line := Current_Line;
  518.     Log_Symbol_Start(For_Start);
  519.     Statement;
  520.     if Bunching and (Start_Line = End_Line) then
  521.         Bunch(For_Start, Successful);
  522.     Undent;
  523.     end; {Do_For}
  524.  
  525.  
  526. procedure Statement; {handle a (possibly empty) statement}
  527.  
  528.     begin
  529.     Stat_Indent := Indent;
  530.  
  531.     if Sym = Number then
  532.         begin
  533.         Indent_Plus( - Tab_Spaces);
  534.         Format_Line(Indent);
  535.         Next_Sym;
  536.         Check_Sym(Colon);
  537.         Undent;
  538.         end;
  539.  
  540.     if Sym in (Stat_Set - [Number]) then
  541.         case Sym of
  542.             Begin_Sym: Do_Begin(false);
  543.             Case_Sym: Do_Case;
  544.             For_Sym: Do_For;
  545.             Goto_Sym: Do_Goto;
  546.             Identifier: Do_Assign_Call;
  547.             If_Sym: Do_If(false);
  548.             Inline_Sym: Do_Inline;
  549.             Repeat_Sym: Do_Repeat;
  550.             While_Sym: Do_While;
  551.             With_Sym: Do_With;
  552.             end; {case}
  553.  
  554.     Stat_Indent := Indent;
  555.     end; {Statement}
  556.