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

  1. {[B+]}
  2.  
  3. {*-----------------------*
  4.  | Formal Parameter List |
  5.  *-----------------------*}
  6.  
  7.  
  8. procedure Parameters;
  9. {
  10. ! Format a formal parameter list: if they start less than halfway
  11. ! across the page, they are all lined up with the first parameter,
  12. ! on successive lines. If they start more than halfway across the
  13. ! page, they begin on the next line, indented double the usual
  14. ! (arbitrary)
  15. }
  16.     begin
  17.     if Write_Col > One_Half_Line then Format_Line(Indent + 2 * Tab_Spaces);
  18.     Next_Sym;
  19.     Indent_Plus(Write_Col - Indent);
  20.  
  21.     while Sym in [Identifier, Var_Sym] do
  22.         begin
  23.         if Sym <> Identifier then Next_Sym;
  24.         if Sym <> Identifier then Abort(Syntax);
  25.         Indent_Plus(Continue_Spaces);
  26.         Ident_List;
  27.         Undent;
  28.  
  29.         if Sym = Colon then
  30.             begin
  31.             Next_Sym;
  32.             Scan_Type;
  33.             end;
  34.  
  35.         if Sym = Semicolon then
  36.             begin
  37.             Next_Sym;
  38.             Format_Line(Indent);
  39.             end;
  40.         end;
  41.  
  42.     Check_Sym(Close_Paren);
  43.     Terminal_Semicolon;
  44.     Undent;
  45.     Stat_Indent := Indent;
  46.     end; {Parameters}
  47.  
  48.  
  49. procedure Field_List;
  50.  
  51.   { Scan field list of type specification }
  52.  
  53.     var
  54.         Invar_Part: Boolean;            {true if there was an invarient part}
  55.         Label_Start, Label_End: Integer; {lines for case label bunching}
  56.         Case_Start: Col_Log;            {start of a variant}
  57.         Successful: Boolean;            {dummy param}
  58.  
  59.     begin
  60.     Invar_Part := false;
  61.  
  62.     while Sym = Identifier do
  63.         begin
  64.         Invar_Part := true;
  65.         Indent_Plus(Continue_Spaces);
  66.         Ident_List;
  67.         Check_Sym(Colon);
  68.         Undent;
  69.         Scan_Type;
  70.         if Sym = Semicolon then Next_Sym;
  71.         if Sym = Identifier then Format_Line(Indent);
  72.         end;
  73.  
  74.     if Sym = Case_Sym then
  75.         begin {case}
  76.         if Invar_Part then Format_Line(Indent);
  77.         Next_Sym;
  78.         Indent_Plus(Continue_Spaces);
  79.  
  80.         if Sym = Identifier then Next_Sym
  81.         else Scan_Type;
  82.  
  83.         if Sym = Colon then
  84.             begin
  85.             Next_Sym;
  86.             Scan_Type
  87.             end;
  88.  
  89.         Check_Sym(Of_Sym);
  90.         Undent;
  91.         Indent_Plus(Tab_Spaces);
  92.         Stat_Indent := Indent;
  93.         Format_Line(Indent);
  94.  
  95.         repeat {variant part}
  96.             Label_Start := Current_Line;
  97.             Const_List;
  98.             Check_Sym(Colon);
  99.             Label_End := Current_Line;
  100.             Indent_Plus(Tab_Spaces);
  101.             Stat_Indent := Indent;
  102.             Log_Symbol_Start(Case_Start);
  103.             Format_Line(Indent);
  104.             Check_Sym(Open_Paren);
  105.             Indent_Plus(1); {compensate for paren}
  106.             Field_List;
  107.             Undent;
  108.             Check_Sym(Close_Paren);
  109.             Undent;
  110.             Stat_Indent := Indent;
  111.             if Sym = Semicolon then Next_Sym;
  112.             if Bunching and (Label_Start = Label_End) then
  113.                 Bunch(Case_Start, Successful);
  114.             if not (Sym in [End_Sym, Close_Paren]) then Format_Line(Indent);
  115.         until not (Sym in Constants);
  116.  
  117.         Undent;
  118.         Stat_Indent := Indent;
  119.         end {case}
  120.     end; {Field_List}
  121.  
  122.  
  123. procedure Record_Type(Packed_Start: Col_Log);
  124. {
  125. ! Handle a record type, includes a kluge to move "packed" down to the
  126. ! next line
  127. }
  128.     begin
  129.     Indent_Plus(Tab_Spaces);
  130.  
  131.     with Packed_Start do
  132.         if Formatting and (Log_Char <> 0) and
  133.            (Char_Count - Log_Char < Buf_Size) then
  134.  
  135.             with Unwritten[Log_Char mod Buf_Size] do
  136.                 begin {note that this kluge assumes the logged point has
  137.                        become a space so it can be changed to a newline}
  138.                 Action_Is := Begin_Line;
  139.                 Spacing := Indent;
  140.                 Write_Col := Indent + Write_Col - Log_Col;
  141.                 Current_Line := Current_Line + 1;
  142.                 end
  143.  
  144.         else Format_Line(Indent);
  145.  
  146.     Next_Sym;
  147.     Indent_Plus(Tab_Spaces);
  148.     Stat_Indent := Indent;
  149.     Format_Line(Indent);
  150.     Field_List;
  151.     Undent;
  152.     Format_Line(Indent);
  153.     Check_Sym(End_Sym);
  154.     Terminal_Semicolon;
  155.     Undent;
  156.     end; {Record_Type}
  157.  
  158.  
  159. procedure Array_Type;
  160. {
  161. ! Format an array type
  162. }
  163.     begin
  164.     Indent_Plus(Tab_Spaces);
  165.     Next_Sym;
  166.     Set_Symbol_Break(0);
  167.     Check_Sym(Open_Brack);
  168.  
  169.     while Sym in Constants do
  170.         begin
  171.         Constant;
  172.  
  173.         if Sym = Subrange then
  174.             begin
  175.             Next_Sym;
  176.             Constant;
  177.             end;
  178.  
  179.         if (Sym = Comma) or (Sym = Semicolon) then
  180.             begin
  181.             Next_Sym;
  182.             Set_Symbol_Break(0);
  183.             end;
  184.         end; {while}
  185.  
  186.     Check_Sym(Close_Brack);
  187.     Check_Sym(Of_Sym);
  188.     Scan_Type;
  189.     Terminal_Semicolon;
  190.     Undent;
  191.     end; {Array_Type}
  192.  
  193.  
  194. procedure String_Type;
  195. {
  196. ! Handle the Turbo string type -- string[constant]
  197. }
  198.     begin
  199.     Next_Sym;
  200.     Set_Symbol_Break(0);
  201.     Check_Sym(Open_Brack);
  202.     Constant;
  203.     Check_Sym(Close_Brack);
  204.     end;
  205.  
  206.  
  207. procedure Enum_Type;
  208. {
  209. ! Handle an enumeration type, align to the right of the opening
  210. ! parenthesis if there is room, otherwise use normal continuation
  211. }
  212.     begin
  213.     Next_Sym;
  214.  
  215.     if Write_Col <= Three_Fourth_Line then Indent_Plus(Write_Col - Indent)
  216.     else Indent_Plus(Continue_Spaces);
  217.  
  218.     Ident_List;
  219.     Check_Sym(Close_Paren);
  220.     Terminal_Semicolon;
  221.     Undent;
  222.     end; {Enum_Type}
  223.  
  224.  
  225. procedure Scan_Type;
  226. {
  227. ! Scan a type, formatting differs for each one
  228. }
  229.  
  230.     var
  231.         Packed_Start: Col_Log;
  232.  
  233.     begin
  234.     Indent_Plus(Continue_Spaces);
  235.  
  236.     if Sym = Packed_Sym then
  237.         begin {mark start of 'packed' - must actually be a space}
  238.         Log_Symbol_Start(Packed_Start);
  239.         Next_Sym;
  240.         end
  241.     else Packed_Start.Log_Char := 0;
  242.  
  243.     Undent;
  244.     check(Type_Beg_Sys);
  245.  
  246.     case Sym of
  247.         Open_Paren: Enum_Type;
  248.         Array_Sym: Array_Type;
  249.         String_Sym: String_Type;
  250.  
  251.         File_Sym:
  252.             begin
  253.             Next_Sym;
  254.  
  255.             if Sym = Of_Sym then
  256.                 begin
  257.                 Next_Sym;
  258.                 Scan_Type;
  259.                 end;
  260.             end;
  261.  
  262.         Set_Sym:
  263.             begin
  264.             Next_Sym;
  265.             Check_Sym(Of_Sym);
  266.             Scan_Type;
  267.             end;
  268.  
  269.         Identifier, Number, Plus, Minus, Str_Const:
  270.             begin {simple or subrange}
  271.             Constant;
  272.             if Sym = Subrange then
  273.                 begin
  274.                 Next_Sym;
  275.                 Constant;
  276.                 end;
  277.             end;
  278.  
  279.         Pointer:
  280.             begin
  281.             Next_Sym;
  282.             Scan_Type;
  283.             end;
  284.  
  285.         Record_Sym: Record_Type(Packed_Start);
  286.         end; {case}
  287.  
  288.     Stat_Indent := Indent;
  289.     end; {Scan_Type}
  290.  
  291.  
  292. procedure Do_Label; {label declaration}
  293.     begin
  294.     Reset_Char_Count;
  295.     Next_On_New_Line(1, Tab_Spaces);
  296.     Format_Line(Indent);
  297.  
  298.     while Sym in [Number, Identifier] do
  299.         begin
  300.         Next_Sym;
  301.         if Sym = Comma then Next_Sym;
  302.         end; {while}
  303.  
  304.     Check_Sym(Semicolon);
  305.     Undent;
  306.     end;
  307.  
  308.  
  309. procedure Structured_Constant;
  310. (*
  311. ! structured_constant ::= set_constant | array_or_record_constant
  312. !
  313. ! array_or_record_constant ::= '(' array_or_record_element_list ')'
  314. !
  315. ! array_or_record_element_list ::=
  316. !       array_or_record_element [{','|';'} array_or_record_element]
  317. !
  318. ! array_or_record_element ::=
  319. !       | [identifier ':']{constant | array_or_record_constant}
  320. !
  321. | set_constant ::= '[' range [',' range] ']'
  322. !
  323. ! range ::= constant ['..' constant]
  324. *)
  325.  
  326.  
  327.     procedure Array_Or_Record_Constant(BreakAt: Integer);
  328.         begin
  329.  
  330.         repeat
  331.             Next_Sym;
  332.  
  333.             if Sym = Identifier then
  334.                 begin
  335.  
  336.                 Next_Sym;
  337.  
  338.                 if Sym = Colon then
  339.                     begin
  340.                     Next_Sym;
  341.  
  342.                     if Sym = Open_Paren then
  343.                         Array_Or_Record_Constant(BreakAt + 1)
  344.                     else Constant;
  345.  
  346.                     end;
  347.                 end
  348.             else if Sym = Open_Paren then
  349.                 Array_Or_Record_Constant(BreakAt + 1)
  350.             else Constant;
  351.  
  352.         until not ((Sym = Comma) or (Sym = Semicolon));
  353.  
  354.         Check_Sym(Close_Paren);
  355.         end;
  356.  
  357.     begin
  358.  
  359.     if Sym = Open_Paren then Array_Or_Record_Constant(0)
  360.     else if Sym = Open_Brack then {set constant }
  361.         begin
  362.  
  363.         repeat
  364.             Next_Sym;
  365.             Constant;
  366.  
  367.             if Sym = Subrange then
  368.                 begin
  369.                 Next_Sym;
  370.                 Constant;
  371.                 end;
  372.         until Sym <> Comma;
  373.  
  374.         Check_Sym(Close_Brack);
  375.         end
  376.     else Constant;
  377.     end;
  378.  
  379.  
  380. procedure Do_Const;
  381.  
  382.     var
  383.         Const_Start: Col_Log;           {start of particular declaration}
  384.         First_Const: Boolean;           {first constant in decl}
  385.  
  386.     begin {constant declaration}
  387.     In_Declaration := true;
  388.     Reset_Char_Count;
  389.     Next_On_New_Line(1, Tab_Spaces);
  390.     First_Const := true;
  391.  
  392.     while Sym = Identifier do
  393.         begin
  394.         Log_Symbol_Start(Const_Start);
  395.         Format_Line(Indent);
  396.         Next_Sym;
  397.  
  398.         if Sym = Colon then
  399.             begin
  400.             Next_Sym;
  401.             Scan_Type;
  402.             end;
  403.  
  404.         Check_Sym(Equal);
  405.         Structured_Constant;
  406.  
  407.         if Sym = Semicolon then Put_Sym
  408.         else Abort(Syntax);
  409.  
  410.         if (Stats_Per_Line > 1) and not First_Const then
  411.             Bunch_Statement(Const_Start);
  412.         Next_Sym; {split so comments format right}
  413.         First_Const := false;
  414.         end; {while}
  415.  
  416.     Undent;
  417.     Stat_Indent := Indent;
  418.     In_Declaration := false;
  419.     end; {Do_Const}
  420.  
  421.  
  422. procedure Do_Type; {type_declaration}
  423.     begin
  424.     In_Type_Or_Var_Dcl := true;
  425.     In_Declaration := true;
  426.     Next_On_New_Line(1, Tab_Spaces);
  427.  
  428.     while Sym = Identifier do
  429.         begin
  430.         Reset_Char_Count;
  431.         Format_Line(Indent);
  432.         Next_Sym;
  433.         Check_Sym(Equal);
  434.         Scan_Type;
  435.         Check_Sym(Semicolon);
  436.         end; {while}
  437.  
  438.     Undent;
  439.     Stat_Indent := Indent;
  440.     In_Type_Or_Var_Dcl := false;
  441.     In_Declaration := false;
  442.     end; {Do_Type}
  443.  
  444.  
  445. procedure Do_Var;
  446.     begin {var declaration}
  447.     In_Type_Or_Var_Dcl := true;
  448.     In_Declaration := true;
  449.     Next_On_New_Line(1, Tab_Spaces);
  450.  
  451.     while Sym = Identifier do
  452.         begin
  453.         Reset_Char_Count;
  454.         Format_Line(Indent);
  455.         Indent_Plus(Continue_Spaces);
  456.         check([Identifier]);
  457.         Ident_List;
  458.         Check_Sym(Colon);
  459.         Undent;
  460.         Scan_Type;
  461.  
  462.         { Check for "absolute constant[:constant] }
  463.  
  464.         if Sym = Absolute_Sym then
  465.             begin
  466.             Next_Sym;
  467.             Constant;
  468.  
  469.             if Sym = Colon then
  470.                 begin
  471.                 Next_Sym;
  472.                 Constant;
  473.                 end;
  474.             end;
  475.  
  476.         Check_Sym(Semicolon);
  477.         end; {while}
  478.  
  479.     Undent;
  480.     Stat_Indent := Indent;
  481.     In_Type_Or_Var_Dcl := false;
  482.     In_Declaration := false;
  483.     end; {Do_Var}
  484.  
  485.  
  486. procedure Do_Program; {program or processor}
  487.     begin
  488.     Next_On_New_Line(0, Continue_Spaces);
  489.     Check_Sym(Identifier);
  490.  
  491.     if Sym = Open_Paren then
  492.         begin
  493.         Next_Sym;
  494.  
  495.         while Sym = Identifier do
  496.             begin
  497.             Next_Sym;
  498.  
  499.             if Sym = Comma then
  500.                 begin
  501.                 Next_Sym;
  502.                 Set_Symbol_Break(0);
  503.                 end;
  504.             end;
  505.  
  506.         Check_Sym(Close_Paren);
  507.         end;
  508.  
  509.     Check_Sym(Semicolon);
  510.     Undent;
  511.     Indent_Plus(Tab_Spaces);
  512.     Do_Block;
  513.     if Sym = Period then Next_Sym;
  514.     Undent;
  515.     end; {Do_Program}
  516.  
  517.  
  518. procedure Do_Procedure;
  519.  
  520.     var
  521.         Start_Sym: Symbols;
  522.  
  523.     begin
  524.     Reset_Char_Count;
  525.     Start_Sym := Sym;
  526.     Next_On_New_Line(2, Continue_Spaces);
  527.  
  528.     if Start_Sym = Overlay_Sym then
  529.         begin
  530.         Start_Sym := Sym;
  531.  
  532.         if (Sym <> Procedure_Sym) and (Sym <> Function_Sym) then
  533.             Abort(Syntax);
  534.         Next_Sym;
  535.         end;
  536.  
  537.     Check_Sym(Identifier);
  538.     if Sym = Open_Paren then Parameters;
  539.  
  540.     if Start_Sym = Function_Sym then
  541.         if Sym = Colon then
  542.             begin {if function was declared forward, the second appearance has
  543.                    no result type}
  544.             Check_Sym(Colon);
  545.             Check_Sym(Identifier);
  546.             end;
  547.  
  548.     Terminal_Semicolon;
  549.     Undent;
  550.     Check_Sym(Semicolon);
  551.     Indent_Plus(Tab_Spaces);
  552.  
  553.     if Sym in [Extern_Sym, Forward_Sym] then
  554.         begin
  555.         Format_Line(Indent);
  556.         if Sym = Extern_Sym then
  557.             begin
  558.             Next_Sym;
  559.             if Sym <> Str_Const then Abort(Syntax);
  560.             end;
  561.         Next_Sym;
  562.         end
  563.     else if Sym in Block_Beg_Sys then Do_Block
  564.     else Abort(Syntax);
  565.  
  566.     if Sym = Semicolon then
  567.         begin
  568.         Put_Sym;
  569.         Undent;
  570.         Stat_Indent := Indent;
  571.         Next_Sym;
  572.         end
  573.     else Abort(Syntax);
  574.     end; {Do_Procedure}
  575.  
  576.  
  577. procedure Do_Block;
  578. {
  579. ! Scan a block, including types, etc
  580. }
  581.     begin
  582.     Stat_Indent := Indent;
  583.  
  584.     while Sym in Heading_Beg_Sys do
  585.         begin {declarations}
  586.         case Sym of
  587.             Label_Sym: Do_Label;
  588.             Const_sym: Do_Const;
  589.             Type_Sym: Do_Type;
  590.             Var_Sym: Do_Var;
  591.             Overlay_Sym, Procedure_Sym, Function_Sym: Do_Procedure;
  592.             end;
  593.  
  594.         Stat_Indent := Indent;
  595.         end; {while}
  596.  
  597.     if Sym = Begin_Sym then
  598.     Do_Begin(true);
  599.  
  600.     end; {Do_Block}
  601.