module Frontend::Nodes {

  /******************/
  /* Internal types */
  /******************/

  typedef octet   Mode_Id;
  typedef octet   Pragma_Type;
  typedef octet   Operator_Id;
  typedef long    Name_Id;
  typedef long    Value_Id;


  /******************/
  /* Internal nodes */
  /******************/

  interface Node_Id {
    Node_Id    Next_Entity;
    boolean    Imported;
   
  };
  
  /* This node kind is useful to link the nodes of the tree to the 
     ones of another tree */
  interface Linkable_Node_Id : Node_Id {
     Node_Id    BE_Node;
  };

  interface Definition : Node_Id {
    Node_Id    Identifier;
    // Identifier associated to definition
    Node_Id    Type_Id;
    Node_Id    Type_Version;
  };

  interface Forward_Declaration : Definition {
    Node_Id    Forward;
  };

  interface List_Id {
    Node_Id    First_Entity;
    Node_Id    Last_Entity;
    long       Size;
  };

  interface Scope_Definition : Definition {
    Node_Id    Scoped_Identifiers;
  };

  interface Identifier : Linkable_Node_Id {
    Name_Id    IDL_Name;
    //  Name in original source form

    Name_Id    Name;
    //  Name converted to lowercase

    Node_Id    Homonym;
    Node_Id    Corresponding_Entity;
    Node_Id    Scope_Entity;
    Node_Id    Potential_Scope;
    boolean    Visible;
    boolean    Implicitly_Visible;
    Node_Id    Next_Identifier;
  };

  /**********/
  /* Pragma */
  /**********/
  
  interface _Pragma : Node_Id {
    Pragma_Type Pragma_Kind;
    Node_Id     Target;
    Name_Id     Data;
  };

  /********************/
  /* Pragma_Range_Idl */
  /********************/
  
  interface Pragma_Range_Idl : Node_Id {
    Pragma_Type Pragma_Kind;
    Node_Id     Target;
    Node_Id     Lower_Bound_Expr;
    Node_Id     Upper_Bound_Expr;
  };

  /*************************/
  /* Typeprefix and Typeid */
  /*************************/

  interface Type_Id_Declaration : Node_Id {
    Node_Id    Target;
    Name_Id    Data;
  };

  interface Type_Prefix_Declaration : Type_Id_Declaration {};
  
  /*****************/
  /* Literal nodes */
  /*****************/

  interface Literal : Node_Id {
    Value_Id   Value;
  };

  interface Integer_Literal : Literal {};
  interface String_Literal : Literal {};
  interface Wide_String_Literal : Literal {};
  interface Character_Literal : Literal {};
  interface Wide_Character_Literal : Literal {};
  interface Fixed_Point_Literal : Literal {};
  interface Floating_Point_Literal : Literal {};
  interface Boolean_Literal : Literal {};


  /********************/
  /* Declarator nodes */
  /********************/

  /* 
     (51) <simple_declarator> ::= <identifier> 
  */

  interface Simple_Declarator : Definition {
    Node_Id    Declaration;
  };

  /* 
     (52) <complex_declarator> ::= <array_declarator>
     (83) <array_declarator> ::= <identifier> <fixed_array_size> + 
     (84) <fixed_array_size> ::= "[" <positive_int_const> "]" 
  */

  interface Complex_Declarator : Simple_Declarator {
    List_Id      Array_Sizes;
  };

  /********************/
  /* Expression nodes */
  /********************/

  interface Expression : Node_Id {
    Operator_Id Operator;
    Value_Id    Value;
    Node_Id     Left_Expr;
    Node_Id     Right_Expr;
  };


  /******************/
  /* Constant nodes */
  /******************/

  /*
    (27) <const_dcl> ::= "const" <const_type> <identifier> "="
                         <const_exp>
  */

  interface Constant_Declaration : Definition {
    Node_Id     Type_Spec;
    Node_Id     Expression;
    Value_Id    Value;
  };


  /****************/
  /* Module nodes */
  /****************/

  /*
    (3) <module> ::= "module" <identifier> "{" <definition> + "}" 
  */

  interface _Module : Scope_Definition {
    List_Id     Definitions;
    List_Id     Type_Prefixes;
  }; 

  interface _Import : Node_Id {
    Node_Id     Imported_Scope;
  };
  
  interface Specification : Definition {
    List_Id     Imports;
    List_Id     Definitions;
    Node_Id     Scoped_Identifiers;
    List_Id     Type_Prefixes;
  };


  /*****************/
  /* Forward nodes */
  /*****************/

  /*
    (6) <forward_dcl> ::= [ "abstract" | "local" ] "interface" <identifier> 
  */

  interface Forward_Interface_Declaration : Forward_Declaration {
    boolean     Is_Abstract_Interface;
    boolean     Is_Local_Interface;
  };

  /*
    (14) <value_forward_dcl> ::= [ "abstract" ] "valuetype" <identifier> 
  */

  interface Value_Forward_Declaration : Forward_Declaration {
    boolean     Is_Abstract_Value;
  };

  /*
    (99) <constr_forward_decl> ::= "struct" <identifier> 
                                 | "union" <identifier> 
  */

