Task

Given a prompt and a list containing a number of strings of which one is to be selected, create a function that:

 prints a textual menu formatted as an index value followed by its corresponding string for each item in the list;
 prompts the user to enter a number;
 returns the string corresponding to the selected index number.


The function should reject input that is not an integer or is out of range by redisplaying the whole menu before asking again for a number. The function should return an empty string if called with an empty list.

For test purposes use the following four phrases in a list:

   fee fie
   huff and puff
   mirror mirror
   tick tock

Note

This task is fashioned after the action of the Bash select statement.

 
## menu.icn : rewrite of the faulty version on Rosetta Code site 24/4/2021
 
procedure main()
 
L := ["fee fie", "huff and puff", "mirror mirror", "tick tock"]
K := ["hidie hi", "hidie ho", "mirror mirror on the Wall", "tick tock tick tok"]
Z := []
 
 choice := choose_from_menu(L)      # call using menu L
 write("Returned value =", choice)
 choice := choose_from_menu(K)      # call using menu K
 write("Returned value =", choice)
 choice := choose_from_menu(Z)      # call using empty list
 write("Returned value =", choice)
 
 
end ## of main
# --------- subroutines below ---------------------------------
 
procedure choose_from_menu(X)
 
 displaymenu(X)
repeat {
   writes("Choose a number from the menu above: ")
   a := read()
   if a == "" then return(a)   ## no selection
 
  write("You selected ",a)
  if numeric(a) then {
   if integer(a) <= 0 | integer(a) > *X  then displaymenu(X) else
      {                    ## check entered option in range
        write(a, " ==> ",X[a])
      return ( string(a))
	 }
	}
  else displaymenu(X)				       
   }
 
end ## choose_from_menu(X)
 
procedure displaymenu(X)
	every i := 1 to *X do
		write(i,") ",X[i])    ## dispay menu options
 
end ## displaymenu(X)
 
 