You can use Turing completeness as a criterion, but it's a little strict (a special-purpose programming language may not be Turing), so I will go with something less rigid.
I think the key is that the output should be a series of instructions and that there will be a non-trivial correspondence between this output and the input. The example you provided violates the last criterion, since only two possible outputs are possible, no matter how complicated the input is: "echo Hi" and nothing.
The correspondence can be very close (both between FORTRAN and the assembly), and more distant (Prolog or Lisp and the assembly), but until you can create a huge amount of behavior through a consistent input language, the compiler.
source share