OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Вторник, 22 Июнь, 2021 22:59

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 12 ] 
Автор Сообщение
 Заголовок сообщения: Консольная версия компилятора
СообщениеДобавлено: Суббота, 10 Апрель, 2021 05:06 
Аватара пользователя

Зарегистрирован: Среда, 22 Апрель, 2015 23:51
Сообщения: 232
Откуда: г. Рига, Латвийская ССР
Идея
Создать кроссплатформенную консольную версию Блекбокса

Мотивация
Это позволит некоторым категориям граждан (и неграждан :D ) пользоваться Блекбоксом более привычным способом (похожим на использование, например, fpc и gcc), легко интегрировать компилятор со своим любимым редактором, а также легко разворачивать проект на системах, не имеющих графической оболочки (например, на серверах).

Собственно, работа уже идёт, о чём выпущено несколько видеоотчётов на канале «Программирование на Обероне» (подписывайтесь, ставьте лайк :D ):
https://youtu.be/96fzbWtFHcQ

Текущее положение дел в Блекбоксе
(здесь речь идёт только о возможностях компиляции из консоли!)

Сейчас в ББ (BBCP) есть возможность компилировать модули и компоновать их в исполняемые файлы из консоли, но задача эта порой нетривиальная даже для тех, кто «в теме». Приходится писать что-то вроде:
Код:
echo "ConsCompiler.Compile('', 'MyProgram.Mod')" | env BB_PRIMARY_DIR="BlackBox" BB_SECONDARY_DIR="$PWD" ./blackbox

На Виндоусе команды, а главное ключи, выглядят по-другому.

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

Код:
env BB_PRIMARY_DIR="BlackBox" BB_SECONDARY_DIR="$PWD" ./blackbox <<DATA
Dev2Linker1.LinkElf Linux MyProgram:= Kernel$+ Files HostFiles Math Strings Dates Meta Log Dialog Services Fonts Ports Stores Converters Sequencers Models Printers Views Controllers Properties Printing Mechanisms Containers Documents Windows Console StdInterpreter HostConsole HostRegistry HostFonts HostWindows HostDates HostDialog StdDialog HostLang TextModels TextRulers TextSetters TextViews TextControllers TextMappers StdApi StdCmds StdLinks HostTextConv Args HostArgs StdLog ConsLog MyProgram
DATA

Набор модулей необходимо подбирать самому, так как их организация относится к внутреннему устройству ББ и, к сожалению, нигде не задокументирована. Мы этот барьер с горем пополам преодолели, но большинство пользователей не захотят связываться с такими проблемами.

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

Разумеется, всё это никуда не годится.

Техническое задание
В процессе работы постепенно вырисовалось техническое задание к данной версии компилятора. (Исполнимый файл здесь назван «foc»)

Расположение файлов с исходным кодом
Чтобы написать небольшую программу на Обероне (на Компонентном Паскале), программист обыкновенно создаёт пустой каталог. Например, «/home/user/prg/gauss» или «C:\Prg\Gauss». Назовём этот каталог рабочим каталогом. В нём программист создаёт текстовые файлы с исходным кодом модулей. Например:
Код:
C:\Prg\Gauss\Gauss.Mod
C:\Prg\Gauss\GaussSolve.Mod
C:\Prg\Gauss\GaussShow.Mod

Имена файлов и имена модулей совпадают с точностью до расширения.
[Идея: позволить суффиксы, связанные со средой. Например, «HostGraph_Win32.Mod».]

Как вариант, если имя модуля состоит из двух частей, его можно поместить в подкаталог (как в ББ):
Код:
C:\Prg\Gauss\Gauss.Mod
C:\Prg\Gauss\Gauss\Solve.Mod ←
C:\Prg\Gauss\Gauss\Show.Mod  ←

Или совсем как в ББ:
Код:
C:\Prg\Gauss\Gauss.Mod
C:\Prg\Gauss\Gauss\Mod\Solve.Mod ←
C:\Prg\Gauss\Gauss\Mod\Show.Mod  ←

Процесс компиляция
Программист, находясь в рабочем каталоге, даёт консольную команду:
Код:
foc Gauss

Варианты:
Код:
foc.exe Gauss
foc Gauss.Mod
foc -o Gauss.exe Gauss.Mod
foc --gui -o Gauss.exe Gauss.Mod

или, находясь в другом каталоге:
  foc C:\Prg\Gauss\Gauss
или:
  foc ..\..\Prg\Gauss\Gauss.Mod
или:
  foc -o C:\Gauss.exe ..\..\Prg\Gauss\Gauss.Mod
в последних случаях компилятор воспринимает указанный каталог как рабочий