  interface Forward_Structure_Type : Forward_Declaration {};
  interface Forward_Union_Type : Forward_Declaration {};


  /*******************/
  /* Interface nodes */
  /*******************/

  /*
    (5) <interface_dcl> ::= <interface_header> "{" <interface_body> "}" 
    (7) <interface_header> ::= [ "abstract" | "local" ] "interface" <identifier> 
                               [ <interface_inheritance_spec> ] 
  */

  interface Interface_Declaration : Scope_Definition {
    boolean     Is_Abstract_Interface;
    boolean     Is_Local_Interface;
    List_Id     Interface_Spec;
    List_Id     Interface_Body;
    List_Id     Type_Prefixes;
  };


  /*******************/
  /* Attribute nodes */
  /*******************/

  /*
    (85) <attr_dcl> ::= [ "readonly" ] "attribute" <param_type_spec>
            <simple_declarator> { "," <simple_declarator> }* 
   */

  interface Attribute_Declaration : Node_Id {
    boolean     Is_Readonly;
    Node_Id     Type_Spec;
    List_Id     Declarators;
    List_Id     Getter_Exceptions;
    List_Id     Setter_Exceptions;
  };


  /*******************/
  /* Parameter nodes */
  /*******************/

  /*
    (91) <param_dcl> ::= <param_attribute> <param_type_spec> 
                         <simple_declarator> 

    (92) <param_attribute> ::= "in" 
                             | "out" 
  			   | "inout" 

  */

  interface Parameter_Declaration : Node_Id {
    Mode_Id     Parameter_Mode;
    Node_Id     Type_Spec;
    Node_Id     Declarator;
  };


  /*******************/
  /* Operation nodes */
  /*******************/

  /*
    (87) <op_dcl> ::= [ <op_attribute> ] <op_type_spec> 
                      <identifier> <parameter_dcls> 
  		    [ <raises_expr> ] [ <context_expr> ] 
  */

  interface Operation_Declaration : Scope_Definition {
    boolean     Is_Oneway;
    Node_Id     Type_Spec;
    List_Id     Parameters;
    List_Id     Exceptions;
    List_Id     Contexts;
  };


  /*********************/
  /* Scoped name nodes */
  /*********************/

  interface Scoped_Name : Definition {
    Node_Id     Reference;
    Node_Id     Parent_Entity;
    long        Depth;
    Node_Id     Next_Scoped_Name;
  };


  /***************/
  /* Value nodes */
  /***************/

  /*
    (15) <value_box_dcl> ::= "valuetype" <identifier> <type_spec> 
  */

  interface Value_Box_Declaration : Scope_Definition {
     Node_Id    Type_Spec;
  };

  /*
    (16) <value_abs_dcl> ::= "abstract" "valuetype" <identifier> 
                             [ <value_inheritance_spec> ] "{" <export>* "}" 

    (17) <value_dcl> ::= <value_header> "{"  <value_element>* "}" 
    (18) <value_header> ::= [" custom" ] "valuetype" <identifier> 
                            [ <value_inheritance_spec> ] 
  */

  interface Generic_Value_Declaration : Value_Box_Declaration {
    Node_Id     Value_Spec;
    List_Id     Value_Body;
  };

  interface Value_Declaration : Generic_Value_Declaration {
    boolean     Is_Custom;
    List_Id     Type_Prefixes;
  };

  interface Abstract_Value_Declaration : Generic_Value_Declaration {};

  /*
    (19) <value_inheritance_spec> ::=
             [ ":" [ "truncatable" ] <value_name> { "," <value_name> }* ] 
             [ "supports" <interface_name> { "," <interface_name> }* ] 
  */

  interface Value_Spec : Node_Id {
    boolean     Is_Truncatable;
    Node_Id     Identifier;
    List_Id     Value_Names;
    List_Id     Interface_Names;
  };


  /**********************/
  /* State member nodes */
  /**********************/

  /*
    (22) <state_member> ::= ( "public" | "private" ) 
                            <type_spec> <declarators> ";" 
  */

  interface State_Member : Node_Id {
    boolean     Is_Public;
    Node_Id     Type_Spec;
    List_Id     Declarators;
  };


  /*********************/
  /* Initializer nodes */
  /*********************/

  /*
    (23) <init_dcl> ::= "factory" <identifier> 
                        "(" [ <init_param_decls> ] ")" ";" 

    (24) <init_param_decls> ::= <init_param_decl> { "," <init_param_decl> }* 
    (25) <init_param_decl> ::= <init_param_attribute> <param_type_spec> 
                               <simple_declarator> 
  */

  interface Initializer_Declaration : Operation_Declaration {};


  /*****************/
  /* Typedef nodes */
  /*****************/

  interface Range : Node_Id {
    Node_Id Low_Bound;
    Node_Id High_Bound;
  };

  /*
    (43) <type_declarator> ::= <type_spec> <declarators> 
    (44) <type_spec> ::= <simple_type_spec> 
                       | <constr_type_spec> 
  */

