Emoji Lisp

(пятница)Всё началось с того, что я прочитал у Станислава Лема в романе «Мир на Земле» (1985), что в будущем общение на языке будет заменено общением при помощи пиктограмм. Мне показалось это довольно пророческим в связи с возрастающим интересом к различным смайликам и другим видам более крупных картинок и я подумал:, а что если программировать при помощи emoji? Поискав в сети я убедился, что мысль такая уже приходила в головы людей и воплотилась в проект https://github.com/wheresaddie/Emojinalно этот проект меня не впечатлил, во-первых язык не обладает полнотой и вообще подход автора как попытка заменить часть операторов при помощи emoji показалась не сильно интересной.Я подумал, что Лисп гораздо лучше будет ложиться на emoji, потому что закрывающие-открывающие скобки это уже будто смайлики, плюс ко всему, сам язык очень прост, компилятор можно написать довольно быстро и для того чтобы всё «работало» не требуется реализации большого количества разных конструкций.Так как хотелось предоставить пользователям возможность легко попробовать этот новый язык, было решено сделать его встраиваемым в браузер. В качестве языка компилятора можно было выбрать любой язык, который компилируется в JavaScript, но я выбрал просто JavaScript и решил написать так, чтобы это можно было компилировать как в окружении node.js, так и в браузере. Второй момент, которого мне бы хотелось достичь это изменяемость набора emoji, я уже с первых операций начал сомневаться в том, что выбор emoji-представления действительно однозначен и решил сделать всё так, чтобы другому разработчику было просто заменить этот набор символов и посмотреть какими получаются новые emoji-программы. По этой причине все примеры с тестами записываются в виде шаблонов, в которые подставляется текущий набор.

В качестве языка для описания грамматики я выбрал PEG, единственная проблема с ним была в том, что unicode-символы не получалось сделать перечислением в условиях (пришлось отдельно перебирать первый и второй символ, потому что для него это несколько символов). Плюс возникла сложность связанная с перекомпиляцией PEG-парсера, поскольку приходилось бы каждый раз менять определение идентификаторов (выкусывая скобки) и пересобирать парсер при помощи PEG.js, что мне показалось достаточно медленным на стороне браузера. Было принято довольно простое решение — перед подачей программы на лексический анализ заменять текущие символы скобок из набора на обычные скобки, а потом уже парсить с обычными скобками. Получился такой PEG:

start = s: sexpr* {return {type: «Program», body: s}}

leftBracket = »(»

rightBracket = »)»

identifier = [\uD83D][\uDC36-\uDE4F] / [\uD83D][\uDE80-\uDEC5] / [\uFE0F] / [\u2702-\u27B0] / [\u24C2] / [\uD83C][\uDC04-\uDFE2] / [\u20E3-\u3299]

number = [0–9]+

_ «whitespace» = [\t\v\f \n\u00A0\uFEFF]*

sexpr = a: atom { return a; } / list

list = leftBracket _ head: sexpr tail:(_ sexpr)* _ rightBracket _ { var result = [head]; for (var i = 0; i < tail.length; i++) { result.push(tail[i][1]); } return {type: 'List', contents:result}; }

atom = d: number _ { return {type: 'Literal', value: parseInt (d.join (»), 10)}} / '»' d:(!'»' [a-z])* '»' _ { return {type: 'Literal', value: d }} / s: identifier _ { return {type: 'Identifier', name: s.join? s.join (»): s}} Дальше-проще: я выбрал набор функций, которые вошли в простенькую стандартную библиотеку, это: a41cf99f90634901a02c6683943d5b3e.pngи для того чтобы продемонстрировать их работу написал вычисление чисел Фибоначчи, вычисление самой себя и ещё несколько простых программоккроме того, экспоритровал картинки и коды из проекта gemoji для более наглядной демонстрации.

Так выглядит программа, вычисляющая саму себя: b8dbc3939ae5422baddb0d7ec2bd81ad.pngздесь месяцы — скобки, животные — идентификаторы, остальные конструкции есть выше.

Так выглядит программа для чисел Фибоначчи: efab34e50d844d83bcadbe79281ca024.pngэто рекурсивная функция имя которой — собачка. Эмоджи символы можно писать подряд, но цифры идущие подряд нужно разделять пробелами, если они относятся к различным числами.

В первой версии вместо месяцев использовались грустные-весёлые смайлики, но из-за их похожести код гораздо сложней было структурировать, по этой причине перешёл на месяцы. Правда, мне не совсем понятно зачем в стандартном наборе emoji есть месяцы, смотрящие в разные стороны.

В процессе выяснил, что emoji не так уж хорошо поддерживаются, к примеру, sublime позволяет копировать только некоторые из них, если попытаться скопировать текст программы вычисляющей саму себя он как бы скопирует, но в буфере обмена будет пусто. Из десктопных браузеров более-менее нормально emoji поддерживаются Safari. Компиляор поддерживает emoji в виде unicode-символов и есть даже repl, но писать терминал тоже не слишком хорошо поддерживает такие символы, они наступают друг на друга, но надеюсь что в будущем ситуация улучшится и мы сможем спокойно писать вызовы эмоджи-утилит прямо в командной строке.

Все исходники доступны на https://github.com/parsifal-47/emojilisp, там можно расширить стандартную библиотеку или написать запрос на это, кроме того, можно попробовать свои силы в программировании на этом простом наборе функций по адресу emojilisp.com. И как я писал в самом начале, мне хотелось, чтобы можно было так же переопределять набор emoji соответствующих функциям без особого труда. Это можно сделать поменяв файлы в папке conf проекта на github или нажав кнопку «create your own set» на сайте, после чего сетом, как и любой программой можно поделиться. Вот, к примеру, вариант с более интересным символом для операции list.

Кроме того, появилась сложно проверяемая идея о том, что такой язык возможно будет легче понимаем детьми и возможно каким-то таким будет программирование будущего.

© Habrahabr.ru