# Polyglot self-interpreter time

Your task is to make a program which interprets the language it is run in, but also works in many languages.

Let's say you make a Brainfuck-Underload self-interpreglot, as it will be called. Run in Brainfuck, this program should be a Brainfuck interpreter; run in Underload, it should be a Underload interpreter.

Your program should work like the hypothetical given above: given a list of languages L1, L2, L3, L4... up to Ln, it should be an L1 interpreter in L1, an L2 interpreter in L2, an L3 interpreter in L3, up to being an Ln interpreter in Ln.

Your program can handle errors in any way. However, it must never output to STDERR (or closest equivalent) if the input given for interpretation has no errors.

It must output to STDOUT (or closest equivalent) and take input from STDIN (or again, closest equivalent).

You can choose any interpretation of a given language, e.g. if your polyglot works in Brainfuck, it can interpret Brainfuck with finite or unbounded tape. You must specify what interpretations you choose to use for each language.

Programs must have at least 2 characters for this challenge to prevent empty programs from competing.

Functions such as exec and eval are allowed.

Only a Turing-complete subset of a language has to be interpreted.

Different languages have to be interpreted, not different language versions.

Your score is C/(L^3), where C is code length, computed in bytes with UTF-8 encoding, and L is the amount of languages. The lowest score wins: if two winning answers have the same score the one posted earlier wins.

Have fun.

• Are functions such as exec and eval allowed? Does the entire language spec have to be interpreted or just a turing complete subset? – FlipTack Dec 28 '19 at 17:27
• Yes and yes. Mostly for non-esoteric languages. – Andrew Dec 28 '19 at 18:47
• @FlipTack's second question was an "either/or" not a "yes/no"! :D – Shaggy Dec 28 '19 at 19:35
• "In languages without any method of input (e.g. ///) programs may get input through an insertion into the source code" does this make the empty program a valid submission in some languages? codegolf.meta.stackexchange.com/a/10553/89930 – 79037662 Dec 29 '19 at 18:47

# Jelly, 05AB1E, GolfScript 8 bytes, score = $$\\frac 8 {27} \approx 0.296\$$

.Vq;~
ɠV


Try it online Jelly!

Try it online 05AB1E!

Try it online GolfScript!

In all cases, takes a program in the relevant language from STDIN and executes it, with any output going to STDOUT.

• The scoring has been updated, so this is now 23/27 ~ 0.851 – Lyxal Dec 29 '19 at 1:43
• Sorry about that. The challenge keeps changing :-/ – Luis Mendo Dec 29 '19 at 9:59

## GolfScript/MathGolf/CJam/Paradoc/FlogScript, 1 byte, score = 1/125 = 0.008

For all stack-based languages, input may be implicitly pushed onto the stack.

The most boring (yet probably the optimal) answer.

Going forward to see what is the most common character choice for an evaluation operator...

~


TIO for MathGolf

TIO for CJam

TIO for GolfScript

## What other languages have ~ as an evaluation built-in?

Not adding this language to the polyglot. Because I'm too lazy.

## Explanation

~    Evaluate the input


# Keg and Python 3, 19 characters, score = $$\ \frac{19}{8} \$$

exec(input())
"ø¿ß"


Try it online! (Keg)

Try it online! (Python 3)

Uses the same approach as Nick first did, but with Keg instead.

I'll have to figure out how to add another language to get competitive again.

## GolfScript/Keg, 6 bytes, score = 3/4 = 0.75

Do we have to use at least one practical language? It doesn't seem to say that in the spec.

ß.~\;


## Golfscript

ß     # Odd undefined ops
.    # Copy the input
~   # Evaluate it
\; # Discard the unevaluated copy


## Keg

ß     # Take input & evaluate the input
.    # Output the result as a number
~   # Push a random number
\; # Escape the ; character


# Clojure/Common Lisp/scheme/bash/ksh/posix sh/zsh/csh/yash/tcsh, 34 33 bytes, score = 33/1000 = 0.033

as low as 0.000327480423 points, see comment

"w";eval $SHELL;exit (eval(read))  Try it online! Alternative for 31 bytes but does not work on clojure: "w";eval$SHELL


Use (print "hoo") as input and it should work for all lisps. Try pwd for shells.

## lisp

Simple. These lisp dialects seem to all be similar enough to all work for this. Unfortunately, there is not a TIO for scheme. The only one of these I know is Common Lisp, which I am still learning.

Are the different implementations of CL different enough to be counted separate? Because then. . .

## shells

Just evaluates itself, then exits so it won't try to do the lisp part.

• This meta question verifies that a language is defined by its implementations, so my score could be 34/(47^3) = 0.000327480423 with 37 implementations, assuming each one worked -- not to mention different shells – Wezl Apr 28 '20 at 22:55

# PHP/Python 3/Javascript, 130 bytes, score = 130/27 ~ 4.814

[1//eval(input())
];eval("\x24a=\"/\";eval(\x24{\x24a}/bin/echo 'eval(fgets(fopen(\"php://stdin\",\"r\")));');eval(prompt());");


Try it online - PHP

Try it online - Python 3

For javascript run it in the browser's console, as prompt is not defined in node.

NOTE - you can also put a brainfuck+ook self interpreter in there but it's too big. Explanation:

Python - the // operator is integer division, so the interpreter tries to calculate it, so it executes eval(input()), and then it errors out (which is allowed according to Should submissions be allowed to exit with an error?).

Javascript - the // is interpreted as a comment, so it gets the array [1]. Then it evals

$a="/";eval(${$a}/bin/echo 'eval(fgets(fopen("php://stdin","r")));');eval(prompt());  And, then ${$a}/bin/echo 'eval(fgets(fopen("php://stdin","r")));'  evaluates to //bin/echo 'eval(fgets(fopen("php://stdin","r")));', which then gets executed and ignored (as a comment), and then it runs eval(prompt()) to execute the input. PHP - //eval(input()) is interpreted as a comment, so it get's the array [1] like in JS and does nothing with it. Then it evals $a="/";eval(${$a}/bin/echo 'eval(fgets(fopen("php://stdin","r")));');eval(prompt());


but in here

${$a}/bin/echo 'eval(fgets(fopen("php://stdin","r")));'


Is executed from the shell, and translates to //bin/echo 'eval(fgets(fopen("php://stdin","r")));' which returns eval(fgets(fopen("php://stdin","r")));. Then that gets evaled, which executes the code from the input. then it tries evaluating prompt() which doesn't exist and errors out.

PS - This is my first post here, so if I've done anything wrong/missed something please let me know.