Oberon space

General Category => Общий раздел => Тема начата: valexey от Март 26, 2011, 09:06:01 pm

Название: Oberon-07M - Нужен ли препроцессор?
Отправлено: valexey от Март 26, 2011, 09:06:01 pm
Цитировать
Хорошо, для констант это можно обойти, но в 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, программа не найдет данную функцию.
Нужна условная компиляция, либо нужно создавать несколько вариантов модулей-держателей констант, для каждой из платформы по отдельности (ведь это мы влезаем в прямое произведение всех констант, то есть в клинических случаях таких модулей может быть МНОГО), либо генерить такие модули-держатели констант отдельной тулзой. В любом случае вводить ради всего лишь этого в язык препроцессор ни в коем разе не нужно.

Как делается условная компиляция культурно, без препроцессора, можно посмотреть в языке D и в Модуле-2.
Название: Re:Oberon-07M - Нужен ли препроцессор?
Отправлено: valexey от Март 26, 2011, 09:11:12 pm
Собственно, как сделано в Модуле можно посмотреть тут:
http://liveweb.waybackmachine.org/http://modula2.net/resources/M2R10.pdf
http://modula2.net/resources/M2R10.pdf

раздел 11.1.1

Как сделано в D можно посмотреть тут: http://www.digitalmars.com/d/2.0/version.html
Название: Re:Oberon-07M - Нужен ли препроцессор?
Отправлено: valexey от Март 26, 2011, 09:12:09 pm
Но вообще, лично я, за внешнюю тулзу которая сгенерит модули с нужными константами проанализировав текущее окружение и параметры.
Название: Re:Oberon-07M - Нужен ли препроцессор?
Отправлено: Geniepro от Март 26, 2011, 09:26:49 pm
Вот никогда не понимал, зачем нужен этот учёт разных версий винда при компиляции программы. Ведь если программу скомпилированную под WINVER >= 0x0500 запустить под WINVER < 0x0500 -- проблемы какие-то будут.
Значит программа должна при старте (а не компилятор при компиляции) выяснять версию окружения и загружать соответствующие модули.
Название: Re:Oberon-07M - Нужен ли препроцессор?
Отправлено: valexey от Март 26, 2011, 09:32:38 pm
Вот никогда не понимал, зачем нужен этот учёт разных версий винда при компиляции программы. Ведь если программу скомпилированную под WINVER >= 0x0500 запустить под WINVER < 0x0500 -- проблемы какие-то будут.
Значит программа должна при старте (а не компилятор при компиляции) выяснять версию окружения и загружать соответствующие модули.
Вай! Какая такая динамическая подгрузка модулей при статической компоновке программы?
Название: Re:Oberon-07M - Нужен ли препроцессор?
Отправлено: Geniepro от Март 26, 2011, 09:41:15 pm
Вай! Какая такая динамическая подгрузка модулей при статической компоновке программы?
А чёй-то вдруг она статическая?
Название: Re:Oberon-07M - Нужен ли препроцессор?
Отправлено: valexey от Март 26, 2011, 09:45:43 pm
Вай! Какая такая динамическая подгрузка модулей при статической компоновке программы?
А чёй-то вдруг она статическая?
А где ты увидел в Oberon-07M динамическую компоновку? Алсо она очень часто не нужна. А иногда и не возможна.
Название: Re:Oberon-07M - Нужен ли препроцессор?
Отправлено: AlexIljin от Март 26, 2011, 10:04:16 pm
Вот никогда не понимал, зачем нужен этот учёт разных версий винда при компиляции программы. Ведь если программу скомпилированную под WINVER >= 0x0500 запустить под WINVER < 0x0500 -- проблемы какие-то будут.
Значит программа должна при старте (а не компилятор при компиляции) выяснять версию окружения и загружать соответствующие модули.
ВОТ! Совершенно верно. Именно поэтому мы либо должны рассчитывать на маленькую версию винды, либо требовать большую при запуске, либо решать в процессе работы, какие фичи нам можно использовать, а какие - нет. Ни одна из этих задач не решается препроцессором. Он просто не нужен. Дополняет документацию, да, но не более того.
Название: Re:Oberon-07M - Нужен ли препроцессор?
Отправлено: valexey от Март 26, 2011, 10:46:30 pm
ВОТ! Совершенно верно. Именно поэтому мы либо должны рассчитывать на маленькую версию винды, либо требовать большую при запуске, либо решать в процессе работы, какие фичи нам можно использовать, а какие - нет. Ни одна из этих задач не решается препроцессором. Он просто не нужен. Дополняет документацию, да, но не более того.
Просто маленькой версией не обойдешься, ибо обратная совместимость часто ломается (я не обязательно винду имею ввиду, винда так, частный не интересный случай). Алсо динамической компоновки вообще говоря может не быть. Но и препроцессор в ЯЗЫКЕ не нужен. Ни в коем ни в разе. Прагмы я тоже не люблю, хотя это конечно уже лучше.
Название: Re:Oberon-07M - Нужен ли препроцессор?
Отправлено: Rifat от Март 27, 2011, 08:41:32 am
Изменять язык для препроцессора я не планирую. Я думаю, это это должна быть внешняя утилита, которая сначала обрабатывает файлы препроцессинга (допустим *.pre) и генерит на основе их ob7 файлы.

Кто что думает по поводу книги "Расширяемые программы" Горбунов-Посадов? Можно ли применить оттуда какие-нибудь идеи?
Название: Re:Oberon-07M - Нужен ли препроцессор?
Отправлено: Димыч от Март 29, 2011, 01:17:48 am
Изменять язык для препроцессора я не планирую. Я думаю, это это должна быть внешняя утилита, которая сначала обрабатывает файлы препроцессинга (допустим *.pre) и генерит на основе их ob7 файлы.

