What kinds of patterns could I enforce on the code to make it easier to translate to another programming language? [closed]
Asked Answered
M

6

98

I am setting out to do a side project that has the goal of translating code from one programming language to another. The languages I am starting with are PHP and Python (Python to PHP should be easier to start with), but ideally I would be able to add other languages with (relative) ease. The plan is:

  • This is geared towards web development. The original and target code will be be sitting on top of frameworks (which I will also have to write). These frameworks will embrace an MVC design pattern and follow strict coding conventions. This should make translation somewhat easier.

  • I am also looking at IOC and dependency injection, as they might make the translation process easier and less error prone.

  • I'll make use of Python's parser module, which lets me fiddle with the Abstract Syntax Tree. Apparently the closest I can get with PHP is token_get_all(), which is a start.

  • From then on I can build the AST, symbol tables and control flow.

Then I believe I can start outputting code. I don't need a perfect translation. I'll still have to review the generated code and fix problems. Ideally the translator should flag problematic translations.

Before you ask "What the hell is the point of this?" The answer is... It'll be an interesting learning experience. If you have any insights on how to make this less daunting, please let me know.


EDIT:

I am more interested in knowing what kinds of patterns I could enforce on the code to make it easier to translate (ie: IoC, SOA ?) the code than how to do the translation.

Marquismarquisate answered 11/8, 2010 at 5:14 Comment(11)
Have you looked at systems like the .NET CLR or Perl6's Parrot? They compile a set of languages down to an intermediate representation which can be run by a common interpreter. If you can go back up from the intermediate representation to a language, you've got a translator.Hohenzollern
@Hohenzollern AFAIK the .NET CIL is (relatively) easy to compile into, but good luck getting readable code back from that. Looking at Parrot now.Marquismarquisate
There are similar projects for other languages; I am not sure how rich their authors are. And I am actually restraining myself a lot here, by needing a framework and adhering to strict coding conventions.Marquismarquisate
I cannot add any specific knowledge, but have you looked at pyjamas (pyjs.org), specifically translator.py? This is a python to javascript compiler.Parik
@Parik I love the name (pyjamas). Thanks for the link. I think Python made it really easy to do these translations thanks to the parser module. That's why there's a Python-to-Perl translator but not the other way around.Marquismarquisate
Have a look at phpqatools.org for some tools that allow AST and opcode based analysis of PHP code.Prism
@Marquismarquisate In response to "AFAIK the .NET CIL is (relatively) easy to compile into, but good luck getting readable code back from that." Well, this is exactly what Reflector does!Anaphylaxis
@Marquismarquisate Indeed, Reflector does a perfect job. Always remember pdbs :)Readymade
Re EDIT: If you have control over the code that will be translated, the most obvious thing to do is to avoid constructs that are hard to translate! For example, C is much easier to translate to Java if there isn't any pointer arithmetic. For Python, I'd probably stay away from closures. The other thing you can do is to write the source code in a way that more difficult parts to translate are always coded idiomatically, making them easier to recognize and to handle special cases.Bonaventure
Can't find a question here.Ophidian
write an llvm frontendWhilst
B
130

I've been building tools (DMS Software Reengineering Toolkit) to do general purpose program manipulation (with language translation being a special case) since 1995, supported by a strong team of computer scientists. DMS provides generic parsing, AST building, symbol tables, control and data flow analysis, application of translation rules, regeneration of source text with comments, etc., all parameterized by explicit definitions of computer languages.

The amount of machinery you need to do this well is vast (especially if you want to be able to do this for multiple languages in a general way), and then you need reliable parsers for languages with unreliable definitions (PHP is perfect example of this).

There's nothing wrong with you thinking about building a language-to-language translator or attempting it, but I think you'll find this a much bigger task for real languages than you expect. We have some 100 man-years invested in just DMS, and another 6-12 months in each "reliable" language definition (including the one we painfully built for PHP), much more for nasty languages such as C++. It will be a "hell of a learning experience"; it has been for us. (You might find the technical Papers section at the above website interesting to jump start that learning).

People often attempt to build some kind of generalized machinery by starting with some piece of technology with which they are familiar, that does a part of the job. (Python ASTs are great example). The good news, is that part of the job is done. The bad news is that machinery has a zillion assumptions built into it, most of which you won't discover until you try to wrestle it into doing something else. At that point you find out the machinery is wired to do what it originally does, and will really, really resist your attempt to make it do something else. (I suspect trying to get the Python AST to model PHP is going to be a lot of fun).

