JSIL - .NET bytecode to JS compiler
jsil.org
jsil.org
- http://sharpkit.net/ (commercial)
- http://scriptsharp.com/ (closed compiler)
- http://www.saltarelle-compiler.com/ (open source)
https://github.com/OurSonic/OurSonicSharp/blob/master/OurSon...
maps to
https://github.com/OurSonic/OurSonicSharp/blob/master/Output...
As a bit of self promotion, if anyone is interested in helping on this project, or any other web based c# -> js game, shoot me an email dested@gmail :-)
The distinction matters for cases where you want to use huge piles of existing .NET code, sometimes written in other languages. VB.net and F# already have partial functionality in JSIL without any dedicated support, and there's a partially functional MonoGame port that only took a small amount of fiddling. You could of course manually port all that stuff over to Saltarelle-compatible C# (and get great results!) but it's a different approach.
EDIT: One other distinction is that the .NET translation approach results in broader feature support. JSIL supports features Saltarelle may never support, like pointers and structs.
- http://cs2hx.codeplex.com/ (open source)
- http://jsc.sourceforge.net/ (open source)
Functions can also have their body entirely replaced by a JavaScript expression, and it's done using an attribute so that it doesn't affect how your code runs in native .NET. This is used in parts of the runtime library and in some of the examples, like so:
[JSReplacement("document.getElementById('speed').innerHTML = $text")]
static void WriteSpeedText (string text) {
Debug.WriteLine(text);
}
You can also directly embed raw JavaScript into function bodies, like this: var a = 2;
var b = 5;
Verbatim.Expression("print($0 + $1)", a, b);
That allows you to embed particular JavaScript constructs that the compiler won't normally generate, call out to things like jQuery directly, etc. The downside to this is that you've now written something that won't run in any other .NET environment, but you can always wrap it in a JavaScript-only conditional.I thought this was a pretty cute little example game.
In my experience with coffeescript, the idea that the source is really readable is only somewhat true. Sure, you can read what's going on. But fancier features aren't always trivially translated; and even where a translation is trivial the small differences in syntax mean that in a large enough codebase it can take some time to find the corresponding source line.
Furthermore, because the code is supposedly "easy to read" that means it must be fairly close to javascript native, and that means (for instance) either a heavy abstraction (JSIL) that's probably slow, or exposing lots of unfortunate javascript quirks (coffeescript) such as 0 vs. null vs. undefined vs. false and/or => vs. ->. Basically, to reason about coffeescript you often enough need to understand in detail how it's translated to javascript; at that point you've lost any productivity gains you were hoping for but are still paying the costs in terms of poor tooling and browser integration.
If you're using javascript like assembly, treat it like that: please don't waste my time being sorta-almost-but-not-quite readable. Just make fast, robust, no-leaky-abstraction javascript, please.
Were I to start from scratch I'd probably drop the goal of producing readable JS entirely.