Страницы

Мир программ физически реален

Слово «виртуальный» в своём изначальном определении означает «вымышленный». В этом отношении применение термина «виртуальная машина», широко используемого в сфере информационных технологий и, вообще, отношение к программному миру как виртуальному является крайне неудачным. Иногда сходно используют термин «абстрактная машина», но и его следует признать неудачным, поскольку абстрактного в этих машинах не больше, чем воображаемого.

Типичная «виртуальная машина», например, для JavaScript, исполняющаяся в браузере, естественно, не является воображаемой. Скорее, её следовало бы называть программной машиной. А программное обеспечение существует в той же физической реальности, что и аппаратное обеспечение, и, соответственно, подчиняется тем же физическим законам. Разница между аппаратным обеспечение и программным пролегает не в реальности и виртуальности, а в лёгкости изменения. Это предопределило, что в современных компьютерах аппаратная часть представлена веществами в преимущественно устойчивой форме, а программная — электромагнитными полями. И то, и другое являются составляющими машины и, естественно, материальными.

Кстати, вычленение из просто машины в отдельное понятие той её части, которую легко и быстро изменять и даёт то грандиозное преимущество, которое обеспечило существенный прогресс в области информационных технологий. Это преимущество само по себе настолько велико, что на десятилетия обеспечило головокружение от успехов, отодвинув на второй план другие важные в инженерии вещи, позволив в области ПО резвиться самыми разными способами.

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

Синтаксис — основа языка программирования, а не что-то там

В среде не только обычных программистов, но даже и некоторых разработчиков, близких к компиляторной тематике, принято пренебрежительное отношение к синтаксису языка программирования как к второстепенной детали, которой противопоставляется семантика, которая только и имеет серьёзное значение. Считается, что в крайнем случае, всегда можно снабдить один язык программирования несколькими синтаксисами и это лишь вопрос вкуса. Но есть одно очевидное соображение, которое, очевидно, оказалось не таким уж очевидным, но которое делает такое отношение абсурдным.

Блог о "Востоке"

Создал отдельный блог, посвященный проекту "Восток" - транслятору из Оберона в ряд распространённых языков. Несмотря на то, что туда были импортированы тематические сообщения из этого блога, здесь сообщения не были удалены. Тем не менее новые будут появляться только там. Первое такое сообщение посвящено созданию привязок к другим языкам.

Восток. deb - пакеты

Сообщения о трансляторе переехали в отдельный блог.

Добавил возможность сборки deb-пакетов для предоставления пользователю GNU/Linux более удобного способа установки транслятора.

Текущая сборка разбивается на 2-е части - исполняемый файл транслятора и первоначальная библиотека поддержки. Из-за того, что библиотека на текущем уровне развития доступна только на уровне исходного кода, то она не зависит от процессорной платформы. Транслятор же для повышения универсальности собирается для i386 со статическим связыванием со стандартной библиотекой. Если для этого вместо glibc использовать musl-libc или dietlibc, то размер выходного файла получается вполне приемлемым.

Для такой сборки я использовал следующую команду в каталоге проекта из 32-битной Ubuntu 18.04:

$ result/bs-ost run 'make.UseCC("musl-gcc -Os -flto -static"); make.Build; make.Deb'\
 -infr . -m source
Предварительно нужно установить вспомогательные утилиты:
$ /usr/bin/sudo apt install hashdeep musl-tools 
И собрать раскруточную версию транслятора:
$ ./init.sh 

В результате сотрудничества в рамках проекта Обертон, deb-пакеты и их обновления доступны в общем репозитории http://obertone.ru/repo.

She-bang для Oberon

Сообщения о трансляторе переехали в отдельный блог.

В операционной системе Oberon в качестве скриптового языка используется одноимённый язык, на котором написана сама система, что в духе минимализма всей системы в целом и языка в частности. Для транслятора "Восток" я воплотил схожий способ запуск команд из модулей. Но если в ОС Оберон для запуска команды достаточно клика мыши на записи, состоящей из имени модуля, точки и имени экспортированной процедуры, например

Hello.Come
текст модуля
MODULE Hello;
  IMPORT Out;

  PROCEDURE Come*;
  BEGIN
    Out.String("Hello"); Out.Ln
  END Come;

  PROCEDURE Gone*;
  BEGIN
    Out.String("Bye"); Out.Ln
  END Gone;
END Hello.
то для запуска в GNU/Linux требуется запись такого рода в командной оболочке
$ result/o7c run Hello.Come -infr . -m example
Так как установка ранее не была предусмотрена, то требовалось указывать полное имя транслятора и пути к основным библиотекам.

Как показал опыт, некоторые люди даже знакомые с принципами ОС Оберон без чтения справки ожидали от транслятора поведения, схожего с компиляторами Си, которые работают с кодом в файлах, то есть, чего-то такого

$ result/o7c run example/Hello.mod -infr .

Я, наконец, решил улучшить интеграцию с GNU/Linux. Сначала добавил возможность установки с использованием в трансляторе пути к основным библиотекам по умолчанию. Для этого я внёс соответствующие изменения в код и добавил процедуры Install, InstallTo, Remove, RemoveFrom в сборочный модуль make.mod. Заодно переименовал исполняемый файл из o7c(Oberon-7 compiler) в ost(Oberon-seven translator). Чтобы установить транслятор нужно выполнить команду:

$ /usr/bin/sudo result/ost run make.Install -infr . -m source
После установки станет возможным запускать модули так:
$ ost run Hello.Come -m example

Следующим шагом я добавил режим запуска модуля с указанием одноимённого файла, в котором он находится

$ ost .Come example/Hello.mod
$ ost . example/Hello.mod Come
Если же автор поместил код для выполнения в секцию инициализации модуля, то запуск ещё упрощается
MODULE Hello;
  IMPORT Out;
BEGIN
  Out.String("Hello"); Out.Ln
END Hello.
$ ost example/Hello.mod
Мне такой подход не нравится, так как снижает гибкость запуска и требует написания разбора текстовых аргументов программы там, где может быть достаточно создания разных экспортированных процедур в коде модуля, но некоторым нравится из-за краткости.

Для всех типов запуска с указанием файла теперь есть возможность задействовать особенность POSIX систем - she-bang, позволяющий запускать скрипты любого языка без привязки иполнителя по расширению файла. Например:

#!/usr/local/bin/ost .
Так как код на Обероне не привязан к понятию файла, а имеет чёткие границы, 
то за пределами модуля можно писать разный текст, в том числе и she-bang
MODULE Hello;
  IMPORT Out;

  PROCEDURE Come*;
  BEGIN
    Out.String("Привет."); Out.Ln
  END Come;

  PROCEDURE Gone*;
  BEGIN
    Out.String("Бывай."); Out.Ln
  END Gone;
END Hello.
После придания файлу атрибута исполнимости:
$ chmod +x example/Hello.mod
Его можно запускать без обращения к транслятору напрямую:
$ example/Hello.mod Come
Привет.
$ example/Hello.mod Gone
Бывай.


Воплощение деления с неотрицательным остатком

Те, кто хотят использовать в программе предметное деление с остатком сталкиваются с тем, что во многих языках программирования деление сделано по-другому, что обусловлено воплощением в распространённых машинных языках. Если для обычного деления остаток всегда ≥ 0, то во многих Си-подобных языках остаток отрицательный для отрицательного делимого, которое не делится нацело.

Результаты деления
делимоеделительчастноеостаток / %
5 3 1 2 1 2
-5 3 -2 1 -1 -2
-4 3 -2 2 -1 -1
-3 3 -1 0 -1 0

Восток. Самотрансляция в Javascript

Сообщения о трансляторе переехали в отдельный блог.

Генератор Javascript достиг того состояния, которое позволяет транслятору получить работоспособную версию себя в Javascript виде. Для этого понадобилось не так уж много после прохождения малых тестов, и основная часть проблем была связана с моим незнанием Javascript и библиотек для него.

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

Восток. Генератор JavaScript кода

Сообщения о трансляторе переехали в отдельный блог.

Сделан ещё один шаг в направлении многоцелевого транслятора Оберона - была добавлена возможность генерации кода в JavaScript. Обеспечена возможность прохождения простых тестов, но для трансляции самого транслятора генератор кода предстоит доработать.

Генератор JavaScript кода был был переделан из генератора Java кода, который в свою очередь был переделан из генератора C кода. Так что артефакты переделок продолжают накапливаться.

Модуль Оберона отображается на безымянную функцию, автоматическое исполнение которой приводит к появлению объекта модуля в специальном объекте o7, который, также, хранит дополнительные функции для более удобной поддержки языка. Как и для Java, переменные примитивных типов, участвующие как фактические параметры-переменные преобразовываются в одноэлементные массивы. Локальные и безымянные записи в духе прототипного ООП отображаются на функции-конструкторы. Для присваивания значения записей генерируются необходимые функции. Для кодирования типа CHAR используются целые числа.

Обновление: достигнута возможность самотрансляции