home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gnat-2.06-src.tgz / tar.out / fsf / gnat / ada / par-ch13.adb < prev    next >
Text File  |  1996-09-28  |  12KB  |  367 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT COMPILER COMPONENTS                         --
  4. --                                                                          --
  5. --                             P A R . C H 1 3                              --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.26 $                             --
  10. --                                                                          --
  11. --           Copyright (c) 1992,1993,1994 NYU, All Rights Reserved          --
  12. --                                                                          --
  13. -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  14. -- terms of the  GNU General Public License as published  by the Free Soft- --
  15. -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
  16. -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  17. -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  18. -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
  19. -- for  more details.  You should have  received  a copy of the GNU General --
  20. -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
  21. -- to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. --
  22. --                                                                          --
  23. ------------------------------------------------------------------------------
  24.  
  25. separate (Par)
  26. package body Ch13 is
  27.  
  28.    --  Local functions, used only in this chapter
  29.  
  30.    function P_Component_Clause return Node_Id;
  31.    function P_Mod_Clause return Node_Id;
  32.  
  33.    --------------------------------------------
  34.    -- 13.1  Representation Clause (also I.7) --
  35.    --------------------------------------------
  36.  
  37.    --  REPRESENTATION_CLAUSE ::=
  38.    --    ATTRIBUTE_DEFINITION_CLAUSE
  39.    --  | ENUMERATION_REPRESENTATION_CLAUSE
  40.    --  | RECORD_REPRESENTATION_CLAUSE
  41.    --  | AT_CLAUSE
  42.  
  43.    --  ATTRIBUTE_DEFINITION_CLAUSE ::=
  44.    --    for LOCAL_NAME'ATTRIBUTE_DESIGNATOR use EXPRESSION;
  45.    --  | for LOCAL_NAME'ATTRIBUTE_DESIGNATOR use NAME;
  46.  
  47.    --  Note: in Ada 83, the expression must be a simple expression
  48.  
  49.    --  AT_CLAUSE ::= for DIRECT_NAME use at EXPRESSION;
  50.  
  51.    --  Note: in Ada 83, the expression must be a simple expression
  52.  
  53.    --  ENUMERATION_REPRESENTATION_CLAUSE ::=
  54.    --    for first_subtype_LOCAL_NAME use ENUMERATION_AGGREGATE;
  55.  
  56.    --  ENUMERATION_AGGREGATE ::= ARRAY_AGGREGATE
  57.  
  58.    --  RECORD_REPRESENTATION_CLAUSE ::=
  59.    --    for first_subtype_LOCAL_NAME use
  60.    --      record [MOD_CLAUSE]
  61.    --        {COMPONENT_CLAUSE}
  62.    --      end record;
  63.  
  64.    --  Note: for now we allow only a direct name as the local name in the
  65.    --  above constructs. This probably needs changing later on ???
  66.  
  67.    --  The caller has checked that the initial token is FOR
  68.  
  69.    --  Error recovery: cannot raise Error_Resync, if an error occurs,
  70.    --  the scan is repositioned past the next semicolon.
  71.  
  72.    function P_Representation_Clause return Node_Id is
  73.       For_Loc         : Source_Ptr;
  74.       Identifier_Node : Node_Id;
  75.       Rep_Clause_Node : Node_Id;
  76.       Expr_Node       : Node_Id;
  77.  
  78.    begin
  79.       For_Loc := Token_Ptr;
  80.       Scan; -- past FOR
  81.  
  82.       --  Note that the name in a representation clause is always a simple
  83.       --  name, even in the attribute case, see AI-300 which made this so!
  84.  
  85.       Identifier_Node := P_Identifier;
  86.  
  87.       --  Check case of qualified name to give good error message
  88.  
  89.       if Token = Tok_Dot then
  90.          Error_Msg_SC
  91.             ("representation clause requires simple name!");
  92.  
  93.          loop
  94.             exit when Token /= Tok_Dot;
  95.             Scan; -- past dot
  96.             Discard_Junk_Node (P_Identifier);
  97.          end loop;
  98.       end if;
  99.  
  100.       --  Attribute Definition Clause
  101.  
  102.       if Token = Tok_Apostrophe then
  103.          Rep_Clause_Node := New_Node (N_Attribute_Definition_Clause, For_Loc);
  104.          Set_Name (Rep_Clause_Node, Identifier_Node);
  105.          Scan; -- past apostrophe
  106.          Identifier_Node := P_Identifier;
  107.          Set_Chars (Rep_Clause_Node, Chars (Identifier_Node));
  108.          Delete_Node (Identifier_Node);
  109.          T_Use;
  110.  
  111.          Expr_Node := P_Expression_No_Right_Paren;
  112.          Check_Simple_Expression_In_Ada_83 (Expr_Node);
  113.          Set_Expression (Rep_Clause_Node, Expr_Node);
  114.  
  115.       else
  116.          TF_Use;
  117.  
  118.          --  AT follows USE (At Clause)
  119.  
  120.          if Token = Tok_At then
  121.             Scan; -- past AT
  122.             Rep_Clause_Node := New_Node (N_At_Clause, For_Loc);
  123.             Set_Identifier (Rep_Clause_Node, Identifier_Node);
  124.             Expr_Node := P_Expression_No_Right_Paren;
  125.             Check_Simple_Expression_In_Ada_83 (Expr_Node);
  126.             Set_Expression (Rep_Clause_Node, Expr_Node);
  127.  
  128.          --  RECORD follows USE (Record Representation Clause)
  129.  
  130.          elsif Token = Tok_Record then
  131.             Rep_Clause_Node :=
  132.               New_Node (N_Record_Representation_Clause, For_Loc);
  133.             Set_Identifier (Rep_Clause_Node, Identifier_Node);
  134.  
  135.             Push_Scope_Stack;
  136.             Scope.Table (Scope.Last).Etyp := E_Record;
  137.             Scope.Table (Scope.Last).Ecol := Start_Column;
  138.             Scope.Table (Scope.Last).Sloc := Token_Ptr;
  139.             Scan; -- past RECORD
  140.  
  141.             --  Possible Mod Clause
  142.  
  143.             if Token = Tok_At then
  144.                Set_Mod_Clause (Rep_Clause_Node, P_Mod_Clause);
  145.             end if;
  146.  
  147.             Set_Component_Clauses (Rep_Clause_Node, New_List);
  148.  
  149.             --  Loop through component clauses
  150.  
  151.             loop
  152.                if Token not in Token_Class_Name then
  153.                   exit when Check_End;
  154.                end if;
  155.  
  156.                Append (P_Component_Clause,
  157.                  Component_Clauses (Rep_Clause_Node));
  158.             end loop;
  159.  
  160.          --  Left paren follows USE (Enumeration Representation Clause)
  161.  
  162.          elsif Token = Tok_Left_Paren then
  163.             Rep_Clause_Node :=
  164.               New_Node (N_Enumeration_Representation_Clause, For_Loc);
  165.             Set_Identifier (Rep_Clause_Node, Identifier_Node);
  166.             Set_Array_Aggregate (Rep_Clause_Node, P_Aggregate);
  167.  
  168.          --  Some other token follows FOR (invalid representation clause)
  169.  
  170.          else
  171.             Error_Msg_SC ("invalid representation clause");
  172.             raise Error_Resync;
  173.          end if;
  174.       end if;
  175.  
  176.       TF_Semicolon;
  177.       return Rep_Clause_Node;
  178.  
  179.    exception
  180.       when Error_Resync =>
  181.          Resync_Past_Semicolon;
  182.          return Error;
  183.  
  184.    end P_Representation_Clause;
  185.  
  186.    ----------------------
  187.    -- 13.1  Local Name --
  188.    ----------------------
  189.  
  190.    --  Local name is always parsed by its parent. In the case of its use in
  191.    --  pragmas, the check for a local name is handled in Par.Prag and allows
  192.    --  all the possible forms of local name. For the uses in chapter 13, we
  193.    --  currently only allow a direct name, but this should probably change???
  194.  
  195.    ---------------------------
  196.    -- 13.1  At Clause (I.7) --
  197.    ---------------------------
  198.  
  199.    --  Parsed by P_Representation_Clause (13.1)
  200.  
  201.    ---------------------------------------
  202.    -- 13.3  Attribute Definition Clause --
  203.    ---------------------------------------
  204.  
  205.    --  Parsed by P_Representation_Clause (13.1)
  206.  
  207.    ---------------------------------------------
  208.    -- 13.4  Enumeration Representation Clause --
  209.    ---------------------------------------------
  210.  
  211.    --  Parsed by P_Representation_Clause (13.1)
  212.  
  213.    ---------------------------------
  214.    -- 13.4  Enumeration Aggregate --
  215.    ---------------------------------
  216.  
  217.    --  Parsed by P_Representation_Clause (13.1)
  218.  
  219.    ------------------------------------------
  220.    -- 13.5.1  Record Representation Clause --
  221.    ------------------------------------------
  222.  
  223.    --  Parsed by P_Representation_Clause (13.1)
  224.  
  225.    ------------------------------
  226.    -- 13.5.1  Mod Clause (I.8) --
  227.    ------------------------------
  228.  
  229.    --  MOD_CLAUSE ::= at mod static_EXPRESSION;
  230.  
  231.    --  Note: in Ada 83, the expression must be a simple expression
  232.  
  233.    --  The caller has checked that the initial Token is AT
  234.  
  235.    --  Error recovery: cannot raise Error_Resync
  236.  
  237.    function P_Mod_Clause return Node_Id is
  238.       Mod_Node  : Node_Id;
  239.       Expr_Node : Node_Id;
  240.  
  241.    begin
  242.       Mod_Node := New_Node (N_Mod_Clause, Token_Ptr);
  243.       Scan; -- past AT
  244.       T_Mod;
  245.       Expr_Node := P_Expression_No_Right_Paren;
  246.       Check_Simple_Expression_In_Ada_83 (Expr_Node);
  247.       Set_Expression (Mod_Node, Expr_Node);
  248.       TF_Semicolon;
  249.       return Mod_Node;
  250.    end P_Mod_Clause;
  251.  
  252.    ------------------------------
  253.    -- 13.5.1  Component Clause --
  254.    ------------------------------
  255.  
  256.    --  COMPONENT_CLAUSE ::=
  257.    --    COMPONENT_CLAUSE_COMPONENT_NAME at POSITION
  258.    --      range FIRST_BIT .. LAST_BIT;
  259.  
  260.    --  COMPONENT_CLAUSE_COMPONENT_NAME ::=
  261.    --    component_DIRECT_NAME
  262.    --  | component_DIRECT_NAME'ATTRIBUTE_DESIGNATOR
  263.    --  | FIRST_SUBTYPE_DIRECT_NAME'ATTRIBUTE_DESIGNATOR
  264.  
  265.    --  POSITION ::= static_EXPRESSION
  266.  
  267.    --  Note: in Ada 83, the expression must be a simple expression
  268.  
  269.    --  FIRST_BIT ::= static_SIMPLE_EXPRESSION
  270.    --  LAST_BIT ::= static_SIMPLE_EXPRESSION
  271.  
  272.    --  Note: the AARM V2.0 grammar has an error at this point, it uses
  273.    --  EXPRESSION instead of SIMPLE_EXPRESSION for FIRST_BIT and LAST_BIT
  274.  
  275.    --  Error recovery: cannot raise Error_Resync
  276.  
  277.    function P_Component_Clause return Node_Id is
  278.       Component_Node : Node_Id;
  279.       Comp_Name      : Node_Id;
  280.       Expr_Node      : Node_Id;
  281.  
  282.    begin
  283.       Component_Node := New_Node (N_Component_Clause, Token_Ptr);
  284.       Comp_Name := P_Name;
  285.  
  286.       if Nkind (Comp_Name) = N_Identifier
  287.         or else Nkind (Comp_Name) = N_Attribute_Reference
  288.       then
  289.          Set_Component_Name (Component_Node, Comp_Name);
  290.       else
  291.          Error_Msg_N
  292.            ("component name must be direct name or attribute", Comp_Name);
  293.          Set_Component_Name (Component_Node, Error);
  294.       end if;
  295.  
  296.       Set_Sloc (Component_Node, Token_Ptr);
  297.       T_At;
  298.       Expr_Node := P_Expression_No_Right_Paren;
  299.       Check_Simple_Expression_In_Ada_83 (Expr_Node);
  300.       Set_Position (Component_Node, Expr_Node);
  301.       T_Range;
  302.       Expr_Node := P_Expression_No_Right_Paren;
  303.       Check_Simple_Expression_In_Ada_83 (Expr_Node);
  304.       Set_First_Bit (Component_Node, Expr_Node);
  305.       T_Dot_Dot;
  306.       Expr_Node := P_Expression_No_Right_Paren;
  307.       Check_Simple_Expression_In_Ada_83 (Expr_Node);
  308.       Set_Last_Bit (Component_Node, Expr_Node);
  309.       TF_Semicolon;
  310.       return Component_Node;
  311.    end P_Component_Clause;
  312.  
  313.    ----------------------
  314.    -- 13.5.1  Position --
  315.    ----------------------
  316.  
  317.    --  Parsed by P_Component_Clause (13.5.1)
  318.  
  319.    -----------------------
  320.    -- 13.5.1  First Bit --
  321.    -----------------------
  322.  
  323.    --  Parsed by P_Component_Clause (13.5.1)
  324.  
  325.    ----------------------
  326.    -- 13.5.1  Last Bit --
  327.    ----------------------
  328.  
  329.    --  Parsed by P_Component_Clause (13.5.1)
  330.  
  331.    --------------------------
  332.    -- 13.8  Code Statement --
  333.    --------------------------
  334.  
  335.    --  CODE_STATEMENT ::= QUALIFIED_EXPRESSION
  336.  
  337.    --  On entry the caller has scanned the SUBTYPE_MARK (passed in as the
  338.    --  single argument, and the scan points to the apostrophe.
  339.  
  340.    --  Error recovery: can raise Error_Resync
  341.  
  342.    function P_Code_Statement (Subtype_Mark : Node_Id) return Node_Id is
  343.       Node1 : Node_Id;
  344.  
  345.    begin
  346.       Scan; -- past apostrophe
  347.  
  348.       --  If left paren, then we have a possible code statement
  349.  
  350.       if Token = Tok_Left_Paren then
  351.          Node1 := New_Node (N_Code_Statement, Sloc (Subtype_Mark));
  352.          Set_Expression (Node1, P_Qualified_Expression (Subtype_Mark));
  353.          TF_Semicolon;
  354.          return Node1;
  355.  
  356.       --  Otherwise we have an illegal range attribute. Note that P_Name
  357.       --  ensures that Token = Tok_Range is the only possibility left here.
  358.  
  359.       else -- Token = Tok_Range
  360.          Error_Msg_SC ("RANGE attribute illegal here!");
  361.          raise Error_Resync;
  362.       end if;
  363.  
  364.    end P_Code_Statement;
  365.  
  366. end Ch13;
  367.