Pull to refresh

Полиглоты

Reading time 5 min
Views 4.1K
Есть люди-полиглоты, которые отличаются тем, что знают несколько языков. А есть программы-полиглоты, исходный код которых интерпретируется или компилируется независимо от языка.

Вся прелесть полиглота в том, что один и тот же исходный код можно сохранить как сишный файл, скомпилировать его, и порадоваться результату работы. А можно этот же файл запустить как bash-скрипт и увидеть точно такой же результат работы!

Пример такой программы:
  1. #define a /*
  2. #<?php
  3. echo "\010Hello, world!\n"// 2> /dev/null > /dev/null \ ;
  4. // 2> /dev/null; x=a;
  5. $x=5 // 2> /dev/null \ ;
  6. if (($x))
  7. // 2> /dev/null; then
  8. return 0;
  9. // 2> /dev/null; fi
  10. #define e ?>
  11. #define b */
  12. #include <stdio.h>
  13. #define main() int main()
  14. #define printf printf(
  15. #define true )
  16. #define function
  17. function main()
  18. {
  19. printf "Hello, world!\n"true/* 2> /dev/null | grep -v true*/;
  20. return 0;
  21. }
  22. #define c /*
  23. main
  24. #*/
* This source code was highlighted with Source Code Highlighter.

Работает в ANSI C, PHP и bash. Подробней:
  • "//" является комментарием в PHP и рутовой директорией в sh
  • Иструкция «function main()» является валидной для PHP и bash, для С она превращается в «int main()» во время компиляции
  • Конструкция вида «if (($x))» может быть использована для bash и PHP
  • Последние 3 строчки использует только bash
  • «printf» в bash аналогична printf в С, за исключением скобок(их добавит препроцессор)


Для написания полиглотов обычно используется С т.к. он обладает мощным препроцессором и какой-нибудь из скриптовых языков, например Perl, PHP, sh или Lisp.

Например:
  1. #include <stdio.h>
  2. #define do main()
  3. do {
  4.   printf("Hello World!\n");
  5. }
* This source code was highlighted with Source Code Highlighter.
Простенький Hello-World для С и Perl.

Но 2 языка это совсем примитивно, предлагаю вам взглянуть на полиглот на 15(!!!) языках:
  1. # /* [  <!-- */ include  <stdio.h> /*   \
  2.   #{\
  3. `""""true \\#{"\n#"};           \
  4.   \
  5. if [ -n "$ZSH_VERSION" ]; then           \
  6.   \
  7.   echo exec  echo I\'m a zsh script.; \
  8.   \
  9. elif [ -n "$BASH_VERSION" ]; then        \
  10.   \
  11.   echo exec  echo I\'m a bash script.; \
  12. else  \
  13.   echo exec  echo  I\'m  a sh  script.;    \
  14. fi`;  #\
  15. BEGIN{print"I'm a ", 0 ? "Ruby"  :"Perl",  " program.\n";  exit; } 
  16.   #\
  17. %q~            
  18.   
  19. set dummy =0; puts [list "I'm"  "a"  "tcl"  "script."]; exit   
  20.   
  21. all: ; @echo "I'm a Makefile."          \
  22.   #*/
  23. /*: */ enum {a, b};            \
  24.   \
  25. static int c99(void) {         
  26.   
  27. #ifndef __cplusplus /* bah */        
  28.   
  29. unused1: if ((enum {b, a})0)          \
  30.   (void)0;
  31. #endif           
  32.   
  33. unused2:  return a;     \
  34. }  \
  35. static int trigraphs(void) {         \
  36.   \
  37.   return sizeof  "??!"  ==  2;    \
  38. }  \
  39. char X;               \
  40.   \
  41. int main(void) {             \
  42.   \
  43.   struct X  {        \
  44.   \
  45.      char  a[2];    \
  46.   };\
  47.   if (sizeof(X)  !=  1) {       \
  48.   \
  49. printf("I'm a C++ program (trigraphs %sabled).\n",         \
  50.   \
  51.    trigraphs()  ? "en"  : "dis");\
  52.   \
  53. }else if (1//**/2
  54.  
  55.  
  56. )unused3 : { ; \
  57.     printf("I'm a C program (C%s, trigraphs %sabled).\n", \
  58.         c99() ? "89 with // comments" : "99", \
  59.         trigraphs() ? "en" : "dis"); \
  60.   } else { \
  61.     printf("I'm a C program (C89, trigraphs %sabled).\n", \
  62.         trigraphs() ? "en" : "dis"); \
  63.   } \
  64.   return 0; \
  65. } /*
  66. # \
  67. > main :: IO () -- -- \
  68. > main = putStr "I'm a Literate Haskell program.\n"
  69. # \
  70. ]>++++++++[<+++++++++>-]<+.>>++++[<++++++++++>-]<-.[-]>++++++++++ \
  71. [<+++++++++++>-]<-.>>++++[<++++++++>-]<.>>++++++++++[<++++++++++> \
  72. -]<- - -.<.>+.->>++++++++++[<+++++++++++>-]<++++.<.>>>++++++++++[ \
  73. <++++++++++>-]<+++++.<<<<+.->>>>- - -.<+++.- - -<++.- ->>>>>+++++ \
  74. +++++[<+++++++++++>-]<- - -.<<<<<.<+++.>>>.<<<-.- ->>>>+.<.<.<<.> \
  75. ++++++++++++++.[-]++++++++++"""`
  76. # \
  77. print "I'm a Python program."; """[-][--><html><head>
  78. <!--:--><title>I'm a HTML page</title></head><body>
  79. <!--:--><h1>I'm a <marquee><blink>horrible HTML</blink></marquee> page</h1>
  80. <!--:--><script language="JavaScript">
  81. <!--: # \
  82. setTimeout( // \
  83.   function () { // \
  84.    document.body.innerHTML = "<h1>I'm a javascript-generated HTML page</h1>"; // \
  85.   }, 10000); // \
  86. //-->
  87. </script><!--: \
  88. </body></html><!-- } # \
  89. say "I'm a Perl6 program", try { " ($?PUGS_VERSION)" } // "", "."; # """ # */
  90. #define FOO ]-->~
* This source code was highlighted with Source Code Highlighter.

Работает в C(x2), C++, Haskell, Ruby, Python, Perl(x2), HTML, tcl, bash, zsh, make, bash и brainfuck(спасибо maxshopen за подсказку :)).

Ну и под конец несколько ссылок на чуть менее монструозные конструкции:
8 языков: COBOL, Pascal, Fortran, C, PostScript, Unix shell, asm x86 и Perl 5
6 языков: Perl, C, Unix shell, Brainfuck, Whitespace и Befunge
Список полиглотов, написанных энтузиастами
Tags:
Hubs:
+123
Comments 66
Comments Comments 66

Articles