Построение графа импорта
Компилятор рекурсивно обходит все модули проекта, начиная с указанного «главного» модуля, и составляет граф импорта, компилирует каждый модуль (кроме системных, см. ниже) и создаёт исполнимый файл (имя и расположение которого можно задать ключом «-o»). Системные модули соответствующим образом помечаются. Месторасположение всех файлов фиксируется. При сборе информации о модулях, импортируемых из данного, анализируется либо исходный код (ищется секция IMPORT; это уже реализовано, см. видеоотчёт №1), либо символьный файл (при отсутствии исходного кода данного модуля).

Системный каталог
Компилятор также знает о месторасположении системного каталога — того, в котором находятся так называемые системные модули, такие как: In, Out (Log), Math, Random, Strings, Files, Graph. Модули в системном каталоге скомпилированы заранее, компилятор ищет только Code- и Sym-файлы соответствующих модулей.

Месторасположение системного каталога (дальше варианты):
  • или задаётся ключом «--sysdir»;
  • или задаётся специальной переменной окружения;
  • или совпадает с расположением исполнимого файла «foc.exe» (в Линуксе — «foc»);
  • или известно компилятору априори ("захардкожено"), в том числе, захардкожеными могут быть несколько каталогов, последовательно проверяемых компилятором.
Файлы с машинным кодом и символьные файлы
Файлы откомпилированных модулей записываются в виде ocf- и osf-файлов в каталогах Code и Sym, которые создаются рядом с соответствующим Mod-файлом (или каталогом Mod, если используется вариант расположения файлов, принятый в ББ).

Ниже показан нетипичный, но возможный, пример:
Код:
C:\Prg\Gauss\Gauss.Mod
C:\Prg\Gauss\GaussSolve.Mod
C:\Prg\Gauss\GaussShow.Mod
C:\Prg\Gauss\Code\Gauss.ocf
C:\Prg\Gauss\Code\GaussSolve.ocf
C:\Prg\Gauss\Code\GaussShow.ocf
C:\Prg\Gauss\Sym\Gauss.osf
C:\Prg\Gauss\Sym\GaussSolve.osf
C:\Prg\Gauss\Sym\GaussShow.osf


Порядок поиска файлов модулей
Так как системные модули заранее скомпилированы, то их исходный код не нужен компилятору и даже может отсутствовать, поэтому компилятор в обычном режиме работы не должен искать Mod-файлов системных модулей.

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

Если системный модуль импортирует некий модуль, но модуль с таким именем есть в рабочем каталоге, используется последний. Таким образом, программисту даётся простой способ заместить некоторые системные модули своими версиями только в рамках данного проекта.
Сами системные модули тоже можно замещать, используя команду:
Код:
foc --install Math

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

К первому варианту относится главный модуль. Например, команда:
Код:
foc Math
при отсутствующих в рабочем каталоге соответствующих файлах должна приводить к ошибке, а не к попытке компиляции системного модуля Math.

Пример
Пусть в определённый момент компилятор должен найти файл модуля EngineMain, причём по варианту б (см. выше).
Тогда порядок поиска будет следующий:
1. В рабочем каталоге: EngineMain.Mod
2. В рабочем каталоге: Sym\EngineMain.osf ←
3. В рабочем каталоге: Engine\Main.Mod
4. В рабочем каталоге: Engine\Mod\Main.Mod
5. В рабочем каталоге: Engine\Sym\Main.osf ←
6. В системном каталоге: Sym\EngineMain.osf
7. В системном каталоге: Engine\Sym\Main.osf

Поиск идёт по порядку и прерывается, как только файл модуля впервые найден.

В случае нахождения файла в пунктах 2 и 5 необходимо проверить также и наличие файла с машинным кодом. Соответственно:
2а. В рабочем каталоге: Code/EngineMain.ocf
5а. В рабочем каталоге: Engine/Code/Main.ocf

Аналогично при нахождении файла в пунктах 6 и 7:
6а. В системном каталоге: Code/EngineMain.ocf
7а. В системном каталоге: Engine/Code/Main.ocf

Системные модули
Если в результате поиска файла модуля он был найден в системном каталоге, то такой модуль называется системным модулем.

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

Команда установки могла бы выглядеть так:
Код:
foc --install Graph
(компилирует модуль Graph, находящийся обязательно в рабочем каталоге, и копирует его в системный каталог; то есть копирует все три файла: Mod, osf, ocf)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Консольная версия компилятора
СообщениеДобавлено: Суббота, 10 Апрель, 2021 10:29 

