λanguage: Неформальний опис мови

Автор оригіналу використовував символ # для коментарів, але Друкарня не відображає такий код коректно, і коментарі зливаються з іншими частинами коду. Читати коментарі на телефонах стає ще складніше через автоматичне перенесення рядків. Тому я вирішив замінити символ # на стандартний //. Майте це на увазі.

Перед усім, ми повинні чітко уявити, що ми намагаємося досягти. Це хороша ідея підготувати детальний опис граматики, але в цьому посібнику я буду триматися більш неформального стилю, тому ось мова за допомогою прикладів:

// Це коментар

println("Hello World!");

println(2 + 3 * 4);

// Функції вводяться за допомогою "lambda" або "λ"
fib = lambda (n) if n < 2 then n else fib(n - 1) + fib(n - 2);

println(fib(15));

print-range = λ(a, b)             // "λ" синонім до "lambda"
                if a <= b then {  // `then` тут, необов'язкове, як видно
                  print(a);
                  if a + 1 <= b {
                    print(", ");
                    print-range(a + 1, b);
                  } else println("");        // перехід на новий рядок
                };
print-range(1, 5);

Зверніть увагу, що імена ідентифікаторів можуть містити символ мінуса (print-range). Це питання особистого смаку: я завжди ставлю пробіли навколо операторів, мені не дуже подобається camelCaseNames, і дефіс виглядає краще, ніж підкреслення. Чудова річ у створенні своєї мови - це можливість робити все так, як вам подобається. :)

Вивід:

Hello World!
14
610
1, 2, 3, 4, 5

Мова схожа на JavaScript, але відрізняється. По-перше, тут немає операторів (statements), лише вирази (expressions).

Вираз повертає значення і може бути використаний на місці будь-якого іншого виразу. Крапки з комою потрібні для розділення виразів у "послідовності". Фігурні дужки, { та }, створюють таку послідовність і самі є виразом. Їх значення - це значення, яке повертає останній вираз. Наступне є правильною програмою:

a = {
  fib(10);  // не має побічних ефектів, але все одно обчислюється
  fib(15)   // останньої крапки з комою може не бути
};
print(a); // вихід: 610

Функції вводяться за допомогою одного з ключових слів lambda або λ (вони є синонімами). Після ключового слова має бути (можливо, пустий) список змінних, розділених комами у дужках, як у JavaScript — це назви аргументів. Тіло функції є одним виразом, але воно може бути послідовністю, обгорнутою у {…}. Немає оператора return (немає операторів) — останній вираз, що обчислюється в функції, визначає значення, яке повертається її викликачу.

Немає var. Для введення нових змінних можна використовувати те, що JavaScript-розробники називають "IIFE". Використовуйте lambda, оголошуйте змінні як аргументи. Змінні мають область видимості функції, а функції є замиканнями — так, як у JavaScript.

Навіть if є сам по собі виразом. У JavaScript ви могли б досягти цього ефекту за допомогою тернарного оператора:

a = foo() ? bar() : baz();           // JavaScript
a = if foo() then bar() else baz();  // λanguage

Ключове слово then є необов'язковим, коли гілка починається з відкритої фігурної дужки ({), як можна побачити в прикладі print-range вище. В іншому випадку воно обов'язкове. Ключове слово else обов'язкове, якщо альтернативна гілка присутня. Знову ж таки, then і else приймають як тіло один вираз, але ви можете {групувати} кілька виразів, використовуючи фігурні дужки та крапки з комами. Коли відсутня гілка else і умова є false, результат виразу if є false. Говорячи про це, false - ключове слово, що позначає єдине хибне значення в нашій λanguage:

if foo() then print("OK");

виведе "OK" тільки тоді, коли результат виклику foo() НЕ дорівнює false. Є також ключове слово true для повноти, але, справді, все, що не є false (за оператором === у JavaScript), буде розглядатися як true в умовних виразах (включаючи число 0 і пустий рядок "").

Також слід зауважити, що немає потреби вимагати дужок навколо умови if. Це не викличе виключення, якщо ви їх додасте, але, оскільки відкрита дужка починає вираз, вони просто зайві.

Весь програмний код розбирається так, ніби він вбудований у фігурні дужки, тому після кожного виразу потрібно ставити крапку з комою. Останній вираз може бути винятком.


Отже, це наша маленька λanguage. Вона не обов'язково є хорошою. Синтаксис виглядає миленьким, але в ньому є свої пастки. Багато чого не вистачає, наприклад, об'єктів або масивів; ми не зосереджуємося на них, тому що вони не є важливими для нашого подорожі. Якщо ви зрозуміли весь цей матеріал, ви зможете легко реалізувати їх.

У наступному розділі ми напишемо парсер для λanguage.

Поділись своїми ідеями в новій публікації.
Ми чекаємо саме на твій довгочит!
Romashka
Romashka@Romashka

Створюю інтерпретатор Mash Src

65Прочитань
1Автори
1Читачі
На Друкарні з 16 березня

Більше від автора

  • λanguage: Написання парсера

    Написання парсера - це досить складне завдання. У сутності, він повинен перетворити фрагмент коду у "абстрактне синтаксичне дерево". Це структуроване представлення програми в пам'яті, воно абстрактне в тому сенсі, що не має значення, з яких саме символів складається вихідний код.

    Теми цього довгочиту:

    Парсер
  • λanguage: Як реалізувати мову програмування на JavaScript

    Це посібник з реалізації мови програмування. Якщо ви вже писали інтерпретатор, то, ймовірно, тут немає нічого нового для вас. Але якщо ви використовуєте регулярні вирази для "розбору" чогось, що схоже на мову програмування, прочитайте хоча б розділ про синтаксичний аналіз.

    Теми цього довгочиту:

    Мова Программування

Вам також сподобається

Коментарі (0)

Підтримайте автора першим.
Напишіть коментар!

Вам також сподобається