Когда мы определяли >if
и >while
, вы могли заметить, что они представляли собой простые обёртки вокруг >if
и >while
в JavaScript. Значения в Egg – также обычные значения JavaScript.
Сравнивая реализацию Egg, построенную на JavaScript, с объёмом работы, необходимой для создания языка программирования непосредственно на машинном языке, то разница становится огромной. Тем не менее, этот пример, надеюсь, даёт вам представление о работе языков программирования.
И когда вам надо что-то сделать, смошенничать будет более эффективно, нежели делать всё с нуля самому. И хотя игрушечный язык ничем не лучше JavaScript, в некоторых ситуациях написание своего языка помогает быстрее сделать работу.
Такой язык не обязан напоминать обычный ЯП. Если бы JavaScript не содержал регулярных выражений, вы могли бы написать свои парсер и интерпретатор для такого суб-языка.
Или представьте, что вы строите гигантского робота-динозавра и вам нужно запрограммировать его поведение. JavaScript – не самый эффективный способ сделать это. Можно вместо этого выбрать язык примерно такого свойства:
>behavior walk
> perform when
> destination ahead
> actions
> move left-foot
> move right-foot
>behavior attack
> perform when
> Godzilla in-view
> actions
> fire laser-eyes
> launch arm-rockets
Обычно это называют языком для выбранной области (domain-specific language) – язык, специально предназначенный для работы в узком направлении. Такой язык может быть более выразительным, чем язык общего назначения, потому что он разработан для выражения именно тех вещей, которые надо выразить в этой области – и больше ничего.
Добавьте поддержку массивов в Egg. Для этого добавьте три функции в основную область видимости: >array(...)
для создания массива, содержащего значения аргументов, >length(array)
для возврата длины массива и >element(array, n)
для возврата n-ного элемента.
>// Добавьте кода
>topEnv["array"] = "...";
>topEnv["length"] = "...";
>topEnv["element"] = "...";
>run("do(define(sum, fun(array,",
> " do(define(i, 0),",
> " define(sum, 0),",
> " while(<(i, length(array)),",
> " do(define(sum, +(sum, element(array, i))),",
> " define(i, +(i, 1)))),",
> " sum))),",
> " print(sum(array(1, 2, 3))))");
>// → 6
Способ определения >fun
позволяет функциям в Egg замыкаться вокруг окружения, и использовать локальные переменные в теле функции, которые видны во время определения, точно как в функциях JavaScript.
Следующая программа иллюстрирует это: функция