В одном комментарие говорили то что «LISP» не говорили 50 лет. Теперь уже нет. Но вообще, в этом рассказе я расскажу как сделал Лисп с обработкой ошибок и сборкой мусора.
Его возможности.
Он имеет прилично команд и функций.
Вот его команды и функции в целом:
-
if
-
defun
-
list
-
cond
-
nth
-
cons
-
append
-
remove
-
begin
-
quote
-
Цифры и строки
-
print
-
and, or и not
-
Вызовы функций
-
def
Так. Теперь главные вопрос по возможностям:
-
Где макросы? Ответ: я до сих пор не понимаю как они работают хоть и понимаю их концепцию.
-
Почему cond это команда? Потому что макросов нету.
Теперь главный секрет:
Мне пришлось делать list, nth, cons, append, remove, print как команды (built-in functions ещё называют).
Вы сразу заминусуете за плохой технический уровень (или как там).
Но, почему то мне было сложно понять как это сделать функционально.
А почему? Потому-что на функцию у меня класс Proc который имеет параметры args, name, body. Args, name это понятно.
Но вот body — это AST функции. Ну, из-за этого все проблемы.
Теперь о возможностях:
-
Сборщик мусора
-
Обработка ошибок (нормальная а не просто «найдены ошибки»)
Ну и всё.
А, операции все есть кроме <= и >=.
Конец главы.
Схема сборки мусора.
Для начало об изначальной схеме:
-
Удалять переменные которые не используются долго
-
И также с функциями
Теперь как работает мой «gc 1.1»:
-
На каждой переменной стоит счётчик.
-
Он считает на каждую переменную 20 строк (как правильно объяснить не знаю)
-
Если же через эти 20 раз не было не каких изменений или использований: удаляет переменную.
Ну… Конечно звучит наверно не правильно, но информаций как сделать нормальный сборщик мусора не нашёл (очевидно потому-что не кто не пишет языки программирования со сборкой мусора и выкладывает это в простую статью).
Так что полностью «by me» (я так говорю).
Устройство языка.
Устройство языка очень простое, это интерпретатор для небольшой REPL.
Ну… Как обычно:
-
Лексер (его почти нету и он был взят со статьи Питера Норвига)
-
Парсер (был взят со статьи Питера Норвига но с небольшими изменениями)
-
Интерпретатор. Полностью создан мной.
Когда происходит сборка мусора? Во время интерпретации и перед интерпретации.
Также можно расширить интепретатор и добавить поддержу много строчных программ.
Обработка ошибок.
Весь механизм обработки ошибок находится в функции handleError.
Пока 3 ошибки (я научился программировать на Лиспе и не знаю других ошибок):
-
Ошибка синтатикса (invalid syntax). Происходит когда ты пишешь (lis 1 2 3) вместо (list 1 2 3)
-
Инвалидное s-выражение (invalid s-expression). Происходит когда ты пишешь (+ 3 3 вместо (+ 3 3)
-
Деление на ноль. Тут очевидно.
Вот как выводится сообщение о ошибке:
Error: invalid s-expression "+ 3 4)" On line 2
Откуда строка? Ну… Вот как работаешь в REPL:
[1]> (list 1 2 3) (1 2 3) [2]> (if (= 0 1) (50) (10)) 10 [3]>
Вот так в REPL.
Примеры кода
(defun fac (n) (if (= n 1) (1) (* n (fac (- n 1)))))
В этом примере кода мы написали функцию факториала.
Ну и так далее. Ну вообще можно уже писать нормальные функции.
Заключение
Ну, теперь давайте объясню если статья выглядит плохо оформлена:
Во первых я писал на телефоне а на телефоне стоит этот Т9 (или как там).
Во вторых я писал статью ночью. Из-за чего бывают ошибки.
Ну, я надеюсь вам понравилась моя идея так что всем пока.
ссылка на оригинал статьи https://habr.com/ru/articles/923644/
Добавить комментарий