Strongly typed language

Colors

Goal: create a package to represent HTML colors in hexadecimal form and its corresponding names.

Steps:

  1. Implement the Color_Types package.

    1. Declare the HTML_Color enumeration.

    2. Declare the Basic_HTML_Color enumeration.

    3. Implement the To_Integer function.

    4. Implement the To_HTML_Color function.

Requirements:

  1. Enumeration HTML_Color has the following colors:

    • Salmon

    • Firebrick

    • Red

    • Darkred

    • Lime

    • Forestgreen

    • Green

    • Darkgreen

    • Blue

    • Mediumblue

    • Darkblue

  2. Enumeration Basic_HTML_Color has the following colors: Red, Green, Blue.

  3. Function To_Integer converts from the HTML_Color type to the HTML color code — as integer values in hexadecimal notation.

    • You can find the HTML color codes in the table below.

  4. Function To_HTML_Color converts from Basic_HTML_Color to HTML_Color.

  5. This is the table to convert from an HTML color to a HTML color code in hexadecimal notation:

Color

HTML color code (hexa)

Salmon

#FA8072

Firebrick

#B22222

Red

#FF0000

Darkred

#8B0000

Lime

#00FF00

Forestgreen

#228B22

Green

#008000

Darkgreen

#006400

Blue

#0000FF

Mediumblue

#0000CD

Darkblue

#00008B

Remarks:

  1. In order to express the hexadecimal values above in Ada, use the following syntax: 16#<hex_value># (e.g.: 16#FFFFFF#).

  2. For function To_Integer, you may use a case for this.

    
        
    
    
    
        
package Color_Types is -- Include type declaration for HTML_Color! -- -- type HTML_Color is [...] -- -- Include function declaration for: -- function To_Integer (C : HTML_Color) return Integer; -- Include type declaration for Basic_HTML_Color! -- -- type Basic_HTML_Color is [...] -- -- Include function declaration for: -- - Basic_HTML_Color => HTML_Color -- -- function To_HTML_Color [...]; -- end Color_Types;
package body Color_Types is -- Implement the conversion from HTML_Color to Integer here! -- -- function To_Integer (C : HTML_Color) return Integer is -- begin -- -- Hint: use 'case' for the HTML colors; -- -- use 16#...# for the hexadecimal values. -- end To_Integer; -- Implement the conversion from Basic_HTML_Color to HTML_Color here! -- -- function To_HTML_Color [...] is -- end Color_Types;
with Ada.Command_Line; use Ada.Command_Line; with Ada.Text_IO; use Ada.Text_IO; with Ada.Integer_Text_IO; with Color_Types; use Color_Types; procedure Main is type Test_Case_Index is (HTML_Color_Range, HTML_Color_To_Integer, Basic_HTML_Color_To_HTML_Color); procedure Check (TC : Test_Case_Index) is begin case TC is when HTML_Color_Range => for I in HTML_Color'Range loop Put_Line (HTML_Color'Image (I)); end loop; when HTML_Color_To_Integer => for I in HTML_Color'Range loop Ada.Integer_Text_IO.Put (Item => To_Integer (I), Width => 6, Base => 16); New_Line; end loop; when Basic_HTML_Color_To_HTML_Color => for I in Basic_HTML_Color'Range loop Put_Line (HTML_Color'Image (To_HTML_Color (I))); end loop; end case; end Check; begin if Argument_Count < 1 then Put_Line ("ERROR: missing arguments! Exiting..."); return; elsif Argument_Count > 1 then Put_Line ("Ignoring additional arguments..."); end if; Check (Test_Case_Index'Value (Argument (1))); end Main;

Integers

Goal: implement a package with various integer types.

Steps:

  1. Implement the Int_Types package.

    1. Declare the integer type I_100.

    2. Declare the modular type U_100.

    3. Implement the To_I_100 function to convert from the U_100 type.

    4. Implement the To_U_100 function to convert from the I_100 type.

    5. Declare the derived type D_50.

    6. Declare the subtype S_50.

    7. Implement the To_D_50 function to convert from the I_100 type.

    8. Implement the To_S_50 function to convert from the I_100 type.

    9. Implement the To_I_100 function to convert from the D_50 type.

Requirements:

  1. Types I_100 and U_100 have values between 0 and 100.

    1. Type I_100 is an integer type.

    2. Type U_100 is a modular type.

  2. Function To_I_100 converts from the U_100 type to the I_100 type.

  3. Function To_U_100 converts from the I_100 type to the U_100 type.

  4. Types D_50 and S_50 have values between 10 and 50 and use I_100 as a base type.

    1. D_50 is a derived type.

    2. S_50 is a subtype.

  5. Function To_D_50 converts from the I_100 type to the D_50 type.

  6. Function To_S_50 converts from the I_100 type to the S_50 type.

  7. Functions To_D_50 and To_S_50 saturate the input values if they are out of range.

    • If the input is less than 10 the output should be 10.

    • If the input is greater than 50 the output should be 50.

  8. Function To_I_100 converts from the D_50 type to the I_100 type.

