LINUX.ORG.RU

Система генерации кода

 


0

1

Допустим, мне нужно написать кроссплатформенную программу. Но кроме кроссплатформенности, она должна уметь «стыковаться» с любой из N библиотек (и под Linux, и под Windows). Ко всем этим N библиотекам можно написать что-то вроде wrapper'а (со своим API), чтобы сам код основного модуля не зависел от backend'а. Но изобретать велосипед в виде нового API - довольно накладно.

И я задумался - в каких случаях имеет смысл вместо wrapper'а писать генератор кода (подставляющий вызовы библиотек на этапе компиляции приложения)? Что лёгкое посоветуете почитать по генерации кода? (мне хотелось бы задавать алгоритм основного модуля каким-нибудь псевдокодом). Например:

Если координата x юнита меньше единицы, то сделать x равным единице.
Если координата y юнита меньше единицы, то сделать y равным единице.
Если координата x юнита больше 64, то сделать x равным 64.
Если координата y юнита больше 64, то сделать y равным 64.

Перемещено mono из talks

★★★★★

ИМХО решение проблемы неверное, зачем изобретать еще один кроссплатформенный язык недообщего назначения?

Но почитать по этой теме можно любую книгу по компиляторам, скорее всего хватит первых глав по лексике (из текста выделяешь «объекты» лексемы: имена команд, цисла и т.д.) и синтаксису (из потока лесем выделяешь что-то значащие последовательности: какие-то конструкции языка, вызовы функций и т.д.). Если к этому моменту не надосет, дальше прочитаешь про семантику и генерацию выходного кода.

staseg ★★★★★
()
Ответ на: комментарий от staseg

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

Это я изучал в 1996-1997 году. Сейчас мне интересна практика, вроде этой: http://citforum.ru/programming/theory/serebryakov/9.shtml

Думаю, с какого hello-world попробовать начать. (у меня отдельный каталог под это есть, что-то вроде ~/Projects/HelloWorlds/)

pacify ★★★★★
() автор топика
Ответ на: комментарий от pacify

Если ты это дело уже изучал, не понимаю, какие вопросы по «практике». Практика — это генерация в какой-то конкретный язык (напрямую или с помощью библиотек). Например можно транслировать в ассемблер, с или LLVM. Если ты все уже изучил, построить синтаксическое дерево можешь. Берешь простую задачу оттранслировать условие:

(if cond expr1 expr2).

в

if(cond){expr1}else{expr2}

По первому языку строишь синтаксическое дерево <IF> -> COND;EXPR1;EXPR2. Теперь генерация, т.е. проход по синтаксическому дереву. Делаем вид, что семантика условий в лиспе и си одинакова, поэтому натравливаем генератор прямо на это дерево, получаем выходную строку.

В общем случае упрощенно процесс трансляции одного языка в другой выглядит так: входной язык -> его дерево -> дерево выходного языка -> выходной язык. Построить синтаксическое дерево довольно легко. Собственно сгенерировать выходные данные по имеющемуся дереву тоже легко. Самое сложное — адекватно преобразовать одно дерево в другое, на этом этапе нужно знать семантику двух языков и верно преобразовывать «команды» одного в «команды» другого.

staseg ★★★★★
()
Ответ на: комментарий от staseg

и верно преобразовывать «команды» одного в «команды» другого.

В общем, в любом случае, лучше начать с wrapper'а. Чтобы изучить «команды» библиотек, и их нестыковки с общим API.

Спасибо за помощь в обдумывании.

pacify ★★★★★
() автор топика
Ответ на: комментарий от AiFiLTr0

У меня получалось так:

#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
...
#elif defined(__linux__)
...
#endif
Впрочем, это всё костыли.

pacify ★★★★★
() автор топика

Похоже на программирование на естественном языке. Я бы сам, с удовольствием, что-нибудь умное про это почитал. Судя по тому, что я видел в интернете, «нормальные программисты» от такого псевдокода срут кирпичами.

Nebuchadnezzar ★★★★
()
Ответ на: комментарий от pacify

Впрочем, это всё костыли.

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

gh0stwizard ★★★★★
()
Ответ на: комментарий от Nebuchadnezzar

Это разве читаемо?

В лучшем случае получится КОБОЛ по-русски.

В худшем:

D равно квадратному корню из разности квадрата b и учетверённого произведения a и c;
x равно разности D и b, делённая на удвоенное a;

Ну и работа со структурами:

x равно полю length поля item элемента 3 поля elements переменной form

monk ★★★★★
()
Ответ на: комментарий от Nebuchadnezzar

программирование на естественном языке

Не практично. Как, например, математические обозначения никто не пытается адаптировать к естественному языку.

quantum-troll ★★★★★
()
Ответ на: комментарий от ados

эта надпись должна быть у всех рядом с ником pacify, несмотря на то, что наверное чел умный, на лоре он только троллит.

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

У него был заоблачный гуру.

Ну и ТСа разумеется стоит всячески наказать за выбор ветки форума.

aedeph_ ★★
()
Последнее исправление: aedeph_ (всего исправлений: 1)
Ответ на: комментарий от monk

Ну, не словом единым, разумеется. Хорошо, если бы математические объекты можно было налепить как в маткаде, циклы и ветвления задать блок-схемами, химические формулы изобразить в виде рисунков, если в программе выполняется модуляция, то форму сигнала нарисовать на графике и т.д. Насчёт программирования на русском языке я ничего не говорю, на мой взгляд лучше писать на английском.

Nebuchadnezzar ★★★★
()
Ответ на: комментарий от ados

А я не уверен. Мне кажется, ОП на самом деле...

dmfd
()

И что за lisp такой?

Кстати, ведь всякие cffi, bordeaux-threads и прочее и представляют из себя обычные обертки над средствами реализации. Почему этим ребятам ещё не пришло в голову использовать КОДОГЕНЕРАЦИЮ?

onanij
()
Ответ на: комментарий от onanij

то не писав обертку ничё не сделаешь.

Идея именно в отсуствии обёртки - вместо функций-оберток встраивать вызовы в код напрямую. Типа гибко управляемых #defines.

pacify ★★★★★
() автор топика

Если координата x юнита меньше единицы, то сделать x равным единице. Если координата y юнита меньше единицы, то сделать y равным единице. Если координата x юнита больше 64, то сделать x равным 64. Если координата y юнита больше 64, то сделать y равным 64.

Этаж кобол!

anonymous
()
Ответ на: комментарий от pacify

У тебя по-любому будет некий слой клея, который будет между библиотеками и прогой, не так ли? И какая разница, как его реализовать. Нагенерировать можно что-нибудь вроде CLOS-оберток вокруг виджетов в какой-нибудь GUI библиотеки. А как ты будешь генерировать любые обертки?

Если надо будет в конкретном случае, напишешь макросы, которые сгенерируют нужные функции, и опишешь всё в декларативной манере.

onanij
()
Ответ на: комментарий от onanij

и опишешь всё в декларативной манере.

Надо будет пробовать. Может быть да, получатся сишные #defines.

pacify ★★★★★
() автор топика

словарь для библиотек (и собственных библиотек адаптеров) + интерпретатор из книжки по компиляторам.

anonymous
()

Я курсовик (расчётный) писал на лиспе. В итоге генерился tex. Преподша прослышала про это и попросила принести. Про языки, отличные от паскаля она не слышала. В общем я посидел часок и замутил в качестве вывода паскаль (не поленился даже в граф. режиме всё сделать). В итоге получилась программа, которая компилялась, чего-то спрашивала и чего-то выводила.

ziemin ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.