Мета-программирование: писать на одном языке X, кросс-компилировать на нескольких языках, таких как C #, PHP, Java, C - PullRequest
17 голосов
/ 16 марта 2011

Во всех проектах, которые я выполнял в течение многих лет, я никогда не сталкивался с таким требованием, хотя на бумаге это выглядит так просто: написать плагин для многих известных CMS.

Очевидно, что каждая плагин-система (или система расширения) отличается, и для этого требуется специальный код моста через шаблон адаптера.Но ядро ​​должно быть написано один раз.Я не ожидаю, что пользователи WordPress будут использовать мост PHP-Java, и я не ожидаю, что пользователи DotNetNuke будут использовать мост .NET-Native (хотя это проще представить).

То, как я это вижу,ядро должно быть компилируемым в трех основных областях, охватывающих большинство систем CMS:

  • нативный, промежуточный язык может быть C или C ++.Target можно использовать в качестве расширения PHP.
  • MSIL / CIL для языков на основе .NET
  • Java-байт-код для систем на основе Java

C # и Java очень хорошо переводятдруг от друга, но C и C # намного сложнее.В конечном счете, было бы неплохо добавить другие цели, чтобы не заставлять пользователя WordPress или WikiMedia устанавливать расширение перед использованием плагина.

Я уверен, что это также придумало и другие.Какой распространенный способ решения таких проблем?Должен ли я сначала определить DSL и использовать DMS или аналогичный для преобразования?Другие варианты?

Ответы [ 5 ]

15 голосов
/ 16 марта 2011

Haxe - это разновидность метаязыка, который компилируется для разных платформ:

4 голосов
/ 16 марта 2011

Поскольку нет единого языка, который компилируется непосредственно для всех ваших целей, не забывайте о наименьшем общем знаменателе.Вы можете создать свой плагин, используя C, а затем обернуть результат для каждой платформы (PInvoke, JNI, расширение PHP).Если вам не нравится идея написания сложного плагина на C, подумайте о том, чтобы сделать тяжелую работу, используя небольшой, простой в использовании и встраиваемый язык сценариев. Луа кажется разумным.В результате вы получите скелет Си, который просто делегирует запросы и ответы хосту и сценариям.

Преобразование программы связано, хотя усилия по созданию эффективного преобразования значительны.Теоретически, вы можете преобразовать исходный код в исходный и использовать платформенный компилятор.Взгляните на TXL и Stratego / XT , чтобы понять, что происходит.

3 голосов
/ 21 марта 2011

Я отвечаю за DMS , о чем, я думаю, вы упоминаете в своем вопросе.

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

Сложные проблемы проявляются, когда семантический разрыв между языком спецификации отличается для каждого изцели.(Наиболее распространенные генераторы многоцелевого кода, с которыми я сталкивался, как правило, создают для выходных языков одного типа, что позволяет избежать этой проблемы).

Один из способов сделать это - написать отдельный переводчик для каждого выводаязык.Это работает за счет большой работы.Другой способ сделать это - перевести язык спецификации в промежуточный язык / представление / домен, в котором были обработаны большинство проблем перевода (например, абстрактный процедурный язык), а затем построить переводчики из промежуточного домена в отдельные цели,Это, как правило, намного проще.Если у вас есть реальное разнообразие целей, вы можете обнаружить, что некоторые цели имеют некоторые общие черты, но не с другими;в этом случае вам нужны несколько промежуточных представлений, по одному для каждого набора общностей.

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

То, что мне нравится, и причина, по которой я построил DMS (а другие создали TXL и Stratego), заключается в использовании преобразований от источника к источнику , потому что таким образом вы можете записатьсопоставление вашего языка ввода с вашим языком вывода в качестве правил, которые вы можете проверить, которые по существу не зависят от основного механизма преобразования;Это большая победа, если вы собираетесь написать множество правил, что особенно часто происходит, когда вы ориентируетесь на несколько языков.Механизмы преобразования имеют еще одно важное преимущество по сравнению с генераторами кода, которые просто разбрызгивают текст: вы можете обработать вывод одного этапа транслятора, применив больше преобразований.Это означает, что вы можете оптимизировать код, вы можете создавать более простые правила (потому что вы можете использовать цепочку правил вместо одного вычисления, представляющего перекрестный продукт, который всегда большой и сложный), и вы можете выполнять перевод через несколько уровней промежуточных доменов.

Теперь, еще одна причина, по которой я построил DMS, - это четкое разделение каждого из «доменов» (входные спецификации, выходные домены, промежуточные домены).Вы (и преобразования) НИКОГДА не путаетесь с тем, что представляет собой структура.Stratgo и TXL ИМХО тут бредят;они манипулируют только «одним» представлением за раз.Если вы переводите между двумя обозначениями A и B, вы должны установить (IMHO screwball) «объединенный» домен, содержащий в себе как A, так и B.И вам нужно как-то беспокоиться, если у вас есть фрагмент синтаксиса "+" в обоих A и B, означает ли "+" "+" в домене A или "+" в домене B.Если вы не можете сказать, как вы узнаете, какие преобразования применить к нему?

Идея усовершенствования нескольких доменов и использования преобразований для этого, увы, не моя.Они были предложены Джеймсом Соседями ( * источник термина "анализ области") в 1980-х годах для его системы Draco .Но я стою на плечах гигантов.DMS наследует доменные концепции соседей и трансформационные основы.Разница в том, что DMS предназначен для масштабирования, произвольных доменов (DSL, а также текущих языков программирования; у него есть предопределенные модули языка для C ++, C #, Java, JavaScript, ...) и для проведения глубокого анализа для поддержки преобразований.

1 голос
/ 16 марта 2011

fantom компилируется в java и .net clr
Я не использовал его, просто видел, как он появился в списке рассылки в прошлом месяце.

0 голосов
/ 21 марта 2011

Я был только в проекте, который использовал метаязык, который компилируется как в Java, так и в C. Он использовал java-подобный синтаксис и моделировал функциональность класса в C (а часть C очень сильно зависела от макросов для " Преобразуйте "часть кода".

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

...