Введение История движется по спирали.
Авторы Go, стоя на плечах авторитетной корпорации Google, смогли воплотить в жизнь свой идеальный язык программирования, подобно тому, как Никлаус Вирт когда-то принес в этот мир язык Oberon, борясь своей стойкостью и авторитетом с зарождающейся тенденцией сложность и обширное развитие основных языков.
Сегодня язык Оберон забыт, но работа Вирта совершенно неожиданно появилась на языке Го.
В некоторых аспектах реализации сходство подходов неоспоримо.
Конечно, каждый язык по-своему уникален и нет необходимости превращать один язык в другой.
Время невозможно повернуть вспять.
Но в разные времена люди стремились сохранить ушедшие в прошлое технологии.
Подумайте о ценности бережно сохранившихся эмуляторов Spectrum и MSX и музеев старых компьютеров в разных странах.
«Муляция, как один из способов остановить мгновение, прочно зарекомендовала себя.
Принято считать, что язык Go нашел себя в нише сетевых сервисов.
Но мы пойдем другим путем.
Задача История языка Оберон включает несколько вариантов языка.
Каждое издание Н.
Вирт создавал под конкретный проект; его языки всегда создавались под задачу, исходя из ее целей.
Оберон-2 создавался как вариант Оберона с развитым механизмом типов данных, реализующим концепцию ООП.
Ученики Н.
Вирта решили, что «Оберон-2» пригоден для промышленного программирования.
Они добавили в язык функции, расширили систему типов для совместимости с набирающей популярность Java, реализовали идею истинной модульности и выпустили продукт BlackBox с языком Component Pascal (CP) внутри.
Шло время, корпорации из-за океана все успешнее выходили на рынок и BlackBox ушел в тень, оставаясь объектом исследования небольшой группы энтузиастов, в том числе из России и стран СНГ.
Одним из принципов CP является модульность, возможность изменять реализацию компонента без изменения его интерфейса (применительно к объектам это называется pimpl).
И вот я задумался, чем конкретный фреймворк отличается от реализации компонента.
И описание языка — его интерфейса… Проще говоря, мне пришло в голову реализовать интерпретатор с функциями фреймворка.
То есть с поддержкой модульности, как описано в сообщении о языке.
Расследование Особенностью платформы BlackBox является динамическое связывание модулей в памяти процесса.
Как известно, процесс создания программы из исходного кода состоит из нескольких этапов.
В разных реализациях разных компиляторов эти этапы могут быть скрыты, пропущены или примитивизированы.
Связывание — это приведение машинного кода к форме, приемлемой для непосредственного выполнения процессором.
Например, в Go компоновка статическая, на этапе компиляции.
А в BlackBox — динамически, на этапе загрузки тела модуля в память.
Интересной особенностью этого решения является независимость кода от операционной системы, когда один и тот же машинный код выполняется в разных ОС без перекомпиляции, при условии, что они имеют одинаковую архитектуру (например, x86).
Однако компилятор BlackBox предоставляет еще один вариант — изменение генератора кода под конкретную архитектуру.
Такой результат достигается за счет использования внутри компилятора структуры AST — абстрактного синтаксического дерева для платформонезависимого сохранения структуры программ и данных.
Нам удалось выяснить, что BlackBox изначально был написан для платформы Mac+PowerPC, а уже потом переписан для Wintel. При этом компилятор практически не изменился.
Съемный бэкенд сегодня не так уж и удивителен, но в 90-е годы это было необычно и ново.
Таким образом, эти две функции позволили мне создать свой собственный бэкэнд. Без особых усилий я преобразовал AST в формат XML, точнее, Graphml, с прицелом на красивую визуализацию процесса интерпретации.
Планов было много.
Решение Для реализации я выбрал язык Go, хотя мог бы выбрать Java, C#, Dart и другие.
Почему? Причин несколько, главная из них — информация о том, что Go по своей природе похож на Оберон, отсекает все лишнее из процесса выражения предметной области.
Взять, к примеру, исключения, эти легкие, легализованные, якобы безобидные аналоги оператора GOTO. Отличный повод изучить Го.
Я просто назвал проект: Рамки .
Небольшой экскурс в описание языка – и в бой.
Десериализация XML в структуры с использованием тегов — это здорово.
Скрывать данные в пакетах — это здорово, давайте воспользуемся нашим любимым пимплом.
Утиный набор интерфейсов меня поначалу смутил, но после пары ударов пришло понимание.
Основная ошибка здесь — сравнение интерфейсов с разными именами с одним и тем же набором методов.
Этот набор может формироваться исторически, и даже опытный разработчик может обнаружить, что typeswitch для типа A обрабатывает тип B и закономерно выходит из строя.
Итак, AST загружен в память, основные узлы описаны, правила интерпретации известны.
Как оказалось, существует множество типов узлов.
Есть еще больше типов данных.
Одним из основных принципов, которые я принял, был принцип «пусть все упадет»; в любой непонятной ситуации программа прекращает свою работу.
Конечно, проект дома допускал такие вольности.
Интерпретация алгоритмов интересна.
АСТ языка КП состоит из операторов, выражений и указателей на объекты (оператор, выражение, указатель).
Операторы следуют друг за другом, модифицируют объекты и изменяют ход программы в зависимости от подчиненных узлов (выражений или указателей).
В данном случае есть два подчиненных узла – левый и правый.
Существуют также дополнительные узлы, такие как ссылка и объект. Для начала выберем схему обхода данных — я предполагал, что ничего придумывать не надо, все уже придумано, поэтому я использовал стек для углубленной обработки узлов и нерекурсивного обхода узлов от одного выражения к другому .
Каждый узел в стеке связан с фреймом, в котором хранится результат обработки дочерних узлов и инструкции от родительских узлов.
Конкретные действия для конкретного узла являются основной частью интерпретации программы.
Программа выполняется, пока операторы, управляющие потоком выполнения, помещают один или несколько следующих операторов в стек для выполнения.
Как только стек опустеет или результат итерации вернет код ошибки, программа останавливается.
Ничего сложного.
Для хранения данных в высокоуровневой среде языка Go можно описывать различные типы данных, в том числе примитивные.
Я увидел в этом еще одно преимущество языка Go для реализации интерпретатора.
Полный список правил, по которым составляется AST-дерево, можно посмотреть Здесь .
Пример Кратко опишу процесс интерпретации узлов простой программы.
Теги: #Go #oberon #GoMODULE XevDemo2; VAR
-
Фоновый Запуск Приложений В Ios 13
19 Oct, 24 -
15 Мелочей Из Поднебесной. Часть 2
19 Oct, 24 -
Мой Велосипед С Открытым Исходным Кодом
19 Oct, 24 -
Реализация Видеорекламы В Интернете.
19 Oct, 24