home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / misc / dunit.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  29.3 KB  |  1,046 lines

  1. ::::::::::
  2. dunit.inc
  3. ::::::::::
  4. -- Include files (in compilation order) for DIMENSIONAL_UNITS
  5. -- by Do-While Jones
  6. DUNITS.ADA
  7. DUNITB.ADA
  8. -- The following is a usage example
  9. DUEX.ADA
  10. -- The following is the prologue file for the ASR
  11. DIM_UNIT.PRO
  12. -- The following is the test program; link DU_TEST after these
  13. -- files are compiled
  14. DUTEST.ADA
  15. DUTEST1.ADA
  16. DUTEST2.ADA
  17. DUTEST3.ADA
  18. ::::::::::
  19. DUNITS.ADA
  20. ::::::::::
  21. --            -- DUNITS.ada
  22. --            -- VERSION 1
  23.  
  24. --            1 January 1986
  25. --            Do-While Jones
  26. --            324 Traci Lane
  27. --            Ridgecrest, CA 93555
  28. --            (619) 375-4607
  29.  
  30. package DIMENSIONAL_UNITS is
  31.  
  32.   -- This package provides useful parent types for derived
  33.   -- dimensional units. That is, it makes it possible to
  34.   -- do this:
  35.  
  36.   -- type Feet is new Integer_unit;
  37.   -- type Radians is new Float_unit;
  38.  
  39.   -- PI           : constant Radians := 3.14159;
  40.   -- TARGET_RANGE : Feet;
  41.   -- ANGLE        : Radians;
  42.   -- REVOLUTIONS  : integer;
  43.  
  44.   -- These derived data types will inherit all the operations
  45.   -- in the package below. These are all the operations that
  46.   -- make sense for dimensional quantities.
  47.  
  48.   -- The modulo operation for Float_units is provided to make
  49.   -- it easy to normalize angular measurements.
  50.  
  51.   -- ANGLE := ANGLE mod (2.0 * PI);
  52.  
  53.   -- The division operator for Float_units which returns integers
  54.   -- truncates toward zero (rather than rounding) to make it
  55.   -- consistant with integer division, and it lets you do this:
  56.  
  57.   -- REVOLUTIONS := ANGLE / (2.0 * PI);
  58.  
  59.   type Integer_unit is private;
  60.  
  61.   function Type_convert(X : integer) return Integer_unit;
  62.     -- Lets you assign values to dimensional objects.
  63.     -- For example,
  64.  
  65.     -- TARGET_RANGE := Type_Convert(587);
  66.  
  67.   function "+"(RIGHT : Integer_unit)
  68.     return Integer_unit;
  69.   function "-"(RIGHT : Integer_unit)
  70.     return Integer_unit;
  71.   function "abs"(RIGHT : Integer_unit)
  72.     return Integer_unit;
  73.   function "+"(LEFT, RIGHT : Integer_unit)
  74.     return Integer_unit;
  75.   function "-"(LEFT, RIGHT : Integer_unit)
  76.     return Integer_unit;
  77.   function "*"(LEFT : integer; RIGHT : Integer_unit)
  78.     return Integer_unit;
  79.   function "*"(LEFT : Integer_unit; RIGHT : integer)
  80.     return Integer_unit;
  81.   function "/"(LEFT : Integer_unit; RIGHT : integer)
  82.     return Integer_unit;
  83.   function "/"(LEFT, RIGHT : Integer_unit)
  84.     return integer;
  85.   function "/"(LEFT, RIGHT : Integer_unit)
  86.     return float;
  87.   function "rem"(LEFT, RIGHT : Integer_unit)
  88.     return Integer_unit;
  89.   function "mod"(LEFT, RIGHT : Integer_unit)
  90.     return Integer_unit;
  91.   function Dimensionless(LEFT : Integer_unit)
  92.     return integer;
  93.   function Dimensionless(LEFT : Integer_unit)
  94.     return float;
  95.  
  96.   -- "=" and "/=" are already defined for private types
  97.   function "<"(LEFT, RIGHT : Integer_unit)
  98.     return boolean;
  99.   function "<="(LEFT, RIGHT : Integer_unit)
  100.     return boolean;
  101.   function ">"(LEFT, RIGHT : Integer_unit)
  102.     return boolean;
  103.   function ">="(LEFT, RIGHT : Integer_unit)
  104.     return boolean;
  105.  
  106.   type Float_unit is private;
  107.  
  108.   function Type_Convert(X : float) return Float_unit;
  109.     -- Lets you assign values to dimensional objects.
  110.     -- For example,
  111.  
  112.     -- ANGLE := Type_Convert(3.14159);
  113.  
  114.   function "+"(RIGHT : Float_unit)
  115.     return Float_unit;
  116.   function "-"(RIGHT : Float_unit)
  117.     return Float_unit;
  118.   function "abs"(RIGHT : Float_unit)
  119.     return Float_unit;
  120.   function "+"(LEFT, RIGHT : Float_unit)
  121.     return Float_unit;
  122.   function "-"(LEFT, RIGHT : Float_unit)
  123.     return Float_unit;
  124.   function "*"(LEFT : integer; RIGHT : Float_unit)
  125.     return Float_unit;
  126.   function "*"(LEFT : Float_unit; RIGHT : integer)
  127.     return Float_unit;
  128.   function "*"(LEFT : float; RIGHT : Float_unit)
  129.     return Float_unit;
  130.   function "*"(LEFT : Float_unit; RIGHT : float)
  131.     return Float_unit;
  132.   function "/"(LEFT : Float_unit; RIGHT : integer)
  133.     return Float_unit;
  134.   function "/"(LEFT : Float_unit; RIGHT : float)
  135.     return Float_unit;
  136.   function "/"(LEFT, RIGHT : Float_unit)
  137.     return integer; -- truncates toward zero
  138.   function "/"(LEFT, RIGHT : Float_unit)
  139.     return float;
  140.   function "rem"(LEFT, RIGHT : Float_unit)
  141.     return Float_unit;
  142.   function "mod"(LEFT, RIGHT : Float_unit)
  143.     return Float_unit;
  144.   function Dimensionless(LEFT : Float_unit)
  145.     return integer;
  146.   function Dimensionless(LEFT : Float_unit)
  147.     return float;
  148.  
  149.   -- "=" and "/=" are already defined for private types
  150.   function "<"(LEFT, RIGHT : Float_unit)
  151.     return boolean;
  152.   function "<="(LEFT, RIGHT : Float_unit)
  153.     return boolean;
  154.   function ">"(LEFT, RIGHT : Float_unit)
  155.     return boolean;
  156.   function ">="(LEFT, RIGHT : Float_unit)
  157.     return boolean;
  158.  
  159. -- The following don't have any application to dimensional
  160. -- problems. I almost hid them in the package body, but I
  161. -- thought that since I needed them to derive some of the
  162. -- Float_unit operations someone else might need them, too.
  163.  
  164.   function "/"(LEFT, RIGHT : float) return integer;
  165.     -- divide and truncate toward zero
  166.  
  167.   function "rem"(LEFT, RIGHT : float) return float;
  168.  
  169.   function "mod"(LEFT, RIGHT : float) return float;
  170.  
  171. private
  172.  
  173.   type Integer_unit is new integer;
  174.   type Float_unit is new float;
  175.  
  176. end DIMENSIONAL_UNITS;
  177. ::::::::::
  178. DUNITB.ADA
  179. ::::::::::
  180.  
  181. --            -- DUNITB.ada
  182. --            -- VERSION 1.0
  183.  
  184. --            9 March 1986
  185. --            Do-While Jones
  186. --            324 Traci Lane
  187. --            Ridgecrest, CA 93555
  188. --            (619) 375-4607
  189.  
  190. package body DIMENSIONAL_UNITS is
  191.  
  192.   function Type_convert(X : integer) return Integer_unit is
  193.   begin
  194.     return Integer_unit(X);
  195.   end Type_Convert;
  196.  
  197.   function "+"(RIGHT : Integer_unit)
  198.     return Integer_unit is
  199.   begin
  200.     return RIGHT;
  201.   end "+";
  202.  
  203.   function "-"(RIGHT : Integer_unit)
  204.     return Integer_unit is
  205.       X : integer;
  206.   begin
  207.     X := integer(RIGHT);
  208.     return Integer_unit(-X);
  209.   end "-";
  210.  
  211.   function "abs"(RIGHT : Integer_unit)
  212.     return Integer_unit is
  213.   begin
  214.     return Integer_unit(abs(integer(RIGHT)));
  215.   end "abs";
  216.  
  217.   function "+"(LEFT, RIGHT : Integer_unit)
  218.     return Integer_unit is
  219.   begin
  220.     return Integer_unit(integer(LEFT) + integer(RIGHT));
  221.   end "+";
  222.  
  223.   function "-"(LEFT, RIGHT : Integer_unit)
  224.     return Integer_unit is
  225.   begin
  226.     return Integer_unit(integer(LEFT) - integer(RIGHT));
  227.   end "-";
  228.  
  229.   function "*"(LEFT : integer; RIGHT : Integer_unit)
  230.     return Integer_unit is
  231.   begin
  232.     return Integer_unit(LEFT * integer(RIGHT));
  233.   end "*";
  234.  
  235.   function "*"(LEFT : Integer_unit; RIGHT : integer)
  236.     return Integer_unit is
  237.   begin
  238.     return Integer_unit(integer(LEFT) * RIGHT);
  239.   end "*";
  240.  
  241.   function "/"(LEFT : Integer_unit; RIGHT : integer)
  242.     return Integer_unit is
  243.   begin
  244.     return Integer_unit(integer(LEFT) / RIGHT);
  245.   end "/";
  246.  
  247.   function "/"(LEFT, RIGHT : Integer_unit)
  248.     return integer is
  249.   begin
  250.     return integer(LEFT) / integer(RIGHT);
  251.   end "/";
  252.  
  253.   function "/"(LEFT, RIGHT : Integer_unit)
  254.     return float is
  255.       EXACT_QUOTIENT : float;
  256.   begin
  257.     EXACT_QUOTIENT := float(LEFT) / float(RIGHT);
  258.     return EXACT_QUOTIENT;
  259.   end "/";
  260.  
  261.   function "rem"(LEFT, RIGHT : Integer_unit)
  262.     return Integer_unit is
  263.   begin
  264.     return Integer_unit(integer(LEFT) rem integer(RIGHT));
  265.   end "rem";
  266.  
  267.   function "mod"(LEFT, RIGHT : Integer_unit)
  268.     return Integer_unit is
  269.   begin
  270.     return Integer_unit(integer(LEFT) mod integer(RIGHT));
  271.   end "mod";
  272.  
  273.   function Dimensionless(LEFT : Integer_unit)
  274.     return integer is
  275.   begin
  276.     return integer(LEFT);
  277.   end Dimensionless;
  278.  
  279.   function Dimensionless(LEFT : Integer_unit)
  280.     return float is
  281.   begin
  282.     return float(LEFT);
  283.   end Dimensionless;
  284.  
  285.   function "<"(LEFT, RIGHT : Integer_unit)
  286.     return boolean is
  287.   begin
  288.     return integer(LEFT) < integer(RIGHT);
  289.   end "<";
  290.  
  291.   function "<="(LEFT, RIGHT : Integer_unit)
  292.     return boolean is
  293.   begin
  294.     return integer(LEFT) <= integer(RIGHT);
  295.   end "<=";
  296.  
  297.   function ">"(LEFT, RIGHT : Integer_unit)
  298.     return boolean is
  299.   begin
  300.     return integer(LEFT) > integer(RIGHT);
  301.   end ">";
  302.  
  303.   function ">="(LEFT, RIGHT : Integer_unit)
  304.     return boolean is
  305.   begin
  306.     return integer(LEFT) >= integer(RIGHT);
  307.   end ">=";
  308.  
  309.   function Type_convert(X : float) return Float_unit is
  310.   begin
  311.     return Float_unit(X);
  312.   end Type_Convert;
  313.  
  314.   function "+"(RIGHT : Float_unit)
  315.     return Float_unit is
  316.   begin
  317.     return RIGHT;
  318.   end "+";
  319.  
  320.   function "-"(RIGHT : Float_unit)
  321.     return Float_unit is
  322.       X : float;
  323.   begin
  324.     X := float(RIGHT);
  325.     return Float_unit(-X);
  326.   end "-";
  327.  
  328.   function "abs"(RIGHT : Float_unit)
  329.     return Float_unit is
  330.   begin
  331.     return Float_unit(abs(float(RIGHT)));
  332.   end "abs";
  333.  
  334.   function "+"(LEFT, RIGHT : Float_unit)
  335.     return Float_unit is
  336.   begin
  337.     return Float_unit(float(LEFT) + float(RIGHT));
  338.   end "+";
  339.  
  340.   function "-"(LEFT, RIGHT : Float_unit)
  341.     return Float_unit is
  342.   begin
  343.     return Float_unit(float(LEFT) - float(RIGHT));
  344.   end "-";
  345.  
  346.   function "*"(LEFT : integer; RIGHT : Float_unit)
  347.     return Float_unit is
  348.   begin
  349.     return Float_unit(float(LEFT) * float(RIGHT));
  350.   end "*";
  351.  
  352.   function "*"(LEFT : Float_unit; RIGHT : integer)
  353.     return Float_unit is
  354.   begin
  355.     return Float_unit(float(LEFT) * float(RIGHT));
  356.   end "*";
  357.  
  358.   function "*"(LEFT : float; RIGHT : Float_unit)
  359.     return Float_unit is
  360.   begin
  361.     return Float_unit(LEFT * float(RIGHT));
  362.   end "*";
  363.  
  364.   function "*"(LEFT : Float_unit; RIGHT : float)
  365.     return Float_unit is
  366.   begin
  367.     return Float_unit(float(LEFT) * RIGHT);
  368.   end "*";
  369.  
  370.   function "/"(LEFT : Float_unit; RIGHT : integer)
  371.     return Float_unit is
  372.       EXACT_QUOTIENT : float;
  373.   begin
  374.     EXACT_QUOTIENT := float(LEFT) / float(RIGHT);
  375.     return Float_unit(EXACT_QUOTIENT);
  376.   end "/";
  377.  
  378.   function "/"(LEFT : Float_unit; RIGHT : float)
  379.     return Float_unit is
  380.       EXACT_QUOTIENT : float;
  381.   begin
  382.     EXACT_QUOTIENT := float(LEFT) / RIGHT;
  383.     return Float_unit(EXACT_QUOTIENT);
  384.   end "/";
  385.  
  386.   function "/"(LEFT, RIGHT : Float_unit)
  387.     return integer is
  388.       TRUNCATED_QUOTIENT : integer;
  389.   begin
  390.     TRUNCATED_QUOTIENT := float(LEFT) / float(RIGHT);
  391.     -- using special "/" operation below
  392.     return TRUNCATED_QUOTIENT;
  393.   end "/";
  394.  
  395.   function "/"(LEFT, RIGHT : Float_unit)
  396.     return float is
  397.       EXACT_QUOTIENT : float;
  398.   begin
  399.     EXACT_QUOTIENT := float(LEFT) / float(RIGHT);
  400.     return EXACT_QUOTIENT;
  401.   end "/";
  402.  
  403.   function "rem"(LEFT, RIGHT : Float_unit)
  404.     return Float_unit is
  405.   begin
  406.     return Float_unit(float(LEFT) rem float(RIGHT));
  407.   end "rem";
  408.  
  409.   function "mod"(LEFT, RIGHT : Float_unit)
  410.     return Float_unit is
  411.   begin
  412.     return Float_unit(float(LEFT) mod float(RIGHT));
  413.   end "mod";
  414.  
  415.   function Dimensionless(LEFT : Float_unit)
  416.     return integer is
  417.   begin
  418.     return integer(LEFT);
  419.   end Dimensionless;
  420.  
  421.   function Dimensionless(LEFT : Float_unit)
  422.     return float is
  423.   begin
  424.     return float(LEFT);
  425.   end Dimensionless;
  426.  
  427.   function "<"(LEFT, RIGHT : Float_unit)
  428.     return boolean is
  429.   begin
  430.     return float(LEFT) < float(RIGHT);
  431.   end "<";
  432.  
  433.   function "<="(LEFT, RIGHT : Float_unit)
  434.     return boolean is
  435.   begin
  436.     return float(LEFT) <= float(RIGHT);
  437.   end "<=";
  438.  
  439.   function ">"(LEFT, RIGHT : Float_unit)
  440.     return boolean is
  441.   begin
  442.     return float(LEFT) > float(RIGHT);
  443.   end ">";
  444.  
  445.   function ">="(LEFT, RIGHT : Float_unit)
  446.     return boolean is
  447.   begin
  448.     return float(LEFT) >= float(RIGHT);
  449.   end ">=";
  450.  
  451. -- The following don't have any application to dimensional
  452. -- problems. I almost hid them in the package body, but I
  453. -- thought that since I needed them to derive some of the
  454. -- Float_unit operations someone else might need them, too.
  455.  
  456.   function "/"(LEFT, RIGHT : float) return integer is
  457.     -- divide and truncate toward zero
  458.     EXACT : float;
  459.     ROUNDED, TRUNCATED : integer;
  460.   begin
  461.     EXACT := LEFT / RIGHT;
  462.     ROUNDED := integer(EXACT);
  463.     if float(abs(ROUNDED)) > abs(EXACT) then
  464.       if ROUNDED > 0 then
  465.         TRUNCATED := ROUNDED-1;
  466.       else
  467.         TRUNCATED := ROUNDED+1;
  468.       end if;
  469.     else
  470.       TRUNCATED := ROUNDED;
  471.     end if;
  472.     return TRUNCATED;
  473.   end "/";
  474.  
  475.   function "rem"(LEFT, RIGHT : float) return float is
  476.     COMPLETE_CYCLES : integer;
  477.     REMAINDER       : float;
  478.   begin
  479.     COMPLETE_CYCLES := LEFT / RIGHT;
  480.     REMAINDER := LEFT - float(COMPLETE_CYCLES) * RIGHT;
  481.     return REMAINDER;
  482.   end "rem";
  483.  
  484.   function "mod"(LEFT, RIGHT : float) return float is
  485.     REMAINDER : float;
  486.   begin
  487.     REMAINDER := LEFT rem RIGHT;
  488.     if LEFT * RIGHT > 0.0 then
  489.       return REMAINDER;
  490.     elsif REMAINDER = 0.0 then
  491.       return REMAINDER;
  492.     else
  493.       return REMAINDER + RIGHT;
  494.     end if;
  495.   end "mod";
  496.  
  497. end DIMENSIONAL_UNITS;
  498. ::::::::::
  499. DUEX.ADA
  500. ::::::::::
  501.  
  502. --            DUEX.ada
  503. -- This is an example of how the use of dimensional units as data
  504. -- types improves program clarity.
  505.  
  506. -------------------    Compilation Unit 1  ------------------------
  507.  
  508. with DIMENSIONAL_UNITS; use DIMENSIONAL_UNITS;
  509. package SPEED_GUN_UNITS is
  510.  
  511.   type Miles_per_hour is new Integer_unit;
  512.   type Hertz is new Float_unit;
  513.   type Miles_per_second is new Float_unit;
  514.  
  515.   function Type_Convert(X : Miles_per_second)
  516.    return Miles_per_hour;
  517.  
  518.   function "*"(LEFT : Miles_per_second; RIGHT : float)
  519.    return Miles_per_hour;
  520.  
  521. end SPEED_GUN_UNITS;
  522.  
  523. with SPEED_GUN_UNITS; use SPEED_GUN_UNITS;
  524. package HARDWARE_CIRCUITS is
  525.  
  526.   function Xmit_Frequency_Measurement return Hertz;
  527.  
  528.   function Doppler_Frequency_Measurement return Hertz;
  529.   procedure put(X : Miles_per_hour);
  530.  
  531. end HARDWARE_CIRCUITS;
  532.  
  533. with HARDWARE_CIRCUITS; use HARDWARE_CIRCUITS;
  534. with SPEED_GUN_UNITS; use SPEED_GUN_UNITS;
  535. procedure Speed_Gun is
  536.   TRANSMIT_FREQUENCY, DOPPLER_FREQUENCY : Hertz;
  537.   SPEED : Miles_per_hour;
  538.   C : constant Miles_per_second
  539.    := Type_Convert(186_280.0); -- speed of light
  540. begin
  541.   TRANSMIT_FREQUENCY := Xmit_Frequency_Measurement;
  542.   DOPPLER_FREQUENCY := Doppler_Frequency_Measurement;
  543.   SPEED := (C/2.0) * (DOPPLER_FREQUENCY / TRANSMIT_FREQUENCY);
  544.   put(SPEED);
  545. end Speed_Gun;
  546.  
  547. package body SPEED_GUN_UNITS is
  548.  
  549.   function Type_Convert(X : Miles_per_second)
  550.    return Miles_per_hour is
  551.     F : float;
  552.   begin
  553.     F := Dimensionless(X) * 60.0 * 60.0;
  554.     return Type_Convert(integer(F));
  555.   end Type_Convert;
  556.  
  557.   function "*"(LEFT : Miles_per_second; RIGHT : float)
  558.    return Miles_per_hour is
  559.   begin
  560.     return Type_Convert(LEFT * RIGHT);
  561.   end "*";
  562.  
  563. end SPEED_GUN_UNITS;
  564.  
  565. with TEXT_IO; use TEXT_IO;
  566. package body HARDWARE_CIRCUITS is
  567.   -- The statements below are standing in for code which would
  568.   -- read the frequency directly from hardware circuits and
  569.   -- would display speed on an LCD or LED display. Since I'm
  570.   -- using a terminal as a substitute IO device I used TEXT_IO
  571.   -- to get and put data.
  572.  
  573.   package INT_IO is new INTEGER_IO(integer); use INT_IO;
  574.   package F_IO is new FLOAT_IO(float); use F_IO;
  575.  
  576.   function Xmit_Frequency_Measurement return HErtz is
  577.     F : float;
  578.   begin
  579.     put("What is the Transmit Frequency (in Hertz)? ");
  580.     get(F);
  581.     -- skip_line; -- TEXT_IO quirk
  582.     return Type_Convert(F);
  583.   end Xmit_Frequency_Measurement;
  584.  
  585.   function Doppler_Frequency_Measurement return Hertz is
  586.     F : float;
  587.   begin
  588.     put("What is the Doppler Frequency (in Hertz)?");
  589.     get(F);
  590.     -- skip_line; -- TEXT_IO quirk
  591.     return Type_Convert(F);
  592.   end Doppler_Frequency_Measurement;
  593.  
  594.   procedure put(X : Miles_per_hour) is
  595.     I : integer;
  596.   begin
  597.     I := Dimensionless(X);
  598.     put("The speed is "); put(I); put_line(" MPH.");
  599.   end put;
  600.  
  601. end HARDWARE_CIRCUITS;
  602. ::::::::::
  603. DIM_UNIT.PRO
  604. ::::::::::
  605.  
  606.  
  607. -------- SIMTEL20 Ada Software Repository Prologue ------------
  608. --
  609. -- Unit name    : DIMENSIONAL_UNITS
  610. -- Version      : 1.0
  611. -- Author       : Do-While Jones
  612. --              : 324 Traci Lane
  613. --              : Ridgecrest, CA 93555
  614. --              : (619) 375-4607
  615. -- DDN Address  : 
  616. -- Copyright    : (c) 
  617. -- Date created :  
  618. -- Release date : 1 May 1987
  619. -- Last update  :  
  620. -- Machine/System Compiled/Run on :
  621. --  DEC Ada on VAX
  622. --  APLEX (Telegen 2) on Gould 32/97 running MPX
  623. --  Does not run on Alsys on AT because of a bug in Alsys.
  624. --  (The DUTEST program will tell you if it works on your system.)
  625. --
  626. ---------------------------------------------------------------
  627. --
  628. -- Keywords     : Dimensional Units
  629. --
  630. -- Abstract     :  
  631. --   This package provides useful parent types for derived
  632. --   dimensional units. That is, it makes it possible to
  633. --   do this:
  634. --      type Feet is new Integer_Unit;
  635. --      type Radians is new Float_Unit;
  636. --   Objects of type Feet can be added together, but can't be
  637. --   multiplied together to get a result in feet.
  638. --
  639. --  See Dr. Dobb's Journal of Software Tools issue #127
  640. --  (May 1987) page 50 for a complete description of how to
  641. --  use this package.
  642. --
  643. --  Unfortunately Dr. Dobb failed to publish the package body and
  644. --  the test routines.
  645. --
  646. --  The complete set of files consists of:
  647. --    DUNITS.ADA (DIMENSIONAL_UNITS package specification)
  648. --    DUNITB.ADA (DIMENSIONAL_UNITS package body)
  649. --    DUEX.ADA   (procedure Speed_Gun example program)
  650. --    DUTEST.ADA (Exhaustive test program with 3 subunits)
  651. --    DUTEST1.ADA (subunit 1)
  652. --    DUTEST2.ADA (subunit 2)
  653. --    DUTEST3.ADA (subunit 3)
  654. --
  655. ------------------ Revision history ---------------------------
  656. --
  657. -- DATE         VERSION    AUTHOR                  HISTORY
  658. --
  659. ------------------ Distribution and Copyright -----------------
  660. --
  661. -- This prologue must be included in all copies of this software.
  662. --
  663. -- This software is released to the Public Domain (note:
  664. --   software released to the Public Domain is not subject
  665. --   to copyright protection).
  666. -- Restrictions on use or distribution:  NONE
  667. --
  668. ------------------ Disclaimer ---------------------------------
  669. --
  670. -- This software and its documentation are provided "AS IS" and
  671. -- without any expressed or implied warranties whatsoever.
  672. -- No warranties as to performance, merchantability, or fitness
  673. -- for a particular purpose exist.
  674. --
  675. -- Because of the diversity of conditions and hardware under
  676. -- which this software may be used, no warranty of fitness for
  677. -- a particular purpose is offered.  The user is advised to
  678. -- test the software thoroughly before relying on it.  The user
  679. -- must assume the entire risk and liability of using this
  680. -- software.
  681. --
  682. -- In no event shall any person or organization of people be
  683. -- held responsible for any direct, indirect, consequential
  684. -- or inconsequential damages or lost profits.
  685. --
  686. -------------------END-PROLOGUE--------------------------------
  687. ::::::::::
  688. DUTEST.ADA
  689. ::::::::::
  690.  
  691. --            DUTEST.ADA
  692. --            Version 1.0
  693. --            1 January 1986
  694.  
  695. --            Do-While Jones
  696. --            324 Traci Lane
  697. --            Ridgecrest, CA 93555
  698. --            (619) 375-4607
  699.  
  700. with DIMENSIONAL_UNITS; use DIMENSIONAL_UNITS;
  701. with TEXT_IO; use TEXT_IO;
  702. procedure DU_Test is
  703.   procedure Test_1 is separate;
  704.   procedure Test_2 is separate;
  705.   procedure Test_3 is separate;
  706. begin
  707.   new_line;
  708.   put_line("Dimensional Units Test - Version 1.0");
  709.   put_line("1 January 1986 by Do-While Jones");
  710.   new_line;
  711.   Test_1; -- checks valid integer operations
  712.   Test_2; -- checks valid float operations
  713.   Test_3; -- checks extra operations
  714.   put_line("Dimensional Unit test complete.");
  715.   new_line;
  716. end DU_Test;
  717. ::::::::::
  718. DUTEST1.ADA
  719. ::::::::::
  720. --            DUTEST1.ADA
  721. --            Version 1.0
  722. --            3 January 1986
  723. --            Do-While Jones
  724.  
  725. separate(DU_Test)
  726. procedure Test_1 is
  727.  
  728.   type Feet is new Integer_unit;
  729.  
  730.   X, Y, Z : Feet;
  731.   F       : float;
  732.   TEST_A_PASSED, TEST_B_PASSED, TEST_C_PASSED, TEST_D_PASSED,
  733.   TEST_E_PASSED, TEST_F_PASSED, TEST_G_PASSED, TEST_H_PASSED,
  734.   TEST_I_PASSED, TEST_J_PASSED, TEST_K_PASSED, TEST_L_PASSED,
  735.   TEST_M_PASSED, TEST_N_PASSED, TEST_O_PASSED, TEST_P_PASSED,
  736.   TEST_Q_PASSED, TEST_R_PASSED : boolean := FALSE;
  737. begin
  738.   X := Type_Convert(3);
  739.   Y := Type_Convert(2);
  740.   Z := Type_Convert(5);
  741.   TEST_A_PASSED := X + Y = Z;
  742.   if not TEST_A_PASSED then
  743.     put_line("ADDITION_OPERATOR DOES NOT WORK!");
  744.   end if;
  745.   TEST_B_PASSED := Z - Y = X;
  746.   if not TEST_B_PASSED then
  747.     put_line("SUBTRACTION OPERATOR DOES NOT WORK!");
  748.   end if;
  749.   Z := Type_Convert(6);
  750.   TEST_C_PASSED := 2 * X = Z;
  751.   if not TEST_C_PASSED then
  752.     put_line("LEFT INTEGER MULTIPLICATION FAILED!");
  753.   end if;
  754.   TEST_D_PASSED := X * 2 = Z;
  755.   if not TEST_D_PASSED then
  756.     put_line("RIGHT INTEGER MULTIPLICATION FAILED!");
  757.   end if;
  758.   TEST_E_PASSED := Z / 2 = X;
  759.   if not TEST_E_PASSED then
  760.     put_line("INTEGER DIVISION FAILED!");
  761.   end if;
  762.   TEST_F_PASSED := Z / X = 2;
  763.   if not TEST_F_PASSED then
  764.     put_line("DIMENSIONAL DIVISION WITH INTEGER RESULT FAILED!");
  765.   end if;
  766.   F := X / Z;
  767.   TEST_G_PASSED := abs(F - 0.5) < 0.001;
  768.   if not TEST_G_PASSED then
  769.     put_line("DIMENSIONAL DIVISION WITH FLOAT RESULT FAILED!");
  770.   end if;
  771.   Z := Type_Convert(5);
  772.   TEST_H_PASSED := Z rem X = Y;
  773.   if not TEST_H_PASSED then
  774.     put_line("INTEGER_UNIT REM OPERATION FAILED!");
  775.   end if;
  776.   TEST_I_PASSED := Z mod X = Y;
  777.   if not TEST_I_PASSED then
  778.     put_line("INTEGER_UNIT MOD OPERATION FAILED!");
  779.   end if;
  780.   TEST_J_PASSED := Dimensionless(Z) = 5;
  781.   if not TEST_J_PASSED then
  782.     put_line("DIMENSIONLESS INTEGER_UNIT INTEGER RESULT FAILED!");
  783.   end if;
  784.   F := Dimensionless(Z);
  785.   TEST_K_PASSED := abs(F - 5.0) < 0.001;
  786.   if not TEST_K_PASSED then
  787.     put_line("DIMENSIONLESS INTEGER_UNIT FLOAT RESULT FAILED!");
  788.   end if;
  789.   X := Type_Convert(1);
  790.   Y := Type_Convert(2);
  791.   Z := Y;
  792.   TEST_L_PASSED := X < Y and not(Y < X);
  793.   if not TEST_L_PASSED then
  794.     put_line("INTEGER_UNIT < FAILED!");
  795.   end if;
  796.   TEST_M_PASSED := X < Y and Y <= Z and not (Z <= X);
  797.   if not TEST_M_PASSED then
  798.     put_line("INTEGER_UNIT <= FAILED!");
  799.   end if;
  800.   TEST_N_PASSED := Y > X and not (X > Y);
  801.   if not TEST_N_PASSED then
  802.     put_line("INTEGER_UNIT > FAILED!");
  803.   end if;
  804.   TEST_O_PASSED := Z >= X and Z >= Y and not (X >= Z);
  805.   if not TEST_O_PASSED then
  806.     put_line("INTEGER_UNIT >= FAILED!");
  807.   end if;
  808.   TEST_P_PASSED := Y = Z and not (X = Z);
  809.   if not TEST_P_PASSED then
  810.     put_line("INTEGER_UNIT = FAILED!");
  811.   end if;
  812.   TEST_Q_PASSED := X = +X;
  813.   if not TEST_Q_PASSED then
  814.     put_line("INTEGER_UNIT UNARY + FAILED!");
  815.   end if;
  816.   TEST_R_PASSED := -X = -1 * X;
  817.   if not TEST_R_PASSED then
  818.     put_line("INTEGER_UNIT UNARY - FAILED!");
  819.   end if;
  820.   if TEST_A_PASSED and TEST_B_PASSED and
  821.      TEST_C_PASSED and TEST_D_PASSED and
  822.      TEST_E_PASSED and TEST_F_PASSED and
  823.      TEST_G_PASSED and TEST_H_PASSED and
  824.      TEST_I_PASSED and TEST_J_PASSED and
  825.      TEST_K_PASSED and TEST_L_PASSED and
  826.      TEST_M_PASSED and TEST_N_PASSED and
  827.      TEST_O_PASSED and TEST_P_PASSED and
  828.      TEST_Q_PASSED and TEST_R_PASSED then
  829.     put_line("All valid integer operations work.");
  830.   end if;
  831.   put_line("Test 1 Complete.");
  832. end Test_1;
  833. ::::::::::
  834. DUTEST2.ADA
  835. ::::::::::
  836. --            DUTEST2.ADA
  837. --            Version 1.0
  838. --            3 January 1986
  839. --            Do-While Jones
  840.  
  841. separate(DU_Test)
  842. procedure Test_2 is
  843.  
  844.   type Feet is new Float_unit;
  845.  
  846.   X, Y, Z : Feet;
  847.   F       : float;
  848.   TEST_A_PASSED, TEST_B_PASSED, TEST_C_PASSED, TEST_D_PASSED,
  849.   TEST_E_PASSED, TEST_F_PASSED, TEST_G_PASSED, TEST_H_PASSED,
  850.   TEST_I_PASSED, TEST_J_PASSED, TEST_K_PASSED, TEST_L_PASSED,
  851.   TEST_M_PASSED, TEST_N_PASSED, TEST_O_PASSED, TEST_P_PASSED,
  852.   TEST_Q_PASSED, TEST_R_PASSED, TEST_S_PASSED, TEST_T_PASSED,
  853.   TEST_U_PASSED, TEST_V_PASSED, TEST_W_PASSED, TEST_X_PASSED,
  854.   TEST_Y_PASSED, TEST_Z_PASSED : boolean := FALSE;
  855. begin
  856.   X := Type_Convert(3.0);
  857.   Y := Type_Convert(2.0);
  858.   Z := Type_Convert(5.0);
  859.   TEST_A_PASSED := X + Y = Z;
  860.   if not TEST_A_PASSED then
  861.     put_line("ADDITION_OPERATOR DOES NOT WORK!");
  862.   end if;
  863.   TEST_B_PASSED := Z - Y = X;
  864.   if not TEST_B_PASSED then
  865.     put_line("SUBTRACTION OPERATOR DOES NOT WORK!");
  866.   end if;
  867.   Z := Type_Convert(6.0);
  868.   TEST_C_PASSED := 2 * X = Z;
  869.   if not TEST_C_PASSED then
  870.     put_line("LEFT INTEGER MULTIPLICATION FAILED!");
  871.   end if;
  872.   TEST_D_PASSED := X * 2 = Z;
  873.   if not TEST_D_PASSED then
  874.     put_line("RIGHT INTEGER MULTIPLICATION FAILED!");
  875.   end if;
  876.   TEST_E_PASSED := Z / 2 = X;
  877.   if not TEST_E_PASSED then
  878.     put_line("INTEGER DIVISION FAILED!");
  879.   end if;
  880.   TEST_F_PASSED := Z / X = 2;
  881.   if not TEST_F_PASSED then
  882.     put_line("DIMENSIONAL DIVISION WITH INTEGER RESULT FAILED!");
  883.   end if;
  884.   F := X / Z;
  885.   TEST_G_PASSED := abs(F - 0.5) < 0.001;
  886.   if not TEST_G_PASSED then
  887.     put_line("DIMENSIONAL DIVISION WITH FLOAT RESULT FAILED!");
  888.   end if;
  889.   Z := Type_Convert(5.0);
  890.   TEST_H_PASSED := Z rem X = Y;
  891.   if not TEST_H_PASSED then
  892.     put_line("FLOAT_UNIT REM OPERATION FAILED!");
  893.   end if;
  894.   TEST_I_PASSED := Z mod X = Y;
  895.   if not TEST_I_PASSED then
  896.     put_line("FLOAT_UNIT MOD OPERATION FAILED!");
  897.   end if;
  898.   TEST_J_PASSED := Dimensionless(Z) = 5;
  899.   if not TEST_J_PASSED then
  900.     put_line("DIMENSIONLESS FLOAT_UNIT INTEGER RESULT FAILED!");
  901.   end if;
  902.   F := Dimensionless(Z);
  903.   TEST_K_PASSED := abs(F - 5.0) < 0.001;
  904.   if not TEST_K_PASSED then
  905.     put_line("DIMENSIONLESS FLOAT_UNIT FLOAT RESULT FAILED!");
  906.   end if;
  907.   X := Type_Convert(1.0);
  908.   Y := Type_Convert(2.0);
  909.   Z := Y;
  910.   TEST_L_PASSED := X < Y and not(Y < X);
  911.   if not TEST_L_PASSED then
  912.     put_line("FLOAT_UNIT < FAILED!");
  913.   end if;
  914.   TEST_M_PASSED := X <= Y and Y <= Z and not (Z <= X);
  915.   if not TEST_M_PASSED then
  916.     put_line("FLOAT_UNIT <= FAILED!");
  917.   end if;
  918.   TEST_N_PASSED := Y > X and not (X > Y);
  919.   if not TEST_N_PASSED then
  920.     put_line("FLOAT_UNIT > FAILED!");
  921.   end if;
  922.   TEST_O_PASSED := Z >= X and Z >= Y and not (X >= Z);
  923.   if not TEST_O_PASSED then
  924.     put_line("FLOAT_UNIT >= FAILED!");
  925.   end if;
  926.   TEST_P_PASSED := Y = Z and not (X = Z);
  927.   if not TEST_P_PASSED then
  928.     put_line("FLOAT_UNIT = FAILED!");
  929.   end if;
  930.   TEST_Q_PASSED := X = +X;
  931.   if not TEST_Q_PASSED then
  932.     put_line("FLOAT_UNIT UNARY + FAILED!");
  933.   end if;
  934.   TEST_R_PASSED := -X = -1 * X;
  935.   if not TEST_R_PASSED then
  936.     put_line("FLOAT_UNIT UNARY - FAILED!");
  937.   end if;
  938.   X := Type_Convert(6.0);
  939.   Y := Type_Convert(2.0);
  940.   Z := Type_Convert(3.0);
  941.   TEST_S_PASSED := X = 3.0 * Y;
  942.   if not TEST_S_PASSED then
  943.     put_line("FLOAT * FLOAT_UNIT FAILED!");
  944.   end if;
  945.   TEST_T_PASSED := X = Y * 3.0;
  946.   if not TEST_T_PASSED then
  947.     put_line("FLOAT_UNIT * FLOAT FAILED!");
  948.   end if;
  949.   TEST_U_PASSED := Z = X / 2.0;
  950.   if not TEST_U_PASSED then
  951.     put_line("FLOAT_UNIT / FLOAT FAILED");
  952.   end if;
  953.   if TEST_A_PASSED and TEST_B_PASSED and
  954.      TEST_C_PASSED and TEST_D_PASSED and
  955.      TEST_E_PASSED and TEST_F_PASSED and
  956.      TEST_G_PASSED and TEST_H_PASSED and
  957.      TEST_I_PASSED and TEST_J_PASSED and
  958.      TEST_K_PASSED and TEST_L_PASSED and
  959.      TEST_M_PASSED and TEST_N_PASSED and
  960.      TEST_O_PASSED and TEST_P_PASSED and
  961.      TEST_Q_PASSED and TEST_R_PASSED and
  962.      TEST_S_PASSED and TEST_T_PASSED and
  963.      TEST_U_PASSED then
  964.     put_line("All valid float operations work.");
  965.   end if;
  966.   put_line("Test 2 Complete.");
  967. end Test_2;
  968. ::::::::::
  969. DUTEST3.ADA
  970. ::::::::::
  971.  
  972. --            DUTEST3.ADA
  973. --            Version 1.0
  974. --            31 August 1986
  975. --            Do-While Jones
  976.  
  977. separate(DU_Test)
  978. procedure Test_3 is
  979.  
  980.   type Radians is new Float_unit;
  981.   type Feet is new Integer_unit;
  982.  
  983.   DISTANCE    : Feet;
  984.   ANGLE       : Radians;
  985.   PI          : constant Radians := Type_Convert(3.14159);
  986.   REVOLUTIONS : integer;
  987.  
  988.  
  989.   TEST_A_PASSED, TEST_B_PASSED, TEST_C_PASSED, TEST_D_PASSED,
  990.   TEST_E_PASSED, TEST_F_PASSED, TEST_G_PASSED, TEST_H_PASSED,
  991.   TEST_I_PASSED, TEST_J_PASSED, TEST_K_PASSED, TEST_L_PASSED,
  992.   TEST_M_PASSED, TEST_N_PASSED, TEST_O_PASSED, TEST_P_PASSED,
  993.   TEST_Q_PASSED, TEST_R_PASSED : boolean := FALSE;
  994. begin
  995.   TEST_A_PASSED := 7.0 / 3.0 = 2;
  996.   TEST_B_PASSED := -7.0 / 3.0 = -2;
  997.   TEST_C_PASSED := 7.0 / (-3.0) = -2;
  998.   TEST_D_PASSED := -7.0 / (-3.0) = 2;
  999.   if not (TEST_A_PASSED and TEST_B_PASSED and TEST_C_PASSED
  1000.    and TEST_D_PASSED) then
  1001.     put_line("EXTRA DIVISION FAILED!");
  1002.   end if;
  1003.   TEST_E_PASSED := 7.0 rem 3.0 = 1.0;
  1004.   TEST_F_PASSED := (-7.0) rem 3.0 = -1.0;
  1005.   TEST_G_PASSED := 7.0 rem (-3.0) = 1.0;
  1006.   TEST_H_PASSED := (-7.0) rem (-3.0) = -1.0;
  1007.   if not (TEST_E_PASSED and TEST_F_PASSED and TEST_G_PASSED
  1008.    and TEST_H_PASSED) then
  1009.     put_line("EXTRA REM FAILED!");
  1010.   end if;
  1011.   TEST_I_PASSED := 7.0 mod 3.0 = 1.0;
  1012.   TEST_J_PASSED := (-7.0) mod 3.0 = 2.0;
  1013.   TEST_K_PASSED := 7.0 mod (-3.0) = -2.0;
  1014.   TEST_L_PASSED := (-7.0) mod (-3.0) = -1.0;
  1015.   if not (TEST_I_PASSED and TEST_J_PASSED and TEST_K_PASSED
  1016.    and TEST_L_PASSED) then
  1017.     put_line("EXTRA MOD FAILED!");
  1018.   end if;
  1019.   if TEST_A_PASSED and TEST_B_PASSED and
  1020.      TEST_C_PASSED and TEST_D_PASSED and
  1021.      TEST_E_PASSED and TEST_F_PASSED and
  1022.      TEST_G_PASSED and TEST_H_PASSED and
  1023.      TEST_I_PASSED and TEST_J_PASSED and
  1024.      TEST_K_PASSED and TEST_L_PASSED then
  1025.     put_line("All valid extra operations work.");
  1026.   end if;
  1027.  
  1028. -- and here are a few extra tests I forgot
  1029.  
  1030.   ANGLE := Type_Convert(7.0);
  1031.   ANGLE := ANGLE mod (2.0 * PI);
  1032.   TEST_M_PASSED := abs(ANGLE-Type_Convert(0.71682))
  1033.    < Type_Convert(0.001);
  1034.   DISTANCE := Type_Convert(-87);
  1035.   TEST_N_PASSED := abs(DISTANCE) = Type_Convert(87);
  1036.   ANGLE := Type_Convert(14.0);
  1037.   REVOLUTIONS := ANGLE / (2.0 * PI);
  1038.   TEST_O_PASSED := REVOLUTIONS = 2;
  1039.   if TEST_M_PASSED and TEST_N_PASSED and TEST_O_PASSED then
  1040.     put_line("The forgotten tests worked, too!");
  1041.   else
  1042.     put_line("OOPS! At least one forgotten test FAILED!");
  1043.   end if;
  1044.   put_line("Test 3 Complete.");
  1045. end Test_3;
  1046.