Write a polyglot that prints the language's name

Bash, C, C++, Obj-C, Obj-C++, Perl, PHP, Ruby, 183 chars

score ~ 0.1236

For the C and C-like codes I owe a debt to @baby-rabbit. The others are inspired by the recognition that many languages have an eval statement that will grudgingly accept invalid syntax.

Outputs the language name to standard output. Sometimes generates a lot of error messages on standard error, so suppress them with 2>/dev/null as you run them.

#if 0
'PHP<?/*';eval "print\$=?'Perl':'Ruby';echo Bash";exit
__END__
#endif
#include <stdio.h>
main(){puts(
#ifdef __OBJC__
"obj-"
#endif
"C"
#ifdef __cplusplus
"++"
#endif
);}//*/?>'

The php solution outputs 'PHP' (including the single quotes), which may be bending the rules a little bit.

Last edit: shaved 12 chars from insight that $= is false in Ruby, 60 in Perl, and print$=?... is almost surely an error in Bash. Shaved 7 more from insight the Perl/Ruby/Bash test can now go into a single eval statement.

If the rules can tolerate more bending, I present this 8 language, 43 character solution (score 0.5262)

print("phperluarscriptrubypythoncatebg13");

for which the output includes the name of the interpreter for php, perl, lua, rscript, ruby, python, cat, and rot13.


C, C++, BF, BASH and Ruby; 280 chars

Score is about 0.040

#include "stdio.h"
#define s "C"
#ifdef __cplusplus
#define s "C++"
#endif
#ifndef s
#"+++++++++[>++++++++++>+++++++++<<-]>>-.<++++.>-.++++++++.<----.>---.<+++++++.>---.++++++++.<<++++++++++.[-]"
if [ 1 == 2 ];then
puts "Ruby"
exit
fi
echo "BASH"
exit
end
#endif
main(){puts(s);}

Note that I am using a Linux system.

The code is run or compiled with the following commands (the file's name is test.c)

C:

gcc test.c

When run with ./a.out, output is C

C++:

c++ test.c

When run with ./a.out, output is C++

BASH:

./test.c

Outputs: BASH

Ruby:

ruby test.c

Outputs: Ruby

BrainF***:

Verified using the following:

  • A JS debugger

  • A free interpreter

  • My interpreter

Outputs: brainfuck

Note that if the JS debugger is used, then the first two minus signs need to be removed. They were included to offset the plus signs in the string literal "C++". This was a very fun project, I'm working on adding more languages.

Just to add further clarity, here are my interpreter's/compiler's specs:

  • gcc version 4.6.3

  • ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]

  • GNU bash, version 4.2.24(1)-release (x86_64-pc-linux-gnu)

SIDE NOTE

Using @baby-rabbit's trick I was able to extend my code to be executable in 7 languages (objective-C and objective-c++ being added). This is not my solution since I did copy some, but I thought I would show it off.

Update 9.12 Added SmallTalk run with gnu-smalltalk!

SmallTalk, C, C++, Objective-C, Objective-C++, BASH, BF, Ruby; 384 chars (Score: 0.059)

#if (a)
##(true) ifTrue: ['SmallTalk' printNl]
##(ObjectMemory quit)
#"+++++++++++[>++++++++++>+++++++++<<-]>>-.<++++.>-.++++++++.<----.>---.<+++++++.>---.++++++++.<<++++++++++.[-]"
if [ 1 == 2 ];then
puts 'Ruby'
exit
fi
echo 'BASH'
exit
end
=begin
#endif
#include "stdio.h"
main(){puts(
#ifdef __OBJC__
"Objective-"
#endif
"C"
#ifdef __cplusplus
"++"
#endif
);}
#ifdef b
=end
#endif

In the above code you will need to rename the file to produce the langauge's name for objective-c, obj-c++, c and c++.


bash, c, c++, obj-c, obj-c++; 134 chars; score=0.083

#if x
echo "bash"
exit
#endif
#include <stdio.h>
int main(){puts(
#ifdef __OBJC__
"obj-"
#endif
"c"
#ifdef __cplusplus
"++"
#endif
);}

rename file and run/compile as:

  • sh file.sh
  • cc file.c
  • cc file.cpp
  • cc file.m
  • cc file.mm

(where cc is clang-421.10.42)