home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / piwg / a000091.ada < prev    next >
Encoding:
Text File  |  1988-05-03  |  14.3 KB  |  426 lines

  1. -------------------------------------------------------------------------------
  2. --                                                                           --
  3. --                "DHRYSTONE" Benchmark Program                              --
  4. --                -----------------------------                              --
  5. --                                                                           --
  6. --         Version ADA/1                                                     --
  7. --                                                                           --
  8. --         Date:   04/15/84                                                  --
  9. --                                                                           --
  10. --         Author: Reinhold P. Weicker                                       --
  11. --                                                                           --
  12. --                                                                           --
  13. --  As published in Communications of ACM, October 1984  Vol 27 No 10        --
  14. --                                                                           --
  15. -------------------------------------------------------------------------------
  16. --                                                                           --
  17. -- The following program contains statements of a high-level programming     --
  18. -- language (Ada) in a distribution considered representative:               --
  19. --                                                                           --
  20. --   assignments               53%                                           --
  21. --   control statements        32%                                           --
  22. --   procedures, function call 15%                                           --
  23.  
  24. -- 100 statements are dynamically executed. The program is balanced with     --
  25. -- respect to the three aspects:                                             --
  26. --                                                                           --
  27. --    - statement type                                                       --
  28. --    - operand type (for simple data types)                                 --
  29. --    - operand access                                                       --
  30. --         operand global, local, parameter, or constant.                    --
  31. --                                                                           --
  32. -- The combination of these three aspects is balanced only approximately.    --
  33. --                                                                           --
  34. -- The program does not compute anything meaningful, but it is syntactically --
  35. -- and semantically correct. All variables have a value assigned to them     --
  36. -- before they are used as a source operand                                  --
  37. -------------------------------------------------------------------------------
  38. package global_def is
  39. ------------------
  40.  
  41. -- global definintions
  42.  
  43. type Enumeration is (ident_1,ident_2,ident_3,ident_4,ident_5);
  44.  
  45. subtype one_to_thirty is integer range 1..30;
  46. subtype one_to_fifty is integer range 1..50;
  47. subtype capital_letter is character range 'A'..'Z';
  48.  
  49. type String_30 is array(one_to_thirty) of character;
  50.     pragma pack(string_30);
  51.  
  52. type array_1_dim_integer is array (one_to_fifty) of integer;
  53. type array_2_dim_integer is array (one_to_fifty,
  54.                                    one_to_fifty)  of integer;
  55.  
  56. type record_type(discr:enumeration:=ident_1);
  57.  
  58. type record_pointer is access record_type;
  59.  
  60. type record_type(discr:enumeration:=ident_1) is
  61.     record
  62.         pointer_comp:           record_pointer;
  63.         case discr is
  64.         when ident_1 =>         -- only this variant is used,
  65.                                 -- but in some cases discriminant
  66.                                 -- checks are necessary
  67.           enum_comp:            enumeration;
  68.           int_comp:             one_to_fifty;
  69.           string_comp:          string_30;
  70.         when ident_2 =>
  71.           enum_comp_2:          enumeration;
  72.           string_comp_2:        string_30;
  73.         when others =>
  74.           char_comp_1,
  75.           char_comp_2:          character;
  76.         end case;
  77.     end record;
  78.  
  79. end global_def;
  80.  
  81.     with global_def;
  82.     use global_def;
  83.  
  84. package pack_1 is
  85. -------------
  86.  
  87.     procedure proc_0;
  88.     procedure proc_1(pointer_par_in:  in      record_pointer);
  89.     procedure proc_2(int_par_in_out:  in out  one_to_fifty);
  90.     procedure proc_3(pointer_par_out: out     record_pointer);
  91.  
  92.     int_glob:   integer;
  93.  
  94. end pack_1;
  95.  
  96.     with global_def;
  97.     use global_def;
  98.  
  99. package pack_2 is
  100. --------------
  101.  
  102.     procedure proc_6 (enum_par_in:      in      enumeration;
  103.                       enum_par_out:     out     enumeration);
  104.  
  105.     procedure proc_7 (int_par_in_1,
  106.                       int_par_in_2:     in      one_to_fifty;
  107.                       int_par_out:      out     one_to_fifty);
  108.  
  109.     procedure proc_8 (array_par_in_out_1: in out array_1_dim_integer;
  110.                       array_par_in_out_2: in out array_2_dim_integer;
  111.                       int_par_in_1,
  112.                       int_par_in_2:       in     integer);
  113.  
  114.     function func_1  (char_par_in_1,
  115.                       char_par_in_2:      in     capital_letter)
  116.                                                    return enumeration;
  117.  
  118.     function func_2  (string_par_in_1,
  119.                       string_par_in_2:    in    string_30)
  120.                                                    return boolean;
  121.  
  122. end pack_2;
  123.  
  124. with global_def, pack_1;
  125. use global_def;
  126.  
  127. procedure A000091 is -- Dhrystone
  128. --------------
  129.  
  130. begin
  131.     pack_1.proc_0;      -- proc_0 is actually the main program, but it is
  132.                         -- part of a package, and a program within a
  133.                         -- package can not be designated as the main
  134.                         -- program for execution. Therefore proc_0 is
  135.                         -- activated by a call from "main".
  136.  
  137. end A000091 ;
  138.  
  139. with global_def,pack_2;
  140. use global_def;
  141. with cpu_time_clock;
  142. with text_io;
  143. with duration_io;
  144.  
  145. package body pack_1 is
  146. -----------
  147.  
  148.     bool_glob:          boolean;
  149.     char_glob_1,
  150.     char_glob_2:        character;
  151.     array_glob_1:       array_1_dim_integer;
  152.     array_glob_2:       array_2_dim_integer;
  153.     pointer_glob,
  154.     pointer_glob_next:  record_pointer;
  155.  
  156.     start_time : duration ;
  157.     stop_time : duration ;
  158.     iteration_count : constant := 10_000 ;
  159.  
  160.     procedure proc_4;
  161.     procedure proc_5;
  162.  
  163. procedure proc_0
  164. is
  165.     int_loc_1,
  166.     int_loc_2,
  167.     int_loc_3:          one_to_fifty;
  168.     char_loc:           character;
  169.     enum_loc:           enumeration;
  170.     string_loc_1,
  171.     string_loc_2:       string_30;
  172.  
  173.     begin
  174.         -- initializations
  175.         pack_1.pointer_glob_next := new record_type;
  176.  
  177.         pack_1.pointer_glob := new record_type
  178.                              '(
  179.                              pointer_comp => pack_1.pointer_glob_next,
  180.                              discr        => ident_1,
  181.                              enum_comp    => ident_3,
  182.                              int_comp     => 40,
  183.                              string_comp  => "DHRYSTONE PROGRAM, SOME STRING"
  184.                                 );
  185.  
  186.         string_loc_1 := "DHRYSTONE PROGRAM, 1'ST STRING";
  187.  
  188. ---------------
  189. -- start timer here
  190. ---------------
  191.      start_time := cpu_time_clock ;
  192.      for i in 1 .. iteration_count loop
  193.  
  194.         proc_5;
  195.         proc_4;
  196.          -- char_glob_1 = 'A', char_glob_2 = 'B', bool_glob = false
  197.  
  198.         int_loc_1 := 2;
  199.         int_loc_2 := 3;
  200.         string_loc_2 := "DHRYSTONE PROGRAM, 2'ND STRING";
  201.         enum_loc := ident_2 ;
  202.         bool_glob := not pack_2.func_2( string_loc_1,string_loc_2);
  203.         -- bool_glob = true
  204.         while int_loc_1 < int_loc_2 loop --loop body executed once
  205.            int_loc_3 := 5 * int_loc_1 - int_loc_2;
  206.            -- int_loc_3 = 7
  207.            pack_2.proc_7(int_loc_1,int_loc_2,int_loc_3);
  208.            -- int_loc_3 = 7
  209.            int_loc_1 := int_loc_1 + 1;
  210.         end loop;
  211.            -- int_loc_1 = 3
  212.         pack_2.proc_8(array_glob_1,array_glob_2,int_loc_1,int_loc_3);
  213.           -- int_glob = 5
  214.         proc_1(pointer_glob);
  215.         for char_index in 'A'..Char_glob_2 loop --loop body executed twice
  216.             if enum_loc = pack_2.func_1(char_index,'C')
  217.             then   -- not executed
  218.                 pack_2.proc_6(ident_1,enum_loc);
  219.             end if;
  220.         end loop;
  221.           -- enum_loc = ident_1
  222.           -- int_loc = 3, int_loc_2 = 3, int_loc_3 = 7
  223.         int_loc_3 := int_loc_2 * int_loc_1;
  224.         int_loc_2 := int_loc_3 / int_loc_1;
  225.         int_loc_2 := 7 * ( int_loc_3 - int_loc_2 ) - int_loc_1;
  226.         proc_2(int_loc_1);
  227.  
  228.      end loop ;
  229.      stop_time := cpu_time_clock ;
  230.      duration_io.put((stop_time-start_time)*1000/iteration_count);
  231.      text_io.put_line(" is time in milliseconds for one Dhrystone");
  232. ------------------
  233. -- stop timer here
  234. ------------------
  235.  
  236. end proc_0;
  237.  
  238. procedure proc_1(pointer_par_in: in record_pointer) is -- executed once
  239.  
  240.         next_record: record_type
  241.             renames pointer_par_in.pointer_comp.all; -- pointer_glob_next.all
  242. begin
  243.         next_record :=pointer_glob.all;
  244.         pointer_par_in.int_comp := 5;
  245.         next_record.int_comp := pointer_par_in.int_comp;
  246.         next_record.pointer_comp:= pointer_par_in.pointer_comp;
  247.         proc_3(next_record.pointer_comp);
  248.            -- next_record.pointer_glob.pointer_comp = pointer_comp.next
  249.         if next_record.discr = ident_1
  250.         then  -- executed
  251.             next_record.int_comp := 6;
  252.             pack_2.proc_6(pointer_par_in.enum_comp,next_record.enum_comp);
  253.             next_record.pointer_comp := pointer_glob.pointer_comp;
  254.             pack_2.proc_7(next_record.int_comp,10,next_record.int_comp);
  255.         else
  256.             pointer_par_in.all := next_record;
  257.         end if;
  258. end proc_1;
  259.  
  260. procedure proc_2 ( int_par_in_out: in out one_to_fifty)
  261. is -- executed once
  262.    -- in_par_in_out = 3 becomes 7
  263.     int_loc : one_to_fifty;
  264.     enum_loc : enumeration;
  265. begin
  266.     int_loc := int_par_in_out + 10;
  267.     loop
  268.         if char_glob_1 = 'A'
  269.         then
  270.             int_loc := int_loc - 1;
  271.             int_par_in_out := int_loc - int_glob;
  272.             enum_loc := ident_1;  -- true
  273.         end if;
  274.     exit when enum_loc = ident_1; -- true
  275.     end loop;
  276. end proc_2;
  277.  
  278. procedure proc_3(pointer_par_out: out record_pointer)
  279. is -- executed once
  280.         -- pointer_par_out becomes pointer_glob
  281. begin
  282.     if pointer_glob /= null
  283.     then   -- executed
  284.         pointer_par_out := pointer_glob.pointer_comp;
  285.     else
  286.         int_glob := 100;
  287.     end if;
  288.     pack_2.proc_7(10,int_glob,pointer_glob.int_comp);
  289. end proc_3;
  290.  
  291. procedure proc_4
  292. is
  293.     bool_loc : boolean;
  294. begin
  295.     bool_loc := char_glob_1 = 'A';
  296.     bool_loc := bool_loc or bool_glob;
  297.     char_glob_2 := 'B';
  298. end proc_4;
  299.  
  300. procedure proc_5
  301. is
  302. begin
  303.     char_glob_1 := 'A';
  304.     bool_glob := false;
  305. end proc_5;
  306.  
  307. end pack_1;
  308.  
  309.     with global_def,pack_1; use global_def;
  310. package body pack_2 is
  311.  
  312. function func_3(enum_par_in: in enumeration) return boolean;
  313.         -- forward declaration
  314. procedure proc_6(enum_par_in:  in  enumeration;
  315.                  enum_par_out: out enumeration) is
  316. begin
  317.     enum_par_out := enum_par_in;
  318.     if not func_3(enum_par_in) then
  319.         enum_par_out := ident_4;
  320.     end if;
  321.     case enum_par_in is
  322.         when ident_1 =>enum_par_out := ident_1;
  323.         when ident_2 =>if pack_1.int_glob>100
  324.                         then enum_par_out := ident_1;
  325.                         else enum_par_out := ident_4;
  326.                         end if;
  327.         when ident_3 =>enum_par_out := ident_2; -- executed
  328.         when ident_4 =>null;
  329.         when ident_5 =>enum_par_out := ident_3;
  330.     end case;
  331. end proc_6;
  332.  
  333. procedure proc_7(int_par_in_1,
  334.                 int_par_in_2: in  one_to_fifty;
  335.                 int_par_out:  out one_to_fifty) is
  336.  
  337. int_loc : one_to_fifty;
  338. begin
  339.    int_loc := int_par_in_1 + 2;
  340.    int_par_out := int_par_in_2 + int_loc;
  341. end proc_7;
  342.  
  343. procedure proc_8 (array_par_in_out_1: in out array_1_dim_integer;
  344.                   array_par_in_out_2: in out array_2_dim_integer;
  345.                   int_par_in_1,
  346.                   int_par_in_2:       in integer)
  347. is
  348.  
  349. int_loc: one_to_fifty;
  350. begin
  351.     int_loc := int_par_in_1 + 5;
  352.     array_par_in_out_1(int_loc) := int_par_in_2;
  353.     array_par_in_out_1(int_loc + 1) :=
  354.                                         array_par_in_out_1(int_loc);
  355.     array_par_in_out_1(int_loc + 30) := int_loc;
  356.     for int_index in int_loc..int_loc + 1 loop -- loop body executed twice
  357.         array_par_in_out_2(int_loc,int_index) := int_loc ;
  358.     end loop;
  359.     array_par_in_out_2(int_loc,int_loc-1) :=
  360.                            array_par_in_out_2(int_loc,int_loc-1) + 1;
  361.     array_par_in_out_2(int_loc + 20,int_loc) :=
  362.                            array_par_in_out_1(int_loc);
  363.     pack_1.int_glob := 5;
  364.  
  365. end proc_8;
  366.  
  367. function func_1 (char_par_in_1,
  368.                 char_par_in_2: in capital_letter) return enumeration
  369. is
  370.  
  371. char_loc_1, char_loc_2 : capital_letter;
  372.  
  373. begin
  374.     char_loc_1 := char_par_in_1;
  375.     char_loc_2 := char_loc_1;
  376.     if char_loc_2 /= char_par_in_2 then
  377.         return ident_1;
  378.     else
  379.         return ident_2;
  380.     end if;
  381. end func_1;
  382.  
  383. function func_2(string_par_in_1,
  384.                 string_par_in_2: in string_30) return boolean
  385. is
  386.  
  387. int_loc: one_to_thirty;
  388. char_loc: capital_letter;
  389.  
  390. begin
  391.     int_loc := 2;
  392.     while int_loc <= 2 loop
  393.         if func_1(string_par_in_1(int_loc),
  394.                   string_par_in_2(int_loc+1)) = ident_1 then
  395.             char_loc := 'A';
  396.             int_loc := int_loc + 1;
  397.         end if;
  398.     end loop;
  399.     if char_loc >='W' and char_loc < 'Z' then
  400.         int_loc := 7;
  401.     end if;
  402.     if char_loc = 'X' then
  403.         return true;
  404.     else
  405.         if string_par_in_1 > string_par_in_2 then
  406.             int_loc := int_loc + 7;
  407.             return true;
  408.         else
  409.             return false;
  410.         end if;
  411.     end if;
  412. end func_2;
  413.  
  414. function func_3(enum_par_in: in enumeration) return boolean
  415. is
  416.  
  417.     enum_loc: enumeration;
  418. begin
  419.     enum_loc := enum_par_in;
  420.     if enum_loc = ident_3 then
  421.         return true;
  422.     end if;
  423. end func_3;
  424.  
  425. end pack_2;
  426.