OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 28 Март, 2024 17:44

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




Начать новую тему Ответить на тему  [ Сообщений: 12 ] 
Автор Сообщение
 Заголовок сообщения: Препроцессор для Oberon-07M
СообщениеДобавлено: Суббота, 26 Март, 2011 21:57 

Зарегистрирован: Пятница, 13 Март, 2009 16:36
Сообщения: 987
Откуда: Казань
Столкнулся с тем, что при программировании для Windows, нужны различные константы, которые описаны в h файлах, например:
#if(_WIN32_WINNT >= 0x0501)
#define WM_UNICHAR 0x0109
#define WM_KEYLAST 0x0109
#define UNICODE_NOCHAR 0xFFFF
#else
#define WM_KEYLAST 0x0108
#endif /* _WIN32_WINNT >= 0x0501 */

WM_KEYLAST может принимать значение 0x0109 или 0x0108 в зависимости от версии Window. Поэтому задумался о реализации препроцессора для Oberon-07М, один из вариантов, просто взять синтаксис команд препроцессора из языка Си и реализовать их в препроцессоре для Oberon-07М. Другой подход это не копировать из языка Си, а сделать свое, возможно, лучше, чем там. Сейчас считаю книгу "Расширяемые программы" Горбунов-Посадов и думаю на тем, можно ли использовать вариантные гнезда и как их лучше реализовать.

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Препроцессор для Oberon-07M
СообщениеДобавлено: Суббота, 26 Март, 2011 22:48 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2449
Откуда: Россия, Томск
Для WM_KEYLAST препроцессор не нужен. Вообще. То есть, совсем вообще.

WM_KEYLAST можно объявить глобальной переменной, экспортировать только для чтения, инициализировать при загрузке модуля Windows.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Препроцессор для Oberon-07M
СообщениеДобавлено: Суббота, 26 Март, 2011 23:16 

Зарегистрирован: Пятница, 13 Март, 2009 16:36
Сообщения: 987
Откуда: Казань
Хорошо, для констант это можно обойти, но в h файлах очень много разных #ifdef не только для констант, но и для структур и функций, например:
#if(WINVER >= 0x0400)
typedef struct tagMENUITEMINFOA
{
UINT cbSize;
UINT fMask;
UINT fType; // used if MIIM_TYPE (4.0) or MIIM_FTYPE (>4.0)
UINT fState; // used if MIIM_STATE
UINT wID; // used if MIIM_ID
HMENU hSubMenu; // used if MIIM_SUBMENU
HBITMAP hbmpChecked; // used if MIIM_CHECKMARKS
HBITMAP hbmpUnchecked; // used if MIIM_CHECKMARKS
ULONG_PTR dwItemData; // used if MIIM_DATA
LPSTR dwTypeData; // used if MIIM_TYPE (4.0) or MIIM_STRING (>4.0)
UINT cch; // used if MIIM_TYPE (4.0) or MIIM_STRING (>4.0)
#if(WINVER >= 0x0500)
HBITMAP hbmpItem; // used if MIIM_BITMAP
#endif /* WINVER >= 0x0500 */
} MENUITEMINFOA, FAR *LPMENUITEMINFOA;

Здесь в зависимости от версии Windows запись содержит или не содержит одно поле.
Кроме того, некоторые функции объявлены только для новых версий Windows, и может получиться так, что программист будет расчитывать, что данная функция есть, раз она описана, а при запуске программы на более старой Windows, программа не найдет данную функцию.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Препроцессор для Oberon-07M
СообщениеДобавлено: Воскресенье, 27 Март, 2011 00:06 

Зарегистрирован: Вторник, 25 Апрель, 2006 16:21
Сообщения: 2180
Откуда: Нижний Новгород
http://oberspace.dyndns.org/index.php?topic=46.0


Последний раз редактировалось Alexey Veselovsky Суббота, 17 Сентябрь, 2011 15:50, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Препроцессор для Oberon-07M
СообщениеДобавлено: Понедельник, 28 Март, 2011 22:01 

