external record (*) name Null == 0
external routine spec Proc 6 (integer {Enumeration} Enum Val Par, integer {Enumeration} name Enum Ref Par)
external routine spec Proc 7 (integer {One Fifty} Int 1 Par Val,
integer {One Fifty} Int 2 Par Val,
integer {One Fifty} name Int Par Ref)
external routine spec Proc 8 (integer array name Arr 1 Par Ref {(0:49)},
integer array name Arr 2 Par Ref {(0:50*50-1)} {(0:49, 0:49)},
integer Int 1 Par Val,
integer Int 2 Par Val)
external integer {Enumeration} fn spec Func 1 (integer {Capital Letter} Ch 1 Par Val,
integer {Capital Letter} Ch 2 Par Val)
external predicate spec Func 2 (string (30) name Str 1 Par Ref, string (30) name Str 2 Par Ref)
external predicate spec Func 3 (integer {Enumeration} Enum Par Val)
! ****************************************************************************
! *
! * "DHRYSTONE" Benchmark Program
! * -----------------------------
! *
! * Version: Imp, Version 2.1
! *
! * File: dhry_1.c (part 2 of 3)
! *
! * Date: May 25, 1988 & Mar 30, 2026
! *
! * Author: Reinhold P. Weicker, translated from C to Imp by Graham Toal
! *
! ****************************************************************************
include "dhry.inc"
const integer DHRY ITERS = 100000
{ Global Variables: }
external record (Rec Type fm) name Ptr Glob,
Next Ptr Glob
external integer Int Glob
external integer {Boolean} Bool Glob
external byte integer Ch 1 Glob,
Ch 2 Glob
external integer array Arr 1 Glob (0:49)
!!! PROBLEM! Imp77 doesn't allow N-D external arrays, only local ones!
external integer array Arr 2 Glob (0:50*50-1) {(0:49, 0:49)}
!extern char *malloc ()
!!%external %integer {Enumeration} %fn %spec Func 1
{ forward declaration necessary since Enumeration may not simply be int }
!#ifndef REG
external integer {Boolean} Reg = false
!#define REG
{ REG becomes defined as empty }
{ i.e. no register variables }
!#else
! %integer {Boolean} Reg = true
!#endif
{ variables for time measurement: }
!#ifdef TIMES
!struct tms time info
!extern int times ()
! { see library function "times" }
!#define Too Small Time (2*HZ)
! { Measurements should last at least about 2 seconds }
!#endif
!#ifdef TIME
!extern long time()
! { see library function "time" }
!#define Too Small Time 2
! { Measurements should last at least 2 seconds }
!#endif
!#ifdef MSC CLOCK
!extern clock t clock()
!#define Too Small Time (2*HZ)
!#endif
const integer Too Small Time = 2 * 1000000 {must run at least 2 seconds}
external long integer Begin Time, c
End Time, c
User Time
external real Microseconds, c
Dhrystones Per Second
{ end of variables for time measurement }
begin
{***}
routinespec Proc 1 (record (Rec Type fm) name Ptr Val Par)
routinespec Proc 2 (integer {One Fifty} name Int Par Ref)
routinespec Proc 3 (record (Rec Type fm) name Ptr Ref Par)
routinespec Proc 4
routinespec Proc 5
{ main program, corresponds to procedures }
{ Main and Proc 0 in the Ada version }
integer {One Fifty} Int 1 Loc
integer {One Fifty} Int 2 Loc
integer {One Fifty} Int 3 Loc
byte integer Ch Index
integer {Enumeration} Enum Loc
string (30) Str 1 Loc
string (30) Str 2 Loc
integer Run Index
integer Number Of Runs
{ Initializations }
record (Rec Type fm) Next Ptr Glob
record (Rec Type fm) Ptr Glob {= (Rec Pointer) malloc (sizeof (Rec Type))}
Ptr Glob_Ptr Comp == Next Ptr Glob
Ptr Glob_Discr = Ident 1
Ptr Glob_variant_var 1_Enum Comp = Ident 3
Ptr Glob_variant_var 1_Int Comp = 40
Ptr Glob_variant_var 1_Str Comp = "DHRYSTONE PROGRAM, SOME STRING"
Str 1 Loc = "DHRYSTONE PROGRAM, 1'ST STRING"
Arr 2 Glob (8*50+7){(8,7)} = 10
{ Was missing in published program. Without this statement, }
{ Arr 2 Glob [8][7] would have an undefined value. }
{ Warning: With 16-Bit processors and Number Of Runs > 32000, }
{ overflow may occur for this array element. }
newline
printstring ("Dhrystone Benchmark, Version 2.1 (Language: Imp)")
newlines(2)
if Reg # 0 start
printstring ("Program compiled with 'register' attribute")
newlines(2)
else
printstring ("Program compiled without 'register' attribute")
newlines(2)
finish
Number Of Runs = DHRY ITERS
! printstring ("Please give the number of runs through the benchmark: ")
! %begin
! %integer n
! read(n)
! Number Of Runs = n
! %end
! newline
printstring ("Execution starts, ")
write(Number Of Runs, -1)
printstring (" runs through Dhrystone")
newline
{*************}
{ Start timer }
{*************}
!#ifdef TIMES
! times (&time info)
! Begin Time = (long) time info.tms utime
!#endif
!#ifdef TIME
! Begin Time = time ( (long *) 0)
!#endif
!#ifdef MSC CLOCK
! Begin Time = clock()
!#endif
Begin Time = cpu time
for Run Index = 1, 1, Number Of Runs cycle
Proc 5
Proc 4
{ Ch 1 Glob == 'A', Ch 2 Glob == 'B', Bool Glob == true }
Int 1 Loc = 2
Int 2 Loc = 3
Str 2 Loc = "DHRYSTONE PROGRAM, 2'ND STRING"
Enum Loc = Ident 2
if not Func 2 (Str 1 Loc, Str 2 Loc) then Bool Glob = false else Bool Glob = true
{ Bool Glob == 1 }
while Int 1 Loc < Int 2 Loc cycle { loop body executed once }
Int 3 Loc = 5 * Int 1 Loc - Int 2 Loc
{ Int 3 Loc == 7 }
Proc 7 (Int 1 Loc, Int 2 Loc, Int 3 Loc)
{ Int 3 Loc == 7 }
Int 1 Loc = Int 1 Loc + 1
repeat { while }
{ Int 1 Loc == 3, Int 2 Loc == 3, Int 3 Loc == 7 }
Proc 8 (Arr 1 Glob, Arr 2 Glob, Int 1 Loc, Int 3 Loc)
{ Int Glob == 5 }
Proc 1 (Ptr Glob)
for Ch Index = 'A', 1, Ch 2 Glob cycle
{ loop body executed twice }
if Enum Loc = Func 1 (Ch Index, 'C') start
{ then, not executed }
Proc 6 (Ident 1, Enum Loc)
Str 2 Loc = "DHRYSTONE PROGRAM, 3'RD STRING"
Int 2 Loc = Run Index
Int Glob = Run Index
finish
repeat
{ Int 1 Loc == 3, Int 2 Loc == 3, Int 3 Loc == 7 }
Int 2 Loc = Int 2 Loc * Int 1 Loc
Int 1 Loc = Int 2 Loc // Int 3 Loc
Int 2 Loc = 7 * (Int 2 Loc - Int 3 Loc) - Int 1 Loc
{ Int 1 Loc == 1, Int 2 Loc == 13, Int 3 Loc == 7 }
Proc 2 (Int 1 Loc)
{ Int 1 Loc == 5 }
repeat { loop "for Run Index" }
{************}
{ Stop timer }
{************}
!#ifdef TIMES
! times (&time info)
! End Time = (long) time info.tms utime
!#endif
!#ifdef TIME
! End Time = time ( (long *) 0)
!#endif
!#ifdef MSC CLOCK
! End Time = clock()
!#endif
End Time = cpu time
printstring ("Execution ends"); newline
printstring (""); newline
printstring ("Final values of the variables used in the benchmark:"); newline
printstring (""); newline
printstring ("Int_Glob: "); write( Int Glob, -1); newline
printstring (" should be: "); write( 5, -1); newline
printstring ("Bool_Glob: "); write( Bool Glob, -1); newline
printstring (" should be: "); write( 1, -1); newline
printstring ("Ch_1_Glob: "); print symbol(Ch 1 Glob); newline
printstring (" should be: "); print symbol('A'); newline
printstring ("Ch_2_Glob: "); print symbol(Ch 2 Glob); newline
printstring (" should be: "); print symbol('B'); newline
printstring ("Arr_1_Glob[8]: "); write( Arr 1 Glob(8), -1); newline
printstring (" should be: "); write( 7, -1); newline
printstring ("Arr_2_Glob[8][7]: "); write( Arr 2 Glob(8*50+7){(8,7)}, -1); newline
printstring (" should be: Number_Of_Runs + 10"); newline
printstring ("Ptr_Glob->"); newline
printstring (" Ptr_Comp: "); write(ADDR(Ptr Glob_Ptr Comp), -1); newline
printstring (" should be: (implementation-dependent)"); newline
printstring (" Discr: "); write( Ptr Glob_Discr, -1); newline
printstring (" should be: "); write( 0, -1); newline
printstring (" Enum_Comp: "); write( Ptr Glob_variant_var 1_Enum Comp, -1); newline
printstring (" should be: "); write( 2, -1); newline
printstring (" Int_Comp: "); write( Ptr Glob_variant_var 1_Int Comp, -1); newline
printstring (" should be: "); write( 17, -1); newline
printstring (" Str_Comp: "); print string(Ptr Glob_variant_var 1_Str Comp); newline
printstring (" should be: DHRYSTONE PROGRAM, SOME STRING"); newline
printstring ("Next_Ptr_Glob->"); newline
printstring (" Ptr_Comp: "); write(ADDR(Next Ptr Glob_Ptr Comp), -1); newline
printstring (" should be: (implementation-dependent), same as above"); newline
printstring (" Discr: "); write( Next Ptr Glob_Discr, -1); newline
printstring (" should be: "); write( 0, -1); newline
printstring (" Enum_Comp: "); write( Next Ptr Glob_variant_var 1_Enum Comp, -1); newline
printstring (" should be: "); write( 1, -1); newline
printstring (" Int_Comp: "); write( Next Ptr Glob_variant_var 1_Int Comp, -1); newline
printstring (" should be: "); write( 18, -1); newline
printstring (" Str_Comp: "); print string(Next Ptr Glob_variant_var 1_Str Comp); newline
printstring (" should be: DHRYSTONE PROGRAM, SOME STRING"); newline
printstring ("Int_1_Loc: "); write( Int 1 Loc, -1); newline
printstring (" should be: "); write( 5, -1); newline
printstring ("Int_2_Loc: "); write( Int 2 Loc, -1); newline
printstring (" should be: "); write( 13, -1); newline
printstring ("Int_3_Loc: "); write( Int 3 Loc, -1); newline
printstring (" should be: "); write( 7, -1); newline
printstring ("Enum_Loc: "); write( Enum Loc, -1); newline
printstring (" should be: "); write( 1, -1); newline
printstring ("Str_1_Loc: "); print string(Str 1 Loc); newline
printstring (" should be: DHRYSTONE PROGRAM, 1'ST STRING"); newline
printstring ("Str_2_Loc: "); print string(Str 2 Loc); newline
printstring (" should be: DHRYSTONE PROGRAM, 2'ND STRING"); newline
newline
User Time = End Time - Begin Time
!! %if User Time < Too Small Time %start
!! printf ("Measured time too small to obtain meaningful results"); newline
!! printf ("Please increase number of runs"); newline
!! newline
!! %else
!#ifdef TIME
! Microseconds = (float) User Time * Mic secs Per Second
! / (float) Number Of Runs
! Dhrystones Per Second = (float) Number Of Runs / (float) User Time
!#else
! Microseconds = (float) User Time * Mic secs Per Second
! / ((float) HZ * ((float) Number Of Runs))
! Dhrystones Per Second = ((float) HZ * (float) Number Of Runs)
! / (float) User Time
!#endif
Microseconds = User Time // Number Of Runs {CPU TIME function has been adjusted to return microseconds!}
Dhrystones Per Second = (Number Of Runs * (1000000//1000)) // (User Time//1000) {need to scale down by 1000 to fit in 32-bit %integer}
printstring ("Microseconds for one run through Dhrystone: ")
write(INT(Microseconds), -1); space; newline
printstring ("Dhrystones per Second: ")
write(INT(Dhrystones Per Second), -1); space; newline
newline
!! %finish
!%end
routine Proc 1 (record (Rec Type fm) name Ptr Val Par)
{****************}
{ executed once }
record (Rec Type fm) name Next Record == Ptr Val Par_Ptr Comp {or '='???}
{ == Ptr Glob Next }
{ Local variable, initialized with Ptr Val Par->Ptr Comp, }
{ corresponds to "rename" in Ada, "with" in Pascal }
{structassign} Ptr Val Par_Ptr Comp = Ptr Glob
Ptr Val Par_variant_var 1_Int Comp = 5
Next Record_variant_var 1_Int Comp = Ptr Val Par_variant_var 1_Int Comp
Next Record_Ptr Comp = Ptr Val Par_Ptr Comp
Proc 3 (Next Record_Ptr Comp)
{ Ptr Val Par_Ptr Comp_Ptr Comp = Ptr Glob_Ptr Comp }
if Next Record_Discr = Ident 1 start
{ then, executed }
Next Record_variant_var 1_Int Comp = 6
Proc 6 (Ptr Val Par_variant_var 1_Enum Comp, Next Record_variant_var 1_Enum Comp)
Next Record_Ptr Comp = Ptr Glob_Ptr Comp
Proc 7 (Next Record_variant_var 1_Int Comp, 10, Next Record_variant_var 1_Int Comp)
else { not executed }
{structassign} Ptr Val Par = Ptr Val Par_Ptr Comp
finish
end { Proc 1 }
routine Proc 2 (integer {One Fifty} name Int Par Ref)
{****************}
{ executed once }
{ *Int Par Ref == 1, becomes 4 }
integer {One Fifty} Int Loc
integer {Enumeration} Enum Loc
Int Loc = Int Par Ref + 10
cycle { executed once }
if Ch 1 Glob = 'A' start
{ then, executed }
Int Loc = Int Loc - 1
Int Par Ref = Int Loc - Int Glob
Enum Loc = Ident 1
finish { if }
repeat until Enum Loc = Ident 1 { true }
end { Proc 2 }
routine Proc 3 (record (Rec Type fm) name Ptr Ref Par)
{****************}
{ executed once }
{ Ptr Ref Par becomes Ptr Glob }
if Ptr Glob ## Null then { then, executed } Ptr Ref Par == Ptr Glob_Ptr Comp
Proc 7 (10, Int Glob, Ptr Glob_variant_var 1_Int Comp)
end { Proc 3 }
routine Proc 4 { without parameters }
{*****}
{ executed once }
integer {Boolean} Bool Loc
if Ch 1 Glob = 'A' then Bool Loc = true else Bool Loc = false
Bool Glob = Bool Loc ! Bool Glob
Ch 2 Glob = 'B'
end { Proc 4 }
routine Proc 5 { without parameters }
{*****}
{ executed once }
Ch 1 Glob = 'A'
Bool Glob = false
end { Proc 5 }
{ Procedure for the assignment of structures, }
{ if the C compiler doesn't support this feature }
endofprogram