  interface Type_Declaration : Node_Id {
    Node_Id     Type_Spec;
    List_Id     Declarators;
    boolean     Marked_As_Subtype;  // #pragma subtype
    Node_Id     Optional_Range;     // #pragma range: see interface Range
  };


  /****************/
  /* Member nodes */
  /****************/

  /*
    (71) <member> ::= <type_spec> <declarators> ";" 
  */

  interface Member : Node_Id {
    Node_Id Type_Spec;
    List_Id Declarators;
  };

  /*******************/
  /* Structure nodes */
  /*******************/

  /*
    (69) <struct_type> ::= "struct" <identifier> "{" <member_list> "}" 
    (70) <member_list> ::= <member> + 
  */

  interface Structure_Type : Scope_Definition {
    List_Id      Members;
  };


  /***************/
  /* Union nodes */
  /***************/

  /*
    (72) <union_type> ::= "union" <identifier> "switch" 
                          "(" <switch_type_spec> ")" 
  			"{" <switch_body> "}" 

    (73) <switch_type_spec> ::= <integer_type> 
                              | <char_type> 
  			    | <boolean_type> 
  			    | <enum_type> 
  			    | <scoped_name> 

    (74) <switch_body> ::= <case> + 
    (75) <case> ::= <case_label> + <element_spec> ";" 
    (76) <case_label> ::= "case" <const_exp> ":" 
                        | "default" ":" 
  */

  interface Case_Label : Node_Id {
    Node_Id     Declaration;
    Node_Id     Expression; // No_Node for "default"
    Value_Id    Value;
  };

  interface Switch_Alternative : Node_Id {
    Node_Id     Declaration;
    List_Id     Labels;
    Node_Id     Element;
  };

  /*
    (77) <element_spec> ::= <type_spec> <declarator> 
  */

  interface Element : Node_Id {
    Node_Id     Type_Spec;
    Node_Id     Declarator;
  };

  interface Union_Type : Scope_Definition {
    Name_Id     Switch_Name;   // may be set by #pragma switchname
    Node_Id     Switch_Type_Spec;
    List_Id     Switch_Type_Body;
  };


  /*********************/
  /* Enumeration nodes */
  /*********************/

  /*
    (78) <enum_type> ::= "enum" <identifier> 
                            "{" <enumerator> { "," <enumerator> } "}" 

    (79) <enumerator> ::= <identifier> 
  */

  interface Enumerator : Definition {
    Value_Id    Value;
  };

  interface Enumeration_Type : Definition {
    List_Id     Enumerators;
  };

  /*******************/
  /* Exception nodes */
  /*******************/

  /*
    (86) <except_dcl> ::= "exception" <identifier> "{" <member>* "}"
  */

  interface Exception_Declaration : Scope_Definition {
    List_Id     Members;
  };


  /****************/
  /* Native nodes */
  /****************/

  /*
    (42) <type_dcl> ::= "typedef" <type_declarator> 
  		    | [...]
  		    | "native" <simple_declarator> 
  */

  interface Native_Type : Node_Id {
    Node_Id     Declarator;
  };


  /******************/
  /* Sequence nodes */
  /******************/

  /*
    (80) <sequence_type> ::= "sequence" "<" <simple_type_spec> "," 
                                 <positive_int_const> ">" 
  			 | "sequence" "<" <simple_type_spec> ">" 
  */

  interface Sequence_Type : Linkable_Node_Id {
    Node_Id     Type_Spec;
    Node_Id     Max_Size;
  };


  /****************/
  /* String nodes */
  /****************/

  /*
    (81) <string_type> ::= "string" "<" <positive_int_const> ">" 
                         | " string" 

    (82) <wide_string_type> ::= "wstring" "<" <positive_int_const> ">" 
                              | " wstring" 
  */

  interface String_Type : Linkable_Node_Id {
    Node_Id     Max_Size;
  };
  interface Wide_String_Type : String_Type {};


  /*********************/
  /* Fixed point nodes */
  /*********************/

  /*
    (96) <fixed_pt_type> ::= "fixed" "<" <positive_int_const> "," 
                                      <positive_int_const> ">" 

    (97) <fixed_pt_const_type> ::= "fixed" 
  */

  interface Fixed_Point_Type : Linkable_Node_Id {
    long     N_Total;
    long     N_Scale;
  };


  /*******************/
  /* Base type nodes */
  /*******************/

  interface Base_Type {
    Name_Id Image;
  };
  interface _Float : Base_Type {};
  interface _Double : Base_Type {};
  interface Long_Double : Base_Type {};
  interface _Short : Base_Type {};
  interface _Long : Base_Type {};
  interface Long_Long : Base_Type {};
  interface Unsigned_Short : Base_Type {};
  interface Unsigned_Long : Base_Type {};
  interface Unsigned_Long_Long : Base_Type {};
  interface _Char : Base_Type {};
  interface Wide_Char : Base_Type {};
  interface _String : Base_Type {};
  interface Wide_String : Base_Type {};
  interface _Boolean : Base_Type {};
  interface _Octet : Base_Type {};
  interface _Object : Base_Type {};
  interface _Any : Base_Type {};
  interface _Void : Base_Type {};
  interface Value_Base : Base_Type {};
};
