Hi! This blog is for news, announcements and questions regarding the
Mascara JavaScript compiler.

See also:
The online demo
Download latest release

Contact:
olav@olav.dk

Disclaimer:
ECMAScript is a trademark of Ecma International.

Powered by Squarespace
Sunday
Jun152008

Version 0.1.8 released

Download. The new release has much improved verification of prototypes.

But why use prototypes at all, you may ask, when we now have true classes and inheritance?
Two reasons:
1) You may have legacy code or third-part libraries which relies on prototype inheritance.
2) You may actually like prototypes. Not everyone thinks that classes are the holy grail, and prototype-based inheritance has its own subversive charm.

Whatever the reason, Mascara now supports prototype-based inheritance. There is however some limitations compared to how you can use it in ordinary JavaScript.
You can assign directly to the prototype on a class:

String.prototype.shuffle = function() {...}

However, you cannot assign to a variable expression:

var cls = String;
cls.prototype.shuffle = function(){...} <-- ERROR!

This will generate a compile-time error, since a variable may change, and therefore the type-engine cannot be completely sure what object we are assigning to.
You can however do this:

const cls = String;
cls.prototype.shuffle = function() {...}

Because a 'const' is constant, and therefore can always be resolved by the compiler. Most patterns using prototypes assign directly to the function as in the first example, however some more clever patterns are more dynamic and can sadly not be verified statically.

Another caveat:
Usually we assign to prototypes of constructor functions. But as the example with String shows, we can also assign to the prototype of a class.
However:
1) the class has to be declared as dynamic before we can modify the prototype.
2) You shouldn't do it anyway, since the interaction between class-based inheritance and prototype-based inheritance is undefined. If B extends A, and you modify B.prototype, then you may or may not change the behavior of A, depending on the phases of the moon.

I have added a new sample to the online demo, which shows an example of prototype-based inheritance. Have fun!

Saturday
Jun142008

Version 0.1.6 released

Download it here. This is basically a bug-fix release, which fixes numerous errors (but remember we are still talking alpha-quality code!). Especially error handling have been improved, both in the translator code and in the web interface. In the previous version, some types of malformed code would cause the web interface to hang rather than provide a useful error message! This should hopefully be a thing of the past. Have fun!

Tuesday
Jun102008

Mascara is not for people who hate JavaScript

Mascara is not the only project which cross-compiles to JavaScript.
If you for some reason don't like JavaScript or ECMAScript 4, these project may be more to your liking:

Google Web Toolkit - compiles Java to Javascript
Script# - compiles C# to JavaScript
HotRuby - compiles and interprets Ruby in JavaScript
CoffeePie - compiles Python to JavaScript
haXe - compiles the Haxe language to JavaScript
JSC - compiles MSIL to JavaScript
...and probably numerous others.

These projects makes totally sense if you work in a pure-Java or pure-.Net environment, and don't really want to learn a new language just because you have to to some client-side programming. Or if you simply don't like to work with JavaScript.

Mascara has a different approach, because we actually like JavaScript. The core of JavaScript is well-designed, powerful and flexible, and in many ways a more modern design than C# and Java. ECMAScript 4 is not a replacement for JavaScript, rather it is a set of powerful extensions to the base language, while still fully backwards compatible with classic JavaScript.

This means you can keep using all your existing JS-code, or gradually upgrade your code step-by-step to ES4. ES4 is actually specifically designed to allow gradual upgrade from classic JavaScript to ES4.

You can keep using your favorite JavaScript libraries like jQuery, Prototype or YUI and the immense amount of JavaScript code available on the web, while still making your own code more robust and structured by utilizing the ESMAScript 4 type verification and constructs like classes and namespaces.

JavaScript have gotten a reputation for incompatibilities across browsers. This is somewhat unfair, since JavaScript the language is quite consistent across browsers. The incompatibilties are caused by differences in the DOM and CSS implementions, which indeed are frustratingly inconsistent across browser. But that problem is not solvable at the language level, but rather at the library level, where jQuery or the alternatives will hide the browser incompatibilities for you.

