Тем временем, в Ofront+ появилась долгожданная
поддержка двухбайтного символьного типа CHAR. Это открывает перед нами отличные перспективы по пересборке модулей BlackBox при помощи Ofront+, а также можно уже смело присмотреться к большой библиотеке
исходников Гельмута Цинна, которые тоже можно пробовать пересобирать Ofront'ом+.
Лично мне очень приятно, что такая серьёзная, не побоюсь этого слова, работа привела к практически полной поддержке в Ofront+ Компонентного Паскаля. У нас нет ещё только поддержки мета-информации для работы BlackBox'овского модуля Meta, но я надеюсь, что нам это ещё долго не понадобится. В GPCP тоже этого нет, но, тем не менее, GPCP имеет право называться компилятором Компонентного Паскаля, согласно описания языка.
В Ofront+ появилась опция командной строки -w, отвечающая за то, как именно интерпретируются символы исходника программы: без -w - как и раньше (т.е. любой символ попадает в строку по его коду, и кодировка может быть абсолютно любая), а с -w транслятор считает, что на вход поступают широкие символы, даже если кодировка исходника UTF-8.
Ещё раз. На вход без режима -w можно подавать что угодно, любую кодировку - хоть 1251, хоть 866, хоть KOI-8R. Она просто ляжет в целевой сишник с теми же кодами, что и входящие символы.
А вот в режиме -w нужно подавать только такие юникодные символы, которые поместятся в два байта. Иначе будет ошибка err 3. Это я предусмотрел специально.
err #3: illegal character in string
Я думаю, будет очень хорошо показывать юзеру, что его хитрый символ (типа эмодзи) не проходит компиляцию как один широкий символ.
С опцией -w пока что поддерживается только входной формат .txt в кодировке UTF-8 (в версии для BlackBox - и .odc), но список входящих форматов мы обязательно расширим. В итоге нам должно быть без разницы, как именно закодирован исходник. Я как раз хотел этот момент автоматизировать и не задавать доп. ключами. А вот как именно интерпретировать символы - совсем другое дело, для этого теперь есть опция -w. А когда мы научим Texts понимать формат .odc (я планирую это сделать), оттуда будут идти широкие символы, но нужно оставить возможность, чтобы они интерпретировались как UTF-8 (без ключа -w).
Кстати, в процессе работы над CHAR появилась интересная мысль сделать ключик -w переключателем широкого или узкого CHAR в Обероне-07. Уже даже реализовал. Я подумал, что ведь раз будут идти широкие символы с входного потока, а тип CHAR в O7 только один, то нормально будет их обрабатывать именно как широкие. А если будут идти узкие, в UTF-8, то нормально будет узкие.
Расклад по широкому CHAR'у:
Oberon-1, Oberon2: CHAR, SYSTEM.CHAR16
Oberon-07: варьируемой длины CHAR
КП: SHORTCHAR, CHAR
Oberon-3: CHAR, LONGCHAR
Одна небольшая тонкость, связанная с ключиком -w:
Модуль
Код:
MODULE TestChar16;
VAR ch: CHAR;
BEGIN
ch := "Ж"
END TestChar16.
С -w поступивший символ "Ж" будет интерпретирован как широкий CHAR и программа нормально скомпилится.
А без -w символ "Ж" это будет юникодовая строка, состоящая из двух байт, и программа уже не скомпилится.
Код:
MODULE TestChar16;
VAR i: INTEGER;
BEGIN
i := LEN("Ж")
END TestChar16.
Здесь с -w длина будет 1, а без -w длина 2. Но тут, надеюсь, всё понятно)
Также ввёл для Оберона-3 новую операцию LCHR. Связано это с тем, что CHAR тут короткий, и поэтому CHR не может и не должна выдавать длинный символ, значит нужна новая операция.
Для O1, O2 реализован SYSTEM.LCHR.
Также во всех диалектах реализованы типы SYSTEM.CHAR8 и SYSTEM.CHAR16.
Я подверг Ofront+ зверскому испытанию - попробовал оттранслировать модуль Strings из BlackBox:

Пришлось включить ключик -w, а то там есть прямое задание широких символьных литералов.
А вот часть ББ, собранная для Linux. Strings и Math должны работать. Из Kernel взято только несколько процедур:

Модули bb* не только транслируются, но и компилятся сишкой. Но их работу я не тестировал. Привязки LinLibc и LinLibW сделаны очень сильно с уклоном на 32-битность, надо перепахивать. Пока сделал, что смог. К сожалению, нет возможности для заимствованных привязок тестировать все функции.
Один очень важный момент: перед сборкой любого проекта новым Ofront+ нужно удалить все символьники. Пришлось немного изменить формат символьников. OP2 вообще очень похабно работает с символьниками: если подсунуть символьник неправильного формата, то транслятор закрэшится почти гарантированно. И это касается и Ofront, и Ofront+, и BlackBox.