OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Пятница, 18 Сентябрь, 2020 11:20

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




Начать новую тему Ответить на тему  [ Сообщений: 172 ]  На страницу Пред.  1 ... 4, 5, 6, 7, 8, 9  След.
Автор Сообщение
СообщениеДобавлено: Среда, 08 Январь, 2020 01:09 

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

Код:
MODULE Ex;

TYPE
  Rec = RECORD
  END;
  Ptr = POINTER TO ARRAY OF Rec;

END Ex.

компилируется Ofront+'ом, но затем происходит ошибка компиляции .c-файла.


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

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 407
Откуда: Украина, Днепропетровская обл.
Эта проблема не так уж тривиальна, как может показаться на первый взгляд. По итогу пришлось пересмотреть логику работы с анонимными записями и массивами. Добавлено довольно много кода, тестирование произвёл, но только самое поверхностное.

Пробуйте.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 09 Январь, 2020 01:39 

Зарегистрирован: Вторник, 22 Май, 2007 15:38
Сообщения: 176
Откуда: Питер
Теперь проблема с таким модулем:

Код:
MODULE Ex;

TYPE
  Ptr = POINTER TO ARRAY 3 OF POINTER TO ARRAY 4 OF BOOLEAN;

END Ex.


Симптомы те же: файл успешно транслируется в c, но дальнейшая компиляция выдаёт ошибку.


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

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

Код:
MODULE Ex;

TYPE
  Rec = RECORD END;
  Ptr = POINTER TO ARRAY OF Rec;

END Ex.

/* Ofront */

typedef
   struct Ex_Rec {
      char _prvt0[1];
   } Ex_Rec;

typedef
   struct {
      LONGINT len[1];
      Ex_Rec data[1];
   } *Ex_Ptr;

/*  CPfront */

typedef
   struct Ex_Rec {
      char _prvt0[1];
   } Ex_Rec;

typedef
   struct Ex_Rec_ARRAY *Ex_Ptr;


#ifndef Ex_Rec_ARRAY_DEF
#define Ex_Rec_ARRAY_DEF
typedef struct Ex_Rec_ARRAY {
   INTEGER gc[3], len[1];
   Ex_Rec data[1];
} Ex_Rec_ARRAY;
#endif

Код:
MODULE Ex2;

TYPE
  Ptr = POINTER TO ARRAY 3 OF POINTER TO ARRAY 4 OF BOOLEAN;

END Ex2.

/*  Ofront */

typedef
   BOOLEAN (*(*Ex2_Ptr)[3])[4];

/*  CPfront */

