Creating a HQ9+ interpreter The goal of this code golf is to create an interpreter for the programming language HQ9+
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"
+ - increments the accumulator


The rules:


Because the accumulator isn't defined, you can ignore the command +
Your program should prompt for input (this input will be the source code) or the source code is read from a file
You are not allowed to put the lyrics of "99 bottles of beer" in a file, and read the text from the file
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)
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
If your interpreter accepts both uppercase and lowercase characters, then you get -8 to your character count
 

Good luck!
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⋄⍵&lt;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