-------------------------------------- ------------------------------------------ -- -- -- OCARINA COMPONENTS -- -- -- -- O C A R I N A . P R O C E S S O R . P R O P E R T I E S -- -- -- -- B o d y -- -- -- -- Copyright (C) 2005-2007, GET-Telecom Paris. -- -- -- -- Ocarina is free software; you can redistribute it and/or modify -- -- it under terms of the GNU General Public License as published by the -- -- Free Software Foundation; either version 2, or (at your option) any -- -- later version. Ocarina is distributed in the hope that it will be -- -- useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -- -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -- -- Public License for more details. You should have received a copy of the -- -- GNU General Public License distributed with Ocarina; see file COPYING. -- -- If not, write to the Free Software Foundation, 51 Franklin Street, Fifth -- -- Floor, Boston, MA 02111-1301, USA. -- -- -- -- As a special exception, if other files instantiate generics from this -- -- unit, or you link this unit with other files to produce an executable, -- -- this unit does not by itself cause the resulting executable to be -- -- covered by the GNU General Public License. This exception does not -- -- however invalidate any other reasons why the executable file might be -- -- covered by the GNU Public License. -- -- -- -- Ocarina is maintained by the Ocarina team -- -- (ocarina-users@listes.enst.fr) -- -- -- ------------------------------------------------------------------------------ with Ocarina.Nodes; with Ocarina.Nutils; with Ocarina.AADL_Values; with Ocarina.Entities; with Ocarina.Entities.Messages; with Ocarina.Builder.Properties; with Ocarina.Analyzer.Queries; with Ocarina.Analyzer.Messages; with Ocarina.Visitor.Properties; package body Ocarina.Processor.Properties is function Duplicate_Property_Value (Property_Value : Types.node_id) return Types.node_id; -- Return a property value node similar to the one given in -- parameter. Thus, the duplicated proeprty value can be inserted -- into lists without interfering with the original node pragma unreferenced (Duplicate_Property_Value); function Evaluate_Property_Value (Property_Value, Reference_Property : Types.node_id) return Types.node_id; -- Compute the value by fetching the property terms and applying -- the operations described in the property value. Return the -- first evaluated value (the following ones are chainded using -- Next_Node), or No_Node is nothing could be -- evaluated. Reference_Property is the property for the value of -- which is evaluated; it is used to display errors, in order to -- indicate what initiated the problem. function Expand_Property_Value (Property, Reference_Property : Types.node_id) return Types.node_id; -- expand the property terms of the property, and return all the -- property values function Expand_Property_Type (Property_Type : Types.node_id) return Types.node_id; -- computes the actual property type, by resolving references function Resolve_Type_Of_Property_Name_Declaration (Root, Container, Property : Types.node_id) return Boolean; -- Set a direct type (i.e. not a reference to a type declaration) -- for the property name declaration function Resolve_Values_Of_Property_Association (Root, Container, Property : Types.node_id) return Boolean; -- Set a direct value (i.e. without value ()) for each value of -- the property association. ----------------------------- -- Compute_Property_Values -- ----------------------------- function Compute_Property_Values (Root : Types.node_id) return Boolean is use Ocarina.Visitor.Properties; Success : Boolean; pragma warnings (Off, Success); begin Success := Visit_All_Property_Associations (Root => Root, Callback => Resolve_Values_Of_Property_Association'access); Success := Visit_All_Property_Names (Root => Root, Callback => Resolve_Type_Of_Property_Name_Declaration'access) and then Success; return Success; end Compute_Property_Values; -------------------------------------------- -- Diffuse_Package_Properties_To_Entities -- -------------------------------------------- procedure Diffuse_Package_Properties_To_Entities (Root : Types.node_id) is use Types; use Ocarina.Nodes; use Ocarina.Nutils; use Ocarina.Entities; use Ocarina.Builder.Properties; use Ocarina.Analyzer.Queries; pragma assert (Root /= No_Node and then Kind (Root) = k_aadl_specification); List_Node, Property_Node, Declaration_Node : node_id; Success : Boolean := True; Diffused_Property : node_id; begin if Declarations (Root) /= No_List then List_Node := First_Node (Declarations (Root)); while List_Node /= No_Node loop if Kind (List_Node) = k_package_specification and then Ocarina.Nodes.Properties (List_Node) /= No_List and then Declarations (List_Node) /= No_List then Property_Node := First_Node (Ocarina.Nodes.Properties (List_Node)); while Property_Node /= No_Node loop Declaration_Node := First_Node (Declarations (List_Node)); while Declaration_Node /= No_Node loop if Is_Private (Property_Node) = Is_Private (Declaration_Node) and then Property_Can_Apply_To_Entity (Property_Node, Declaration_Node) then Diffused_Property := Add_New_Property_Association (Loc => Loc (Property_Node), Name => Duplicate_Identifier (Identifier (Property_Node)), Property_Name => Property_Name (Property_Node), Container => Declaration_Node, In_Binding => In_Binding (Property_Node), In_Modes => In_Modes (Property_Node), Property_Value => Property_Association_Value (Property_Node), Is_Constant => Is_Constant (Property_Node), Is_Access => Is_Access (Property_Node), Is_Additive => Is_Additive_Association (Property_Node), Applies_To => Applies_To_Prop (Property_Node), Check_For_Conflicts => True, Override => False); -- We add a new property, by duplicating the -- one of the package Success := Success and then Diffused_Property /= No_Node; end if; Declaration_Node := Next_Node (Declaration_Node); end loop; Remove_Node_From_List (Property_Node, Ocarina.Nodes.Properties (List_Node)); -- Simply detach the legacy property from the list. Its -- elements are reused in the new properties Property_Node := Next_Node (Property_Node); end loop; end if; List_Node := Next_Node (List_Node); end loop; end if; end Diffuse_Package_Properties_To_Entities; ----------------------------------------------- -- Resolve_Type_Of_Property_Name_Declaration -- ----------------------------------------------- function Resolve_Type_Of_Property_Name_Declaration (Root, Container, Property : Types.node_id) return Boolean is use Types; use Ocarina.Nodes; use Ocarina.Nutils; use Ocarina.Entities; use Ocarina.Analyzer.Queries; pragma assert (Root /= No_Node and then Kind (Root) = k_aadl_specification); pragma assert (Property /= No_Node and then Kind (Property) = k_property_name_declaration); pragma unreferenced (Container); Prop_Type : constant node_id := Property_Name_Type (Property); Expanded_Value, Prop_Value : node_id; Success : Boolean := True; begin Set_Expanded_Type_Designator (Prop_Type, Expand_Property_Type (Property_Type_Designator (Prop_Type))); if Expanded_Type_Designator (Prop_Type) /= No_Node and then Kind (Expanded_Type_Designator (Prop_Type)) = k_invalid_node then Success := False; end if; if Default_Value (Property) /= No_Node then Prop_Value := Default_Value (Property); Expanded_Value := Expand_Property_Value (Property, Property); if Expanded_Value = No_Node then Set_Expanded_Single_Value (Prop_Value, No_Node); Set_Expanded_Multi_Value (Prop_Value, No_List); elsif Kind (Expanded_Value) = k_invalid_node then Success := False; Set_Expanded_Single_Value (Prop_Value, No_Node); Set_Expanded_Multi_Value (Prop_Value, No_List); elsif Kind (Expanded_Value) = k_list_id then Set_Expanded_Single_Value (Prop_Value, No_Node); Set_Expanded_Multi_Value (Prop_Value, list_id (Expanded_Value)); elsif Next_Node (Expanded_Value) = No_Node and then Single_Value (Prop_Value) /= No_Node then Set_Expanded_Single_Value (Prop_Value, Expanded_Value); Set_Expanded_Multi_Value (Prop_Value, No_List); else Set_Expanded_Single_Value (Prop_Value, No_Node); Set_Expanded_Multi_Value (Prop_Value, New_List (k_list_id, Loc (Expanded_Value))); Append_Node_To_List (Expanded_Value, Expanded_Multi_Value (Prop_Value)); end if; end if; return Success; end Resolve_Type_Of_Property_Name_Declaration; -------------------------- -- Expand_Property_Type -- -------------------------- function Expand_Property_Type (Property_Type : Types.node_id) return Types.node_id is use Types; use Ocarina.Nodes; use Ocarina.Nutils; use Ocarina.Entities; Expanded_Type : node_id; begin case Kind (Property_Type) is when k_unique_property_type_identifier => Expanded_Type := Get_Referenced_Entity (Property_Type); -- We first get the property type of the corresponding -- declaration Expanded_Type := Expand_Property_Type (Property_Type_Designator (Expanded_Type)); -- Then we expand it also when k_number_range => Expanded_Type := New_Node (k_number_range, Loc (Property_Type)); Set_Lower_Bound (Expanded_Type, Evaluate_Property_Value (Lower_Bound (Property_Type), Property_Type)); Set_Upper_Bound (Expanded_Type, Evaluate_Property_Value (Upper_Bound (Property_Type), Property_Type)); if (Upper_Bound (Expanded_Type) /= No_Node and then Kind (Upper_Bound (Expanded_Type)) = k_invalid_node) or else (Lower_Bound (Expanded_Type) /= No_Node and then Kind (Lower_Bound (Expanded_Type)) = k_invalid_node) then Set_Kind (Expanded_Type, k_invalid_node); end if; when k_real_type | k_integer_type => Expanded_Type := New_Node (Kind (Property_Type), Loc (Property_Type)); Set_Unit_Designator (Expanded_Type, Unit_Designator (Property_Type)); if Type_Range (Property_Type) /= No_Node then Set_Type_Range (Expanded_Type, New_Node (k_number_range, Loc (Type_Range (Property_Type)))); Set_Lower_Bound (Type_Range (Expanded_Type), Evaluate_Property_Value (Lower_Bound (Type_Range (Property_Type)), Property_Type)); Set_Upper_Bound (Type_Range (Expanded_Type), Evaluate_Property_Value (Upper_Bound (Type_Range (Property_Type)), Property_Type)); if (Upper_Bound (Type_Range (Expanded_Type)) /= No_Node and then Kind (Upper_Bound (Type_Range (Expanded_Type))) = k_invalid_node) or else (Lower_Bound (Type_Range (Expanded_Type)) /= No_Node and then Kind (Lower_Bound (Type_Range (Expanded_Type))) = k_invalid_node) then Set_Kind (Expanded_Type, k_invalid_node); end if; end if; when k_range_type => Expanded_Type := New_Node (k_range_type, Loc (Property_Type)); Set_Number_Type (Expanded_Type, Expand_Property_Type (Number_Type (Property_Type))); if Number_Type (Expanded_Type) /= No_Node and then Kind (Number_Type (Expanded_Type)) = k_invalid_node then Set_Kind (Expanded_Type, k_invalid_node); end if; when others => Expanded_Type := Property_Type; end case; return Expanded_Type; end Expand_Property_Type; -------------------------------------------- -- Resolve_Values_Of_Property_Association -- -------------------------------------------- function Resolve_Values_Of_Property_Association (Root, Container, Property : Types.node_id) return Boolean is use Types; use Ocarina.Nodes; use Ocarina.Nutils; use Ocarina.Analyzer.Queries; pragma assert (Root /= No_Node and then Kind (Root) = k_aadl_specification); pragma assert (Property /= No_Node and then Kind (Property) = k_property_association); pragma unreferenced (Container); Prop_Value : constant node_id := Property_Association_Value (Property); Expanded_Value : node_id; Success : Boolean := True; begin Expanded_Value := Expand_Property_Value (Property, Property); if Expanded_Value = No_Node then Set_Expanded_Single_Value (Prop_Value, No_Node); Set_Expanded_Multi_Value (Prop_Value, No_List); elsif Kind (Expanded_Value) = k_invalid_node then Success := False; Set_Expanded_Single_Value (Prop_Value, No_Node); Set_Expanded_Multi_Value (Prop_Value, No_List); elsif Kind (Expanded_Value) = k_list_id then Set_Expanded_Single_Value (Prop_Value, No_Node); Set_Expanded_Multi_Value (Prop_Value, list_id (Expanded_Value)); elsif Next_Node (Expanded_Value) = No_Node and then Single_Value (Prop_Value) /= No_Node then Set_Expanded_Single_Value (Prop_Value, Expanded_Value); Set_Expanded_Multi_Value (Prop_Value, No_List); else Set_Expanded_Single_Value (Prop_Value, No_Node); Set_Expanded_Multi_Value (Prop_Value, New_List (k_list_id, Loc (Expanded_Value))); Append_Node_To_List (Expanded_Value, Expanded_Multi_Value (Prop_Value)); end if; return Success; end Resolve_Values_Of_Property_Association; --------------------------- -- Expand_Property_Value -- --------------------------- function Expand_Property_Value (Property, Reference_Property : Types.node_id) return Types.node_id is -- Take a property declaration and return its expanded value use Types; use Ocarina.Nodes; use Ocarina.Analyzer.Messages; use Ocarina.Nutils; pragma assert (Property = No_Node or else Kind (Property) = k_property_association or else Kind (Property) = k_constant_property_declaration or else Kind (Property) = k_property_name_declaration or else DNKE (Property)); pragma assert (Reference_Property /= No_Node); Value, List_Node, Expanded_List_Node, Computed_Value : node_id; Expanded_List : list_id; Undefined_Values : Boolean; begin if Property = No_Node then return No_Node; end if; -- First get the value of the property case Kind (Property) is when k_property_association => Value := Property_Association_Value (Property); when k_constant_property_declaration => Value := Constant_Value (Property); when k_property_name_declaration => Value := Default_Value (Property); when others => raise Program_Error; end case; if Value = No_Node then return Value; elsif Single_Value (Value) /= No_Node then Computed_Value := Evaluate_Property_Value (Single_Value (Value), Reference_Property); if Computed_Value /= No_Node then if Kind (Computed_Value) = k_list_id then Expanded_List_Node := First_Node (list_id (Computed_Value)); else Expanded_List_Node := Computed_Value; end if; while Expanded_List_Node /= No_Node loop Set_Loc (Expanded_List_Node, Loc (Single_Value (Value))); Expanded_List_Node := Next_Node (Expanded_List_Node); end loop; -- The location of the evaluated values should be the -- same as the primitive value end if; return Computed_Value; else List_Node := First_Node (Multi_Value (Value)); Expanded_List := New_List (k_list_id, Loc (node_id (Multi_Value (Value)))); Undefined_Values := (List_Node /= No_Node); -- If the list is empty, then the value is defined. Else, -- the value may be undefined if all the elements of the -- list expand to an undefined value (i.e. no node) while List_Node /= No_Node loop Computed_Value := Evaluate_Property_Value (List_Node, Property); if Computed_Value /= No_Node then Undefined_Values := False; if Kind (Computed_Value) = k_invalid_node then return Computed_Value; elsif Kind (Computed_Value) = k_list_id then Expanded_List_Node := First_Node (list_id (Computed_Value)); while Expanded_List_Node /= No_Node loop Set_Loc (Expanded_List_Node, Loc (List_Node)); Expanded_List_Node := Next_Node (Expanded_List_Node); end loop; Append_List_To_List (list_id (Computed_Value), Expanded_List); else Expanded_List_Node := Computed_Value; while Expanded_List_Node /= No_Node loop Set_Loc (Expanded_List_Node, Loc (List_Node)); Expanded_List_Node := Next_Node (Expanded_List_Node); end loop; Append_Node_To_List (Computed_Value, Expanded_List); end if; end if; List_Node := Next_Node (List_Node); end loop; if Undefined_Values then return No_Node; else return node_id (Expanded_List); end if; end if; end Expand_Property_Value; ----------------------------- -- Evaluate_Property_Value -- ----------------------------- function Evaluate_Property_Value (Property_Value, Reference_Property : Types.node_id) return Types.node_id is use Types; use Ocarina.Nodes; use Ocarina.Entities; use Ocarina.Analyzer.Messages; use Ocarina.AADL_Values; use Ocarina.Nutils; pragma assert (Property_Value = No_Node or else Kind (Property_Value) = k_literal or else Kind (Property_Value) = k_property_term or else Kind (Property_Value) = k_number_range_term or else Kind (Property_Value) = k_reference_term or else Kind (Property_Value) = k_property_term or else Kind (Property_Value) = k_minus_numeric_term or else Kind (Property_Value) = k_signed_aadlnumber or else Kind (Property_Value) = k_not_boolean_term or else Kind (Property_Value) = k_and_boolean_term or else Kind (Property_Value) = k_or_boolean_term or else Kind (Property_Value) = k_parenthesis_boolean_term or else Kind (Property_Value) = k_component_classifier_term or else DNKE (Property_Value)); pragma assert (Reference_Property /= No_Node); Evaluated_Value : node_id; begin if Property_Value = No_Node then Evaluated_Value := No_Node; else case Kind (Property_Value) is when k_literal => Evaluated_Value := New_Node (Kind (Property_Value), Loc (Property_Value)); Set_Value (Evaluated_Value, New_Value (Value (Value (Property_Value)))); -- We clone the literal value when k_number_range_term => declare Evaluated_Lower_Bound, Evaluated_Upper_Bound, Evaluated_Delta_Term : node_id; begin Evaluated_Value := New_Node (Kind (Property_Value), Loc (Property_Value)); Evaluated_Lower_Bound := Evaluate_Property_Value (Lower_Bound (Property_Value), Reference_Property); Evaluated_Upper_Bound := Evaluate_Property_Value (Upper_Bound (Property_Value), Reference_Property); Evaluated_Delta_Term := Evaluate_Property_Value (Delta_Term (Property_Value), Reference_Property); -- Check the consistency of the evaluated values if Evaluated_Lower_Bound /= No_Node and then ((Kind (Evaluated_Lower_Bound) /= k_literal and then Kind (Evaluated_Lower_Bound) /= k_signed_aadlnumber) or else Next_Node (Evaluated_Lower_Bound) /= No_Node) then Display_Inconsistency_In_Property_Values (Property_Value, Evaluated_Lower_Bound, Reference_Property); Set_Kind (Evaluated_Lower_Bound, k_invalid_node); end if; if Evaluated_Upper_Bound /= No_Node and then ((Kind (Evaluated_Upper_Bound) /= k_literal and then Kind (Evaluated_Upper_Bound) /= k_signed_aadlnumber) or else Next_Node (Evaluated_Upper_Bound) /= No_Node) then Display_Inconsistency_In_Property_Values (Property_Value, Evaluated_Upper_Bound, Reference_Property); Set_Kind (Evaluated_Upper_Bound, k_invalid_node); end if; if Evaluated_Delta_Term /= No_Node and then ((Kind (Evaluated_Delta_Term) /= k_literal and then Kind (Evaluated_Delta_Term) /= k_signed_aadlnumber) or else Next_Node (Evaluated_Delta_Term) /= No_Node) then Display_Inconsistency_In_Property_Values (Property_Value, Evaluated_Delta_Term, Reference_Property); Set_Kind (Evaluated_Delta_Term, k_invalid_node); end if; -- Set the evaluated values if Evaluated_Lower_Bound /= No_Node and then Evaluated_Upper_Bound /= No_Node and then (Evaluated_Delta_Term /= No_Node or else Delta_Term (Property_Value) = No_Node) then if Kind (Evaluated_Lower_Bound) /= k_invalid_node and then Kind (Evaluated_Upper_Bound) /= k_invalid_node and then (Evaluated_Delta_Term = No_Node or else Kind (Evaluated_Delta_Term) /= k_invalid_node) then -- If we could evaluate the lower and upper -- bounds, and the delta term (unless there -- was no original value), we store the -- evaluated values Set_Lower_Bound (Evaluated_Value, Evaluated_Lower_Bound); Set_Upper_Bound (Evaluated_Value, Evaluated_Upper_Bound); Set_Delta_Term (Evaluated_Value, Evaluated_Delta_Term); else -- If at least an evaluated value is invalid Set_Kind (Evaluated_Value, k_invalid_node); end if; else Evaluated_Value := No_Node; end if; end; when k_reference_term => Evaluated_Value := New_Node (Kind (Property_Value), Loc (Property_Value)); Set_Identifier (Evaluated_Value, Duplicate_Identifier (Identifier (Property_Value))); Set_Path (Evaluated_Value, Path (Property_Value)); Set_Namespace_Path (Evaluated_Value, Namespace_Path (Property_Value)); Set_Namespace_Identifier (Evaluated_Value, Duplicate_Identifier (Namespace_Identifier (Property_Value))); Set_Referenced_Entity (Evaluated_Value, Entity (Property_Value)); when k_property_term => Evaluated_Value := Expand_Property_Value (Get_Referenced_Entity (Property_Value), Reference_Property); when k_minus_numeric_term => declare Val : value_type; Literal : node_id; begin Evaluated_Value := Evaluate_Property_Value (Numeric_Term (Property_Value), Reference_Property); if Evaluated_Value /= No_Node then if Kind (Evaluated_Value) = k_literal and then Next_Node (Evaluated_Value) = No_Node then Literal := Evaluated_Value; elsif Kind (Evaluated_Value) = k_signed_aadlnumber and then Next_Node (Evaluated_Value) = No_Node then Literal := Number_Value (Evaluated_Value); -- Since the number has been evaluated, the -- number_value can only be a literal else Display_Inconsistency_In_Property_Values (Property_Value, Evaluated_Value, Reference_Property); Literal := No_Node; Evaluated_Value := New_Node (k_invalid_node, Loc (Property_Value)); end if; if Literal /= No_Node then if Get_Value_Type (Value (Literal)).T = lt_integer then Val := Get_Value_Type (Value (Literal)); Val.ISign := not Get_Value_Type (Value (Literal)).ISign; Set_Value (Value (Literal), Val); elsif Get_Value_Type (Value (Literal)).T = lt_real then Val := Get_Value_Type (Value (Literal)); Val.RSign := not Val.RSign; Set_Value (Value (Literal), Val); else Display_Inconsistency_In_Property_Values (Property_Value, Literal, Reference_Property); Evaluated_Value := New_Node (k_invalid_node, Loc (Property_Value)); end if; if Evaluated_Value /= No_Node then if Kind (Evaluated_Value) = k_literal then Evaluated_Value := Literal; elsif Kind (Evaluated_Value) = k_signed_aadlnumber then Set_Number_Value (Evaluated_Value, Literal); end if; end if; else Evaluated_Value := No_Node; end if; end if; end; when k_signed_aadlnumber => declare Evaluated_Number_Value : node_id; begin Evaluated_Value := New_Node (Kind (Property_Value), Loc (Property_Value)); Set_Unit_Identifier (Evaluated_Value, Unit_Identifier (Property_Value)); Evaluated_Number_Value := Evaluate_Property_Value (Number_Value (Property_Value), Reference_Property); if Evaluated_Number_Value /= No_Node then if Kind (Evaluated_Number_Value) /= k_literal or else Next_Node (Evaluated_Number_Value) /= No_Node then Display_Inconsistency_In_Property_Values (Property_Value, Evaluated_Number_Value, Reference_Property); Set_Kind (Evaluated_Value, k_invalid_node); else Set_Number_Value (Evaluated_Value, Evaluated_Number_Value); end if; else Evaluated_Value := No_Node; end if; end; when k_not_boolean_term => declare Val : value_type; begin Evaluated_Value := Evaluate_Property_Value (Boolean_Term (Property_Value), Reference_Property); if Evaluated_Value /= No_Node then if Kind (Evaluated_Value) = k_literal and then Get_Value_Type (Value (Evaluated_Value)).T = lt_boolean and then Next_Node (Evaluated_Value) = No_Node then Val := Get_Value_Type (Value (Evaluated_Value)); Val.BVal := not Val.BVal; Set_Value (Value (Evaluated_Value), Val); else Display_Inconsistency_In_Property_Values (Property_Value, Evaluated_Value, Reference_Property); Set_Kind (Evaluated_Value, k_invalid_node); end if; else Evaluated_Value := No_Node; end if; end; when k_and_boolean_term => declare Auxiliary_Value : node_id; Val : value_type; Val1_OK, Val2_OK : Boolean; begin Evaluated_Value := Evaluate_Property_Value (First_Term (Property_Value), Reference_Property); Auxiliary_Value := Evaluate_Property_Value (Second_Term (Property_Value), Reference_Property); if Evaluated_Value /= No_Node then if Kind (Evaluated_Value) = k_literal and then Get_Value_Type (Value (Evaluated_Value)).T = lt_boolean and then Next_Node (Evaluated_Value) = No_Node then Val1_OK := True; else Display_Inconsistency_In_Property_Values (Property_Value, Evaluated_Value, Reference_Property); Set_Kind (Evaluated_Value, k_invalid_node); Val1_OK := False; end if; else Val1_OK := False; Evaluated_Value := No_Node; end if; if Auxiliary_Value /= No_Node then if Kind (Auxiliary_Value) = k_literal and then Get_Value_Type (Value (Auxiliary_Value)).T = lt_boolean and then Next_Node (Auxiliary_Value) = No_Node then Val2_OK := True; else Display_Inconsistency_In_Property_Values (Property_Value, Auxiliary_Value, Reference_Property); Set_Kind (Auxiliary_Value, k_invalid_node); Evaluated_Value := Auxiliary_Value; Val2_OK := False; end if; else Val2_OK := False; Evaluated_Value := No_Node; end if; if Val1_OK and then Val2_OK then Val := Get_Value_Type (Value (Evaluated_Value)); Val.BVal := Val.BVal and then Get_Value_Type (Value (Auxiliary_Value)).BVal; Set_Value (Value (Evaluated_Value), Val); end if; end; when k_or_boolean_term => declare Auxiliary_Value : node_id; Val : value_type; Val1_OK, Val2_OK : Boolean; begin Evaluated_Value := Evaluate_Property_Value (First_Term (Property_Value), Reference_Property); Auxiliary_Value := Evaluate_Property_Value (Second_Term (Property_Value), Reference_Property); if Evaluated_Value /= No_Node then if Kind (Evaluated_Value) = k_literal and then Get_Value_Type (Value (Evaluated_Value)).T = lt_boolean and then Next_Node (Evaluated_Value) = No_Node then Val1_OK := True; else Display_Inconsistency_In_Property_Values (Property_Value, Evaluated_Value, Reference_Property); Set_Kind (Evaluated_Value, k_invalid_node); Val1_OK := False; end if; else Val1_OK := False; Evaluated_Value := No_Node; end if; if Auxiliary_Value /= No_Node then if Kind (Auxiliary_Value) = k_literal and then Get_Value_Type (Value (Auxiliary_Value)).T = lt_boolean and then Next_Node (Auxiliary_Value) = No_Node then Val2_OK := True; else Display_Inconsistency_In_Property_Values (Property_Value, Auxiliary_Value, Property_Value); Set_Kind (Auxiliary_Value, k_invalid_node); Evaluated_Value := Auxiliary_Value; Val2_OK := False; end if; else Val2_OK := False; Evaluated_Value := No_Node; end if; if Val1_OK and then Val2_OK then Val := Get_Value_Type (Value (Evaluated_Value)); Val.BVal := Val.BVal or else Get_Value_Type (Value (Auxiliary_Value)).BVal; Set_Value (Value (Evaluated_Value), Val); end if; end; when k_parenthesis_boolean_term => Evaluated_Value := Evaluate_Property_Value (Boolean_Term (Property_Value), Reference_Property); if Evaluated_Value /= No_Node then if Kind (Evaluated_Value) = k_literal and then Get_Value_Type (Value (Evaluated_Value)).T = lt_boolean and then Next_Node (Evaluated_Value) = No_Node then null; else Display_Inconsistency_In_Property_Values (Property_Value, Evaluated_Value, Reference_Property); Set_Kind (Evaluated_Value, k_invalid_node); end if; else Evaluated_Value := No_Node; end if; when k_component_classifier_term => Evaluated_Value := New_Node (Kind (Property_Value), Loc (Property_Value)); Set_Referenced_Entity (Evaluated_Value, Get_Referenced_Entity (Property_Value)); Set_Component_Cat (Evaluated_Value, Component_Cat (Property_Value)); when others => raise Program_Error; end case; end if; return Evaluated_Value; end Evaluate_Property_Value; ------------------------------ -- Duplicate_Property_Value -- ------------------------------ function Duplicate_Property_Value (Property_Value : Types.node_id) return Types.node_id is use Ocarina.Nodes; use Types; use Ocarina.Nutils; use Ocarina.Entities; use Ocarina.Entities.Messages; use Ocarina.Analyzer.Queries; pragma assert (Property_Value = No_Node or else Kind (Property_Value) = k_literal or else Kind (Property_Value) = k_property_term or else Kind (Property_Value) = k_number_range_term or else Kind (Property_Value) = k_reference_term or else Kind (Property_Value) = k_minus_numeric_term or else Kind (Property_Value) = k_signed_aadlnumber or else Kind (Property_Value) = k_not_boolean_term or else Kind (Property_Value) = k_and_boolean_term or else Kind (Property_Value) = k_or_boolean_term or else Kind (Property_Value) = k_parenthesis_boolean_term or else Kind (Property_Value) = k_component_classifier_term or else DNKE (Property_Value)); Duplicated_Value : node_id := No_Node; begin if Property_Value = No_Node then Duplicated_Value := No_Node; else case Kind (Property_Value) is when k_literal => Duplicated_Value := New_Node (Kind (Property_Value), Loc (Property_Value)); Set_Value (Duplicated_Value, Value (Property_Value)); when k_property_term => raise Program_Error; -- We should not have to duplicate property terms when k_number_range_term => Duplicated_Value := New_Node (Kind (Property_Value), Loc (Property_Value)); Set_Lower_Bound (Duplicated_Value, Lower_Bound (Property_Value)); Set_Upper_Bound (Duplicated_Value, Upper_Bound (Property_Value)); Set_Delta_Term (Duplicated_Value, Delta_Term (Property_Value)); when k_reference_term => Duplicated_Value := Property_Value; -- XXX we should duplicate something here when k_signed_aadlnumber => Duplicated_Value := New_Node (Kind (Property_Value), Loc (Property_Value)); Set_Number_Value (Duplicated_Value, Number_Value (Property_Value)); Set_Unit_Identifier (Duplicated_Value, Unit_Identifier (Property_Value)); when k_minus_numeric_term => Duplicated_Value := New_Node (Kind (Property_Value), Loc (Property_Value)); Set_Numeric_Term (Duplicated_Value, Numeric_Term (Property_Value)); when k_and_boolean_term | k_or_boolean_term => Duplicated_Value := New_Node (Kind (Property_Value), Loc (Property_Value)); Set_First_Term (Duplicated_Value, First_Term (Property_Value)); Set_Second_Term (Duplicated_Value, Second_Term (Property_Value)); when k_not_boolean_term | k_parenthesis_boolean_term => Duplicated_Value := New_Node (Kind (Property_Value), Loc (Property_Value)); Set_Boolean_Term (Duplicated_Value, Boolean_Term (Property_Value)); when k_component_classifier_term => Duplicated_Value := New_Node (Kind (Property_Value), Loc (Property_Value)); Set_Referenced_Entity (Duplicated_Value, Get_Referenced_Entity (Property_Value)); Set_Component_Cat (Duplicated_Value, Component_Cat (Property_Value)); when others => raise Program_Error; end case; end if; return Duplicated_Value; end Duplicate_Property_Value; end Ocarina.Processor.Properties;