Remarks:

  1. For the implementation of functions To_D_50 and To_S_50, you may use the type attributes D_50'First and D_50'Last:

    1. D_50'First indicates the minimum value of the D_50 type.

    2. D_50'Last indicates the maximum value of the D_50 type.

    3. The same attributes are available for the S_50 type ( S_50'First and S_50'Last).

  2. We could have implemented a function To_I_100 as well to convert from S_50 to I_100. However, we skip this here because explicit conversions are not needed for subtypes.

    
        
    
    
    
        
package Int_Types is -- Include type declarations for I_100 and U_100! -- -- type I_100 is [...] -- type U_100 is [...] -- function To_I_100 (V : U_100) return I_100; function To_U_100 (V : I_100) return U_100; -- Include type declarations for D_50 and S_50! -- -- [...] D_50 is [...] -- [...] S_50 is [...] -- function To_D_50 (V : I_100) return D_50; function To_S_50 (V : I_100) return S_50; function To_I_100 (V : D_50) return I_100; end Int_Types;
package body Int_Types is function To_I_100 (V : U_100) return I_100 is begin -- Implement the conversion from U_100 to I_100 here! -- null; end To_I_100; function To_U_100 (V : I_100) return U_100 is begin -- Implement the conversion from I_100 to U_100 here! -- null; end To_U_100; function To_D_50 (V : I_100) return D_50 is Min : constant I_100 := I_100 (D_50'First); Max : constant I_100 := I_100 (D_50'Last); begin -- Implement the conversion from I_100 to D_50 here! -- -- Hint: using the constants above simplifies the checks needed for -- this function. -- null; end To_D_50; function To_S_50 (V : I_100) return S_50 is begin -- Implement the conversion from I_100 to S_50 here! -- -- Remark: don't forget to verify whether an explicit conversion like -- S_50 (V) is needed. -- null; end To_S_50; function To_I_100 (V : D_50) return I_100 is begin -- Implement the conversion from I_100 to D_50 here! -- -- Remark: don't forget to verify whether an explicit conversion like -- I_100 (V) is needed. -- null; end To_I_100; end Int_Types;
with Ada.Command_Line; use Ada.Command_Line; with Ada.Text_IO; use Ada.Text_IO; with Int_Types; use Int_Types; procedure Main is package I_100_IO is new Ada.Text_IO.Integer_IO (I_100); package U_100_IO is new Ada.Text_IO.Modular_IO (U_100); package D_50_IO is new Ada.Text_IO.Integer_IO (D_50); use I_100_IO; use U_100_IO; use D_50_IO; type Test_Case_Index is (I_100_Range, U_100_Range, U_100_Wraparound, U_100_To_I_100, I_100_To_U_100, D_50_Range, S_50_Range, I_100_To_D_50, I_100_To_S_50, D_50_To_I_100, S_50_To_I_100); procedure Check (TC : Test_Case_Index) is begin I_100_IO.Default_Width := 1; U_100_IO.Default_Width := 1; D_50_IO.Default_Width := 1; case TC is when I_100_Range => Put (I_100'First); New_Line; Put (I_100'Last); New_Line; when U_100_Range => Put (U_100'First); New_Line; Put (U_100'Last); New_Line; when U_100_Wraparound => Put (U_100'First - 1); New_Line; Put (U_100'Last + 1); New_Line; when U_100_To_I_100 => for I in U_100'Range loop I_100_IO.Put (To_I_100 (I)); New_Line; end loop; when I_100_To_U_100 => for I in I_100'Range loop Put (To_U_100 (I)); New_Line; end loop; when D_50_Range => Put (D_50'First); New_Line; Put (D_50'Last); New_Line; when S_50_Range => Put (S_50'First); New_Line; Put (S_50'Last); New_Line; when I_100_To_D_50 => for I in I_100'Range loop Put (To_D_50 (I)); New_Line; end loop; when I_100_To_S_50 => for I in I_100'Range loop Put (To_S_50 (I)); New_Line; end loop; when D_50_To_I_100 => for I in D_50'Range loop Put (To_I_100 (I)); New_Line; end loop; when S_50_To_I_100 => for I in S_50'Range loop Put (I); New_Line; end loop; end case; end Check; begin if Argument_Count < 1 then Put_Line ("ERROR: missing arguments! Exiting..."); return; elsif Argument_Count > 1 then Put_Line ("Ignoring additional arguments..."); end if; Check (Test_Case_Index'Value (Argument (1))); end Main;

Temperatures

Goal: create a package to handle temperatures in Celsius and Kelvin.

Steps:

  1. Implement the Temperature_Types package.

    1. Declare the Celsius type.

    2. Declare the Int_Celsius type.

    3. Implement the To_Celsius function.

    4. Implement the To_Int_Celsius function.

    5. Declare the Kelvin type.

    6. Implement the To_Celsius function to convert from the Kelvin type.

    7. Implement the To_Kelvin function.

Requirements:

  1. The custom floating-point types declared in Temperature_Types must use a precision of six digits.

  2. Types Celsius and Int_Celsius are used for temperatures in Celsius:

    1. Celsius is a floating-point type with a range between -273.15 and 5504.85.

    2. Int_Celsius is an integer type with a range between -273 and 5505.

  3. Functions To_Celsius and To_Int_Celsius are used for type conversion:

    1. To_Celsius converts from Int_Celsius to Celsius type.

    2. To_Int_Celsius converts from Celsius and Int_Celsius types:

  4. Kelvin is a floating-point type for temperatures in Kelvin using a range between 0.0 and 5778.0.

  5. The functions To_Celsius and To_Kelvin are used to convert between temperatures in Kelvin and Celsius.

    1. In order to convert temperatures in Celsius to Kelvin, you must use the formula \(K = C + 273.15\), where:

      • K is the temperature in Kelvin, and

      • C is the temperature in Celsius.

Remarks:

  1. When implementing the To_Celsius function for the Int_Celsius type:

    1. You'll need to check for the minimum and maximum values of the input values because of the slightly different ranges.

    2. You may use variables of floating-point type (Float) for intermediate values.

  2. For the implementation of the functions To_Celsius and To_Kelvin (used for converting between Kelvin and Celsius), you may use a variable of floating-point type (Float) for intermediate values.

    
        
    
    
    
        
package Temperature_Types is -- Include type declaration for Celsius! -- -- Celsius is [...]; -- Int_Celsius is [...]; -- function To_Celsius (T : Int_Celsius) return Celsius; function To_Int_Celsius (T : Celsius) return Int_Celsius; -- Include type declaration for Kelvin! -- -- type Kelvin is [...]; -- -- Include function declarations for: -- - Kelvin => Celsius -- - Celsius => Kelvin -- -- function To_Celsius [...]; -- function To_Kelvin [...]; -- end Temperature_Types;
package body Temperature_Types is function To_Celsius (T : Int_Celsius) return Celsius is begin null; end To_Celsius; function To_Int_Celsius (T : Celsius) return Int_Celsius is begin null; end To_Int_Celsius; -- Include function implementation for: -- - Kelvin => Celsius -- - Celsius => Kelvin -- -- function To_Celsius [...] is -- function To_Kelvin [...] is -- end Temperature_Types;
with Ada.Command_Line; use Ada.Command_Line; with Ada.Text_IO; use Ada.Text_IO; with Temperature_Types; use Temperature_Types; procedure Main is package Celsius_IO is new Ada.Text_IO.Float_IO (Celsius); package Kelvin_IO is new Ada.Text_IO.Float_IO (Kelvin); package Int_Celsius_IO is new Ada.Text_IO.Integer_IO (Int_Celsius); use Celsius_IO; use Kelvin_IO; use Int_Celsius_IO; type Test_Case_Index is (Celsius_Range, Celsius_To_Int_Celsius, Int_Celsius_To_Celsius, Kelvin_To_Celsius, Celsius_To_Kelvin); procedure Check (TC : Test_Case_Index) is begin Celsius_IO.Default_Fore := 1; Kelvin_IO.Default_Fore := 1; Int_Celsius_IO.Default_Width := 1; case TC is when Celsius_Range => Put (Celsius'First); New_Line; Put (Celsius'Last); New_Line; when Celsius_To_Int_Celsius => Put (To_Int_Celsius (Celsius'First)); New_Line; Put (To_Int_Celsius (0.0)); New_Line; Put (To_Int_Celsius (Celsius'Last)); New_Line; when Int_Celsius_To_Celsius => Put (To_Celsius (Int_Celsius'First)); New_Line; Put (To_Celsius (0)); New_Line; Put (To_Celsius (Int_Celsius'Last)); New_Line; when Kelvin_To_Celsius => Put (To_Celsius (Kelvin'First)); New_Line; Put (To_Celsius (0)); New_Line; Put (To_Celsius (Kelvin'Last)); New_Line; when Celsius_To_Kelvin => Put (To_Kelvin (Celsius'First)); New_Line; Put (To_Kelvin (Celsius'Last)); New_Line; end case; end Check; begin if Argument_Count < 1 then Put_Line ("ERROR: missing arguments! Exiting..."); return; elsif Argument_Count > 1 then Put_Line ("Ignoring additional arguments..."); end if; Check (Test_Case_Index'Value (Argument (1))); end Main;