So, if you like JavaScript, but want more of it, ECMAScript may be for you.

Saturday
Jun072008

Version 0.1.5 released

I have just released version 0.1.5. Download.

It includes a proof-of-concept CGI-script that allows us to serve ES4 translated on the fly. I will not recommend it for any kind of production use: Since there is no caching involved, it is rather slow and unreliable. There are also some security issues.

However, if you like to develop by alternating between writing in an editor and reloading a browser, this script will make it easy and fun.

It is used like this:

  1. Drop the root folder somewhere on your server where it can be executed, e.g. in the /cgi-bin folder. The script cgitranslate.py is the entry point, and should be made executable.

  2. Configure the setting cgi_scriptbase in config.py to point to the folder where you keep your ES4 files (e.g /testfiles)
    You should now be able to request a translation like this:
    /cgi-bin-or-whatever/cgitranslate.py?classtest.es4

    (assuming classtest.es4 is a file in the root of the configured cgi_scriptbase folder)

  3. Use it in HTML like this:
    (script
    language="text/javascript" src="/cgi/cgitranslate.py?classtest.es4")
    (/script)

    (Sorry for the parentheses, haven't figured out how to enter HTML in blogger)

The release includes the file testweb/index.html which shows how a HTML-file can use an ECMAScript 4 file.

Have fun!

Friday
Jun062008

Release 0.1.3

Today we released version 0.1.3. Download
The most important improvement is to the command-line tool. It now supports compilation and execution in one step, which makes it much more fun to use, when integrated with an text editor. Instant gratification!

You should be able to set this up as a custom tool in your favorite editor, so you can translate and then execute an open file with one click.

It works like this:
translator.py inputfile --execute

A command-line JavaScript interpreter should be configured in config.py in the root folder. As default it is configured to cscript.exe, which is the command line interface to Microsofts JScript engine. Just change the config to your favorite engine.

When receiving a runtime error from the JavaScript engine, it might not be immediately obvious which line in the source file generated the error, since the engine of course reports the position in the intermediate translated file. This is solved like this: Error messages emitted from the engine are intercepted. If an error messages contain a line numbers, these are annotated with the corresponding line number and file name for the input ES4 source file.

Eg. if the engine writes this to stderr:
runtimeerrtest.es4.translated.js(2, 1) Microsoft JScript runtime error: 'a.something' is null or not an object
Then the translator identifies the corresponding position in the source file, and adds:
[ES4 Source: runtimeerrtest.es4 line 3]

Since the output format for error messages may vary from engine to engine, you may have to configure a custom regular expression to capture messages. This is also done in config.py.

Setting it up in Eclipse
In Eclipse:

1) Run -> External tools -> Open External Tools Dialog

2) In the External Tools dialog:

  1. Create a new Launch Configuration
  2. Give it a name like "Translate ES4"
  3. Set Location to the Python interpreter. E.g. C:\Program Files\Python25\pythonw.exe
  4. Set Arguments to something like:
    path-to-mascara-root-folder\translate.py
    "${resource_loc}"
    --tempdir

    --execute
  5. Apply and Close
3) Now you should be able to translate and execute the current open file using:
Run -> External tools -> Translate ES4

The translator does not care which extension you file has, but I prefer to use .es4.

Other text editors or IDE's can be configured much the same way.

Writing to stdout
Since we are executing the script in a console context, we have a special problem: There is no standard way to write to stdout from inside JavaScript.

For your convenience, we have a standard library file that defines a write function. So you can do:

import write;
write("Hello world");

The write function is defined as native, that is, you have to provide an implementation in the host. A quick (hacky) way to do that, is to prepend the generated file with some additional code that provides an implemention of "write" that writes to stdout. This can be configured with the outfile_prelude setting in config.py.
The default configuration defines en implementation compatible with cscript.exe.

Have fun!