Основываясь на комментарии Джорджа Эдисона к этому вопросу , напишите наименьший интерпретирующий себя переводчик.
- Вы можете использовать язык по вашему выбору.
- Пустые языки не учитываются. Ваша программа должна быть длиной не менее двух символов.
- Программе не нужно интерпретировать весь язык, только полное по Тьюрингу подмножество языковых возможностей (которое содержит интерпретатор).
- Куайны не в счет.
- Не используйте встроенную
eval
функцию вашего языка или ее эквивалент. То же самоеapply
и т. Д.
code-golf
interpreter
Хоа Лонг Там
источник
источник
/usr/bin/cat
) как насчет полноты по Тьюрингу?sexp
парсер.Ответы:
КИ - 260
320 → 260: нажмите простые сопоставления символов и команд, затем сложите их. Это вдвое уменьшает размер кода для каждого случая (есть 18 случаев), но для свертывания требуется 30 символов.
Это еще один из моих построенных языков (базовый переводчик, размещенный на Gist ). Он уникален тем, что язык распознает фрагменты кода. То есть строки инструкций в этом языке на основе стека используются с тем же эффектом, что и структуры данных или замыкания в других языках:
Интерпретатор создает фрагмент кода всей программы перед ее запуском, поэтому его также можно считать компилятором. Из-за этого наложение интерпретатора не приводит к экспоненциальным накладным расходам во время выполнения.
Интерпретатор получает все свои операторы непосредственно из интерпретатора хоста. Однако он выполняет синтаксический анализ сам по себе, поэтому большая часть кода - это просто последовательности, которые переводят символы в соответствующие им литералы кода. Это не то же самое, что использование
eval
, но оно показывает, насколько зависима любая реализация языка программирования от семантики своего основного языка / архитектуры.Справочник по языку:
Получить переводчика здесь
Блоки
(
...)
Создайте «блок», который фактически представляет собой список инструкций без контекста. Внутренне это может быть даже машинный код.
блок
$
Вызовите блок. Вызываемому абоненту передается глобальный стек, который включает вызываемый блок.
ценность
^
Поднимите значение. А именно, превратить его в блок, который толкает это значение.
Пример :
блок1 блок2
&
Соедините два блока, образуя один, который запускает оба в последовательности.
Пример :
Манипулирование стеком
N
c
Скопируйте n-е значение стека.
Пример :
N
p
Соберите n-е значение стека (уберите его и перенесите на передний план).
Пример :
N
d
Удалите n значений из стека.
0d
это неоперация.Пример :
Реляционные операторы
ab (on_true) (on_false)
=
Проверьте, равно ли а б. Поглотить все, кроме первого аргумента, и вызвать on_true или on_false. Если один аргумент равен нулю, а другой - любого другого типа, результат будет ложным. В противном случае a и b должны быть целыми числами.
Пример :
ab (on_true) (on_false)
<
Проверьте, если а меньше, чем б. a и b должны быть целыми числами.
Пример :
ab (on_true) (on_false)
>
Проверьте, если а больше, чем б. a и b должны быть целыми числами.
Пример :
Ло привет (on_true) (on_false)
~
Проверьте, что lo <= a <= hi. a, lo и hi должны быть целыми числами.
Пример :
I / O
с
.
Положите символ с (потребляя его из стека).
,
Получить персонажа и положить его в стек. Если достигнут конец файла, нажимается -1.
с
!
Unget персонаж. Точно так же, как ungetc в C, разрешен только один возврат.
Целочисленные литералы
'c
Нажмите на символ c.
[0-9] +
Нажмите десятичное целое.
арифметика
+
-
аб
*
Добавить / вычесть / умножить два числа.
Пример :
аб
/
аб
%
Деление и модуль. В отличие от C, они округляются в сторону отрицательной бесконечности.
Разнообразный
код
#
комментария#
Характер закомментирует все до конца строки.)
Используется для окончания блоков. Может использоваться и для завершения всей программы.
Все остальные символы игнорируются.
источник
Двоичное лямбда-исчисление, 232 бита (29 байт)
0101000110100000000101011000000000011110000101111110011110000101110011110000001111000010110110111001111100001111100001011110100111010010110011100001101100001011111000011111000011100110111101111100111101110110000110010001101000011010
См. Http://en.wikipedia.org/wiki/Binary_lambda_calculus#Lambda_encoding для получения подробной информации.
источник
Я не могу взять кредит на этот , но я думал, что поделюсь этим удивительным:
Брейнф *** (423)
источник
BlockScript - 535
BlockScript - это тривиальный язык на основе стека спагетти, который я создал специально для этой задачи. Базовый интерпретатор - blockscript.c .
Пример программы (печатает первые 15 чисел Фибоначчи):
Интерпретатор считывает как исходный код, так и программный ввод со стандартного ввода в указанном порядке. Это означает, что для запуска интерпретатора внутри интерпретатора внутри интерпретатора просто скопируйте и вставьте:
Как и в фильме « Начало» , вы не можете пройти глубже трех уровней. Это не вопрос времени, а пространство. BlockScript утечка памяти обильно, и это связано с тем, как сам язык разработан.
Справочник по языку:
Получить переводчика здесь
В BlockScript «стек» не является массивом, который перезаписывается последующими операциями, к которым вы привыкли. На самом деле он реализован в виде неизменяемого связанного списка, и стек сохраняется в течение всей программы. Кроме того, ни один оператор (кроме
@
) не удаляет значения из стека. Однако модификации стека влияют только на блок, в котором они происходят.Выбор значения
a
черезz
Извлеките 0-25-й предмет из стека и поместите его в стек.
a
относится к заголовку или к последнему добавленному элементу стека.A
черезZ
Получите 0-25-й элемент текущего кадра и поместите его в стек.
[
Откройте «рамку», чтобы выбрать элементы из стековой ссылки (см. Ниже) в начале стека.
[
не требует соответствия]
, но рамки имеют лексическую область видимости. В BlockScript «область действия» определяется фигурными скобками ({
...}
), которые образуют блоки. Таким образом, открытие кадра внутри блока не повлияет на код вне блока.]
Закройте текущий кадр, вернувшись к предыдущему кадру (если есть).
Блоки
{
...}
Создайте «блок» и поместите его в стек. Внутри блока стек будет начинаться с того, что был до блока, за исключением того, что стек вызывающей стороны будет помещен сверху. Стеки являются постоянными и неизменными в BlockScript, поэтому блоки являются замыканиями. Идиома
{[
означает открыть блок, затем открыть фрейм, чтобы начать выбор аргументов (используяA
сквознойZ
). Возвращаемое значение блока - это заголовок стека при}
достижении.Пример:
Это печатает
123BCD123DCB123BCD123DCB…
. Буквы в нижнем регистре относятся к значениям стека, а буквы в верхнем регистре относятся к аргументам (потому что фрейм установлен в стеке вызывающей стороны).A!
берет голову вызывающего абонента (который гарантированно будет вызываемым блоком) и вызывает его. Если вам интересно, почему он обращается вспятьBCD
каждый раз, это потому, чтоB. C. D.
эти аргументы передаются в обратном порядке прямо перед вызовом самого блока.!
Вызовите блок. Вставьте возвращаемое значение в стек.
Ссылки на стек
&
Создайте ссылку на стек и поместите ее в стек. Думайте об этом как о «супер-минусах», так как он эффективно отбирает каждый элемент в стеке и формирует из него «кортеж». Идиомы
&[
означает , что всеa
,b
,c
упомянутые до настоящего времени могут быть доступны сA
,B
,C
(для оставшейся части блока или пока]
не встретится).Частично потому, что
&
захватывает больше значений, чем обычно требуется, BlockScript утечка памяти по своей конструкции.@
Переключиться на стек, на который указывает ссылка на стек
a
. Этот оператор довольно странный, но самоинтерпретатор BlockScript использует его пару раз, чтобы избежать необходимости выдвигать одни и те же аргументы дважды. Эффекты@
(или любая стековая операция, в этом отношении) ограничены блоком, в котором он вызывается. Кроме того, на фрейм это не влияет@
, поэтому фрейм можно использовать для получения значений, которые вам нужны после переключения стеков.Условное выражение
?
<на true>:
<на false>Условное выражение, как и тернарный оператор в C. То есть, если
a
"true" (т. Е. Не равно целому нулю), тогда делать <on true> , иначе делать <on false> .I / O
Примечание: ввод и вывод выполняются в UTF-8. «Символ» - это целое число, соответствующее индексу Unicode.
,
Получите следующий символ ввода и поместите его в стек. Если достигнут конец ввода, вместо этого нажмите -1.
.
Выведите символ на верхушку стека.
Целочисленные / символьные литералы
Примечание. Целые числа и символы - это одно и то же в BlockScript.
'c
Нажмите на символ c.
[0-9] +
Нажмите десятичное целое.
арифметика
Эти операторы работают только с целочисленными значениями.
+
Вычислитьb
+a
(сдвигая результат, но не сбрасывая ни одно из значений).-
Computeb
-a
.*
Вычислитьb
*a
./
Вычислитьb
/a
(целочисленное деление; округление до отрицательной бесконечности).%
Вычислитьb
%a
(целочисленный модуль; округляет до отрицательной бесконечности).Реляционные операторы
Эти операторы работают только с целочисленными значениями.
<
Еслиb
меньше чемa
, нажмите 1, иначе нажмите 0.>
=
Разнообразный
#
Комментарий к концу строки;
источник
Зозотез ЛИСП : 414
Добавлены переводы строк, чтобы получить хороший блок, который не нужен и не учитывается.
Теоретически он должен быть в состоянии работать сам, но поскольку оригинальный интерпретатор является двоичным файлом BrainFuck, а сам интерпретатор, я смог протестировать только каждую часть. Когда дано само по себе и простое выражение,
(p p)
я думаю, что ему нужно больше времени, чем 40 минут, которые я ждал до сих пор, и я использую свой постjitbf
для его запуска, который (неправильно) использует Perl Inline-C для запуска кода C на лету.Невозможно реализовать весь Zozotez в Zozotez, так как у него нет средств для изменения минусов и
:
(setq / define) это необходимо для обновления привязок. Я также не реализовал явный аргумент begin / progn или & rest, макросы и специальные аргументы печати, поскольку не использовал его в интерпретаторе. Я включилp
(печать), хотя я не использую его, поэтому программы должны явно печатать свои расчеты, как и оригинальный интерпретатор.Тот же безгольфен
источник
CHIQRSX9 + (вероятно, не конкурирующий), 2 байта
На этом языке HQ9 + нет возможности написать интерпретатор с самоинтерпретацией без использования
I
, который запускает встроенный интерпретатор, который обрабатывает STDIN.источник
eval
, что для выражений, а не программ.X
сделает язык Turing-полным (таким образом, способным вычислять простые числа) зависимым от реализации способом.X
случайным образом возмущает программу и выполняет ее, что означает, что нельзя использовать команду, кроме как для детерминированного вычисления простых чисел. Можете ли вы привести пример интерпретатора, который позволит вам использоватьX
способ, который вы указали?Одновременная файловая система Befunge 98 - 53 \ 18 байт (почти наверняка читерство)
Полный 53-байтовый интерпретатор без ограничений (хотя я не тестировал сложные временные взаимодействия, включающие разделение и перенос IP-адресов):
Читает ввод из файла с именем
a
и выполняет его. В правилах не указано, что мы не можем использовать самоизменяющийся код.18-байтовый интерпретатор, который не допускает перенос (IP-перемещение одного края кода и начало с противоположного края):
источник