Вот очень простое определение языка:
A Variable is any string that does not contain ^, <, >, !, or ?
The empty string is a valid variable identifier
The value of every variable starts at 0.
A Statement is one of (var is a Variable, P is a Program):
var^ -> changes var to be equal to 1 more than itself
var<P> -> while var > 0, changes var to be equal to 1 less than itself, then runs P
var! -> output value of var
var? -> ask for non-negative integer as input, increase var by that value
A Program is a concatenation of Statements, running a Program means running each Statement in order
Примеры программ (обратите внимание, что пустая строка является переменной, но я буду использовать ее экономно для ясности, а некоторые переменные обнуляются в программе, когда они обычно равны 0 по умолчанию):
<>: sets the value of the empty string variable to 0
b<>b?b<a^>: asks for b, then adds the value stored in b to a, zeroing b in the process
b<>b?a<>b<a^>: asks for b, then sets a to the value of b, zeroing b in the process
a<>c<>b<a^c^>c<b^> : copies the value in b into a without zeroing it
b<>c<>a<c^c^c<b^>>b! : outputs a multiplied by 2
b^b<a<>a?a!b^> : outputs what you input, forever
Ваша цель - написать самого маленького переводчика для этого языка.
Значение переменной может быть произвольно большим и должно быть ограничено только общим объемом памяти, к которому у вашего языка есть доступ, теоретически, но вы должны обрабатывать только значения до 2 ^ 256.
Ваша программа должна быть в состоянии обрабатывать произвольно длинные программы, теоретически, но вам нужно будет работать только с программами длиной до 2 ^ 32 символов. Вы также должны обрабатывать вложенные циклы глубиной до 2 ^ 32.
Вы можете предположить, что эта программа является допустимой, и что вы всегда получите неотрицательные целые числа только тогда, когда попросите ввести. Вы также можете предположить, что во входную строку включены только печатные символы ASCII.
Скорость интерпретируемой вами программы не имеет значения, она уже будет мучительно медленной для таких простых вещей, как пятизначное умножение без оптимизации.
Если вы хотите использовать язык, который не может разумно принимать ввод или производить вывод способом, описанным языком, используйте любую интерпретацию, которую вы хотите сделать возможной. Это относится к любой причине, по которой ваш язык не может реализовать требуемое поведение. Я хочу, чтобы все языки могли конкурировать.
Кратчайшая программа выигрывает. Применяются стандартные лазейки.
источник
Ответы:
Рубин, 182 байта
Попробуйте это так:
Как это устроено
r
Функция размечает входную строку и выполняет каждый маркер:Мы ищем какое-то
$2
совпадение имен переменных[^!?^<>]*
, а затем либо<...>
где...
соответствует нулю или более программ (\g
это рекурсия), в этом случае$4
неnil
!
,?
Или^
характер, захвачен$3
, и в этом случае$4
этоnil
.Тогда логика выполнения токена довольно проста, если сделать для него отступ:
источник
JavaScript (ES6) 184
194 209Edit Упрощенный (использование параметров функции для ввода и вывода казалось хорошей идеей, но это не так), еще 1 байт сохранен thx @ ӍѲꝆΛҐӍΛПҐӍЦꝆ
Редактировать 2 Модифицированный разбор. Логика приращения / ввода заимствована из ответа @ Линн
Меньше гольфа
ТЕСТ Фрагмент начала оценки 2016 года с помощью программы, опубликованной @Neil. Потерпи...
источник
eval
чтобы избежатьreturn
не вариант?Perl, 251 байт
Легче читать версию:
Это тратит кучу байтов, исправляя циклы, чтобы быть прямыми прыжками, но сканирование назад для начала цикла оскорбило мое чувство эстетики.
источник
Стандарт С ++, 400 байт
Это компилируется с
g++ -g test.cpp -Wall -Wextra -pedantic -std=gnu++11
Я мог бы сократить это еще немного. Если у вас есть предложения, пожалуйста, прокомментируйте.
источник