fabiosantoscode / js2cpp

A toy js -> c++ compiler written in coffeescript. Uses escodegen to write c++ and tern to figure out types.
111 stars 11 forks source link

Interesting concept and simple implementation, what if... #1

Open mcanthony opened 9 years ago

mcanthony commented 9 years ago

The subject of transpilation of arbitrary source seemed to be taboo until ecmascripten shook things up. I stumbled onto this project and wondered if I could ask your thoughts on something that has been nagging me for some time.

I am working on a project where a whole lot of algorithmic code is used. The project will be in the form of an "isomorphic" code-base which intends to be able to support its operation purely from the browser, unless a node environment is available, in which case it would leverage node in order to operate without security/performance limitations imposed by the browser.

This would operate in the same manner as a progressively enhancing UI would - except in this case it is progressively enhancing features not related to UI enhancement such as direct file-system access, and native code execution in the form of node extensions.

This is the part that I would like to use a project somewhat like this to accomplish. Here is the ideal goal and how I would intend to implement it:

Portions of the code-base in the form of loosely coupled modules dealing exclusively with algorithmic computation, or in some cases file I/O (perhaps more, I have not thought of the possibilities and what limitations may arise). Your idea of using TURN to infer and inflect types would come in handy here... Would I would like to do is be able to dynamically trans-pile eligible modules into C++ from JS without modification. I would like it if the only required step was to specify which modules and/or objects should be targeted for "progressively enhancing trans-pilation" - and the result should be such that their original interfaces are available now as if they are part of the native JSAPI, where everything would operate as normal with no further specification... The JS implementation of these modules serves as a front-line/fallback for browser based execution, and as a reference implementation for the generated equivalent node-extensions.

Perhaps this idea is too far fetched or possibly not very useful as this step could be done ahead of time... The project I have in mind is a sort of IDE, so it seemed like it would be neat if I could arbitrarily add modules to the code-base and automatically allow for native execution where possible, without a thought to hand crafting node-extensions.

Now that I have typed it out for the first time I am not sure if it would be as cool as it seemed to me before... Sorry if this is not an appropriate or preferred forum for this discussion, and don't sweat it if you don't want to get into analyzing my crazy thoughts! Any comments, advice, or harsh criticism would be welcome anyway...

fabiosantoscode commented 9 years ago

Dynamic transpilation of modules at run time doesn't seem like such a good idea. Why would you do that? By specifying some types ahead of time, one could transpile to C++ at compile time.

That said, it could be done for C through tcc, which is a tiny C compiler which provides a lib allowing you to compile some C at runtime.

My original target for js2cpp was not C++, it was C, because of my desire to use that lib.

However, this project is admittedly impossible, and although I didn't completely understand what you envision, it does seem like something at least very hard to do.

One thing I found for sure while building this project is that not all javascript can be turned into C++. Things like using the same variable name for different types just won't ever work, for example:

var x = isNaN(something) ? false : 6;

What's the type of x? Easy, it's either a number or a boolean! But how would you express that in C++?

I feel that the resistance of turning JS into C++ is much, much greater than that of turning C++ into JS. Since C++ is less dynamic, and Emscripten being on our side and all.

If you'd create compiled code for both the browser and node, I'd say, write some Rust, C, C++, Clasp, or anything that compiles to LLVM IR, and write some kind of wrapper node C++ extension which can talk to this compiled code (not sure how yet! maybe drop the extension entirely and use ffi?). In node, use native. In the browser, use emscripten.

This is where I want to go with my other crazy project, fabiosantoscode/require-emscripten. It is just some glue code that eases the process of compiling emscripten and using the compiled code. But in a later stage maybe a child project of it could be able to use both emscripten and C++ to leverage compiled code, much as I describe above.