[prev] [up] [next]

JavaScript Compiler and Interpreter

Overview

This framework provides a JavaScript language parser and bytecode compiler, which uses the underlying Smalltalk bytecode and dynamic machine code interpreter. This results in a JavaScript implementation with excellent performance.

Syntax

The standard JavaScript syntax is supported:

Semantic Differences

Some tradeoffs had to be made, in order to avoid confusion, when interfacing/mixing JavaScript and Smalltalk code.
The biggest differences are:

1-based array indexing

In order to allow reuse of the rich collection protocol without numerous index confusions, and to allow for transparent use of either Smalltalk or JavaScript code in a method's implementation, this JavaScript uses 1-based array indexing.
This means, that in contrast to other JavaScript systems (which use 0-based indexing), an array's first element has an index of 1. The array's last element has the index "array.size".

Class based object model

JavaScript as provided by current browsers implement an object model which is instance and array based. Slots may be dynamically added in order to add methods (function slots).
The ST/X JavaScript implementation uses the existing Smalltalk object model.

Special Features

Access to the full Smalltalk environment

All of Smalltalk's classes can be accessed by global names and their message protocol. This includes a classes class-protocol.
Thus, it is possible to write:
openWindow() {
    var view, panel, button;
    function closeView() { view.destroy(); };

    view = new StandardSystemView;
    view.width (100);
    view.height (100);
    view.add( panel = new VerticalPanelView );

    button = new Button;
    button.label("Press me");
    button.action( closeView );

    panel.add( button );

    view.open();
}
the full metaclass protocol is accessible. Therefore, instead of:
    ...
    view = new StandardSystemView;
    ...
you can also write:
    ...
    view = StandardSystemView.new();
    ...

Inner Functions (Closures)

Inner functions are supported and mapped onto the block mechanism of Smalltalk. These inner functions have access to and close over variables as visible by scoping rules (i.e. they are closures). Closures can be passed around as argument, returned from a function or stored into other objects.
The following example demonstrates this:
fooMethod() {
    var pre = "from within: ";

    function outputEach(val){
	Transcript.show(pre);
	Transcript.showCR( val);
    };

    var lines = [
		    "hello world" ,
		    "these are some" ,
		    "messages" ,
		    "from" ,
		    "a javaScript" ,
		    "method." ,
		];

    lines.do( outputEach );
}
of course, inner functions can also be used in an expression, as in:
fooMethod() {
    var lines = [
		    "hello world" ,
		    "these are some" ,
		    "messages" ,
		    "from" ,
		    "a javaScript" ,
		    "method." ,
		];

    lines.do( function(val) { Transcript.showCR( val); }; );
}
As we use 1-based indexing, an explicit loop would look like:
fooMethod() {
    var lines = [
		    "hello world" ,
		    "these are some" ,
		    "messages" ,
		    "from" ,
		    "a javaScript" ,
		    "method." ,
		];

    for (var i = 1; i <= lines.size(); i++) {
	Transcript.showCR( lines[i] );
    }
}

Another typical use of inner functions is as a sort criteria:
fooMethod() {
    function outputEach(val) {
	Transcript.showCR( val);
    };

    function sortFunction(line1, line2) {
	return line1.asLowercase() < line2.asLowercase();
    }

    var lines, sortedLines;

    lines = [
		    "hello world" ,
		    "these are some" ,
		    "messages" ,
		    "from" ,
		    "a javaScript" ,
		    "method." ,
	    ];

    sortedLines = lines.sort(sortFunction);

    sortedLines.do( outputEach );
}

Usage

JavaScript can be used as an embedded scripting language or as implementation language in the browser.
It is also used by the remote scripting service.

The standAlone smalltalk-to-c compiler (stc) does not support JavaScript syntax. This will be made available in the future as a non-free addOn.

Debugging

The Smalltalk debugger handles both Smalltalk and JavaScript code transparently. This includes access to local variables, single stepping etc.
For example, try single stepping after the "halt" in:
squaresMethod() {
    halt();
    for (var i = 1; i <= 10; i++) {
	Transcript.show( i );
	Transcript.show( " " );
	Transcript.show( i*i );
	Transcript.cr;
    }
}

Examples

To be added.

No Warranty

This goody is provided AS-IS without any warranty whatsoever.

Origin/Authors


Claus Gittinger


Copyright © 2005 eXept Software AG

<info@exept.de>

Doc $Revision: 1.12 $