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_2.c (part 3 of 3)
! *
! *  Date:       May 25, 1988 & Mar 30, 2026
! *
! *  Author:     Reinhold P. Weicker, translated from C to Imp by Graham Toal
! *
! ****************************************************************************

include "dhry.inc"

external integer spec        Int Glob
external byte integer spec  Ch 1 Glob


external routine Proc 6 (integer {Enumeration} Enum Val Par, integer {Enumeration} name Enum Ref Par)
{*******************************}
    { executed once }
    { Enum Val Par == Ident 3, Enum Ref Par becomes Ident 2 }
  switch EV(Ident 1:Ident 5)
  
  Enum Ref Par = Enum Val Par
  Enum Ref Par = Ident 4 if not Func 3 (Enum Val Par)    { then, not executed }

  ->EV(Enum Val Par)
  
    EV(Ident 1): 
      Enum Ref Par = Ident 1
      ->end
      
    EV(Ident 2): 
      if Int Glob > 100 then Enum Ref Par = Ident 1 c
      else Enum Ref Par = Ident 4
      ->end
      
    EV(Ident 3): { executed }
      Enum Ref Par = Ident 2
      ->end
      
    EV(Ident 4): ->end
    
    EV(Ident 5): 
      Enum Ref Par = Ident 3
      ->end

  end: { switch }
end { Proc 6 }


external routine Proc 7 (integer {One Fifty} Int 1 Par Val,
                           integer {One Fifty} Int 2 Par Val,
                           integer {One Fifty} name Int Par Ref)
{********************************************}
    { executed three times                                      } 
    { first call:      Int 1 Par Val == 2, Int 2 Par Val == 3,  }
    {                  Int Par Ref becomes 7                    }
    { second call:     Int 1 Par Val == 10, Int 2 Par Val == 5, }
    {                  Int Par Ref becomes 17                   }
    { third call:      Int 1 Par Val == 6, Int 2 Par Val == 10, }
    {                  Int Par Ref becomes 18                   }
  integer {One Fifty} Int Loc

  Int Loc = Int 1 Par Val + 2
  Int Par Ref = Int 2 Par Val + Int Loc
end { Proc 7 }


external routine 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)
{*******************************************************************}
    { executed once      }
    { Int Par Val 1 == 3 }
    { Int Par Val 2 == 7 }
  integer {One Fifty} Int Index
  integer {One Fifty} Int Loc

  Int Loc = Int 1 Par Val + 5
  Arr 1 Par Ref (Int Loc) = Int 2 Par Val
  Arr 1 Par Ref (Int Loc+1) = Arr 1 Par Ref (Int Loc)
  Arr 1 Par Ref (Int Loc+30) = Int Loc
  Arr 2 Par Ref (Int Loc*50 + Int Index) {(Int Loc, Int Index)} = Int Loc for Int Index = Int Loc, 1, Int Loc+1
  Arr 2 Par Ref (Int Loc*50 + Int Loc-1) {(Int Loc, Int Loc-1)} = Arr 2 Par Ref (Int Loc*50 + Int Loc-1){(Int Loc, Int Loc-1)} + 1
  Arr 2 Par Ref ((Int Loc+20)*50 + Int Loc) {(Int Loc+20, Int Loc)} = Arr 1 Par Ref (Int Loc)
  Int Glob = 5
end { Proc 8 }


external integer {Enumeration} fn Func 1 (integer {Capital Letter} Ch 1 Par Val,
                                             integer {Capital Letter} Ch 2 Par Val)
{***********************************************}
    { executed three times                                         }
    { first call:      Ch 1 Par Val == 'H', Ch 2 Par Val == 'R'    }
    { second call:     Ch 1 Par Val == 'A', Ch 2 Par Val == 'C'    }
    { third call:      Ch 1 Par Val == 'B', Ch 2 Par Val == 'C'    }

  integer {Capital Letter}        Ch 1 Loc
  integer {Capital Letter}        Ch 2 Loc

  Ch 1 Loc = Ch 1 Par Val
  Ch 2 Loc = Ch 1 Loc
  if Ch 2 Loc # Ch 2 Par Val start
    { then, executed }
    result = Ident 1
  else  { not executed }
    Ch 1 Glob = Ch 1 Loc
    result = Ident 2
  finish
end { Func 1 }


external predicate Func 2 (string (30) name Str 1 Par Ref, string (30) name Str 2 Par Ref)
{***********************************************}
    { executed once }
    { Str 1 Par Ref == "DHRYSTONE PROGRAM, 1'ST STRING" }
    { Str 2 Par Ref == "DHRYSTONE PROGRAM, 2'ND STRING" }

  integer {One Thirty}        Int Loc
  integer {Capital Letter}    Ch Loc

  Int Loc = 2
  while Int Loc <= 2 cycle { loop body executed once }
    if Func 1 (CHARNO(Str 1 Par Ref, Int Loc),
                CHARNO(Str 2 Par Ref, Int Loc+1)) = Ident 1 start { then, executed }
      Ch Loc = 'A'
      Int Loc = Int Loc + 1
    finish { if }
  repeat { while }
  Int Loc = 7 if 'W' <= Ch Loc < 'Z'    { then, not executed }
    
  true if Ch Loc = 'R'                 { then, not executed }

  { else executed }
  if Str 1 Par Ref > Str 2 Par Ref start
    { then, not executed }
    Int Loc  = Int Loc + 7
    Int Glob = Int Loc
    true
  finish else false { executed }
  { if Ch Loc }
end { Func 2 }


external predicate Func 3 (integer {Enumeration} Enum Par Val)
{*************************}
    { executed once        }
    { Enum Par Val == Ident 3 }
  integer {Enumeration} Enum Loc
  Enum Loc = Enum Par Val
  true if Enum Loc = Ident 3     { then, executed }
  false                           { not executed }
end { Func 3 }

end of file