Марейн Хавербеке - Выразительный JavaScript

Тут можно читать онлайн Марейн Хавербеке - Выразительный JavaScript - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.

Марейн Хавербеке - Выразительный JavaScript краткое содержание

Выразительный JavaScript - описание и краткое содержание, автор Марейн Хавербеке, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

В процессе чтения вы познакомитесь с основами программирования и, в частности, языка JavaScript, а также выполните несколько небольших проектов. Один из самых интересных проектов — создание своего языка программирования.

Выразительный JavaScript - читать онлайн бесплатно полную версию (весь текст целиком)

Выразительный JavaScript - читать книгу онлайн бесплатно, автор Марейн Хавербеке
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

while (program[0] != ")") {

var arg = parseExpression(program);

expr.args.push(arg.expr);

program = skipSpace(arg.rest);

if (program[0] == ",")

program = skipSpace(program.slice(1));

else if (program[0] != ")")

throw new SyntaxError("Ожидается ',' or ')'");

}

return parseApply(expr, program.slice(1));

}

Если следующий символ программы – не открывающая скобка, то это не приложение, и parseApplyпросто возвращает данное ей выражение.

В ином случае, она пропускает открывающую скобку и создаёт объект синтаксического дерева для этого выражения. Затем она рекурсивно вызывает parseExpressionдля разбора каждого аргумента, пока не встретит закрывающую скобку. Рекурсия непрямая, parseApplyи parseExpressionвызывают друг друга.

Поскольку приложение само по себе может быть выражением ( multiplier(2)(1)), parseApplyдолжна, после разбора приложения, вызвать себя снова, проверив, не идёт ли далее другая пара скобок.

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

function parse(program) {

var result = parseExpression(program);

if (skipSpace(result.rest).length > 0)

throw new SyntaxError("Неожиданный текст после программы");

return result.expr;

}

console.log(parse("+(a, 10)"));

// → {type: "apply",

// operator: {type: "word", name: "+"},

// args: [{type: "word", name: "a"},

// {type: "value", value: 10}]}

Работает! Она не выдаёт полезной информации при ошибке, и не хранит номера строки и столбца, с которых начинается каждое выражение, что могло бы пригодиться при разборе ошибок – но для нас и этого хватит.

Интерпретатор

А что нам делать с синтаксическим деревом программы? Запускать её! Этим занимается интерпретатор. Вы даёте ему синтаксическое дерево и объект окружения, который связывает имена со значениями, а он интерпретирует выражение, представляемое деревом, и возвращает результат.

function evaluate(expr, env) {

switch(expr.type) {

case "value":

return expr.value;

case "word":

if (expr.name in env)

return env[expr.name];

else

throw new ReferenceError("Неопределённая переменная: "

expr.name);

case "apply":

if (expr.operator.type == "word" &&

expr.operator.name in specialForms)

return specialForms[expr.operator.name](expr.args,

env);

var op = evaluate(expr.operator, env);

if (typeof op != "function")

throw new TypeError("Приложение не является функцией.");

return op.apply(null, expr.args.map(function(arg) {

return evaluate(arg, env);

}));

}

}

var specialForms = Object.create(null);

У интерпретатора есть код для каждого из типов выражений. Для литералов он возвращает их значение. Например, выражение 100интерпретируется в число 100. У переменной мы должны проверить, определена ли она в окружении, и если да – запросить её значение.

С приложениями сложнее. Если это особая форма типа if, мы ничего не интерпретируем, а просто передаём аргументы вместе с окружением в функцию, обрабатывающую форму. Если это простой вызов, мы интерпретируем оператор, проверяем, что это функция и вызываем его с результатом интерпретации аргументов.

Для представления значений функций Egg мы будем использовать простые значения функций JavaScript. Мы вернёмся к этому позже, когда определим специальную форму fun.

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

Вот и всё, что нужно для интерпретации Egg. Вот так просто. Но без определения нескольких специальных форм и добавления полезных значений в окружение, вы с этим языком ничего не сможете сделать.

Специальные формы

Объект specialFormsиспользуется для определения особого синтаксиса Egg. Он сопоставляет слова с функциями, интерпретирующими эти специальные формы. Пока он пуст. Давайте добавим несколько форм.

specialForms["if"] = function(args, env) {

if (args.length != 3)

throw new SyntaxError("Неправильное количество аргументов для if");

if (evaluate(args[0], env) !== false)

return evaluate(args[1], env);

else

return evaluate(args[2], env);

};

Конструкция ifязыка Egg ждёт три аргумента. Она вычисляет первый, и если результат не false, вычисляет второй. В ином случае вычисляет третий. Этот ifбольше похож на тернарный оператор ?:. Это выражение, а не инструкция, и она выдаёт значение, а именно, результат второго или третьего выражения.

Egg отличается от JavaScript тем, как он обрабатывает условие if. Он не будет считать ноль или пустую строку за false.

ifпредставлено в виде особой формы а не обычной функции, потому что аргументы функций вычисляются перед вызовом, а ifдолжен интерпретировать один из двух аргументов – второй или третий, в зависимости от значения первого.

Форма для whileсхожая.

specialForms["while"] = function(args, env) {

if (args.length != 2)

throw new SyntaxError("Неправильное количество аргументов для while");

while (evaluate(args[0], env) !== false)

evaluate(args[1], env);

// Поскольку undefined не задано в Egg,

// за отсутствием осмысленного результата возвращаем false

return false;

};

Ещё одна основная часть языка – do, выполняющий все аргументы сверху вниз. Его значение – это значение, выдаваемое последним аргументом.

specialForms["do"] = function(args, env) {

var value = false;

args.forEach(function(arg) {

value = evaluate(arg, env);

});

return value;

};

Чтобы создавать переменные и давать им значения, мы создаём форму define. Она ожидает wordв качестве первого аргумента, и выражение, производящее значение, которое надо присвоить этому слову в качестве второго. define, как и всё, является выражением, поэтому оно должно возвращать значение. Пусть оно возвращает присвоенное значение (прямо как оператор =в JavaScript).

specialForms["define"] = function(args, env) {

if (args.length != 2 || args[0].type != "word")

throw new SyntaxError("Bad use of define");

var value = evaluate(args[1], env);

env[args[0].name] = value;

return value;

};

Окружение

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

Для использования конструкции ifмы должны создать булевские значения. Так как их всего два, особый синтаксис для них не нужен. Мы просто делаем две переменные со значениями trueи false.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Марейн Хавербеке читать все книги автора по порядку

Марейн Хавербеке - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Выразительный JavaScript отзывы


Отзывы читателей о книге Выразительный JavaScript, автор: Марейн Хавербеке. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x