开发者

Meta-programming: write in one language X, cross-compile in multiple languages like C#, PHP, Java, C

开发者 https://www.devze.com 2023-02-17 10:14 出处:网络
In all projects I\'ve done through the years I never came across a requirement like this, though it seems so easy on paper: write a plugin for many well-known CMS\'s.

In all projects I've done through the years I never came across a requirement like this, though it seems so easy on paper: write a plugin for many well-known CMS's.

Obviously, each plugin-system (or extension system) is different and this requires specific bridging code through an adapter pattern. But the core should be written once. I don't expect WordPress users to use a PHP-Java bridge, and I don't expect DotNetNuke users to use a .NET-Native bridge (though that's easier conceived).

The way I see it, the core should be compilable in three main domains that cover most CMS systems:

  • native, intermediate language could be C, or C++. Target can be used as PHP extension.
  • MSIL/CIL for .NET based languages
  • Java byte code for Java based systems

C# and Java translate pretty well to and from each other, but C and C# is much harder. Ultimately, it would be nice to possibly add other targets, so as not to force a WordPress or WikiMedia user to install an extension prior to using a plugin.

I'm sure this has come up with other too. What's a common way of tackling such problems? Should I开发者_C百科 define a DSL first and use DMS or similar to transform? Other options?


Haxe is a sort of meta-language that compiles for different platforms:

  • JavaScript
  • C++
  • C#
  • HashLink
  • Java
  • Lua
  • PHP
  • Python 3
  • NekoVM
  • Flash
  • ActionScript 3


Since there's no one language that compiles directly to all of your targets, don't overlook the lowest common denominator. You could build your plug-in using C and then wrap the result for each platform (PInvoke, JNI, PHP extension). If you don't relish the idea of writing a complex plug-in in C, consider doing the heavy lifting using a small, easy-to-use, and embeddable scripting language. Lua seems reasonable. Your final result would be a C skeleton that simply delegates requests and responses to and from the host and scripts.

Program Transformation is related, though the effort to build an effective transformation is significant. In theory, you could transform from the source to source and use the platform-specific compiler. Take a look at TXL and Stratego / XT to get an idea of what's involved.


I'm the guy responsible for DMS, which is what I think you refer to in your question.

When trying to generate code for multiple target domains, you somehow have to express how to map the specification to the individual targets, no matter what machinery you use to do it.

Hard issues show up when the semantic gap between the specification language is different for each of the targets. (Most common multi-target code generators I've encountered tend to produce for the same type output languages, which sort of avoids this problem).

One way to do this is to write a separate translator for each output language. That works, at the cost of a lot of work. Another way to do it is to translate the specification language to an intermediate langauge/representation/domain in which most of the translation issues have been handled (e.g., an abstract procedural language), and then build translators from the intermediate domain to the individual targets. This tends to be a lot easier. If you have a real variety of targets, you may find that some targets have some things in common, but not with others; in this case, what you want is multiple intermediate representations, one for each set of commonalities.

All of this is orthogonol to how you actually express these translators. You can write them as classic compilers; you'll be busy for a long time. You can write them as some type of syntax-directed translation from an input specification captured as a graph ("crawl the graph an spit out text for each node") which seems pretty common (most "model driven" code generators seem to be of this type), but doing it this way doesn't offer much help beside the insight of doing it this way.

The way I like, and the reason I built DMS (and others built TXL and Stratego), is to use source-to-source transformations, because this way you can write down the mapping from your input language to your output language as rules that you can inspect that are essentially independent of the underlying transformation machinery; this is a big win if you are going to write, in effect, lots of rules, which occurs especially often when you are targeting multiple languages. Transformation engines have another major advantage over code generators that just spit text: you can process the output of one stage of the translator by applying more transformations. This means you can optimize code, you can build simpler rules (because you can use a chain of rules instead of one computation that represents the crossproduct, which is always big and hairy), and you can translate through several levels of intermediate domains.

Now, the other reason I built DMS the way I did, forces the clear separation of each of the "domains" (input spec, output domains, intermediate domains). You (and the transforms) are NEVER confused as to what a structure represents. Stratgo and TXL IMHO goofed here; they only manipulate "one" representation at time. If you are translating between two notations A and B you have to set up a (IMHO screwball) "union" domain having both A and B in it. And you have to somehow worry about, if you have a "+" piece of syntax in both A an B, whether "+" means the "+" in the A domain, or the "+" in the B domain. If you can't tell, how are you going to know which transformations to apply to it?

The idea of refining across multiple domains, and using transformations to do it, alas, aren't mine. They were proposed by James Neighbors (the source of the term "domain analysis") back in the 1980s, for his Draco system. But I get to stand on the shoulders of giants. DMS inherits Neighbors' domain concepts and transformational foundations. A difference is that DMS is designed for scale, arbitrary domains (DSLs as well as current programming langauges; it has predefined langauge modules for C++, C#, Java, JavaScript, ...), and carrying out deep analyses to support the transformations.


fantom compiles to java and .net clr
I haven't used it, just saw it come up on a mailing list last month.


I was just on a project that used a meta-language that compiled into both Java and C. It used a java-like syntax and simulated the class functionality in C (and the C portion was very heavily reliant on macros to "Convert" some of the code).

It was horrid. Being given this pile to maintain we just split it into two codebases and went from there. I know the initial company had some great people on it, but it's just too difficult a thing to do (especially since they were both compiling to embedded platforms).

0

精彩评论

暂无评论...
验证码 换一张
取 消