A non-prepared procedure only works if the procedure has no parameters. It should be allowed to work even with parameters through literal substitution.
Also the parsing loop incorrectly increments the parsing position after a match. This means that the character after a positional reference is lost. The workaround for typical scenarios would be to use extra whitespace. i.e.
Note the extra space after $1.