[Question]
  [
The goal of this code golf is to create an interpreter for the programming language [HQ9+](http://esolangs.org/wiki/HQ9%2B)  
There are 4 commands in this programming language:
* **H** - prints "Hello, world!"
* **Q** - prints the source code of the program
* **9** - prints the lyrics of the song ["99 bottles of beer"](http://esolangs.org/wiki/99_bottles_of_beer)
* **+** - increments the accumulator
The rules:
1. Because the accumulator isn't defined, you can ignore the command **+**
2. Your program should prompt for input (this input will be the source code) or the source code is read from a file
3. You are not allowed to put the lyrics of "99 bottles of beer" in a file, and read the text from the file
4. You are not allowed to use a compression algorithm such as GZip or BZip to compress the song text: you have to create your own compression algorithm. This doesn't have to be a complex algorithm, but try to compress the text as much as possible (remember: this is a code-golf, the code with the fewest bytes wins)
5. If the source code contains a char that isn't **H**, **Q**, **9** or **+**, then output "Source code contains invalid characters" **before running any commands!** This means that, if the source code is `H1` for example, then don't output `Hello, world!` before you output `Source code contains invalid characters`. No, immediately output `Source code contains invalid characters`
6. If your interpreter accepts both uppercase and lowercase characters, then you get **-8** to your character count
Good luck!
  
[Answer]
## APL (Dyalog) (326 - 8 = 318)
Paste it in an editor window and call `H`. Input is taken from the keyboard.
```
H
⎕←'Source code contains invalid characters'/⍨~∧/'HhQq9+'∊⍨V←⍞
B←' of beer'
W←' on the wall'
L←⎕TC[2]
Z←{k←' bottle','s'/⍨⍵≠1⋄⍵<0:'99',k⋄⍵=0:'No',k⋄k,⍨⍕⍵}
{⍵∊'Hh':⎕←'Hello, world!'
⍵∊'Qq':⎕←V
⍵∊'9':{⎕←G,K,(G←Z⍵),B,L,(⊃'Go to the store and buy some more' 'Take one down and pass it around'[1+×⍵]),L,(Z⍵-1),K←B,W,L}¨1-⍨⌽⍳100}¨V
```
[Answer]
# C, 599 587 487 481 467 characters
I'm sure this can be beaten. I'm using C after all. There's a reason you don't see a lot of winning golf entries written in C. This is now 467 characters thanks to criminal abuse of `#define`.
Specify the HQ9+ source file as a command line argument.
EDIT: Now accepts the source from stdin, not a file. Start the program, start typing the code, `CTRL`‑`C` when done to run it.
It compiles at least in MinGW/GCC with: `gcc -o hq9+.exe hq9+.c`
Should work in MSVC, but I didn't feel like creating a whole solution just for this. :)
```
#define B "bottles of beer"
#define C case
#define P printf
#define R break
a,i,j,s;
main(){
char p[9999],c;
for(;;) {
    switch(c=getch()){
    C 'H':C 'Q':C '9':C '+': C 3: R;
    default:P("Source code contains invalid characters\n");
    }
    if (c==3) R;
    p[s++]=c;
}
for(i=0;i<s;i++){
    c = p[i];
    switch(c){
    C 'H':
        P("Hello world!");
        R;
    C 'Q':
        for(j=0;j<s;j++)putchar(p[j]);
        R;
    C '9':
        j=99;
        while(j){
            P("%d "B" on the wall,\n%d "B".\nTake one down, pass it around,\n%d "B".\n",j,j,j-1);
            j--;
        }
        R;
    C '+':
        a++;
    }
}
}
```
Or:
```
#define B "bottles of beer"
#define C case
#define P printf
#define R break
a,i,j,s;main(){char p[9999],c;for(;;){switch(c=getch()){C 'H':C 'Q':C '9':C '+': C 3: R;default:P("Source code contains invalid characters\n");}if (c==3) R;p[s++]=c;}for(i=0;i<s;i++){c = p[i];switch(c){C 'H':P("Hello world!");R;C 'Q':for(j=0;j<s;j++)putchar(p[j]);R;C '9':j=99;while(j){P("%d "B" on the wall,\n%d "B".\nTake one down, pass it around,\n%d "B".\n",j,j,j-1);j--;}R;C '+':a++;}}}
```
[Answer]
# Mathematica, ~~349 346~~ 341 chars
```
h = If[StringMatchQ[#, ("H" | "Q" | "9" | "+") ...], 
   b = If[# > 0, ToString@#, "No"] <> " bottle" <> 
      If[# == 1, "", "s"] <> " of beer" &; 
   w = b@# <> " on the wall" &; 
   Print /@ 
    StringCases[#, {"H" -> "Hello, world!", "Q" -> #, 
      "9" -> "" <> 
        Table[w@n <> ",\n" <> b@n <> 
          ".\ntake one down, pass it around,\n" <> w[n - 1] <> 
          If[n == 1, ".", ".\n\n"], {n, 99, 1, -1}]}];, 
   "Source code contains invalid characters"] &
```
[Answer]
# J - 444 bytes
I liked the number, so stopped golfing. Here 'ya go, single expression function!
```
f=:'Source code contains invalid characters'"_`('Hello, world!'"_`[`((((s=:(<:@[s],L,(v,LF,'Take one down and pass it around, '"_,b@<:,' of beer on the wall.'"_)@[,''"_)`(],(L=:LF,LF),(v=:1&b,' of beer on the wall, '"_,b,' of beer.'"_)@[)@.([<1:))''"_),LF,'Go to the store and buy some more, '"_,(b=:({&'Nn'@([=0:),'o more'"_)`(":@])@.(]>0:),{.&' bottles'@(8:-=&1@])),' of beer on the wall.'"_)@(99"_))`]@.('HQ9+'&i.@])"0 1 0])@.(*./@e.&'HQ9+')
```
Examples:
```
   hq9 '9QHHQ+'
99 bottles of beer on the wall, 99 bottles of beer.
Take one down and pass it around, 98 bottles of beer on the wall.
98 bottles of beer on the wall, 98 bottles of beer.
Take one down and pass it around, 97 bottles of beer on the wall.
...
3 bottles of beer on the wall, 3 bottles of beer.
Take one down and pass it around, 2 bottles of beer on the wall.
2 bottles of beer on the wall, 2 bottles of beer.
Take one down and pass it around, 1 bottle of beer on the wall.
1 bottle of beer on the wall, 1 bottle of beer.
Take one down and pass it around, no more bottles of beer on the wall.
No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.
9QHHQ+
Hello, world!
Hello, world!
9QHHQ+
+
   hq9 '9QHHaQ'
Source code contains invalid characters
```
[Answer]
# Fortran 528 ~~470~~ ~~481~~
~~It requires compiling with `-fpp` flag (+3 to score)1 to use preprocessing directives (which saves way more than 3 chars, so I'm totally okay with that). It is also case insensitive, so there's -8 :D. *Saved 5 chars by not preprocessing the `endif` as that is used once anyway*.~~
Requires the file to have a `.F90` extension (makes sense to call it `hq9+.F90`) so that the compiler forces preprocessing. The code is case-sensitive; making it case-insensitive adds something like 16 characters, so it's not really worth it to save 8 characters. My previous answer did not account for the changing plurals in `bottles` for `9`; this version corrects it (and sadly adds a lot more characters).
```
#define P print*,
#define W " of beer on the wall"
#define N print'(x,i0,a,a)',
#define e enddo
#define S case
#define J len(trim(c))
character(len=99)::c,b=" bottles";read*,c;do i=1,J;if(all(c(i:i)/=["H","Q",'9',"+"])) then;P"Source code contains invalid characters";exit;endif;e;do i=1,J;select S(c(i:i));S("H");P"Hello, world!";S("Q");P c;S("9");l=8;do k=99,1,-1;N k,b(1:l),W;N k,b(1:l)," of beer";P "Take one down, pass it around";if(k==2)l=l-1;if(k==1)exit;N k-1,b(1:l),W;P"";e;P"No more",trim(b),W;S default;endselect;e;end
```
Looks a lot better ungolfed & non-preprocessed (probably because you can see what's going on):
```
program hq9
   character(len=99)::c,b=" bottles"
   read*,c
   do i=1,len(trim(c))
! change the below to ["H","h","Q","q","9","+"] to be case-insensitive
      if(all(c(i:i)/=["H","Q","9","+"]))then
         print*,"Source code contains invalid characters"
         exit
      endif
   enddo
   do i=1,len(trim(c))
      select case(c(i:i))
        case("H")                ! change to case("H","h") for case-insensitive
           print*,"Hello, world!"
        case("Q")                ! change to case("Q","q") for case-insensitive
           print*, c
        case("9")
           l=8
           do k=99,1,-1
              print'(x,i0,a,a)', k,b(1:l)," of beer on the wall"
              print'(x,i0,a)', k,b(1:l)," of beer"
              print*,"Take one down, pass it around"
              if(k==2) l=l-1
              if(k==1) exit
              print'(x,i0,a)', k-1,b(1:l)," of beer on the wall"
              print*,""
           enddo
           print*,"No more",trim(b)," of beer on the wall"
        case default
           ! do nothing
      endselect
   enddo
end program hq9
```
[Answer]
# Perl, 325 - 8 = 317
```
sub p{print@_}$_=<>;$a=' on the wall';$b=' bottle';$e=' of beer';$c='Take one down, pass it around';if(!/^[hqHQ9+]+$/){p"Source code contains invalid characters";exit}$k=$_;for(/./g){/H|h/&&p"Hello, World!";if(/9/){$i=99;$d=$b."s$e";while($i>0){p"$i$d$a
$i$d
$c
";$q=--$i==1?'':'s';$d="$b$q$e";$i||=No;p"$i$d$a
"}}/Q|q/&&p$k}
```
Expanded:
```
sub p{print@_}
$_=<>;
$a=' on the wall';
$b=' bottle';
$e=' of beer';
$c='Take one down, pass it around';
if(!/^[hqHQ9+]+$/){
    p"Source code contains invalid characters";
    exit
}
$k=$_;
for(/./g){
    /H|h/&&p"Hello, World!";
    if(/9/){
        $i=99;
        $d=$b."s$e";
        while($i>0){
            p"$i$d$a
$i$d
$c
";
            $q=--$i==1?'':'s';
            $d="$b$q$e";
            $i||=No;
            p"$i$d$a
"
        }
    }
    /Q|q/&&p$k
}
```
[Answer]
# [Python 2](https://docs.python.org/2/), ~~452~~ ~~453~~ 443 bytes
```
q=raw_input()
if set(q)-set('HQ9+'):print'Source code contains invalid characters'
b=' bottles of beer'
b=[b,b.replace('s','')]
w=[a+' on the wall'for a in b]
t='Take one down, pass it around,\n'
c={'H':'Hello, world!','Q':q,'9':''.join(`i`+w[i<2]+',\n'+`i`+b[i<2]+'.\n'+t+(`i`if i>1 else'No')+w[0]+'.\n'for i in range(1,100)[::-1])+'No'+w[0]+',\nNo'+b[0]+'.\n'+'Go to the store, buy some more,\n99'+w[0]+'.'}
for d in q:
 if d in c:print c[d]
```
[Try it online!](https://tio.run/##PVHBTsMwDL33K8zJrdpN626rKFd2Qprg1lUsaT0WyOIuSakmxLePZAwucfz83rMTD2d/YLO8XE61FdOrMsPo0yxRe3Dk01M2iwHXm1WOWTVYZTw@82g7go77eBgvlHGgzKfQqofuIKzoPFmHiawRJHuvyQHvQRLZCDaykHNLgxYdpeiwQMzaZKobkSOwAX8gmITWuGcLIjiDbBNf44v4oFAn6HkyBQzChbYehOXR9MXWYNLVX7jGCtekNRcwsdX9XfDfYHUqcBUqOH9nZdKd2uVTo@6XbY5RmUdA3oB5BHweSeEb1EMJpB3hE2MWRIsbIw6n4nBWmDdKy6JcLLKmqmZlm@WRfOMG@5jIf2GOjwyer890ni0VIMczOD4SHGO6NavVn3qO30ns1MdOpyqBMNH13v0uA7qmby@XuJ/1Dw "Python 2 – Try It Online")
Bleh. It was already bleh, but then I discovered a bug that cost me a byte to fix. Bleh.
Saved some characters by not exiting on invalid input like I thought you were supposed to.
~~Explained version coming shortly.~~ I gave up. I barely even understand how this monstrosity works any more. If there's demand I'll give it another go but until then it's not happening.
[Answer]
# Ruby, ~~364~~ 360 - 8 = 352
Still has *lots* of room for improvement. 99 bottles code stolen from [here](http://www.99-bottles-of-beer.net/language-ruby-673.html).
```
p=gets.upcase
if p=~/[^HQ9+
]/
puts"Source code contains invalid characters"else
p.each_char{|x|case x
when ?H
puts"Hello, world!"
when ?Q
puts p
when ?9
def c;"#{$n} bottle#{'s'if$n>1} of beer on the wall"end
($n=99).times{puts"#{c}, #{c[0..-13]}.
#{$n<2?"Go to the store and buy some more":"Take one down and pass it around"}, #{$n=($n-2)%99+1;c}.
"}end}end
```
[Answer]
# Haskell, 298
```
main=interact g
g s|all(`elem`"HQ9+")s=s>>=(%s)|0<1="Source code contains invalid characters"
'H'%_="hello World!"
'Q'%s=s
'9'%_=drop 32$d 99
_%_=""
k=" bottles of beer on the wall"
d 0="No more"++k++"."
d n|a<-shows n k=[a,".\n\n",a,",\n",take 18a,".\ntake one down, pass it around\n",d$n-1]>>=id
```
this is quite straightforward. `%` returns a command's output (given the source cod for use on `Q`). `d` returns the 99 bottles song with a junk line at the start for golfing reasons. 
everything is wrapped in an interact (you might want to use `g` instead of `main` when testing)
[Answer]
# Python 2, 340 - 8 = 332
```
s,o=raw_input(),''
for z in s:
 if z in'Hh':o+='Hello World!'
 elif z in'Qq':o+=s
 elif'9'==z:
  i=298
  while~-i:print i/3or 99,'bottle'+'s of beer on the wall.\n'[2<i<6:9+i%3*12]+'..\nGToa kteo  otnhee  dsotwonr,e ,p absusy  isto maer omuonrde,,'[(i>3)+i%3*68::2];i-=1
 elif'+'!=z:o='Source code contains invalid characters';break
print o
```
[Answer]
## Java, 546 bytes
This is my first code golf submission. I am sure we could do more with it. It reads the input as the command line argument.
Beer code "borrowed" from ["99 Bottles of Beer"](https://codegolf.stackexchange.com/questions/64198/99-bottles-of-beer?rq=1) java answer (creative commons) 
```
class a{public static void main(String[] a){if(a[0].matches("^[HQ9\\Q+\\E]+$")){for(char c:a[0].toCharArray()){if(c=='H')p("Hello, world!");if(c=='Q')p(a[0]);if(c=='9')b();}}else{System.out.println("Source code contains invalid characters");}}static void p(String s){System.out.println(s);}static void b(){String b=" of beer",c=" on the wall",n=".\n",s;for(int i=100;i-->1;){s=" bottle"+(i>1?"s":"");p(i+s+b+c+", "+i+s+b+n+(i<2?"Go to the store and buy some more, 99":"Take one down and pass it around, "+(i-1))+" bottle"+(i!=2?"s":"")+b+c+n);}}}
```
Let me know if command line args is not acceptable.
This was a lot of fun!
[Answer]
# Lua 443 - 8 = 435 ~~464 - 8 = 456~~
I managed to save 21 characters by using multiple `if-end`s instead of `if-elseif-end`. I also had some extra white spaces floating around after a few `)`.
```
p=print o=" of beer"t=" on the wall"B=" bottle"b=" bottles"l=io.read("*l");g=l:lower()if g:match"[^hq9+]"then p("Source code contains invalid characters")end for i=1,#g do s=g:sub(i,i)if s=='h'then p("Hello, world")end if s=='q'then p(l)end if s=='9'then n=99 repeat p(n..b..o..t..", "..n..b..o)n=n-1 p("Take one down, pass it around, "..n..b..o..t..".")p()until n==1 p("1"..B..o..t..", 1"..B..o)p("No more"..b..o..t..", no more"..b..o)end end
```
I'm fairly happy with this one, even though it's not much shorter than [my Fortran answer](https://codegolf.stackexchange.com/a/32043/11376). The 99 bottles of beer code has been modified from [this answer by Alessandro](https://codegolf.stackexchange.com/questions/31506/99-bottles-of-beer-99-languages/31816#31816). Ungolfed, we have
```
-- reuse stuff
p=print
o=" of beer"
t=" on the wall"
B=" bottle"
b=" bottles"
-- read the line & then lowercase it for case insensitivity
l=io.read("*l");g=l:lower()
if g:match"[^hq9+]" then -- horray for basic regex
   p("Source code contains invalid characters")
end
for i=1,#g do
   s=g:sub(i,i)               -- take substring
   if s=='h' then p("Hello, world") end
   if s=='q' then p(l) end
   if s=='9' then
      n=99
      repeat
         p(n..b..o..t..", "..n..b..o)
         n=n-1
         p("Take one down, pass it around, "..n..b..o..t..".")
         p()
      until n==1
      p("1"..B..o..t..", 1"..B..o)
      p("No more"..b..o..t..", no more"..b..o)
   end
end
```
[Answer]
# Julia, 362
```
s = chomp(readline(STDIN))
l=""
z=" of beer"
q,r,w,t=" bottles$z"," bottle$z"," on the wall.\n","take one down, pass it around,\n"
for j=99:-1:2
b="$j$q"
l*="$b$w$b.\n$t"
end
l*="1$r$(w)1$r.\n$(t)No$q$w"
p=println
all(c->c in "HQ9+", s)||p("Source code contains invalid characters")
for c in s
    c=='Q'&&p(s)
    c=='H'&&p("Hello, world!")
    c=='9'&&p(l)
end
```
[Answer]
# Tcl, 515
```
set d [read stdin]
if {![regexp {^[hq9\+HQ]*$} $d]} {puts "Source code contains invalid characters"}
lmap c [split $d {}] {set b { bottles of beer}
switch -- $c H {puts "Hello, world"} Q {puts $d} 9 {for {set i 99} {$i>2} {incr i -1} {puts "$i$b on the wall,
$i$b.
Take one down, pass it around,
[expr $i-1]$b on the wall.
"}
puts "2$b on the wall,
2$b.
Take one down, pass it around,
1 bottle of beer on the wall.
1 bottle of beer on the wall,
1 bottle of beer.
Take one down, pass it around,
No$b on the wall."}}
```
Just a bit golfed, still smaller than C and the correct 99 Bottles of beer end verse.
[Answer]
## JavaScript (ES6), 385
```
s=>{n=99,b=' bottle',j=' of beer',d=' on the wall',e='Take one down, pass it around',k='Go to the store, buy some more',l='No',o='s',f=', ';for(i=s.split(m=v='');~n;)v+=[n||l,b,n-1?o:m,j,d,f,n||l,b,n-1?o:m,j,f,n?e:k,f,--n<1?99:n,b,n-1?o:m,j,d,'! '].join(m);return s.match(/[^HQ9\+]/,r='')?'Source code contains invalid characters':[...s].map(c=>({H:'Hello World!',9:v,Q:s})[c]).join``}
```
Didn't opt for the case-insensitive, would have cost too many characters. Not even close to some of the other entries, but was fun nonetheless!
## JavaScript, 344
I made a version with a less complete version of the song:
```
(function(i){if(s.match(/[^HQ9\+]/)){m='Source code contains invalid characters'}else{n=99,b=' bottles of beer ',d='on the wall',e='take one down, pass it around',f=', ';for(;n;)v+=[n,b,d,f,n,b,f,e,f,--n||'no more',b,d,'! '].join(m);h={H:'Hello World!',Q:arguments.callee+m,9:v};for(;c=i[n++];)m+=h[c]||''}alert(m)})((s=prompt()).split(m=v=''))
```
but after seeing the other entries (and looking at the actual lyrics, who knew!), I thought it was a bit of a cop out!
[Answer]
# C, 562 bytes
```
char*c="%1d %3$s of %4$s on the %5$s, %1d %3$s of %4$s.\n\0Take one down and pass it around, %2d %3$s of %4$s on the %5$s.\n\0Go to the store and buy some more, %1d %3$s of %4$s on the %5$s.\n";main(int a,char**b){int x=0;for(int i=0;i<strlen(b[1]);i++){if(b[1][i]=='+')x++;else if(b[1][i]=='9'){int k=99;while(1){printf(&c[0],k,k,k==1?"bottle":"bottles","beer","wall");if(k!=1){printf(&c[49],k,k,"bottles","beer","wall");k--;}else{k=99;printf(&c[114],k,k,"bottles","beer","wall");break;}}}else printf("%s",b[1][i]=='H'?"Hello, world!":(b[1][i]=='Q'?b[1]:""));}}
```
As a full program. First argument is the HQ9+ program. With an actual accumulator. I challanged myself not to use define statements.
Ungolfed version:
```
char* c = "%1d %3$s of %4$s on the %5$s, %1d %3$s of %4$s.\n\0Take one down and pass it around, %2d %3$s of %4$s on the %5$s.\n\0Go to the store and buy some more, %1d %3$s of %4$s on the %5$s.\n";
main (int a, char** b) {
    int x = 0;
    for (int i = 0; i < strlen(b[1]); i++) {
        if (b[1][i] == '+')
            x++;
        else if (b[1][i] == '9') {
            int k = 99;
            while (1) {
                printf(&c[0], k, k, k == 1 ? "bottle" : "bottles", "beer", "wall");
                if (k != 1) {
                    printf(&c[49], k, k, "bottles", "beer", "wall");
                    k--;
                } else {
                    k=99;
                    printf(&c[114], k, k, "bottles", "beer", "wall");
                    break;
                }
            }
        } else
            printf("%s",b[1][i] == 'H' ? "Hello, world!" : (b[1][i] == 'Q' ? b[1] : ""));
    }
}
```
[Answer]
## GNU C, ~~429~~ 423 bytes
Compiles and runs correctly on GCC-8.3, without any compiler flags. No other configuration was tested.
It considers a file to be a stream of text up to the first `'\n'` that it encounters (this just makes testing easier, can be fixed by replacing the `10` in `(c=getchar())!=10` with a `-1`). However, keep in mind that newlines will not be considered valid.
```
char*b="bottles of beer\0on the wall\0Take one down, pass it around",s[4096];n;Q(){puts(s);}W(){puts("Hello, world!");}B(){for(n=100;--n;){printf("%d %s %s,\n%d %s.\n%s,\n%d %s %s.\n\n",n,b,b+16,n,b,b+28,n-1,b,b+16);}}N(){}l=0,c,i,(*t[])()={[43]=N,[57]=B,[72]=W,[81]=Q};main(){while((c=getchar())!=10){if(c!=43&&c!=57&&c!=72&&c!=81){exit(puts("Source code contains invalid characters"));}s[l++]=c;}for(;i<l;++i)t[s[i]]();}
```
## Degolfed
```
// we stick all the strings in a single string, null separated.
// We will later index into the right indices to print the right pieces.
char*b="bottles of beer\0on the wall\0Take one down, pass it around";
// Here we store the source code. I chose 4kiB, but this was rather arbitrary.
char s[4096];
// n is the counter for the B function
n;
Q() { // Q for quine
    // puts is shorter than printf and it prints a newline for free
    puts(s);
}
W() { // W for world
    puts("Hello, world!");
}
B() { // B for bottles
    // n is the current count
    for (n = 100; --n;) {
        printf("%d %s %s,\n"    // n bottles of beer on the wall,
               "%d %s.\n"       // n bottles of beer.
               "%s,\n"          // Take one down, pass it around,
               "%d %s %s.\n\n", // n-1 bottles of beer on the wall
               n, b, b + 16, // Index into the right positions
               n, b,         // in the string.
               b + 28, n - 1, b, b + 16);
    }
}
N() {} // N for nothing, we need it for the table
// l is the length of source code
// c is the currently read character
// i is an index
l = 0, c, i;
// This array of function pointers is a bit like a jump table.
// This table tells us which function to call depending on the current char.
// It is essentially a hand-rolled switch statement, but shorter.
// NOTE: the [index]=value syntax is a GNU extension
int(*t[])()={
    [43/* ASCII + */] = N, // do nothing
    [57/* ASCII 9 */] = B, // print 99 bottles
    [72/* ASCII H */] = W, // print hello world
    [81/* ASCII Q */] = Q  // print source
};
main() {
    // consume input until we hit \n. this
    while ((c = getchar()) != 10) {
        // if we find a character not in "HQ9+", we log and exit
        if (c != 43 && c != 57 && c != 72 && c != 81) {
            exit(puts("Source code contains invalid characters"));
        }
        // populate the source code
        s[l++] = c;
    }
    // go over the source code (at this point validated)
    // and call the function that is set in the table
    // We can skip initializing i because it is a static, and statics
    // get implicitly initialized to 0. this saves 3 bytes
    for (; i < l; ++i)
        t[s[i]]();
}
```
I will admit I cheated a bit with the 99 bottles.
[Answer]
# Excel VBA, 489 Bytes
Unindented:
```
Sub h(s)
For c=1 To Len(s)
Select Case Mid(s,c,1)
Case "H"
Debug.? "Hello,World!"
Case "Q"
Set v=ActiveWorkbook.VBProject.VBComponents("M").CodeModule:For n=1 To v.countoflines:Debug.? v.Lines(n,1):Next
Case "+"
a=a+1
Case "9"
s=" Bottles of Beer":o=" Bottle of Beer":w=" on the wall":t=". Take 1 down pass it around,":p=",":d=".":For n=99 To 3 Step -1:Debug.? n;s;w;p;n;s;t;n-1;s;w;d:Next:Debug.? 2;s;w;p;2;s;t;1;o;w;d:Debug.? 1;o;w;p;1;o;t;"No";s;w;d
End Select
Next
End Sub
```
---
(indented for readability)
```
Sub h(s)
For c=1 To Len(s)
Select Case Mid(s,c,1)
    Case "H"
        Debug.? "Hello,World!"
    Case "Q"
        Set v=ActiveWorkbook.VBProject.VBComponents("M").CodeModule
        For n=1 To v.countoflines
            Debug.? v.Lines(n,1)
        Next
    Case "+"
        a=a+1
    Case "9"
        s=" Bottles of Beer"
        o=" Bottle of Beer"
        w=" on the wall"
        t=". Take 1 down pass it around,"
        p=","
        d="."
        For n=99 To 3 Step -1
            Debug.? n;s;w;p;n;s;t;n-1;s;w;d
        Next
        Debug.? 2;s;w;p;2;s;t;1;o;w;d
        Debug.? 1;o;w;p;1;o;t;"No";s;w;d
End Select
Next
End Sub
```
Rename default *Module1* to *M*  
call with `h "+++++++++Your Code"`  
]