OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 01 Июнь, 2023 13:09

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




Начать новую тему Ответить на тему  [ Сообщений: 319 ]  На страницу Пред.  1 ... 12, 13, 14, 15, 16
Автор Сообщение
СообщениеДобавлено: Понедельник, 14 Март, 2022 00:21 
Аватара пользователя

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


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

Зарегистрирован: Вторник, 01 Март, 2011 09:34
Сообщения: 582
Откуда: Москва
Oleg N. Cher писал(а):
Эта ошибка также присутствует в CPfront и в Мульти-Обероне. В Ofront и voc её нет, там такой код просто вызовет ошибку рекурсивного определения.

Я прошу помощи у Дмитрия Викторовича Дагаева, если ему ещё интересна доработка Мульти-Оберона. Тем более, что он уже патчил код, связанный с рекурсивным определением типов.

Код компилируется МультиОбероном, к сожалению, в связи со сменой компа компилятора C нет. Поэтому проверить до конца не могу. В процедуре DefineType у меня есть код.
Код:
IF (obj # NIL) & (Undefined(obj) OR (obj^.linkadr = TEMPORARY_TYPE)) THEN
        ...
   IF (str^.form = fPOINTER) & (str^.base_typ^.comp = CF_ARRAY) THEN
      obj := str.base_typ.strobj;
      IF (obj # NIL) & (obj^.linkadr = RECURSIVE_TYPE) THEN
         obj^.linkadr := TEMPORARY_TYPE;
         DefineType(str^.base_typ);
         obj^.linkadr := RECURSIVE_TYPE;
      END
   END
END

Насколько могу судить, Вы предлагаете аналогичное решение извне DefineType. Возражений против такого не имею.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 16 Март, 2022 00:47 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 514
Откуда: Украина, Днепропетровская обл.
Заинтересованы ли Вы в улучшении совместимости бэк-энда в Си с BlackBox? Я тут заметил, что у нас сломалась (или не работала) компиляция некоторых модулей с рекурсивным определением типов.

Прикладываю эти модули, которые компилируются в BlackBox, но в Мульти-Обероне (бэк-энд в Си) их стоит проверить. Хорошо бы также проверить их компилируемость сишкой.

Когда Вы зайдёте в тупик при определении типа, который ссылается сам на себя, вроде:

Код:
TYPE
  Arr = ARRAY 2 OF POINTER TO Arr;

То я предлагаю в случае определения такого типа подменять тип указателя на самого себя (что не соберётся сишкой) на void*, а потом при разыменовании приводить к нужному типу (для чего детектить тип на присутствие тега RecursiveType):

OPV.design
Код:
-      ELSE OPM.Write(Deref); expr(n^.left, designPrec)
+      ELSE
+         OPM.Write(Deref);
+         IF (n^.typ^.strobj # NIL) & (n^.typ^.strobj^.linkadr = RecursiveType) THEN
+            OPM.Write("("); OPC.Ident(n^.typ^.strobj); OPM.WriteString("*)")
+         END;
+         expr(n^.left, designPrec)

Если рекурсивное определение не слишком дикое (тип массив имеет элементы типа запись, где поля являются массивами этого же типа), то в рекурсивном определении в кольце обязательно есть указатель. И если его нельзя описать в Си через самого себя, то тут сам просится void*. Мне это решение кажется даже в чём-то изящным. Хотя может я что-то упустил.

Дмитрий Викторович, только Вы можете навести в этом порядок. Я конечно пробую, но у меня получается пока не очень — неуклюже и корявенько. Буду пробовать ещё.


Вложения:
Recursive.zip [1.43 КБ]
Скачиваний: 98
Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 17 Март, 2022 20:07 

Зарегистрирован: Вторник, 01 Март, 2011 09:34
Сообщения: 582
Откуда: Москва
Понятно, буду смотреть ещё.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 18 Март, 2022 19:31 

Зарегистрирован: Вторник, 01 Март, 2011 09:34
Сообщения: 582
Откуда: Москва
Oleg N. Cher писал(а):
Прикладываю эти модули, которые компилируются в BlackBox, но в Мульти-Обероне (бэк-энд в Си) их стоит проверить. Хорошо бы также проверить их компилируемость сишкой.

Докладываю. Собираются с успешной компиляцией Ex, Ex3, Ex4, Ex7. Не собираются Ex2, Ex5, Ex6, Ex8. Я в один код все объединил.
Код:
      (* Ex.cp + *)
      REx1Rec = RECORD END;
      REx1Ptr = POINTER TO ARRAY OF REx1Rec;
      (* Ex2.cp - *)
      REx2Ptr = POINTER TO ARRAY 3 OF POINTER TO ARRAY 4 OF BOOLEAN;
      (* Ex3.cp + *)
      REx3ArrPtr = POINTER TO REx3Arr;
      REx3Arr = ARRAY 2,3 OF REx3ArrPtr;
      (* Ex4.cp + *)
      REx4ArrPtr = POINTER TO REx4Arr;
      REx4Arr = ARRAY OF REx4ArrPtr;
      (* Ex5.cp - *)
      REx5Arr = ARRAY 2 OF POINTER TO REx5Arr;
      (* Ex6.cp - *)
      REx6ArrPtr = POINTER TO ARRAY OF REx6ArrPtr;
      (* Ex7.cp + *)
      REx7Elem = POINTER TO RECORD
         next: REx7Elem;
         pos: INTEGER;
      END;
      REx7CaseTable = ARRAY 1 OF
           RECORD
            low, high: INTEGER
         END;
      (* Ex8.cp - *)
      REx8Rec0 * = RECORD
      END;
      REx8Arr0 = ARRAY 4 OF REx8Rec0;

   PROCEDURE RExRun;
      VAR a: REx3Arr; p: REx3ArrPtr;
         (*a5: REx5Arr; p5: POINTER TO REx5Arr;*)
   BEGIN
      a := p^;
   END RExRun;
   
   PROCEDURE (VAR r: REx8Rec0) Ex (VAR a: REx8Arr0), NEW;
   BEGIN
   END Ex;

Тесты хорошие. Надо думать над устранением.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 23 Март, 2022 08:32 

Зарегистрирован: Вторник, 01 Март, 2011 09:34
Сообщения: 582
Откуда: Москва
Устранено Ex6. Процедура OmfOPC.DefineType. Старый код закомментирован с пометкой [Ex6].
Код:
            IF obj # NIL THEN (* check for cycles *)
               IF obj^.linkadr = PROCESSING_TYPE THEN
                  IF (str^.form # fPOINTER) OR (str.base_typ.strobj = NIL) (*[Ex6] str^.form # fPOINTER*) THEN
                     obj^.linkadr := RECURSIVE_TYPE
                  END
               ELSE obj^.linkadr := PROCESSING_TYPE
               END
            END ;


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 01 Апрель, 2022 00:16 

Зарегистрирован: Вторник, 22 Май, 2007 15:38
Сообщения: 219
Откуда: Питер
Следующая ошибка.

Код:
MODULE Test;

TYPE
  Rec0 * = RECORD
  END;
  Arr0 = ARRAY 4 OF Rec0;

PROCEDURE (VAR r:Rec0) Ex * (VAR a:Arr0), NEW;
  BEGIN
  END Ex;

END Test.
(этот модуль отличается от предыдущего ошибочного модуля только тем, что процедура Rec0.Ex экспортируется)

Код:
MODULE Main;

IMPORT
  Test;

END Main.


Транслируется в си, но затем не компилируется.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 05 Апрель, 2022 18:32 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 514
Откуда: Украина, Днепропетровская обл.
Дмитрий Дагаев писал(а):
Устранено Ex6. Процедура OmfOPC.DefineType. Старый код закомментирован с пометкой [Ex6].
Код:
IF (str^.form # fPOINTER) OR (str.base_typ.strobj = NIL) (*[Ex6] str^.form # fPOINTER*) THEN
Хорошая правка, устраняет зацикливание. Внёс в Ofront+.

Сейчас пытаюсь разобраться с Ex5 и вклинить определение рекурсивного типа в OPC.DefineType, пока не очень понятно как там всё устроено.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 27 Июнь, 2022 15:56 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 514
Откуда: Украина, Днепропетровская обл.
Торжественно сообщаю, что Ofront+ опять перешёл в статус "все критичные проблемы исправлены". На сей раз серьёзно поправлена обработка определений циклических типов, которая потребовала немало времени, чтобы с этим разобраться.

Дмитрий Викторович, мы с Вами называли такие определения рекурсивными, но по терминологии разработчиков ETH Oberon и BlackBox они называются циклическими. А рекурсивными называются определения вида:
Код:
TYPE Typ = Typ; (* error 58: recursive type definition *)

Получается, что рекурсивные определения типов не имеют смысла, а циклические согласно описания языка Компонентный Паскаль допустимы:
Цитата:
A declaration of a type T containing references to another type T1 may occur at a point where
T1 is still unknown. The declaration of T1 must follow in the same block to which T is local.
Здесь прямо не говорится о циклических определениях, но они и не запрещены.

В связи с чем я изменил константу OPC.RecursiveType на CyclicType.

Итак, сейчас Ofront+ успешно транслирует все примеры, о которых были посты выше, плюс даже такой:

Код:
MODULE Ex111;

TYPE
  Proc = PROCEDURE (b: Proc);

VAR p: Proc;

PROCEDURE Abc (b: Proc); END Abc;

BEGIN
  p := Abc
END Ex111.

А вот если результатом процедуры типа Proc будет Proc, то на таком коде Ofront+ просто выдаст ошибку "not yet implemented":
Код:
TYPE
  Proc = PROCEDURE (): Proc;
Вопрос дискуссионный, но я не знаю как это транслировать в Си. Мы обсудили это в группе по Ofront+ в Telegram и единодушно решили, что польза от этих циклических определений весьма сомнительна.

Да, циклические определения разрешены в Ofront+ только для Компонентного Паскаля.

P.S. Могу посодействовать исправлению этих моментов в МультиОбероне. Напрямую брать моё решение в лоб вряд ли нужно — в Ofront+ работа с массивами устроена несколько иначе, чем в CPfront. Но пока в моей голове свежи все эти моменты, можем заняться, если конечно есть интерес.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 27 Июнь, 2022 21:41 

Зарегистрирован: Вторник, 01 Март, 2011 09:34
Сообщения: 582
Откуда: Москва
Да, Вы правы, RecursiveType оказалось неудачным определением. Очень хорошо, что в Ofront+ эти вопросы закрыты. Циклические определения типов точно нужны, а процедуры через процедуры - экзотика.
Надо внимательно все посмотреть.


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

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 514
Откуда: Украина, Днепропетровская обл.
Реализовал поддержку типов ANYPTR и ANYREC:


Пробую собирать модуль Services из BlackBox, в котором есть такой код:

Код:
   TYPE
      Action* = POINTER TO ABSTRACT RECORD
         notBefore: LONGINT;
         next: Action   (* next element in linear list *)
      END;

   (** Action **)

   PROCEDURE (a: Action) Do- (), NEW, ABSTRACT;

Может ли кто-нибудь объяснить этот модификатор Do- ?


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

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2444
Откуда: Россия, Томск
Oleg N. Cher писал(а):
Код:
   TYPE
      Action* = POINTER TO ABSTRACT RECORD
         notBefore: LONGINT;
         next: Action   (* next element in linear list *)
      END;

   (** Action **)

   PROCEDURE (a: Action) Do- (), NEW, ABSTRACT;

Может ли кто-нибудь объяснить этот модификатор Do- ?

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

Ни в каком другом модуле нельзя написать "VAR a: Services.Action; BEGIN a.Do();", будет ошибка компиляции.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 22 Март, 2023 16:31 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 514
Откуда: Украина, Днепропетровская обл.
Коллеги, я вынужден сделать пост уже в "своей" теме. Не в продолжение срачика, а в защиту своего кода. Может arisu и запудрил кое-кому мозги, кто не в теме, но в BlackBox нет AST анализатора. Так что моё решение вполне корректно. Оно корректно не "в общем", не в "идеальной рабочей среде, где может быть всё", а в конкретно взятом OP2, где много кода, работающего с mnolev и vis подобным образом. Сделайте поиск в Dev по "mnolev := -128".

Переменную r/o для цикла FOR я внедрил в диалект О3. Там есть ещё одно решение, предложенное Олегом Комлевым, до которого не додумался arisu. Это требование для переменной цикла быть как можно наиболее локальной. Это нужно, чтобы предотвратить использование в качестве счётчика цикла глобальной переменной. Т.е.:


Вложения:
photo_2023-03-16_23-08-41.jpg
photo_2023-03-16_23-08-41.jpg [ 33.38 КБ | Просмотров: 1446 ]
Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 22 Март, 2023 18:19 

Зарегистрирован: Вторник, 01 Март, 2011 09:34
Сообщения: 582
Откуда: Москва
Вполне разумное решение. К тому же ясно сформировано: для чего сделано, что сделано и как.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 10 Апрель, 2023 05:41 

Зарегистрирован: Вторник, 22 Май, 2007 15:38
Сообщения: 219
Откуда: Питер
Ещё одна ошибка при трансляции данного модуля в си:
Ex.cp translating Ex
6:28 err 200 not yet implemented

Код:
MODULE Ex;

TYPE
  Arr = ARRAY 4 OF LONGINT;

PROCEDURE ExProc ( z: ARRAY 4 OF LONGINT );
BEGIN
END ExProc;

END Ex.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 10 Апрель, 2023 16:51 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 514
Откуда: Украина, Днепропетровская обл.
Давненько Вы ошибок не постили :?
Данная ошибка присутствует в оригинальном Ofront, но исправлена в CPfront.
Есть фикс.

P. S. А вообще для Оберона-2 это даже и не ошибка, потому что такое объявление параметра не будет совместимо ни с чем, поэтому ничего удивительного нет в том, что Йозеф Темпл не реализовал такое. Это один из спорных моментов КП, где строгость проверки совместимости массивов ослаблена. Непонятно зачем. Структурное совпадение массивов не обязательно обозначает необходимость их совместимости. Меня лично не напрягает объявить их для совместимости вместе под одним алиасом.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 27 Апрель, 2023 06:29 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 514
Откуда: Украина, Днепропетровская обл.
GameHunter, а в чём высокий смысл? Всё равно ведь использовать это некак.
(разве что через SYSTEM.THISARRAY)


Вложения:
TestArr.png
TestArr.png [ 36.97 КБ | Просмотров: 501 ]
Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 01 Май, 2023 00:16 

Зарегистрирован: Вторник, 22 Май, 2007 15:38
Сообщения: 219
Откуда: Питер
В нижеприведённом модуле намеренно сделана ошибка: индекс массива выходит за его пределы. По умолчанию включена проверка индексов. Однако, программа завершается, ничего не выводя на экран. А если отключить проверку индексов параметром -x, то, как и ожидалось, выводится 'Finish'.
Вопрос: это проверка индекса глючит, или она работает втихую? В последнем случае надо бы как-нибудь сообщать об этом...
Код:
MODULE Ex;

IMPORT
  C:=Console;

PROCEDURE TestCheckIndex ();
  VAR
    x:ARRAY 3 OF LONGINT;
    i,j:LONGINT;
  BEGIN
    i:=4;
    j:=x[i]
  END TestCheckIndex;

BEGIN
  TestCheckIndex();
  C.String('Finish'); C.Ln; C.Flush;
END Ex.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 01 Май, 2023 02:51 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 514
Откуда: Украина, Днепропетровская обл.
Проверка индекса не глючит. Втихую - было решено, чтобы простая программа не тянула за собой сам принцип консольного вывода, поэтому по умолчанию программа только возвращает в ОС код ошибки. Чтобы получить консольное сообщение, сделайте хотя бы из одного модуля IMPORT Kernel


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

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


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

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


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

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