Overloading
Subprogram overloading
Subprograms which have the same name but different behaviour are declared as usual. This applies to both procedures and functions. According to the following criteria it has to be possible to choose exactly one procedure or function (overloading_resolution):
- Number of arguments
- Argument types
- Names of arguments (in case of an argument transfer by explicitly naming it “named association”, [⇒ see Examples])
- Type of return value
If in a function call several variants are valid the local variant (e.g., in the architecture`s declarative part) hides the variant which ranks higher in hierarchy (e.g., from a package). By giving the complete subprogram name and hierarchy one still access any desired variant (Qualified Expression).
Overloading operators
Operators are different from simple functions in two ways:
- The name or the symbol of an operator is not a normal designator but a string and therefore in declaration it stands in inverted commas.
- In a common operator call the operands are placed before or after the operator (unary operators only afterwards) and not in round brackets placed after the operator. However, it is also possible to call operators with the syntax of normal function calls (⇒see Examples).
It is important to consider the handling of operators as strings when declaring overloaded operators. Apart from that the overloading of operators is not different from that of functions and procedures.
Examples
In these examples only the declarations and calls of the overloaded subprograms are shown. Of course a subprogram definition has to be written for every declaration.
Two procedures write are declared, with the transfer value value being declared once as integer and once as string.
In the procedure call the type of the individual second transfer value determines which procedure is to be used.
PROCEDURE write ( F : INOUT Text ; value : Integer ) ; PROCEDURE write ( F : INOUT Text ; value : String ) ; write (sys_error, "Unexpected output"); write (sys_output, 12) ;
Two procedures check are declared. They differ in the name of the first transfer value as well as in the sequence of definition of the two signals C and D .
With the first two procedure calls the name of the first transfer value determines which procedure is to be used. If types Data and Clock are identical to each other the third call is not unique and therefore forbidden.
PROCEDURE check ( setup : Time ; SIGNAL D : Data ; SIGNAL C : Clock ) ; PROCEDURE check ( hold : Time ; SIGNAL C : Clock ; SIGNAL D : Data ) ; check ( setup => 10 ns, D => D_Bus, C => Clk_1 ) ; check ( hold => 5 ns, D => D_Bus, C => Clk_2 ) ; check ( 15 ns, D_Bus, Clk ) ;
According to the definition of the type mvl the standard operators AND , OR and NOT are overloaded. Type mvl is used as transfer and result value.
The signal assignments to Q , R and S show the use of overloaded operators. The second call is interesting as in it the operator is called explicitly as a function and the operands serve as transfer values.
TYPE mvl IS ( '0', '1', 'Z', 'X' ) ; FUNCTION "AND" (L, R : mvl) RETURN mvl; FUNCTION "OR" ( L, R : mvl ) RETURN mvl ; FUNCTION "NOT" ( R : mvl ) RETURN mvl ; SIGNAL Q, R, S : mvl ; Q <= 'X' OR '1' ; R <= " OR "( '0', 'Z' ) ; S <= ( Q AND R ) OR NOT S ;