Task

Implement a    HQ9+    interpreter or compiler.




procedure main(A)
repeat writes("Enter HQ9+ code: ") & HQ9(get(A)|read()|break)
end
 
procedure HQ9(code)
static bnw,bcr
initial {  # number matching words and line feeds for the b-th bottle 
   bnw   := table(" bottles"); bnw[1] := " bottle"; bnw[0] := "No more bottles"
   bcr   := table("\n"); bcr[0]:=""
   }
every c := map(!code) do                         # ignore case 
   case c of {                                   # interpret
   "h"  : write("Hello, World!")                 # . hello
   "q"  : write(code)                            # . quine
   "9"  : {                                      # . 99 bottles 
          every b := 99 to 1 by -1 do writes(
             bcr[b],b,bnw[b]," of beer on the wall\n",
             b,bnw[b]," of beer\nTake one down, pass it around\n",
             1~=b|"",bnw[b-1]," of beer on the wall",bcr[b-1])            
          write(", ",map(bnw[b-1])," of beer.\nGo to the store ",
                "and buy some more, 99 bottles of beer on the wall.")               
          }
   "+"  : { /acc := 0 ; acc +:=1 }                # . yes it is weird
   default: stop("Syntax error in ",code)         # . error/exit
   }
return
end