Книга: Выразительный JavaScript

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

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

Объект 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;
};

Оглавление книги


Генерация: 1.938. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз