expr ::= expr op expr | (expr) | identifier | { expr, expr } | number | map(expr, identifier -> expr) | reduce(expr, expr, identifier identifier -> expr)
op ::= + | - | * | / | ^
stmt ::= var identifier = expr | out expr | print "string"
program ::= stmt | program stmt
- number - произвольное целое или вещественное число
- приоритеты операторов такие (в возрастающем порядке): + и -, * и /, ^
- {expr1, expr2}, где expr1 и expr2 - выражения с целым результатом - последовательность чисел { expr1, expr1 + 1, expr + 2 .. expr2 } включительно. Если результат вычисления expr1 или expr2 не целый или expr1 > expr2, результат не определен.
- map - оператор над элементами последовательности, применяет отображение к элементам последовательности и получает другую последовательность. Последовательность может из целой стать вещественной. Лямбда у map имеет один параметр - элемент последовательности.
- reduce - свертка последовательности. Первый аргумент - последовательность, второй - нейтральный элемент, третий - операция. Свертка применяет операцию (лямбду) ко всем элементам последовательности. Например, “reduce({5, 7}, 1, x y -> x * y)” должен вычислять 1 * 5 * 6 * 7. Можно полагаться на то, что операция в reduce будет ассоциативна.
- области видимости переменных - от ее объявления (var) до конца файла. Переменные у лямбд в map / reduce - имеют областью видимости соответствующую лямбду. У лямбд отсутствует замыкание, к глобальным переменным обращаться нельзя
- out, print - операторы вывода. "string" - произвольная строковая константа, не содержащая кавычек, без экранирования
var n = 500
var sequence = map({0, n}, i -> (-1)^i / (2 * i + 1))
var pi = 4 * reduce(sequence, 0, x y -> x + y)
print "pi = "
out pi
- Интерпретатор должен выдавать ошибки парсинга и ошибки несоответствия типов (складывание чисел и последовательностей, применение map/reduce к числам, итд).
- map и reduce должны выполняться интерпретатором параллельно по разумной стратегии.
- Все, что не учтено в правилах грамматики, на твое усмотрение.
- По желанию: поддержка вычислений на длинных последовательностях (миллионы элементов).
- Ошибки от интерпретатора должны подсвечиваться по месту автоматически.
- Результаты работы программы должны автоматически рассчитываться в фоне и показываться.
- Долгие вычисления не должны приводить к блокировке UI и мешать работе.
- UI на твое усмотрение.
- Программа должна быть написана на Java/Kotlin.
- Допускается разумное использование готовых средств и библиотек.
- Исходный код должен быть предоставлен в виде полностью настроенного самодостаточного проекта, размещенного на github.
- Должен быть предоставлен необходимый набор тестов.
- Там где это имеет смысл, API должен быть документирован на английском языке.