Зарегистрирован: Вторник, 01 Март, 2011 09:34
Сообщения: 558
Откуда: Москва
Для информации:
1. BlackBox все-таки графическая оболочка, а не ЯП, а здесь речь идет о консольном компиляторе, поэтому относить следует к другой теме
2. В МультиОбероне реализован как консольный компилятор, так и компилятор из среды BlackBox
3. В МульитОбероне реализована как сборка, так и компоновка с учетом обхода деревьев импорта
4. МультиОберон действительно кросс-платформенный (X86 X64 ARM32 ARM64, можно расширять)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Консольная версия компилятора
СообщениеДобавлено: Суббота, 10 Апрель, 2021 11:24 
Аватара пользователя

Зарегистрирован: Воскресенье, 09 Декабрь, 2018 15:14
Сообщения: 73
Откуда: Equestria
Наверно у многих оберонщиков есть такой велосипед %)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Консольная версия компилятора
СообщениеДобавлено: Вторник, 13 Апрель, 2021 05:02 
Аватара пользователя

Зарегистрирован: Среда, 22 Апрель, 2015 23:51
Сообщения: 232
Откуда: г. Рига, Латвийская ССР
Дмитрий Викторович, спасибо за информацию, будем смотреть. Ну и своё сделаем, тоже, думаю, будет польза. Будем с вами по-социалистически соревноваться.

* * *

Мы опубликовали на GitHub'е исходный код проекта по созданию консольного компилятора. Это тот самый, по которому делаются видео на Ютубе.
Сейчас он работает на Линуксе и Виндоусе, компилирует простые проекты, рекурсивно обходя модули, выводит сообщения об ошибке с указанием файла и строки.

Запустить очень просто: скачать с Гита и написать:
Код:
make
./foc Main
Будет скомпилирована простая тестовая программа из нескольких модулей.
Это на Линуксе, для Виндоуса почти также — в README всё сказано.

* * *

Товарищи, что думаете насчёт идеи позволить суффиксы, связанные с ОС и архитектурой (или со средой выполнения).

Для примера: если в каталоге с проектом будут следующие файлы:
Args_Win32.Mod
Args_Linux.Mod
в каждом из которых находится своя версия модуля Args, то компилятор будет автоматически выбирать тот или иной файл в зависимости от окружения.
А вызвав компилятор со специальным ключом, можно было бы изменить его поведение. Например:
Код:
foc --mode Win32 Main
В таком случае, можно будет использовать и свои режимы.

Это вместо переименования файлов вручную и вместо ./switch_target.

Вот думаю, как лучше сделать: через знак подчёркивания или через точку (Args.Win32.Mod).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Консольная версия компилятора
СообщениеДобавлено: Вторник, 13 Апрель, 2021 07:42 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1376
Лучше через точку. Или через дефис, или через любой другой символ, недопустимый в имени модуля.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Консольная версия компилятора
СообщениеДобавлено: Вторник, 13 Апрель, 2021 10:11 

Зарегистрирован: Вторник, 01 Март, 2011 09:34
Сообщения: 558
Откуда: Москва
Trurl писал(а):
Лучше через точку. Или через дефис, или через любой другой символ, недопустимый в имени модуля.

Именно так.
Я в МультиОбероне сделал _, но это неудобно, буду переходить на '.' https://forum.oberoncore.ru/viewtopic.php?f=157&t=6629#p113412.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Консольная версия компилятора
СообщениеДобавлено: Вторник, 13 Апрель, 2021 13:20 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1298
Откуда: Киев
kekc_leader писал(а):
Для примера: если в каталоге с проектом будут следующие файлы:
Args_Win32.Mod
Args_Linux.Mod
в каждом из которых находится своя версия модуля Args, то компилятор будет автоматически выбирать тот или иной файл в зависимости от окружения.
А вызвав компилятор со специальным ключом, можно было бы изменить его поведение. Например:
Код:
foc --mode Win32 Main
В таком случае, можно будет использовать и свои режимы.
По-моему, лучше так:
Linux/Module.Mod
Windows/Module.Mod
И тогда выбор конфигурации - это просто выбор каталога, где искать исходный код.
Или это плохо вписывается в нынешние соглашения компилятора?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Консольная версия компилятора
СообщениеДобавлено: Вторник, 13 Апрель, 2021 21:27 
Аватара пользователя

Зарегистрирован: Среда, 22 Апрель, 2015 23:51
Сообщения: 232
Откуда: г. Рига, Латвийская ССР
Вот дефис — вроде классная идея.

Он в идентификаторах не встречается никогда, а в именах файлах позволен всегда.

Возможно, две точки в имени файла могут иногда сбить ОС с толку. Скажем, есть же расширение .tar.gz, которое воспринимается как нечто целое.
«Module.Win32.Mod» тогда бы мог сбить ОС с толку, а «Module-Win32.Mod» уже нет.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Консольная версия компилятора
СообщениеДобавлено: Среда, 14 Апрель, 2021 00:36 
Аватара пользователя

