Выразительный JavaScript (Хавербеке) - страница 115

Можете ли вы придумать способ, который позволил бы воплотить систему поддержки таких зависимостей? Посмотрите на определение >require и подумайте, что нужно сделать этой функции для этого.

11. Проект: язык программирования

То, что проверяет и определяет смысл выражений в языке программирования, является в свою очередь просто программой.

Хэл Абельсон и Жеральд Сасман, «Структура и интерпретация компьютерных программ».

Когда ученик спросил учителя о природе цикла Данных и Контроля, Юань-Ма ответил: «Подумай о компиляторе, компилирующем самого себя».

Мастер Юань-Ма, «Книга программирования»

Создать свой язык программирования удивительно легко (пока вы не ставите запредельных целей) и довольно поучительно.

Главное, что я хочу продемонстрировать в этой главе – в построении языка нет никакой магии. Мне часто казалось, что некоторые человеческие изобретения настолько сложны и заумны, что мне их никогда не понять. Однако после небольшого самообразования и ковыряния такие штуки часто оказываются довольно обыденными.

Мы построим язык программирования Egg (Яйцо). Он будет небольшим, простым, но достаточно мощным для выражения любых расчётов. Он также будет осуществлять простые абстракции, основанные на функциях.

Разбор (parsing)

То, что лежит на поверхности языка – синтаксис, запись. Грамматический анализатор, или парсер – программа, читающая кусок текста и выдающая структуру данных, описывающую структуры программы, содержавшейся в тексте. Если текст не описывает корректную программу, парсер должен пожаловаться и указать на ошибку.

У нашего языка будет простой и однородный синтаксис. В Egg всё будет являться выражением. Выражение может быть переменной, число, строка или приложение. Приложения используются для вызова функций и конструкций типа >if или >while.

Для упрощения парсинга строки в Egg не будут поддерживать обратных слэшей и подобных вещей. Строка – просто последовательность символов, не являющихся двойными кавычками, заключённая в двойные кавычки. Число – последовательность цифр. Имена переменных могут состоять из любых символов, не являющихся пробелами и не имеющих специального значения в синтаксисе.

Приложения записываются так же, как в JavaScript — при помощи скобок после выражения и с любым количеством аргументов в скобках, разделённых запятыми.

>do(define(x, 10),

>   if(>(x, 5)),

>      print("много"),

>      print("мало"))

Однородность языка означает, что то, что в JavaScript является операторами (например, >>), применяется так же, как и остальные функции. Так как в синтаксисе нет концепции блоков, нам нужна конструкция