> As far as I know any program that translates code from one language to another is a compiler.

No, there's a distinction between a code translation and a code compilation. At an abstract level, it's the difference between an actual Turing machine encoded with a specific set of instructions, and a Universal Turing machine along with an encoded representation of a program. Logically equivalent, yes, but that's not the same thing as saying that they're actually the same thing. (If they were, this would mean that any Turing-complete languages would be the same, so you might as well just write COBOL!)

Compilation is not just a matter of "produce another piece of source code that appears to have the same logic when executed". With compilation, the only information required at runtime is the input to the program itself (which is never known at compiletime, unless your program is one massive thunk - which would be kind of a useless program!). When translating code to another language like, eg., Javascript, this isn't the case, because the input to the program isn't fed directly to the output of the translation; rather, both are fed to the interpreter which executes one on the other.

This applies whether the target language for the translation is itself an interpreted language or a compiled language, but in practice, the translated form of a compiled language (ie, C) can itself be compiled immediately as part of the translation, so this isn't really a relevant distinction there.

(By this logic, it would seem that javac is a translator, not a compiler, which is almost half-true, but only because Java itself blurs the distinction[1]. javac compiles Java code to run "natively" on the Java virtual machine, and that machine is virtualized on actual hardware. So no input is required at runtime from the perspective of someone inside the virtual machine; however, since we're outside that hypothetical bubble, we can't actually execute that code natively and need to run a second translation at runtime - ie, the "just-in-time" portion of the process).

The reason this distinction is important has to do with the portability, reliability, and predictability of the generated code. Compiled code is inherently less portable (or at least, no more portable) than the pre-compilation source (whatever that language is). This is why languages like C are compiled for a particular system. On the other hand, the compiled form "solves" a lot of the decision problems that don't require executing (or even knowing) the input before-the-fact.

An interesting example of this problem is hiphop-php. As one of the other commenters pointed out, when translating code from one language to another, you have to encompass all of the quirks of the language (like 'wat') properly. The hiphop-php output is incredibly large because it has to statically determine the actions required when, ie, two variables are added, but one is a number and one is a string. This is just a feature of a dynamically typed language, yes, but it's not an issue if you simply wanted to translate Ruby to PHP, because you don't have to factor in any of that logic at compilation time - rather, it gets factored out and passed on to the interpreter. To create a truly self-executing, compiled form, that requires solving a lot of this logic insofar as your target system will allow, which is a much trickier process - you can't just rely on the runtime or the interpreter to pick up the slack for you.

[1] Incidentally, this was one of Java's selling points back in the day - hard to believe now!