Зарегистрирован: Суббота, 16 Февраль, 2008 02:47
Сообщения: 486
Ориентироваться на файлы, которые волею судеб оказались в папке или не оказались - это кмк так себе идея, хоть и распространена повсеместно. Ориентироваться на файлы - удел файловых менеджеров. Если конструируется (мало-мальски сложная) многоплатформенная программная система, состоящая из множества модулей, некоторые из которых имеют разные реализации для разных платформ - неужели такая система не заслуживает отдельного человекочитаемого текстового описания? Достаточно формального, чтобы инструмент мог обеспечить компиляцию этой системы, а другой инструмент - передачу ее в хранилище, а третий - ...

Формальное текстовое описание системы - это как объявление переменных: вроде избыточность, компилятор же и сам может типы вывести. Но эта избыточность позволяет построить великолепные компиляторы, проверяющие ошибки, особенно при рефакторинге и миграциях.

В архитектуре компилятора предусматривается библиотекарь (типа того, что обсуждали здесь на форуме), и в его реализации локализуются все вопросы, связанные с именованием файлов, расположением папок. В ветке StdLib компилятор CP2 уже использует такого библиотекаря.

switch_target - это следствие ориентации на файлы и отсутствия текстового определения системы, отличного от де-факто обнаруженных файлов.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Консольная версия компилятора
СообщениеДобавлено: Среда, 14 Апрель, 2021 00:57 
Аватара пользователя

Зарегистрирован: Среда, 22 Апрель, 2015 23:51
Сообщения: 232
Откуда: г. Рига, Латвийская ССР
Модули находятся в файлах, поэтому ориентироваться на файлы приходится, коль скоро мы ориентируемся на модули.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Консольная версия компилятора
СообщениеДобавлено: Среда, 14 Апрель, 2021 23:37 
Аватара пользователя

Зарегистрирован: Суббота, 16 Февраль, 2008 02:47
Сообщения: 486
Вот пример ориентации на файлы.

./switch-target GUI Linux
./build
Нет, говорит, такого файла!

Лезу в switch-target, читаю, вникаю - и вспоминаю, что надо Linux GUI, а не GUI Linux. Но почему же программа switch-target мне об этом не сообщила? А она не может: она написана с ориентацией на файлы, и первый параметр - суффикс или префикс, который добавляется к каким-то путям, и все, что по этим путям находится - компилируется. В моем случае - ничего не находится. Но такое ведь бывает, когда ориентируешься на файлы. Поэтому это не ошибка - точнее, невыявимая ошибка. В итоге потеряно рабочее время, доверие системе, а главное - удовольствие. И еще я ведь "переключал контексты": решал свою задачу, а тут вдруг пришлось вникать в чужую программу на крючкосинтаксисе; когда решил - забыл, с чего начал. Начинай с начала.

И вот незадача: я уже правил Switch-target, чтобы она выдавала подсказку, если ей не передано аргументов. Но тут-то я передал аргументы... Таким образом, при ориентации на файлы появляется класс формально невыявимых ошибок.

Одним словом, комстрока + ориентация на файлы = адская сатана. Продолжение сишного бардака за пределами языка программирования.

В ББ/Обероне, по крайней мере, был был текст с коммандером для каждой платформы. Вероятность ошибиться и необходимость переключать контекст и вникать во что-то - гораздо меньше.

Может, конечно, я программист ненастоящий: настоящие-то не делают ошибок ;)

ПС
Я критикую файлоориентированный подход как таковой, а не компилятор kekc_leader или switch_target. Я считаю, что файлы - зло, и негоже пользователям давать их трогать руками; однако я понимаю, что "весь мир во зле лежит" ;) и иные программы приходится писать для работы в мире зла. Если для целевой аудитории программа - это набор файлов, то, что ж, надо дать им этих файлов...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Консольная версия компилятора
СообщениеДобавлено: Четверг, 15 Апрель, 2021 10:47 

Зарегистрирован: Вторник, 01 Март, 2011 09:34
Сообщения: 558
Откуда: Москва
adimetrius писал(а):
Одним словом, комстрока + ориентация на файлы = адская сатана.

Антон, зря вы так эмоционально накачиваете.
1. Есть множество задач на комстроку (IoT, серверное, Web) в отличие от DeskTop. Даже на мобильных платформах разработчики компиляторов для устройств мне говорили про "ничего, кроме gdb".
2. Абстрактный модуль вместо файла - это хорошо. А библиотекарь в том интерфейсе, что есть, для меня например, не подходит, используются свои средства: и типы файлов другие (.o, .bc, .ll), и Locator не нужен, а нужны кросс-платформенные разделы модулей (Code/Clwe/Cfu8).


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 12 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2021, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB