Страницы

пятница, 8 января 2021 г.

Проверка границ массива в JavaScript

Добавил проверку индекса на выход за границы массива для кода, сгенерированного в JavaScript, что было анонсировано почти 2-а года назад. Применённая модель проверки, естественно, замедляет выполнение, но всё же не приводит к взрывной деградации скорости в современных браузерах и в node.js, как это бывает с исполнителями JavaScript.

Был применён такой подход:

array = new Array(len);
this.at = function(index) {
  if (0 <= index && index < len) {
    return array[index];
  } else {
    throw new RangeError();
  }
};

..

a = arr.at(i);

len находится в контексте объемлющей функции и не меняется после установления, что позволяет jit-компилятору оптимизировать проверки вплоть до сравнения с константами, что может быть очень эффективным. Впрочем, накладные расходы на методы никуда не деваются, а Object.freeze для обеспечения гарантии отсутствия подмены методов и гипотетической возможности их встраивания не помог для оптимизации.

понедельник, 28 декабря 2020 г.

Создание rpm пакетов

Добавил в систему сборки возможность собирать rpm пакеты. Для пакетирования нужен установленный rpmbuild, который доступен не только в дистрибутивах, основанных на rpm, но и в Debian. В чистом каталоге проекта достаточно выполнить 3-и команды:

./init.sh && result/bs-ost run make.Build -infr . -m source
result/ost run make.Rpm -infr . -m source

Сборка, как минимум, работает в Ubuntu 20.04 и в Alt Linux 9

Кроме установки в Alt попробовал устанавливать rpm пакеты и в Ubuntu. С помощью утилиты alien успешно преобразовал собранные rpm в deb. Полученные пакеты устанавливаются, и всё работает. Правда, у пакетов теряются прописанные зависимости, поэтому появляется возможность установить без них, что может отрицательно сказаться на работоспособности. К сожалению, надежда на возможность сборки только rpm-пакетов с последующим преобразованием в deb оправдалась не полностью.

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

понедельник, 23 декабря 2019 г.

Генератор Оберон-кода

Добавлен генератор кода на Обероне. Сейчас поддерживается исходный же Оберон-07 и Активный Оберон на уровне, позволяющем транслировать полученный код соответствующими исполнителями.

Сейчас это позволяет портировать код на Обероне-07 на A2OS, а в перспективе, по мере расширения поддержки разбора и генерации других диалектов Оберона, позволит конвертировать исходные коды в самых разных направлениях. Не исключено, что в скором времени транслятор Восток можно запустить как подсистему Blackbox Component Builder

суббота, 13 июля 2019 г.

Проба создания привязки к коду на C++

Для примера я взял открытую C++ библиотеку Open Babel для работы с моделями молекул. API библиотеки необъятно, поэтому решено было сделать только ту привязку, которая необходима для тестовой задачи — чтения молекулы из файла и вывод координат её атомов. Так как для ввода Open Babel использует стандартные классы С++, то в привязку было добавлены функции открытия и закрытия std::ifstream

среда, 26 июня 2019 г.

Связка с кодом на других высокоуровневых языках

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

В трансляторе "Востока" сейчас применён более простой модульный подход. Входной язык не содержит никаких расширений, а для связывания используется подмена кода на входном языке на код на выходном языке. То есть, интерфейсный модуль на Обероне с, возможно, пустыми типами и процедурами во время полной трансляции заменяется соответствующим файлом-"модулем" на С, Java или JavaScript, заполненным нужным функционалом.

понедельник, 17 июня 2019 г.

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 
Под командой make.Deb скрываются команды оболочки sh:
для сборки vostok-deflib.deb
rm -r result/vostok-deflib
mkdir -p result/vostok-deflib result/vostok-deflib/DEBIAN result/vostok-deflib/usr/share/doc/vostok-deflib result/vostok-deflib/usr/share/vostok
cp -r library result/vostok-deflib/usr/share/vostok/
cp -r singularity result/vostok-deflib/usr/share/vostok/
cp package/DEBIAN/control-deflib result/vostok-deflib/DEBIAN/control
gzip -9cn package/DEBIAN/changelog-deflib > result/vostok-deflib/usr/share/doc/vostok-deflib/changelog.gz
cp package/DEBIAN/copyright-deflib result/vostok-deflib/usr/share/doc/vostok-deflib/copyright
cd result/vostok-deflib
md5deep -rl usr > DEBIAN/md5sums
cd ..
fakeroot dpkg-deb --build vostok-deflib
для сборки vostok-bin.deb
rm -r result/vostok-bin
mkdir -p result/vostok-bin/DEBIAN result/vostok-bin/usr/share/doc/vostok-bin result/vostok-bin/usr/bin
cp result/ost result/vostok-bin/usr/bin/
cp package/DEBIAN/control-bin result/vostok-bin/DEBIAN/control
gzip -9cn package/DEBIAN/changelog-bin > result/vostok-bin/usr/share/doc/vostok-bin/changelog.gz
cp package/DEBIAN/copyright-bin result/vostok-bin/usr/share/doc/vostok-bin/copyright
cp package/DEBIAN/ost.1 result/vostok-bin/DEBIAN/ost.1
cd result/vostok-bin
md5deep -rl usr > DEBIAN/md5sums
cd ..
fakeroot dpkg-deb --build vostok-bin

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

воскресенье, 26 мая 2019 г.

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/bin/env -S 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
Бывай.

Расширение командного режима

Расширены возможности кода Oberon-команд в трансляторе Восток. Эти возможности являются альтернативой частным и в то же время однообразным р...