typedef
   struct Ex2__3 (*(*Ex2_Ptr);


typedef struct Ex2__1 {
   INTEGER gc[3];
   BOOLEAN data[4];
} Ex2__1;

typedef struct Ex2__3 {
   INTEGER gc[3];
   struct Ex2__1 (*data[3]);
} Ex2__3;

Так что исследования продолжаю, но склоняюсь больше к Ofront'овскому варианту. Правда, предполагаю, что какая-то из фич КП требует такого усложнения, возможно, это абстрактные записи.

Вообще должен заметить, что при вроде бы незначительном усложнении между Обероном-2 и КП, сложность кода компилятора значительно возрастает — реализация КП требует примерно в два раза больше кода.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 12 Январь, 2020 01:10 
Аватара пользователя

Зарегистрирован: Суббота, 16 Февраль, 2008 02:47
Сообщения: 300
Oleg N. Cher писал(а):
Вообще должен заметить, что при вроде бы незначительном усложнении между Обероном-2 и КП, сложность кода компилятора значительно возрастает — реализация КП требует примерно в два раза больше кода.

А расскажите подробнее, пожалуйста


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 12 Январь, 2020 17:29 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 407
Откуда: Украина, Днепропетровская обл.
Очень много кода требуется для поддержки взаимодействий между типами CHAR и SHORTCHAR. Также очень много кода требуется для атрибутов записей и методов. Чуть меньше кода идёт для поддержки объявлений типов не подряд, т.е. чтобы можно было объявить элемент записи типа запись, но описанную позже. Ещё горсть кода на IN/OUT-параметры. Функции типа BITS требуют мало кода. Ну а всё вместе получается сильно сложнее, чем традиционный OP2 для Оберона-2.

А, в принципе, поддержка кодогенерации в натив требует ещё на порядки больше кода.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 12 Январь, 2020 22:24 
Аватара пользователя

Зарегистрирован: Суббота, 16 Февраль, 2008 02:47
Сообщения: 300
СПасибо, очень любопытно.

Поддержка атрибутов записей - я полагаю, это все в разделе проверки типов?

Цитата:
поддержка кодогенерации в натив требует ещё на порядки больше кода.

А почему так, собсно? Казалось бы, абстрактное синтаксическое дерево практически идентичное?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 13 Январь, 2020 02:38 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 407
Откуда: Украина, Днепропетровская обл.
Я забыл ещё про поддержку конкатенации. Она тоже требует очень много кода. Например, когда у нас есть вызов типа WriteStr(str1 + str2), компилятору надо заводить неявную промежуточную переменную.

Так что стремление к простоте а-ля Оберон-07 даже как-то оправдано. Хотя писать на КП на порядок приятнее.

adimetrius писал(а):
Поддержка атрибутов записей - я полагаю, это все в разделе проверки типов?
Ну да, во фронт-энде.

adimetrius писал(а):
А почему так, собсно? Казалось бы, абстрактное синтаксическое дерево практически идентичное?
При генерации машинного кода больше нюансов надо учитывать. А генерация оптимизированного машкода ещё в несколько раз сложнее.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 13 Январь, 2020 18:10 

Зарегистрирован: Вторник, 22 Май, 2007 15:38
Сообщения: 176
Откуда: Питер
Цитата:
При генерации машинного кода больше нюансов надо учитывать. А генерация оптимизированного машкода ещё в несколько раз сложнее.

А разве это не забота бэкенд-компилятора C?


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

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

Ну как, нет идей, почему CPfront так транслирует?

Поговорить бы с его доработчиками (OMinc) по поводу деталей, да, боюсь, они сами уже всё забыли.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 13 Январь, 2020 21:34 

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 23 Январь, 2020 21:43 

Зарегистрирован: Вторник, 22 Май, 2007 15:38
Сообщения: 176
Откуда: Питер
Код:
MODULE Ex;

IMPORT
  S:=SYSTEM;

PROCEDURE ValToArr (VAR x:REAL): POINTER [notag] TO ARRAY 1 OF REAL;
  BEGIN
    RETURN S.VAL(S.PTR,S.ADR(x))
  END ValToArr;

END Ex.


Этот модуль успешно транслируется в си, но при компилировании .c-файла происходит ошибка


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 26 Январь, 2020 09:14 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 407
Откуда: Украина, Днепропетровская обл.
Интересно. Этот баг есть и в CPfront'е. Вот что генерит:
Код:
static struct Ex__1 (*Ex_ValToArr (REAL *x);

  ...

static struct Ex__1 (*Ex_ValToArr (REAL *x)
{
  ...
}

BlackBox это компилирует, только меняем notag на untagged (Ofront+ поддерживает untagged и notag как синонимы; последнее несовместимо с ББ, но более коротко. Идея взята из ETH Oberon).

Дмитрий Викторович, как будем чинить?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 26 Январь, 2020 11:35 

Зарегистрирован: Вторник, 01 Март, 2011 09:34
Сообщения: 482
Откуда: Москва
Frontend в используемой версии МультиОберона предполагаем для указателя sys-флаги untagged, handle, interface, som. На флаг POINTER [notag] TO выдается ошибка "illegal sys flag".
Если все-таки POINTER [untagged] TO, то да, баг, закрывающая скобочка теряется. Если что накопаю, напишу.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 26 Январь, 2020 12:30 

Зарегистрирован: Вторник, 01 Март, 2011 09:34
Сообщения: 482
Откуда: Москва
Лишняя скобка убирается модификацией процедуры Stars в OPC: добавлением дополнительного параметра forproc, если генерация запускается для процедуры - из ProcHeader (или определения процедуры - из DefineTProcMacros). В Stars код меняется на
Код:
IF openClause THEN
   IF ~forproc THEN OPG.Write(OPEN_PAREN) END;
   openClause := FALSE
END ;

Но надо прогнать еще регрессионные тесты, чтобы не поломать что-нибудь.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 28 Январь, 2020 13:44 

Зарегистрирован: Вторник, 01 Март, 2011 09:34
Сообщения: 482
Откуда: Москва
Тесты прошли для исправленного кода
Код:
   PROCEDURE ValToArr (VAR x: REAL): POINTER TO ARRAY [untagged] 1 OF REAL;
   BEGIN
      RETURN SYSTEM.VAL(SYSTEM.PTR, SYSTEM.ADR(x))
   END ValToArr;

Изменения только в процедуре Stars и в ее вызовах (если, скажем, вставлять в Ofront+).


Вложения:
OmfOPC.txt [51.26 КБ]
Скачиваний: 95
Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 29 Январь, 2020 18:55 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 407
Откуда: Украина, Днепропетровская обл.
Благодарю за предложенный фикс, Дмитрий Викторович. Хорошая аналитическая работа.
Напрашиваются такие вопросы/предложения:

1. Если менять местами порядок в условии:
IF (typ^.comp # CF_RECORD) & ((typ^.strobj = NIL) OR (typ^.strobj^.name^ = "")) THEN
тогда хорошо бы и это:
WHILE ((typ^.strobj = NIL) OR (typ.strobj.name^ = "")) & (typ^.form = fPOINTER) DO
изменить на:
WHILE (typ^.form = fPOINTER) & ((typ^.strobj = NIL) OR (typ.strobj.name^ = "")) DO
Просто для единообразия.

2. До сих пор не понял, зачем Вы вставили вызов Stars в ветку:
ELSIF typ^.form = fPROC_TYP THEN Stars(typ.base_typ, forproc, openClause);
Он делает какую-то дополнительную работу?

3. ELSIF typ.form = fPOINTER THEN тоже спорно, хотя ладно.

4. Переменную forproc я назвал forProc, для единостильности с openClause.

5. Что призвана делать добавленная Вами проверка ASSERT в ветке IF typ^.comp # CF_DYN_ARRAY ?

Ещё интересно про регрессионные тесты. Я много раз обдумывал вопрос тестирования Ofront'а+. Что именно представляют из себя подобные тесты у Вас? Это просто набор исходников на КП, который Вы транслируете в Си и убеждаетесь, что Си-файл потом компилируется? А если он породит при этом некорректный машинный код? Ведь убедиться в этом всё равно не так просто. Или эти тесты у Вас устроены как-то по-другому?

У меня нет набора тестов. Я больше по наитию программирую. И практика показала, что своих ошибок в Ofront+ я вношу меньше, чем правлю имеющихся ошибок, унаследованных от предыдущих авторов.

P.S. По поводу моих копирайтов в МультиОбероне. Мне конечно лестно, но, ей-богу, не стоило. В этом было бы больше смысла, если бы Вы брали в работу мои правки к CPfront, но их у Вас не так много. Так что если уберёте, я не обижусь.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 29 Январь, 2020 21:48 

Зарегистрирован: Вторник, 01 Март, 2011 09:34
Сообщения: 482
Откуда: Москва
Oleg N. Cher писал(а):
1. Если менять местами порядок в условии:
IF (typ^.comp # CF_RECORD) & ((typ^.strobj = NIL) OR (typ^.strobj^.name^ = "")) THEN
тогда хорошо бы и это:
WHILE ((typ^.strobj = NIL) OR (typ.strobj.name^ = "")) & (typ^.form = fPOINTER) DO
изменить на:
WHILE (typ^.form = fPOINTER) & ((typ^.strobj = NIL) OR (typ.strobj.name^ = "")) DO
Просто для единообразия.

2. До сих пор не понял, зачем Вы вставили вызов Stars в ветку:
ELSIF typ^.form = fPROC_TYP THEN Stars(typ.base_typ, forproc, openClause);
Он делает какую-то дополнительную работу?

3. ELSIF typ.form = fPOINTER THEN тоже спорно, хотя ладно.

Я не помню, чтобы менял осознанно вызов Stars ранее (может, и ошибаюсь), видимо, версии у нас разошлись. Можно выяснять почему. Я в данном случае вставлял только forproc.

Oleg N. Cher писал(а):
4. Переменную forproc я назвал forProc, для единостильности с openClause.

В мультиобероне я как-то решил, что для глобальных переменных удобнее запись верблюдом (stdDir). И для понятности переименовал многие переменные. Поэтому openClause должно стать open_clause.

Oleg N. Cher писал(а):
Ещё интересно про регрессионные тесты. Я много раз обдумывал вопрос тестирования Ofront'а+. Что именно представляют из себя подобные тесты у Вас? Это просто набор исходников на КП, который Вы транслируете в Си и убеждаетесь, что Си-файл потом компилируется? А если он породит при этом некорректный машинный код? Ведь убедиться в этом всё равно не так просто. Или эти тесты у Вас устроены как-то по-другому?

У меня нет набора тестов. Я больше по наитию программирую. И практика показала, что своих ошибок в Ofront+ я вношу меньше, чем правлю имеющихся ошибок, унаследованных от предыдущих авторов.

Для компилятора Test-Driven-Development полезно. У меня есть набор тестов >400, которые используются. Они в скомпилированном виде прогоняются для всех Omb, Omf, Oml. В принципе, можно и опубликовать, наверное ...

Oleg N. Cher писал(а):
P.S. По поводу моих копирайтов в МультиОбероне. Мне конечно лестно, но, ей-богу, не стоило. В этом было бы больше смысла, если бы Вы брали в работу мои правки к CPfront, но их у Вас не так много. Так что если уберёте, я не обижусь.

Но таковые есть. И будут еще. А указывать на авторство источника, - это честно. Плюс уважение, если хотите.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 30 Январь, 2020 00:09 
Аватара пользователя

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

Дмитрий Дагаев писал(а):
Я не помню, чтобы менял осознанно вызов Stars ранее (может, и ошибаюсь), видимо, версии у нас разошлись. Можно выяснять почему. Я в данном случае вставлял только forproc.
Изменения, которые делали именно Вы, там точно присутствуют. Достаточно сравнить Stars с оригинальным исходником. Будет интересно узнать причины.

Дмитрий Дагаев писал(а):
Для компилятора Test-Driven-Development полезно. У меня есть набор тестов >400, которые используются. Они в скомпилированном виде прогоняются для всех Omb, Omf, Oml. В принципе, можно и опубликовать, наверное ...
Не просто можно, а даже нужно. Это будет уместно опубликовать прямо в репозитории, пусть всё вместе лежит.

GameHunter'у спасибо за активное использование Ofront'а+ :-)


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 30 Январь, 2020 01:03 

Зарегистрирован: Вторник, 22 Май, 2007 15:38
Сообщения: 176
Откуда: Питер
Код:
MODULE Ex;

TYPE
  ArrPtr = POINTER TO Arr;
  Arr = ARRAY 2,3 OF ArrPtr;

END Ex.

Этот модуль компилируется в ББ, но Ofront+ выдаёт ошибку


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 172 ]  На страницу Пред.  1 ... 4, 5, 6, 7, 8, 9  След.

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


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

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


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

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