Зарегистрирован: Вторник, 22 Май, 2007 15:38
Сообщения: 220
Откуда: Питер
В XDS'е я использую препроцессор для правильного выбора импортируемых модулей в зависимости от описания типа:

Код:
MODULE MyMath;

<* IF Float="REAL" THEN *>
  IMPORT
    FMath:=RealMath;
  TYPE
    Float * = REAL;

<* ELSIF Float="LONGREAL" THEN *>
  IMPORT
    FMath:=LongMath;
  TYPE
    Float * = LONGREAL;
<* ELSE *>
  'ERROR: equation Float is not defined
<* END *>

PROCEDURE sqrt * (x:Float): Float;
  BEGIN
      RETURN FMath.sqrt(x)
  END sqrt;

END MyMath.

Насколько я знаю, в рамках Оберона эта проблема (возможно не единственная) не решается.

В свете этого вопрос - может сначала обсудить задачи, которые препроцессор должен решать?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Препроцессор для Oberon-07M
СообщениеДобавлено: Понедельник, 28 Март, 2011 22:09 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
GameHunter писал(а):
Насколько я знаю, в рамках Оберона эта проблема (возможно не единственная) не решается.
Вы какой Оберон имеете в виду? И на чём у Вас пример?

Если говорить про исходное определение Оберона, то эта проблема там решаться и не должна.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Препроцессор для Oberon-07M
СообщениеДобавлено: Вторник, 29 Март, 2011 10:07 

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

Цитата:
Если говорить про исходное определение Оберона, то эта проблема там решаться и не должна.
Возможно. Но как-то она решаться должна? Вот, при помощи препроцессора.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Препроцессор для Oberon-07M
СообщениеДобавлено: Вторник, 29 Март, 2011 10:11 

Зарегистрирован: Пятница, 13 Март, 2009 16:36
Сообщения: 987
Откуда: Казань
Согласен с тем, что в языке не надо делать изменений для препроцессора. Препроцессор - это отдельная утилита, которая будет обрабатывать файлы перед компиляцией. Потребность в препроцессоре возникла в связи с тем, что для того, чтобы написать какое-нибудь приложение под Windows, необходимо использовать WinApi функции, структуры, константы, которые определены в h файлах, но там очень часто используются директивы препроцессора. Делать различные версии файлов для различных вариантов переменных практически не возможно, так как таких вариантов очень много, поэтому необходим аналогичный инструмент. В принципе можно скопировать препроцессор один в один, можно сделать его проще, а можно сделать что-нибудь новое, что будет позволять делать то же самое, но можно будет использовать и для чего-нибудь другого.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Препроцессор для Oberon-07M
СообщениеДобавлено: Вторник, 29 Март, 2011 10:40 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
Rifat писал(а):
Согласен с тем, что в языке не надо делать изменений для препроцессора. ... В принципе можно скопировать препроцессор один в один, можно сделать его проще, а можно сделать что-нибудь новое, что будет позволять делать то же самое, но можно будет использовать и для чего-нибудь другого.
С этим я согласен полностью: препроцессор --- это один способов решить конкретно-насущные проблемы, порожденные спецификой решения этих задач при помощи препроцессора в Си-языках. Здесь: windows.h. Однако это не означает, что эти решения самые лучшие и должны тащиться всюду.

Непосредственно к ЯП Оберон эти проблемы отношения не имеют. Т.е. решаться средствами языка не должны.
---
Примеры других способов:
1) Портируемость, котрую любят в Си решать препроцессором, решается выделением "железозависимых" мест в отдельные модули. Которые для Оберон-систем можно заменять во время зарузки (или выполнения).
2) DevSelectors в BlackBox --- "нестандартный" аналог препроцессора. Помогает решать проблемы перевода сишных заголовоков.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Препроцессор для Oberon-07M
СообщениеДобавлено: Среда, 06 Апрель, 2011 13:20 

Зарегистрирован: Пятница, 13 Март, 2009 16:36
Сообщения: 987
Откуда: Казань
Нашел решение, которое меня устраивает. Решение дешевое и сердитое :)

Решил не делать внешний препроцессор, так как потребуется реализовывать свой парсер, обработку выражений и т.д. Зачем? Если все это уже есть в языке Oberon-07. Можно написать программу, которая будет генерировать модуль WinApi для различных параметров. Программа выглядит примерно так:
Код:
MODULE WinApiPre;

  IMPORT Out, p := PreProc;

  PROCEDURE Do*;
  BEGIN
    Out.WriteLn('MODULE WinApi;');
    Out.WriteLn('');
    Out.WriteLn('  CONST');
    ...
    Out.WriteLn('    WM_RBUTTONUP* = 0205H;');
    Out.WriteLn('    WM_RBUTTONDBLCLK* = 0206H;');
    Out.WriteLn('    WM_MBUTTONDOWN* = 0207H;');
    Out.WriteLn('    WM_MBUTTONUP* = 0208H;');
    Out.WriteLn('    WM_MBUTTONDBLCLK* = 0209H;');
    IF p.IntGeq(p.Find("_WIN32_WINNT"), 0400H) OR p.IntGeq(p.Find("_WIN32_WINDOWS"), 0400H) THEN
      Out.WriteLn('    WM_MOUSEWHEEL* = 020AH;');
    END;
    IF p.IntGeq(p.Find("_WIN32_WINNT"), 0500H) THEN
      Out.WriteLn('    WM_XBUTTONDOWN* = 020BH;');
      Out.WriteLn('    WM_XBUTTONUP* = 020CH;');
      Out.WriteLn('    WM_XBUTTONDBLCLK* = 020DH;');
    END;
    IF p.IntGeq(p.Find("_WIN32_WINNT"), 0600H) THEN
      Out.WriteLn('    WM_MOUSEHWHEEL* = 020EH;');
    END;
    IF p.IntGeq(p.Find("_WIN32_WINNT"), 0600H) THEN
      Out.WriteLn('    WM_MOUSELAST* = 020EH;');
    ELSIF p.IntGeq(p.Find("_WIN32_WINNT"), 0500H) THEN
      Out.WriteLn('    WM_MOUSELAST* = 020DH;');
    ELSIF p.IntGeq(p.Find("_WIN32_WINNT"), 0400H) OR p.IntGeq(p.Find("_WIN32_WINDOWS"), 0400H) THEN
      Out.WriteLn('    WM_MOUSELAST* = 020AH;');
    ELSE
      Out.WriteLn('    WM_MOUSELAST* = 0209H;');
    END;
    Out.WriteLn('    WM_PARENTNOTIFY* = 0210H;');
    Out.WriteLn('    WM_ENTERMENULOOP* = 0211H;');
    Out.WriteLn('    WM_EXITMENULOOP* = 0212H;');
    ...
    Out.WriteLn('');
    Out.WriteLn('END WinApi.');
  END Do;

END WinApiPre.

Параметры также задаются в модуле написанном на Oberon-07, внешний файл параметров не стал делать, так как потребуется его парсить.

Думаю, что гененировать модуль WinApi потребуется не очень часто, например, раз в пол года, и это решение вполне подходит для этого. При этом не потребуется создавать WinApi модуль с нуля для других определенных параметров, а просто изменить параметр внутри программы, перекомпилировать программу и запустить полученную программу, которая сгенерирует выходной файл с константами.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Препроцессор для Oberon-07M
СообщениеДобавлено: Среда, 06 Апрель, 2011 13:59 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
Rifat писал(а):
Решил не делать внешний препроцессор.... Можно написать программу, которая будет генерировать модуль WinApi для различных параметров.
Поддерживаю. Именно так и надо: решать возникающие задачи как можно более простым способом, не оглядываясь на то, как и чем эти задачи решаются у других.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Препроцессор для Oberon-07M
СообщениеДобавлено: Среда, 06 Апрель, 2011 15:26 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Rifat писал(а):
Нашел решение, которое меня устраивает. Решение дешевое и сердитое :)
Тут главное -- мозг правильно настроить :)

Евгений Эдуардович проницательно покритиковал чуть ранее инерцию мышления насчет препроцессора.

Привычные шаблоны трудно из головы выковыривать.
Но надо. Иначе какой прогресс :)


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 12 ] 

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


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

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


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

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