Skip to content

Latest commit

 

History

History
238 lines (145 loc) · 12 KB

File metadata and controls

238 lines (145 loc) · 12 KB

Общее описание

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

Исходники

Файлы исходного кода должны быть в кодировке ASCII и иметь концы строк как в UNIX (LF).

Ключевые слова

3 ключевых слова: fn, let, as.

Типы

Типизация: сильная полустатическая.

Менеджмент памяти: сборка мусора.

Копирование: по ссылке.

Хранение:

  • ссылки — на стеке;
  • значения — в куче.
Нулевой тип

Название: nil.

Тип: фиктивный тип; не хранит значение, а служит маркером его отсутствия; существует единственное значение данного типа.

Определение: значение данного типа доступно через вызов функции рантайма nil.

Вещественные числа

Название: num.

Тип: с плавающей запятой, 8 байт.

Определение:

/\d+(\.\d+)?(e-?\d+)?/
/0x[A-Fa-f0-9]+/
/'(\\.|\\x[A-Fa-f0-9]{2}|[^'])'/
Списки

Название: list.

Тип: LISP-подобный список — или пустой список, или пара из головы и хвоста, где голова может иметь любой тип (и является хранимым элементом), а хвост является аналогичным списком.

Определение:

  • пустого списка — через вызов функции рантайма [];
  • списка из головы и хвоста — через вызов функции рантайма ,.

Доступ к элементам:

  • к количеству элементов — через вызов функции рантайма size;
  • к голове списка — через вызов функции рантайма head;
  • к хвосту списка — через вызов функции рантайма tail;
  • к элементу по индексу — через вызов функции рантайма ..
Строки

Строками являются списки, хранящие коды символов. Используется кодировка ASCII.

Определение: /"(\\.|\\x[A-Fa-f0-9]{2}|[^"])*"/.

Хеш-таблицы

Название: hash.

Тип: ассоциативный массив, реализованный через хеш-таблицу; порядок ключей не гарантируется.

Определение:

  • пустой хеш-таблицы — через вызов функции рантайма {};
  • новой хеш-таблицы из старой и пары ключа и значения — через вызов функции рантайма #;
  • новой хеш-таблицы из старой без определённого ключа — через вызов функции рантайма #.

Доступ:

  • к количеству пар ключей и значений — через вызов функции рантайма size;
  • к списку ключей — через вызов функции рантайма keys;
  • к значению по ключу — через вызов функции рантайма ..
Паки

Название: pack.

Тип: обёртка над значением; единственное предназначение — остановка автоматического вызова замыканий нулевой арности.

Определение: оборачивание значения в пак доступно через вызов функции рантайма >@.

Доступ к обёрнутому значению:

  • однократный доступ (на один уровень вглубь) — через вызов функции рантайма <@;
  • итеративный доступ (на максимальный уровень вглубь) — через вызов функции рантайма <<@; функция итеративно разворачивает значение до тех пор, пока результат является обёрнутым значением.
Замыкания

Название: closure.

Объявление:

"fn", [identifier], "(", {identifier, {":", INTEGRAL NUMBER}}, ")", {":", INTEGRAL NUMBER},
	{entity},
";"

Здесь первый identifier — имя замыкания, по которому оно будет доступно ниже в текущей области видимости, а также внутри самого себя, а все последующие identifier — имена аргументов замыкания.

{":", INTEGRAL NUMBER} — определение типа аргументов замыкания и результата замыкания (в последнем случае). Тип указывается только для замыканий (полустатическая типизация) и является списком арностей этих замыканий и их результатов.

Перегрузка замыканий не поддерживается, но поддерживается их переопределение.

Вызов замыкания: entity, entity, {entity}.

Здесь первая entity — идентификатор, являющийся замыканием, или аналогичный вызов замыкания (вложенный вызов), возвращающий замыкание, а все последующие entity — аргументы.

Логический тип

В качестве значений логического типа используются значения других типов:

  • ложным логическим значением являются:
    • значение nil;
    • число 0;
    • пустой список;
    • пустые хеш-таблицы;
  • истинным логическим значением являются:
    • числа, отличные от 0;
    • непустые списки;
    • непустые хеш-таблицы;
    • любые паки;
    • любые замыкания.

Операции

Определение переменных
"let", [identifier], {":", INTEGRAL NUMBER},
	{entity},
";"

Здесь identifier — имя переменной, по которому она будет доступна ниже в текущей области видимости. При этом внутри определения самой себя она доступна не будет.

{":", INTEGRAL NUMBER} — определение типа переменной. Тип указывается только для замыканий (полустатическая типизация) и является списком арностей этих замыканий и их результатов.

Присваивание переменным нового значения не поддерживается, но поддерживается переопределение переменных.

Преобразование типа
"as", "(", {entity}, ")", {":", INTEGRAL NUMBER}

Управляющие конструкции

Условие

В качестве условного оператора используется функция рантайма if:

"if", condition,
	true value,
	false value

Здесь:

  • condition — это вызов замыкания; его результат трактуется как значение логического типа;
  • true value — это вызов замыкания; его значение возвращается, если результат condition является истинным логическим значением;
  • false value — это вызов замыкания; его значение возвращается, если результат condition является ложным логическим значением.

Стоит учесть, что и true value, и false value вычисляются до выбора значения результата. Поэтому, если их вычисление производит побочные эффекты, нужно обернуть их в замыкания:

if condition
	fn() true value;
	fn() false value;
Цикл

Отсутствует.

Точка входа

Отсутствует. Интерпретатор исполняет весь предоставленный код в порядке его следования.

Комментарии

Шебанг: /^#!.*/.

Однострочные: /(?<![A-Za-z_])nb(?![:A-Za-z_]).*/.

Многострочные: /(?<![A-Za-z_])nb:.*?(?<![A-Za-z_])nb;/s.

Модульность

Тип: включением кода как текста и его последующим исполнением.

Для включения кода используется функция рантайма load:

load filename

Здесь filename — это вызов замыкания, результат которого должен быть строкой и содержать относительный путь к файлу с кодом.

Функция ищет указанный файл, читает его и исполняет, после чего возвращает полученный результат.

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

Поиск файла

Поиск указанного файла осуществляется в несколько этапов. Функция по очереди перебирает следующие возможные места расположения файла:

  • директория того скрипта, из которого был осуществлён вызов функции load;
  • директория vendor, расположенная в директории того скрипта, который был передан интерпретатору;
  • директории, указанные в переменной окружения MICRO_LIBRARY (перечисляются через символ :; перебираются в обратном порядке);
  • директория установки pip-пакета интерпретатора.

В каждом месте расположения функция по очереди пытается найти следующие файлы:

  • файл, непосредственно указанный в функции load;
  • файл, указанный в функции load, с добавленным расширением .micro;
  • файл __main__.micro, лежащий в директории, указанной в функции load.
Шебанг

Интерпретатор поддерживает шебанг (то есть игнорирует его). Шебанг может выглядеть, например, так: #!/usr/bin/env micro.