OberonCore
https://forum.oberoncore.ru/

Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x86
https://forum.oberoncore.ru/viewtopic.php?f=30&t=6344
Страница 7 из 17

Автор:  GameHunter [ Среда, 08 Январь, 2020 01:09 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

Вот такой модуль

Код:
MODULE Ex;

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

END Ex.

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

Автор:  Oleg N. Cher [ Среда, 08 Январь, 2020 21:10 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

Эта проблема не так уж тривиальна, как может показаться на первый взгляд. По итогу пришлось пересмотреть логику работы с анонимными записями и массивами. Добавлено довольно много кода, тестирование произвёл, но только самое поверхностное.

Пробуйте.

Автор:  GameHunter [ Четверг, 09 Январь, 2020 01:39 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

Теперь проблема с таким модулем:

Код:
MODULE Ex;

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

END Ex.


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

Автор:  Oleg N. Cher [ Суббота, 11 Январь, 2020 20:54 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

Эту проблему я поправил, но, честно говоря, сам зашёл в тупик. С анонимными записями/массивами был вариант "сделать как в 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 и КП, сложность кода компилятора значительно возрастает — реализация КП требует примерно в два раза больше кода.

Автор:  adimetrius [ Воскресенье, 12 Январь, 2020 01:10 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

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

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

Автор:  Oleg N. Cher [ Воскресенье, 12 Январь, 2020 17:29 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

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

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

Автор:  adimetrius [ Воскресенье, 12 Январь, 2020 22:24 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

СПасибо, очень любопытно.

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

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

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

Автор:  Oleg N. Cher [ Понедельник, 13 Январь, 2020 02:38 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

Я забыл ещё про поддержку конкатенации. Она тоже требует очень много кода. Например, когда у нас есть вызов типа WriteStr(str1 + str2), компилятору надо заводить неявную промежуточную переменную.

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

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

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

Автор:  GameHunter [ Понедельник, 13 Январь, 2020 18:10 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

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

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

Автор:  Oleg N. Cher [ Понедельник, 13 Январь, 2020 21:10 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

А. Ну, при трансляции в Си, конечно да.

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

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

Автор:  GameHunter [ Понедельник, 13 Январь, 2020 21:34 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

Идей нет. Делайте как проще.

Автор:  GameHunter [ Четверг, 23 Январь, 2020 21:43 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

Код:
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-файла происходит ошибка

Автор:  Oleg N. Cher [ Воскресенье, 26 Январь, 2020 09:14 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

Интересно. Этот баг есть и в 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 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

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

Автор:  Дмитрий Дагаев [ Воскресенье, 26 Январь, 2020 12:30 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

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

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

Автор:  Дмитрий Дагаев [ Вторник, 28 Январь, 2020 13:44 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

Тесты прошли для исправленного кода
Код:
   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 КБ]
Скачиваний: 252

Автор:  Oleg N. Cher [ Среда, 29 Январь, 2020 18:55 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

Благодарю за предложенный фикс, Дмитрий Викторович. Хорошая аналитическая работа.
Напрашиваются такие вопросы/предложения:

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 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

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, но их у Вас не так много. Так что если уберёте, я не обижусь.

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

Автор:  Oleg N. Cher [ Четверг, 30 Январь, 2020 00:09 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

Ну что же. Спасибо Дмитрию Викторовичу за грамотный фикс, я беру его в работу. Вот коммит.

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

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

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

Автор:  GameHunter [ Четверг, 30 Январь, 2020 01:03 ]
Заголовок сообщения:  Re: Ofront+: транслятор Оберон-языков в Си для ARM, x64 и x8

Код:
MODULE Ex;

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

END Ex.

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

Страница 7 из 17 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/