The reason I started to build DMS originally was to build foundations that had very few such assumptions built in. It has some that give us headaches. So far, no black holes. (The hardest part of my job over the last 15 years is to try to prevent such assumptions from creeping in).

Lots of folks also make the mistake of assuming that if they can parse (and perhaps get an AST), they are well on the way to doing something complicated. One of the hard lessons is that you need symbol tables and flow analysis to do good program analysis or transformation. ASTs are necessary but not sufficient. This is the reason that Aho&Ullman's compiler book doesn't stop at chapter 2. (The OP has this right in that he is planning to build additional machinery beyond the AST). For more on this topic, see Life After Parsing.

The remark about "I don't need a perfect translation" is troublesome. What weak translators do is convert the "easy" 80% of the code, leaving the hard 20% to do by hand. If the application you intend to convert are pretty small, and you only intend to convert it once well, then that 20% is OK. If you want to convert many applications (or even the same one with minor changes over time), this is not nice. If you attempt to convert 100K SLOC then 20% is 20,000 original lines of code that are hard to translate, understand and modify in the context of another 80,000 lines of translated program you already don't understand. That takes a huge amount of effort. At the million line level, this is simply impossible in practice. (Amazingly there are people that distrust automated tools and insist on translating million line systems by hand; that's even harder and they normally find out painfully with long time delays, high costs and often outright failure.)

What you have to shoot for to translate large-scale systems is high nineties percentage conversion rates, or it is likely that you can't complete the manual part of the translation activity.

Another key consideration is size of code to be translated. It takes a lot of energy to build a working, robust translator, even with good tools. While it seems sexy and cool to build a translator instead of simply doing a manual conversion, for small code bases (e.g., up to about 100K SLOC in our experience) the economics simply don't justify it. Nobody likes this answer, but if you really have to translate just 10K SLOC of code, you are probably better off just biting the bullet and doing it. And yes, that's painful.

