OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Суббота, 14 Декабрь, 2024 00:17

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




Начать новую тему Ответить на тему  [ Сообщений: 350 ]  На страницу Пред.  1 ... 14, 15, 16, 17, 18  След.
Автор Сообщение
СообщениеДобавлено: Пятница, 08 Март, 2024 20:20 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 560
Откуда: Украина, Днепропетровская обл.
Посмотрел ошибку. Также она присутствует в Ofront (voc) и в CPfront (МультиОберон).

Ofront:
Код:
static void Ex_Example (CHAR *b, LONGINT b__len, LONGINT b__len1)
{
   struct Example__1 _s;
   _s.b = (void*)b; _s.b__len = b__len; _s.b__len = b__len;

CPfront:
Код:
static void Ex_Example (CHAR *b, INTEGER b__len, INTEGER b__len1)
{
   struct Example__1 _s;
   __ENTER("Ex.Example");
   _s.b = (void*)b; _s.b__len = b__len; _s.b__len = b__len;
      <-- нужно _s.b__len = b__len; _s.b__len1 = b__len1;


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 08 Март, 2024 21:33 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 560
Откуда: Украина, Днепропетровская обл.
Починил. Спасибо за информацию.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 12 Март, 2024 20:35 

Зарегистрирован: Вторник, 12 Март, 2024 20:31
Сообщения: 25
Здравствуйте, Олег!

Думаю перейти с содержащего ошибки и не поддерживаемого oo2c на Ofront+, но столкнулся с проблемой. Возможно ли каррирование в Ofront+?

Вот такая программа не проходит трансляцию в Офронте+:
Код:
MODULE test;
IMPORT Out;

TYPE f = PROCEDURE(b: INTEGER): INTEGER;

PROCEDURE Add(a: INTEGER): f;
        PROCEDURE F(b: INTEGER): INTEGER;
        BEGIN
                RETURN a + b
        END F;
BEGIN
        RETURN F
END Add;

BEGIN
        Out.Int(Add(16)(25),2);
        Out.Ln;
END test.

Транслятор выдаёт ошибку:
Код:
test.ob2  translating test
    13:1  err 73  procedure must have level 0

voc тоже отказывается компилировать, выдавая похожую ошибку:
Код:
test.Mod  Compiling test.

  12:   RETURN F
              ^
    pos   177  err 73  procedure must have level 0

  16:   Out.Int(Add(16)(25),2);
                     ^
    pos   210  err 113  incompatible assignment

Module compilation failed.

При этом oo2c компилирует без проблем, и программа работает, как задумано.
Единственное, что можно отметить, это предупреждение от линковщика:
Код:
/usr/bin/ld: warning: obj/test.o: requires executable stack (because the
.note.GNU-stack section is executable)

Это так и было задумано? Но почему? Ведь такое каррирование, как я
понимаю, разрешается описанием языка Оберон-2. Если так и задумано, то как
подобные задачи решают в Офронте+?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 13 Март, 2024 14:22 

Зарегистрирован: Вторник, 12 Март, 2024 20:31
Сообщения: 25
olenellus писал(а):
Ведь такое каррирование, как я
понимаю, разрешается описанием языка Оберон-2.

Наверно, я неправ. Вот цитата:
The Programming Language Oberon-2 писал(а):
If a procedure P is assigned to a procedure variable of type T… P must not be declared local to another procedure, and neither can it be a standard procedure.

Как же мне теперь мою задачу решать?..


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 13 Март, 2024 20:11 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 560
Откуда: Украина, Днепропетровская обл.
Похоже, что Вы пытаетесь вытащить вложенную процедуру в общее поле видимости. На самом деле внутренне вложенная процедура прикреплена к специальной структуре данных, которая заполняется родительской процедурой неявно, и через которую вложенная и родительская процедура обмениваются данными. И я не вижу простого способа сделать вложенную процедуру равноценной внешней, это противоречит самой логике её вложенности. Вложенная процедура это внутренняя процедура, она для этого таковой задумана. Нет возможности воспользоваться ею как внешней. Зато она имеет доступ к параметрам и переменным родительской процедуры (оставим пока за бортом извращения Оберона-07) как раз через эту внутреннюю структуру. Кстати, извращения в O7 как раз и вызваны желанием избавиться от этой внутренней структуры.

Да. Слово "каррирование" слышу вообще впервые, но абсолютно уверен, что Ваш код можно переписать при помощи обычной (не вложенной) процедуры.

Ну смотрите сами, здесь же явная неувязка:
Код:
PROCEDURE Add(a: INTEGER): f;
        PROCEDURE F(b: INTEGER): INTEGER;
        BEGIN
                RETURN a + b  <-- допустим, Вы передали процедуру F вовне; откуда она возьмёт значение a?
        END F;


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 13 Март, 2024 22:48 

Зарегистрирован: Вторник, 12 Март, 2024 20:31
Сообщения: 25
Хм. Тогда значит вопрос мой не по транслятору, а по общим принципам программирования, и его следует по-хорошему в другом месте задать. Интересно, что oo2c делает как раз то, что мне надо. Суть такая. Я написал модуль для численного интегрирования ОДУ методом Рунге-Кутты с намерением использовать его для всякого рода задач. Вот его интерфейс
Код:
MODULE RK;

TYPE
  State* = POINTER TO ARRAY OF LONGREAL;
  RHSElement* = PROCEDURE(input: State): LONGREAL;
  RightHandSide* = POINTER TO ARRAY OF RHSElement;


PROCEDURE UpdateRK4*(VAR state: State; RHS: RightHandSide; step: LONGREAL);
(* An application of the Runge-Kutta 4 method with time-step 'step'.  The
   array of state and of the right hand side functions must be defined in
   the calling application *)

PROCEDURE UpdateRKF45*(VAR state: State; RHS: RightHandSide; VAR step: LONGREAL; VAR oldStep: LONGREAL; rtol: LONGREAL; atol: LONGREAL);
(* An application of the Runge-Kutta-Fehlberg 45 method with the initial
   time-step guess 'step'.  The array of state and of the right hand side
   functions must be defined in the calling application.  Internally RK4 and
   RK5 are performed and the result is compared. If significantly different
   (w.r.t.  to the tolerance), 'step' is updated. The new 'step' estimate
   (for the next application) is returned alongside with the updated
   'state'. The actually used step during the 'state' update is returned in
   'oldStep'. 'rtol' is the relative error tolerance, 'atol' is the absolute
   error tolerance *)

END RK.

От конкретного приложения требуется определить вектор состояния и задать длину (тип State — это указатель на него) а также предоставить правые части динамических уравнений (тип RightHandSide — это указатель на компоненты векторного поля, каждая из них берёт (указатель на) вектор состояния и выдаёт действительное число — скорость изменения соответствующей координаты). Дальше модуль обсчитывает один шаг интегрирования с такими вводными. Я намеревался использовать модуль для задач самого широкого круга: от расчёта входа спускаемого аппарата в плотные слои атмосферы до расчёта кинетики взаимодействия олигонуклеотидов.

В некоторых прикладных задачах оказывается удобнее задавать праве части с помощью параметризированного общего вида функции. Я намеревался решать эту задачу с помощью каррирования. Внутри тела прикладного модуля это выглядит примерно так
Код:

PROCEDURE dotBT(i: LONGINT; SunY: LONGREAL): RK.RHSElement;
    PROCEDURE ParametrizedFunction(composition: RK.State): LONGREAL;
    VAR X: Chemicals;
    BEGIN
        ComputeChemicals(X, composition);
        RETURN
        - kATon[i]*X.A*X.BT + kAToff[i]*X.ABT + kBTon[i]*X.B*X.T - kBToff[i]*X.BT
        + kEnz*SunY*X.BDE
    END ParametrizedFunction;
BEGIN
    RETURN ParametrizedFunction;
END dotBT;


В теле самого модуля далее присвоение производится следующим образом
Код:

VAR
    composition: RK.State;
    RHS: RK.RightHandSide;

RHS^[10] := dotBT(0,SunY);

где 0 и SunY — внешние параметры.

Короче, мне надо как-то сконструировать функцию типа RightHandSide (берущую указатель типа State и возвращающую LONGREAL) с использование внешних параметров. Как это правильно сделать в Обероне?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 14 Март, 2024 01:31 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 560
Откуда: Украина, Днепропетровская обл.
Самое простое, что я предложу, это сделать процедуру ParametrizedFunction не внутренней и добавить ей параметров i: LONGINT; SunY: LONGREAL, которые сейчас передаются ей через родительскую процедуру.

Но вообще наверное тянет на объект. Завести запись с этими значениями, передавать параметром VAR эту запись в ParametrizedFunction.

Удивлён, что oo2c "делает как раз то, что Вам надо" — кабы это не очередной его баг ;)


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 19 Март, 2024 02:34 

Зарегистрирован: Вторник, 12 Март, 2024 20:31
Сообщения: 25
Спасибо! Вы навели меня на возможное решение. Помучившись немного и прочитав пару соседних веток про функциональные переменные и объекты, реализовал-таки решение через обероновское ООП. Наконец, понял, как это вообще работает. До этого про ООП у меня были мифические представления.

Короче, теперь интерфейс выглядит так (в стиле oo2c):
Код:
MODULE RKrec;

TYPE
  State* = POINTER TO ARRAY OF LONGREAL;
  DynamicalSystem* = POINTER TO DynamicalSystemVariables;
  DynamicalSystemVariables* = RECORD
    (* May be extended to include external parameters *)
    state*: State;

    PROCEDURE (ds: DynamicalSystem) ComputeRHS*(result: State);
    (* Must be redefined by the target application, for now does nothing *)

    PROCEDURE (ds: DynamicalSystem) GenerateK(VAR k1: State; VAR k3: State; VAR k4: State; VAR k5: State; VAR k6: State; h: LONGREAL; generateK6: BOOLEAN);

    PROCEDURE (ds: DynamicalSystem) UpdateRK4K(k1: State; k3: State; k4: State; k5: State; step: LONGREAL);

    PROCEDURE (ds: DynamicalSystem) UpdateRK4*(step: LONGREAL);
    (* An application of the Runge-Kutta 4 method with time-step 'step'.
       The array of state and of the right hand side functions must be
       defined in the calling application *)

    PROCEDURE (ds: DynamicalSystem) UpdateRKF45*(VAR step: LONGREAL; VAR oldStep: LONGREAL; rtol: LONGREAL; atol: LONGREAL);
    (* An application of the Runge-Kutta-Fehlberg 45 method with the initial
       time-step guess 'step'.  The array of state and of the right hand
       side functions must be defined in the calling application.
       Internally RK4 and RK5 are performed and the result is compared. If
       significantly different (w.r.t.  to the tolerance), 'step' is
       updated. The new 'step' estimate (for the next application) is
       returned alongside with the updated 'state'. The actually used step
       during the 'state' update is returned in 'oldStep'. 'rtol' is the
       relative error tolerance, 'atol' is the absolute error tolerance *)
  END;

END RKrec.

где все процедуры теперь связаны с соответствующими записями, а вычисление правых частей — пустая процедура. В целевой же программе я расширяю тип DynamicalSystem путём добавления полей с нужными параметрами и объявляю новый тип указателя на такие переменные (т. е. сужаю класс, тут забавная дуальность: расширение записи приводит к сужению класса) и переопределяю вычисление правых частей сообразно задаче:
Код:
MODULE test2;

IMPORT RK := RKrec, Out;

CONST
    step = 1.0;
    parameter = 0.5;

TYPE
    DynamicalSystem = POINTER TO DSVars;
    DSVars = RECORD (RK.DynamicalSystemVariables)
        parameter: LONGREAL;
    END;

VAR
    ds: DynamicalSystem;

PROCEDURE (ds: DynamicalSystem) ComputeRHS*(result: RK.State);
VAR i: LONGINT;
BEGIN
    FOR i := 0 TO LEN(ds.state^)-1 DO;
        result[i] := ds.state[i]*ds.parameter;
    END;
END ComputeRHS;

BEGIN
    NEW(ds); NEW(ds.state,2);
    ds.parameter := parameter;
    ds.state[0] := 1.0;
    ds.state[1] := 2.0;
    Out.LongReal(ds.state[0],5,0); Out.Ln;
    Out.LongReal(ds.state[1],5,0); Out.Ln; Out.Ln;
    ds.UpdateRK4(step);
    Out.LongReal(ds.state[0],5,0); Out.Ln;
    Out.LongReal(ds.state[1],5,0); Out.Ln; Out.Ln;
END test2.

и всё работает. oo2c зачем-то заставил меня экспортировать переопределённую процедуру ComputeRHS, но, вообще-то, в Обероне-2 это не требуется (ofronto-подобные компиляторы нормально работают и без этого). Так вот ты какое, ООП.

Шёл я к этому неделю. Спасибо за наводку. Раньше не имел дел с ООП. Сначала утонул в чужеродной терминологии. Потом открыл книжку Object-Oriented Programming in Oberon-2, и стало более-менее понятно.

Кстати, вернёмся к офронту+. Мне кажется очень удобным то, что утилита oo2c для чтения интерфейсов показывает комментарии (но только особые комментарии — начинающиеся с (** ). showdef этого не делает. Например, в случае выше пришлось бы лезть в исходный текст, чтобы понять, что требуется от целевой программы.

И ещё один вопрос. А в Обероне-2 в принципе запрещено присваивание переменных типа массива или только не реализовано (что в oo2c, что в офронто-подобных)? Вроде бы, из описание языка это напрямую не следует. В Обероне-07 присваивание массивов разрешено (реализовано, например, в obnc), правда, там и массивы все с заранее известной длиной. А то приходится городить специальную процедуру для копирования.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 20 Март, 2024 18:07 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 560
Откуда: Украина, Днепропетровская обл.
Рад Вашим успехам! :)

olenellus писал(а):
Кстати, вернёмся к офронту+. Мне кажется очень удобным то, что утилита oo2c для чтения интерфейсов показывает комментарии (но только особые комментарии — начинающиеся с (** ). showdef этого не делает. Например, в случае выше пришлось бы лезть в исходный текст, чтобы понять, что требуется от целевой программы.
Я всецело с Вами согласен. Думал когда-то о таком функционале. В ETH Oberon есть утилита Watson, которая делает именно это. Тут, по-видимому, два возможных подхода: или пихать такие "экспортированные коммментарии" в символьные файлы, или же давать утилите доступ к исходнику. По крайней мере, чтобы она однозначно находила исходный модуль по символьнику. Что не всегда возможно, поскольку имя файла модуля может отличаться от имени модуля.

Мне не нравятся оба подхода. Я взялся было портировать утилиту Watson (там в репозитории болтается), но не закончил. А так - функционал нужный, ещё думаю над этим. Любая помощь приветствуется.

olenellus писал(а):
И ещё один вопрос. А в Обероне-2 в принципе запрещено присваивание переменных типа массива или только не реализовано (что в oo2c, что в офронто-подобных)?
Да всё там есть, смотрите:


Вложения:
CopyArr.png
CopyArr.png [ 53.8 КБ | Просмотров: 6008 ]
Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 28 Март, 2024 03:00 

Зарегистрирован: Вторник, 12 Март, 2024 20:31
Сообщения: 25
Я тут ещё поковырял A2 на предмет среды запуска своих программ. И вот, что хочу доложить. Обсчёт вышеприведённого модуля test с 2000000 итерациями ds.UpdateRK4(step) (ну и с другим значением параметра, чтобы за допустимые пределы не вылетело) занял такое время:
  • A2: 11 с
  • voc: 7,5 c
  • Ofront+: 1,5 с
  • oo2c: 1,5 с
А я думал, Ofront+ будет на ровне с voc, а он, оказывается, в спину дышит oo2c. Намучился я, правда, с компиляцией и линковкой без установки офронта+ в систему. Для меня сишные телодвижения с линковкой непривычны.

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

А ещё не знаю пока, как на этом сервере собрать офронт+. Там старая Убунту, и версия libc не подходит. Жаль. Быстро работает, однако.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 28 Март, 2024 15:23 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 560
Откуда: Украина, Днепропетровская обл.
olenellus писал(а):
  • voc: 7,5 c
  • Ofront+: 1,5 с
Скорее всего, тут дело не в Ofront'е+, а в опциях GCC -O0-3 -Os, с которыми собирается код. voc, вероятно, и сам собран с -O0, и GCC вызывает тоже с -O0 (может быть с -O1). Разработчики трансляторов Оберона в Си почему-то боятся сишной оптимизации. Вероятно, потому, что она может добавить нестабильности. Что до меня, я сознательно использую при работе с Ofront+ GCC с оптимизацией даже не по скорости, а по размеру -Os (скорость - побочный эффект), что в своё время позволило найти проблемы в сборщике мусора (при переводе его на 64-битность), которые могли остаться в voc. Но на 100% ничего утверждать не буду, т.к. voc не пользуюсь.

olenellus писал(а):
Для меня сишные телодвижения с линковкой непривычны.
Прошу прощения. Но так больше гибкости при вызове разных сишных компиляторов.

olenellus писал(а):
А ещё не знаю пока, как на этом сервере собрать офронт+. Там старая Убунту, и версия libc не подходит. Жаль. Быстро работает, однако.
Есть ли возможность обновить там Убунту?

Ofront+ должен собираться и со старой libc. А в чём конкретно трудности?

Смотрите. Если на старой Убунту не запускается бинарь Ofront'а+, собранный для более новой libc, делайте так:

Скопируйте туда дистриб Ofront'а+. Переходите в нужную папочку (Target/Linux_amd64 если линукс 64-битный и Target/Linux_i386 если 32-битный).

Идёте на https://github.com/Oleg-N-Cher/OfrontPlus-bootstrap

Для 64-битного линукса нас интересует папочка unix-88, для 32-битного unix-44.

Всё там конечно свалено в одну кучу, но для упрощения из папочки unix* нужной разрядности копируете все файлы *.c и *.oh в Obj и их же в Lib/Obj

Потом запускаете Lib/Bin/cc и Bin/cc

Всё собрано именно для вашей версии libc. Дальше Ofront+ сможет пересобирать сам себя.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 28 Март, 2024 15:53 

Зарегистрирован: Вторник, 12 Март, 2024 20:31
Сообщения: 25
Спасибо! Попробую совладать.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 23 Май, 2024 13:53 

Зарегистрирован: Вторник, 12 Март, 2024 20:31
Сообщения: 25
Забыл поблагодарить. Большое спасибо, всё работает!

Вообще, офронт+ оказался очень удобным компилятором, особенно после настройки прилагаемого omake и написания небольшого скрипта для организации файлов где надо и как надо. И при этом всё быстро летает. И прилагаемые библиотеки достаточно богаты (я активно пользуюсь не совсем обероновской aria). Удалось (правда, не напрямую, а немного через одно место, через простой дополнительный сишный файл) прицепиться к библиотеке для моделирования сворачивания РНК ViennaRNA. Всё работает! Активно делаю науку.

Ещё раз спасибо!


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 23 Май, 2024 14:26 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 560
Откуда: Украина, Днепропетровская обл.
Очень рад, что Вам нравится Ofront+
Мы старались :D

Кстати, там некоторые вещи по низкоуровневым биндингам не вполне очевидны. Больше можно подсмотреть в подсистемах к XDev: Pdp11Dev NesDev SmdDev MsxDev K580Dev DosDev GBDev UkncDev WinDev ZXDev

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

Также есть Телеграм-группа по поддержке Ofront+


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 07 Ноябрь, 2024 20:05 

Зарегистрирован: Вторник, 22 Май, 2007 15:38
Сообщения: 226
Откуда: Питер
Как работает опция -w, которая вроде должна указывать, что входной файл в кодировке UTF-16? Я пробую скормить oFtont+'у разные вариантв UTF-16, не получается...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 08 Ноябрь, 2024 11:15 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 560
Откуда: Украина, Днепропетровская обл.
GameHunter писал(а):
Как работает опция -w, которая вроде должна указывать, что входной файл в кодировке UTF-16?
Не UTF-16, а UTF-8. Как более распространённая.

Но исходник по мере считывания перекодируется в двухбайтовую кодировку UCS-2 (принятую в Windows). Отсюда и такое описание опции:
Цитата:
"w": UCS-2 encoded wide character format enabled (off)

Так что внутренняя кодировка символов CHAR(КП) / LONGCHAR(O3) / SYSTEM.CHAR16 будет именно UCS-2.

Или дописать к описанию опции так? Чтобы было понятнее.
Цитата:
"w": UTF-8 to UCS-2 encoded wide character format enabled (off)


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 09 Ноябрь, 2024 06:27 

Зарегистрирован: Вторник, 22 Май, 2007 15:38
Сообщения: 226
Откуда: Питер
Цитата:
Так что внутренняя кодировка символов CHAR(КП) / LONGCHAR(O3) / SYSTEM.CHAR16 будет именно UCS-2.


Внутреннее представление - что вы имеете в виду для КП? Насколько я знаю, тип CHAR там всегда 16-битный...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 09 Ноябрь, 2024 21:04 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 560
Откуда: Украина, Днепропетровская обл.
GameHunter писал(а):
Внутреннее представление - что вы имеете в виду для КП? Насколько я знаю, тип CHAR там всегда 16-битный...
Я имею в виду кодировку. Именно она регламентирует как интерпретировать числа (коды) символов. Какие коды каким символам соответствуют. КП/ББ из мира Windows, поэтому для внутреннего представления символов используется двухбайтовая фиксированная кодировка UCS-2, как в Windows.

Более того, 16-битное кодирование символов тоже не единственно применяющееся. Где-то 16 бит не хватает, а где-то 8 хватает. А где-то применяются кодировки с переменным размером каждого символа.

Хотел Вас поразить тем, что есть много кодировок типа UCS-2, но ChatGPT не согласился.
Цитата:
Перечисли какие есть кодировки символов, использующие одинаковый размер бит для каждого символа. В данном случае 16 бит. Нас интересуют кодировки типа UCS-2

ChatGPT
Существует несколько кодировок, использующих фиксированный размер в 16 бит (2 байта) на символ. Наиболее известные из них:

UCS-2 (Universal Character Set 2-byte) — использует ровно 16 бит для каждого символа, ограничивается символами из базовой многоязыковой плоскости (BMP). Не поддерживает символы вне диапазона BMP (0x0000–0xFFFF), такие как эмодзи и дополнительные иероглифы.

UTF-16 (16-bit Unicode Transformation Format) — по сути, является расширением UCS-2 и совместим с ним для символов из BMP. Хотя UTF-16 использует 16 бит на символ для BMP-символов, она также поддерживает дополнительные символы за счёт использования парных суррогатов (каждый из них также занимает 16 бит).

UTF-16BE и UTF-16LE (Big Endian и Little Endian) — варианты UTF-16, которые используют прямой порядок байтов (Big Endian) или обратный порядок байтов (Little Endian) соответственно. Эти кодировки также фиксируют размер в 16 бит для каждого кода в BMP и могут использовать суррогатные пары для символов вне BMP.

Основные различия между UCS-2 и UTF-16 заключаются в диапазоне поддерживаемых символов и поддержке суррогатных пар.
Цитата:
Нельзя сказать, что в UTF-16, UTF-16BE и UTF-16LE каждый символ занимает 16 бит. Из-за суррогатных пар символ может занимать 32 бита, 48 и так далее. Нас интересует именно чтобы каждый символ имел одинаковое 16-битное представление. Есть ли ещё такие кодировки?

ChatGPT
Вы правы, UTF-16 не гарантирует фиксированное 16-битное представление для всех символов из-за использования суррогатных пар.

Кодировки с фиксированным 16-битным представлением каждого символа, кроме UCS-2, встречаются крайне редко, так как UCS-2 в основном удовлетворяет требованию фиксированного 2-байтового размера для символов из базовой многоязыковой плоскости (BMP). Однако, помимо UCS-2, других широко используемых 16-битных кодировок, сохраняющих строго фиксированный размер для каждого символа, практически не существует.

Если для вашего случая важно ограничиться 16-битной кодировкой с фиксированным размером на каждый символ, то UCS-2 остаётся практически единственным вариантом, так как другие 16-битные кодировки, такие как UTF-16, неизбежно вводят поддержку суррогатов для символов вне BMP.

Получается, что двухбайтный CHAR в КП практически не оставляет никакого манёвра, прибивая представление к UCS-2. Но хоть так. Всё же лучше, чем разброд и шатания, как с верхней половиной таблицы (> 127) и обилия кодировок типа 1251, KOI8-R и т.п.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 10 Ноябрь, 2024 06:15 

Зарегистрирован: Вторник, 22 Май, 2007 15:38
Сообщения: 226
Откуда: Питер
Получается, что опция -w просто означает, что входной файл в UTF-8, а без неё - в ANSI. Правильно я понял? Она не означает каких-нибудь выходных изменений в выходных файлах си?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 11 Ноябрь, 2024 01:13 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 560
Откуда: Украина, Днепропетровская обл.
GameHunter писал(а):
Получается, что опция -w просто означает, что входной файл в UTF-8, а без неё — в ANSI. Правильно я понял? Она не означает каких-нибудь выходных изменений в выходных файлах си?
Я бы сказал, что без -w кодировка будет raw, т.е. что на входе — то и на выходе. Старшая половина таблицы (> 127) поддерживается, т.е. можно подать исходник в однобайтных кодировках 866, 1251, KOI8-R и т.п.

А если исходник у нас в UTF-8, то с опцией -w будет предпринята попытка перекодировать символы. Если она не удалась — будет ошибка компиляции. А без -w символы поступят "как есть" и останутся многобайтовыми, что часто используется в Linux.

Пример (кодировка исходника UTF-8):
Код:
VAR ch: SYSTEM.CHAR16;
...
ch := "Ж"; (* без опции -w не скомпилируется, потому что в UTF-8 символ "Ж" займёт 2 байта и будет воспринят как 2 символа *)
С таким решением появляется хитрая возможность с одного исходника в кодировке UTF-8 получить для Windows (с опцией -w) символы, которые перекодируются в момент компиляции в UCS-2, как принято в винде. А для Linux (без опции -w) строки останутся UTF-8.

Была мысль сделать поддержку прямой компиляции исходников в формате .odc, но я не вижу простого способа перейти на позицию ошибки (вывод вида строка:столбец мало поможет, потому что перейти в BlackBox в позицию ошибки — много лишних телодвижений), т.е. от такого вывода будет мало проку, если мы редактируем .odc в BlackBox. А больше его нигде и не отредактируешь. Я знаю про навигатор по исходнику в BlackBox, но он мало удобен для этого.

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


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 350 ]  На страницу Пред.  1 ... 14, 15, 16, 17, 18  След.

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


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

Сейчас этот форум просматривают: Oleg N. Cher и гости: 0


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

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