Кто что думает по поводу книги "Расширяемые программы" Горбунов-Посадов? Можно ли применить оттуда какие-нибудь идеи?
http://keldysh.ru/gorbunov/index.htm (http://keldysh.ru/gorbunov/index.htm)

У меня эта книжка на полке. Два раза читал, до применения руки не дошли, к сожалению.

Для тех, кто не в теме, попробую вкратце пояснить, в чем суть.
Для безболезненного (т.е. без модификации исходного кода) расширения программы используется механизм т.н. "гнезд", т.е. своеобразных разъемов в коде, в который можно вставлять куски кода. Причем речь идет именно о коде во время компиляции, а не о runtime. Использование гнезд позволяет перейти от переписывания кода к дописыванию того, что вставляется в гнезда и последующей сборке. Программирование становится сборочным.

Гнезда, могут использоваться не только по тексту (скажем, в отдельных процедурах или даже в модулях), но и в повторяющихся конструкциях, например, в циклах или в метках case, для чего в гнездах используется соответствующий синтаксис.

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

Идея создания гнезд в коде перекликается с точками расширения в ББ и технологией (паттерном?) inversion of control, но эта лишь малая часть из предложенного в книге. Кроме того, это отчасти похоже на обобщенное программирование, хотя подходы Ada к обобщенному программированию в книге разносятся в пух и прах.

Для меня остался нераскрытым вопрос типизации гнезд, т.е. механизм соотнесения между собой гнезда и его содержимого. Кроме того, не совсем не раскрыт вопрос вложения гнезд (в C++, насколько я знаю, вложение templates может привести к огромным накладным расходам при трансляции, поправьте, если не так).

Идея, конечно, просто просится к реализации.
Название: Re:Oberon-07M - Нужен ли препроцессор?
Отправлено: Rifat от Март 29, 2011, 05:35:07 am
Идея с гнездами конечно интересная, но думаю, что это может усложнить программирование. Допустим, я открываю какой-нибудь исходник и вижу там 10 гнезд, чтобы понять что делает исходник мне надо будет открыть каждое из этих гнезд и возможно просмотреть еще и варианты этих гнезд, чтобы убедиться, что программа будет правильно работать с различными вариантами.
Название: Re:Oberon-07M - Нужен ли препроцессор?
Отправлено: Илья Ермаков от Март 29, 2011, 07:32:39 am
У Горбунова-Посадова интересная проработка идей гнёзд, красивая, но надо понимать, что он "живёт" в рамках специфических требований, возникающих в очень ресурсоёмких вычислительных задачах.
В обычных случаях лучше решать всё это методами КОП и не откатываться назад к "модульности" на уровне исходного текста.
Название: Re:Oberon-07M - Нужен ли препроцессор?
Отправлено: Димыч от Март 29, 2011, 04:28:08 pm
Идея с гнездами конечно интересная, но думаю, что это может усложнить программирование. Допустим, я открываю какой-нибудь исходник и вижу там 10 гнезд, чтобы понять что делает исходник мне надо будет открыть каждое из этих гнезд и возможно просмотреть еще и варианты этих гнезд, чтобы убедиться, что программа будет правильно работать с различными вариантами.

Программирование становится сборочным. Важным становится не сам исходник, а "конфигурация", т.е. набор гнезд и их содержимое. На это надо смотреть в первую очередь. Только потом в исходник. Я, впрочем, соглашусь, что это усложняет (ввиду непривычности) создание программ.
Название: Re:Oberon-07M - Нужен ли препроцессор?
Отправлено: valexey от Март 29, 2011, 04:58:03 pm
Задо будет почитать. Но по описанию что тут привели -- подозрительно на шаблоны смахивает :-)
Название: Re:Oberon-07M - Нужен ли препроцессор?
Отправлено: Илья Ермаков от Март 29, 2011, 05:21:16 pm
Да нет, это вообще может быть применимо к любым текстовым документам.

Я бы даже сказал, что это технология ближе к репозиторной - версионирования.
Название: Re:Oberon-07M - Нужен ли препроцессор?
Отправлено: valexey от Март 29, 2011, 05:46:27 pm
Да нет, это вообще может быть применимо к любым текстовым документам.

Я бы даже сказал, что это технология ближе к репозиторной - версионирования.
Значит похоже на макросы какие-то :-) (не обязательно сишные)
Впрочем, в общем то шаблоны плюсов это и есть макросы (не в сишном понимании этого слова конечно же).
Название: Re:Oberon-07M - Нужен ли препроцессор?
Отправлено: Rifat от Апрель 06, 2011, 11:36:17 am
http://forum.oberoncore.ru/viewtopic.php?f=61&t=3357&p=62182#p62182 (http://forum.oberoncore.ru/viewtopic.php?f=61&t=3357&p=62182#p62182)
Название: Re:Oberon-07M - Нужен ли препроцессор?
Отправлено: valexey от Апрель 06, 2011, 02:48:36 pm
Нашел решение, которое меня устраивает. Решение дешевое и сердитое :)

Решил не делать внешний препроцессор, так как потребуется реализовывать свой парсер, обработку выражений и т.д. Зачем? Если все это уже есть в языке 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 модуль с нуля для других определенных параметров, а просто изменить параметр внутри программы, перекомпилировать программу и запустить полученную программу, которая сгенерирует выходной файл с константами.

Да, я видел такие решения на си и с++. Эдакий бутстрап. Для маленьких конкретных задачек вполне вариант. Но, к сожалению, в общем случае это не отменяет надобности в обсуждаемом тут механизме.