I consider our tools to be extremely good (but then, I'm pretty biased). And it is still very hard to build a good translator; it takes us about 1.5-2 man-years and we know how to use our tools. The difference is that with this much machinery, we succeed considerably more often than we fail.

Bonaventure answered 11/8, 2010 at 5:14 Comment(10)
Have you ever considered contributing your "painfully built" PHP definition back to the PHP community at large, or is to too closely associated with your own revenue stream to make that feasible?Demitria
I've been asked to make everything we do "open source" by lots of folks that didn't want to contribute to a revenue stream, and didn't have the energy to do the work and open source it themselves. If you only contribute a small part to a very big project, and/or you have another source of income, "open source" seems fine. If you've done all the work yourself and its your only source of income, this is a lot less attractive. [I don't want to get into a discussion about the relative merits of "free software" philosophy, so I won't participate in any futher comments along this line]Bonaventure
I agree with what you said here, which is why I phrased the question as I did. I guess we are to intuit from that response that you feel it's too closely tied to your revenue, and there's absolutely nothing wrong with that - I just thought it worth asking.Demitria
@IraBaxter You just say common idioms about pratices related to computer that can be applied to a lot of other pratices. The only thing intersting in all you've written are the links to semanticdesigns.com (which happens to be your company)Unreality
@IraBaxter why is there a link to a press release for your company in this answer?Potentiate
@xaxxon: It provides explicit proof that I know what I'm talking about. Readers appear to approve of the answer, even if you don't.Bonaventure
It provides proof you made a web page. Why don't you provide a link to relevant source for it. That would actually be useful -- assuming it's any good.Potentiate
You often provide links to Clang-related pages in your answers. That only proves that somebody else can make a web page. Most of us assume that a well-written web page implies there is serious, real work behind and not just some fraudulent attempt to deceive the reader as you seem to imply in your answer. Do you actually believe that web page is fraudulent? The page contains reference information to "relevant" source; it is anonomized because the contract for the work required that. That I can't help.Bonaventure
@xaxxon: assuming its any good. OK, you can accuse the vision and tools of being useless ("not any good'). Or, you can decide that I am not a liar, and that the tools were used to accomplish a very hard technical reengineering task for a critical system in one of the world's most advanced aircraft. I may not be able to change your opinion. Your opinion doesn't change the facts.Bonaventure
If you want validation of the ideas in/behind DMS, you can look at some technical paper published after being reviewed by presumably unbiased researchers knowledgeable in the field. See semanticdesigns.com/Company/Publications/… and Akers, R., Baxter, I., Mehlich, M. , Ellis, B. , Luecke, K., Case Study: Re-engineering C++ Component Models Via Automatic Program Transformation, Information & Software Technology 49(3):275-291 2007. sciencedirect.com/science/article/pii/S0950584906001856Bonaventure
O
14

My answer will address the specific task of parsing Python in order to translate it to another language, and not the higher-level aspects which Ira addressed well in his answer.

In short: do not use the parser module, there's an easier way.

The ast module, available since Python 2.6 is much more suitable for your needs, since it gives you a ready-made AST to work with. I've written an article on this last year, but in short, use the parse method of ast to parse Python source code into an AST. The parser module will give you a parse tree, not an AST. Be wary of the difference.

Now, since Python's ASTs are quite detailed, given an AST the front-end job isn't terribly hard. I suppose you can have a simple prototype for some parts of the functionality ready quite quickly. However, getting to a complete solution will take more time, mainly because the semantics of the languages are different. A simple subset of the language (functions, basic types and so on) can be readily translated, but once you get into the more complex layers, you'll need heavy machinery to emulate one language's core in another. For example consider Python's generators and list comprehensions which don't exist in PHP (to my best knowledge, which is admittedly poor when PHP is involved).

To give you one final tip, consider the 2to3 tool created by the Python devs to translate Python 2 code to Python 3 code. Front-end-wise, it has most of the elements you need to translate Python to something. However, since the cores of Python 2 and 3 are similar, no emulation machinery is required there.

Oversubtlety answered 14/8, 2010 at 14:7 Comment(4)
Weeeell. 2to3 is just AST to AST. It doesn't support doing anything that goes beyond the capabilities of the ast module. Notice that all of the translations go from syntax supported by the host python process to syntax supported by the host python process. There's no translator that does adds, say, function annotations, because 2.6 doesn't support it.Esdraelon
... and the OP's question might be framed, short term, how to get from Python 2.6 AST to ... something in PHP. The ast module likely won't want to represent the PHP syntax well, so its not even ast to ast.Bonaventure
@Aaron: 2to3 can be seen as an example of using the AST generated from ast.Oversubtlety
AFAIK, 2to3 arguably is an easier translation than Python to PHP (after all, its Python to Python, right)? And even it doesn't work particularly well. Notice the large amount of Python 2.6 that hasn't been shoved through 2to3 yet... because there's apparantly a bunch of post translation hand patching that still has to be done. If were 100% automated, Python 2.6 would be dead.Bonaventure
R
4

Writing a translator isn't impossible, especially considering that Joel's Intern did it over a summer.

If you want to do one language, it's easy. If you want to do more, it's a little more difficult, but not too much. The hardest part is that, while any turing complete language can do what another turing complete language does, built-in data types can change what a language does phenomenally.

For instance:

word = 'This is not a word'
print word[::-2]

takes a lot of C++ code to duplicate (ok, well you can do it fairly short with some looping constructs, but still).

That's a bit of an aside, I guess.

Have you ever written a tokenizer/parser based on a language grammar? You'll probably want to learn how to do that if you haven't, because that's the main part of this project. What I would do is come up with a basic Turing complete syntax - something fairly similar to Python bytecode. Then you create a lexer/parser that takes a language grammar (perhaps using BNF), and based on the grammar, compiles the language into your intermediate language. Then what you'll want to do is do the reverse - create a parser from your language into target languages based on the grammar.

The most obvious problem I see is that at first you'll probably create horribly inefficient code, especially in more powerful* languages like Python.

But if you do it this way then you'll probably be able to figure out ways to optimize the output as you go along. To summarize:

  • read provided grammar
  • compile program into intermediate (but also Turing complete) syntax
  • compile intermediate program into final language (based on provided grammar)
  • ...?
  • Profit!(?)

*by powerful I mean that this takes 4 lines:

myinput = raw_input("Enter something: ")
print myinput.replace('a', 'A')
print sum(ord(c) for c in myinput)
print myinput[::-1]

Show me another language that can do something like that in 4 lines, and I'll show you a language that's as powerful as Python.

Rouble answered 18/8, 2010 at 22:43 Comment(9)
"Have you ever written a tokenizer/parser based on a language grammar? " I have done it using JavaCC.Marquismarquisate
Joel's intern did a partial job over a summer. His source language was a subset of an existing language, and presumably this subset could be adjusted somewhat. That makes the job a lot easier. Similarly, NullPointerException might want to start with the easier parts of Python, perhaps passing through the harder stuff for manual conversion (as noted in the questions).Hart
@NullUserException: You'll have some exposure, but you'll basically be doing a re-implementation of JavaCC, only instead of Java as the output language, you'll be doing <insert langauge here>. @David, quite so. Even Thistle needs some help on some of the language constructs. If I were the OP, I'd go for functional first, then optimize, otherwise I'd be stuck forever trying to get C++ to do string slicing (with steps) :pRouble
@WayneWerner For the record, languages like C# don't require newlines at all. (At least, not after you've stripped out the single-line comments.) So you could write any C# program in one line. But of course I understand what you're getting at.Wildeyed
@aboveyou00: I don't think that is right. If you disallow preprocessor conditionals, you might be right.Bonaventure
@IraBaxter (you again...) the syntax you say hard to translate is not hard to translate at all if you write it as myinput.__getitem__(Slice(None, None, -1)) or myinput.__slice__(None, None, -1). I don't understand what you find difficult.Unreality
@amirouche: You seem to be willfully misreading what is said. I merely made the point, specifically in response to aboveyou00, that C# does have preprocessor conditionals, and those conditionals require newlines, so you cannot write "any C# program" in a single line. Frankly, presence of newlines or not do not affect the fundamental difficulties of translation in any interesting way.Bonaventure
@IraBaxter it's of course not willfully at all, I'm not coming to SO to fool people around especially with my real name. The comment was meant to Wayne Werner.Unreality
@amirouche: if the comment was meant for Wayne, don't prefix it with my name. That just adds confusion. I don't understand your remark about "real name". AFAIK, only "aboveyou00" hasn't provided his real name, and I don't see how it matters in this discussion.Bonaventure
O
3

There are a couple answers telling you not to bother. Well, how helpful is that? You want to learn? You can learn. This is compilation. It just so happens that your target language isn't machine code, but another high-level language. This is done all the time.

There's a relatively easy way to get started. First, go get http://sourceforge.net/projects/lime-php/ (if you want to work in PHP) or some such and go through the example code. Next, you can write a lexical analyzer using a sequence of regular expressions and feed tokens to the parser you generate. Your semantic actions can either output code directly in another language or build up some data structure (think objects, man) that you can massage and traverse to generate output code.

You're lucky with PHP and Python because in many respects they are the same language as each other, but with different syntax. The hard part is getting over the semantic differences between the grammar forms and data structures. For example, Python has lists and dictionaries, while PHP only has assoc arrays.

The "learner" approach is to build something that works OK for a restricted subset of the language (such as only print statements, simple math, and variable assignment), and then progressively remove limitations. That's basically what the "big" guys in the field all did.

Oh, and since you don't have static types in Python, it might be best to write and rely on PHP functions like "python_add" which adds numbers, strings, or objects according to the way Python does it.

Obviously, this can get much bigger if you let it.

Ongoing answered 17/8, 2010 at 12:8 Comment(2)
Actually, I didn't say "don't bother". What I said was, "translating languages in a general ways is very hard". If the OP proceeds down his original path of using Python trees to try and generate PHP, he will learn a lot and I'm all in favor of the learning experience; I started there, too. He won't be able to add new languages easily.Bonaventure
@IraBaxter I can't support your statement, doing Python->PHP and PHP->Javascript would be kind of easy. cf. last part of https://mcmap.net/q/216872/-what-kinds-of-patterns-could-i-enforce-on-the-code-to-make-it-easier-to-translate-to-another-programming-language-closed in the middle of the answer I also deal with your "argumentation"Unreality
U
2

I will second @EliBendersky point of view regarding using ast.parse instead of parser (which I did not know about before). I also warmly recommend you to review his blog. I used ast.parse to do Python->JavaScript translator (@https://bitbucket.org/amirouche/pythonium). I've come up with Pythonium design by somewhat reviewing other implementations and trying them on my own. I forked Pythonium from https://github.com/PythonJS/PythonJS which I also started, It's actually a complete rewrite . The overall design is inspired from PyPy and http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-89-1.pdf paper.

Everything I tried, from beginning to the best solution, even if it looks like Pythonium marketing it really isn't (don't hesitate to tell me if something doesn't seem correct to the netiquette):

  • Implement Python semantic in Plain Old JavaScript using prototype inheritance: AFAIK it's impossible to implement Python multiple inheritance using JS prototype object system. I did try to do it using other tricks later (cf. getattribute). As far as I know there is no implementation of Python multiple inheritance in JavaScript, the best that exists is Single inhertance + mixins and I'm not sure they handle diamond inheritance. Kind of similar to Skulpt but without google clojure.

  • I tried with Google clojure, just like Skulpt (compiler) instead of actually reading Skulpt code #fail. Anyway because of JS prototype based object system still impossible. Creating binding was very very difficult, you need to write JavaScript and a lot of boilerplate code (cf. https://github.com/skulpt/skulpt/issues/50 where I am the ghost). At that time there was no clear way to integrate the binding in the build system. I think that Skulpt is a library and you just have to include your .py files in the html to be executed, no compilation phase required to be done by the developer.

  • Tried pyjaco (compiler) but creating bindings (calling Javascript code from Python code) was very difficult, there was too much boilerplate code to create every time. Now I think pyjaco is the one that more near Pythonium. pyjaco is written in Python (ast.parse too) but a lot is written in JavaScript and it use prototype inheritance.

I never actually succeed at running Pyjamas #fail and never tried to read the code #fail again. But in my mind PyJamas was doing API->API tranlation (or framework to framework) and not Python to JavaScript translation. The JavaScript framework consume data that is already in the page or data from the server. Python code is only "plumbing". After that I discovered that pyjamas was actually a real python->js translator.

Still I think it's possible to do API->API (or framework->framework) translation and that's basicly what I do in Pythonium but at lower level. Probably Pyjamas use the same algorithm as Pythonium...

Then I discovered brython fully written in Javascript like Skulpt, no need for compilation and lot of fluff... but written in JavaScript.

Since the initial line written in the course of this project, I knew about PyPy, even the JavaScript backend for PyPy. Yep, you can, if you find it, directly generate a Python interpreter in JavaScript from PyPy. People say, it was a disaster. I read no where why. But I think the reason is that the intermediate language they use to implement the interpreter, RPython, is a subset of Python tailored to be translated to C (and maybe asm). Ira Baxter says you always make assumptions when you build something and probably you fine tune it to be the best at what it's meant to do in the case of PyPy: Python->C translation. Those assumptions might not be relevant in another context worse they can infere overhead otherwise said direct translation will most likely always be better.

Having the interpreter written in Python sounded like a (very) good idea. But I was more interested in a compiler for performance reasons also it's actually more easy to compile Python to JavaScript than interpret it.

I started PythonJS with the idea of putting together a subset of Python that I could easily translate to JavaScript. At first I didn't even bother to implement OO system because of past experience. The subset of Python that I achieved to translate to JavaScript are:

  • function with full parameters semantic both in definition and calling. This is the part I am most proud of.
  • while/if/elif/else
  • Python types were converted to JavaScript types (there is no python types of any kind)
  • for could iterate over Javascript arrays only (for a in array)
  • Transparent access to JavaScript: if you write Array in the Python code it will be translated to Array in javascript. This is the biggest achievement in terms of usability over its competitors.
  • You can pass function defined in Python source to javascript functions. Default arguments will be taken into account.
  • It add has special function called new which is translated to JavaScript new e.g: new(Python)(1, 2, spam, "egg") is translated to "new Python(1, 2, spam, "egg").
  • "var" are automatically handled by the translator. (very nice finding from Brett (PythonJS contributor).
  • global keyword
  • closures
  • lambdas
  • list comprehensions
  • imports are supported via requirejs
  • single class inheritance + mixin via classyjs

This seems like a lot but actually very narrow compared to full blown semantic of Python. It's really JavaScript with a Python syntax.

The generated JS is perfect ie. there is no overhead, it can not be improved in terms of performance by further editing it. If you can improve the generated code, you can do it from the Python source file too. Also, the compiler did not rely on any JS tricks that you can find in .js written by http://superherojs.com/, so it's very readable.

The direct descendant of this part of PythonJS is the Pythonium Veloce mode. The full implementation can be found @ https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/veloce/veloce.py?at=master 793 SLOC + around 100 SLOC of shared code with the other translator.

An adapted version of pystones.py can be translated in Veloce mode cf. https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pystone/?at=master

After having setup basic Python->JavaScript translation I choosed another path to translate full Python to JavaScript. The way of glib doing object oriented class based code except the target language is JS so you have access to arrays, map-like objects and many other tricks and all that part was written in Python. IIRC there is no javascript code written by in Pythonium translator. Getting single inheritance is not difficult here are the difficult parts making Pythonium fully compliant with Python:

  • spam.egg in Python is always translated to getattribute(spam, "egg") I did not profile this in particular but I think that where it loose a lot of time and I'm not sure I can improve upon it with asm.js or anything else.
  • method resolution order: even with the algorithm written in Python, translating it to Python Veloce compatible code was a big endeavour.
  • getattributre: the actual getattribute resolution algorithm is kind of tricky and it still doesn't support data descriptors
  • metaclass class based: I know where to plug the code, but still...
  • last bu not least: some_callable(...) is always transalted to "call(some_callable)". AFAIK the translator doesn't use inference at all, so every time you do a call you need to check which kind of object it is to call it they way it's meant to be called.

This part is factored in https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/runtime.py?at=master It's written in Python compatible with Python Veloce.

The actual compliant translator https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/compliant.py?at=master doesn't generate JavaScript code directly and most importantly doesn't do ast->ast transformation. I tried the ast->ast thing and ast even if nicer than cst is not nice to work with even with ast.NodeTransformer and more importantly I don't need to do ast->ast.

Doing python ast to python ast in my case at least would maybe be a performance improvement since I sometime inspect the content of a block before generating the code associated with it, for instance:

  • var/global: to be able to var something I must know what I need to and not to var. Instead of generating a block tracking which variable are created in a given block and inserting it on top of the generated function block I just look for revelant variable assignation when I enter the block before actually visiting the child node to generate the associated code.
  • yield, generators have, as of yet, a special syntax in JS, so I need to know which Python function is a generator when I want to write the "var my_generator = function"

So I don't really visit each node once for each phase of the translation.

The overall process can be described as:

Python source code -> Python ast -> Python source code compatible with Veloce mode -> Python ast -> JavaScript source code

Python builtins are written in Python code (!), IIRC there is a few restrictions related to bootstraping types, but you have access to everything that can translate Pythonium in compliant mode. Have a look at https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/builtins/?at=master

Reading JS code generated from pythonium compliant can be understood but source maps will greatly help.

The valuable advice I can give you in the light of this experience are kind old farts:

  • extensively review the subject both in literature and existing projects closed source or free. When I reviewed the different existing projects I should have given it way more time and motivation.
  • ask questions! If I knew beforehand that PyPy backend was useless because of the overhead due to C/Javascript semantic mismatch. I would maybe had Pythonium idea way before 6 month ago maybe 3 years ago.
  • know what you want to do, have a target. For this project I had different objectives: pratice a bit a javascript, learn more of Python and be able to write Python code that would run in the browser (more and that below).
  • failure is experience
  • a small step is a step
  • start small
  • dream big
  • do demos
  • iterate

With Python Veloce mode only, I'm very happy! But along the way I discovered that what I was really looking for was liberating me and others from Javascript but more importantly being able to create in a comfortable way. This lead me to Scheme, DSL, Models and eventually domain specific models (cf. http://dsmforum.org/).

About what Ira Baxter response:

The estimations are not helpful at all. I took me more or less 6 month of free time for both PythonJS and Pythonium. So I can expect more from full time 6 month. I think we all know what 100 man-year in an enterprise context can mean and not mean at all...

When someone says something is hard or more often impossible, I answer that "it only takes time to find a solution for a problem that is impossible" otherwise said nothing is impossible except if it's proven impossible in this case a math proof...

If it's not proven impossible then it leaves room for imagination:

  • finding a proof proving it's impossible

and

  • If it is impossible there may be an "inferior" problem that can have a solution.

or

  • if it's not impossible, finding a solution

It's not just optimistic thinking. When I started Python->Javascript everybody was saying it was impossible. PyPy impossible. Metaclasses too hard. etc... I think that the only revolution that brings PyPy over Scheme->C paper (which is 25 years old) is some automatic JIT generation (based hints written in the RPython interpreter I think).

Most people that say that a thing is "hard" or "impossible" don't provide the reasons. C++ is hard to parse? I know that, still they are (free) C++ parser. Evil is in the detail? I know that. Saying it's impossible alone is not helpful, It's even worse than "not helpful" it's discouraging, and some people mean to discourage others. I heard about this question via https://stackoverflow.com/questions/22621164/how-to-automatically-generate-a-parser-code-to-code-translator-from-a-corpus.

What would be perfection for you? That's how you define next goal and maybe reach the overall goal.

I am more interested in knowing what kinds of patterns I could enforce on the code to make it easier to translate (ie: IoC, SOA ?) the code than how to do the translation.

I see no patterns that can not be translated from one language to another language at least in a less than perfect way. Since language to language translation is possible, you'd better aim for this first. Since, I think according to http://en.wikipedia.org/wiki/Graph_isomorphism_problem, translation between two computer languages is a tree or DAG isomorphism. Even if we already know that they are both turing complete, so...

Framework->Framework which I better visualize as API->API translation might still be something that you might keep in mind as a way to improve the generated code. E.g: Prolog as very specific syntax but still you can do Prolog like computation by describing the same graph in Python... If I was to implement a Prolog to Python translator I wouldn't implement unification in Python but in a C library and come up with a "Python syntax" that is very readable for a Pythonist. In the end, syntax is only "painting" for which we give a meaning (that's why I started scheme). Evil is in the detail of the language and I'm not talking about the syntax. The concepts that are used in the language getattribute hook (you can live without it) but required VM features like tail-recursion optimisation can be difficult to deal with. You don't care if the initial program doesn't use tail recursion and even if there is no tail recursion in the target language you can emulate it using greenlets/event loop.

For target and source languages, look for:

  • Big and specific ideas
  • Tiny and common shared ideas

From this will emerge:

  • Things that are easy to translate
  • Things that are difficult to translate

You will also probably be able to know what will be translated to fast and slow code.

There is also the question of the stdlib or any library but there is no clear answer, it depends of your goals.

Idiomatic code or readable generated code have also solutions...

Targeting a platform like PHP is much more easy than targeting browsers since you can provide C-implementation of slow and/or critical path.

Given you first project is translating Python to PHP, at least for the PHP3 subset I know of, customising veloce.py is your best bet. If you can implement veloce.py for PHP then probably you will be able to run the compliant mode... Also if you can translate PHP to the subset of PHP you can generate with php_veloce.py it means that you can translate PHP to the subset of Python that veloce.py can consume which would mean that you can translate PHP to Javascript. Just saying...

You can also have a look at those libraries:

Also you might be interested by this blog post (and comments): https://www.rfk.id.au/blog/entry/pypy-js-poc-jit/

Unreality answered 3/4, 2014 at 22:25 Comment(6)
The only thing that remains thrilling for me about one-to-one computer language to computer language translation are described in #22621664Unreality
I second the other answer about data types. In Pythonium I wasn't even planning to support a correct integer & float type in the compliant mode without asm.js.Unreality
OK, so if I give you a Python package of 100K SLOC, and you run it through your "translator", do I get a working program? How much post-translation hand-work does it take to fix it? What you said here was, "given an already existing good parser for Python that builds ASTs, I can build a partial translator in 6 months". Nobody is surprised. 6 months isn't by most people's standards "kind of easy" (quoting from another of your comments). Solving the remaining problems will require more effort. My answer said, basically "doing this isn't easy", and "doing it in a general way is hard".Bonaventure
... that last point in response to OP's original desire: "ideally I would be able to add other languages with (relative) ease.", which my answer addresses specifically.Bonaventure
I beg to disagree, especially when you know what you are doing, it's easy and what follows is not hard it's just a matter of getting things done. I'm not sure where you are dealing with anything specific to the question. You are saying in 4 or 5 paragraph that your company does it, and it's hard. But otherwise you are spreading FUD about the subject, while being kind off-topic like you are in #22621664. In full time 6 month I would have written a full translator.Unreality
@IraBaxter anwser is not answering question.Unreality
M
0

You could take a look at the Vala compiler, which translates Vala (a C#-like language) into C.

Marxismleninism answered 18/8, 2010 at 9:35 Comment(1)
It was a design goal of Vala to be translated to C and make development with gnome libraries easy.Unreality

© 2022 - 2024 — McMap. All rights reserved.