Browse Source

Retab boot.js

Nicolas Petton 12 years ago
parent
commit
67402a6042
1 changed files with 417 additions and 417 deletions
  1. 417 417
      js/boot.js

+ 417 - 417
js/boot.js

@@ -36,13 +36,13 @@
 /* Make that console is defined */
 
 if (typeof console === "undefined") {
-    this.console = {
-	log: function() {},
-	warn: function() {},
-	info: function() {},
-	debug: function() {},
-	error: function() {}
-    };
+	this.console = {
+		log: function() {},
+		warn: function() {},
+		info: function() {},
+		debug: function() {},
+		error: function() {}
+	};
 }
 
 
@@ -53,472 +53,472 @@ function SmalltalkBehavior(){};
 function SmalltalkClass(){};
 function SmalltalkPackage(){};
 function SmalltalkMetaclass(){
-    this.meta = true;
+	this.meta = true;
 };
 function SmalltalkMethod(){};
 function SmalltalkNil(){};
 
 function Smalltalk(){
 
-    var st = this;
-
-    /* This is the current call context object. While it is publicly available,
-       Use smalltalk.getThisContext() instead which will answer a safe copy of 
-       the current context */
-
-    st.thisContext = undefined;
-
-    /* List of all reserved words in JavaScript. They may not be used as variables
-       in Smalltalk. */
-
-    st.reservedWords = ['break', 'case', 'catch', 'char', 'class', 'continue', 'debugger', 
-			'default', 'delete', 'do', 'else', 'finally', 'for', 'function', 
-			'if', 'in', 'instanceof', 'new', 'private', 'protected', 
-			'public', 'return', 'static', 'switch', 'this', 'throw',
-			'try', 'typeof', 'var', 'void', 'while', 'with', 'yield'];
-    
-    /* We hold all Packages in a separate Object */
-
-    st.packages = {};
-
-    /* Smalltalk package creation. To add a Package, use smalltalk.addPackage() */
-
-    function pkg(spec) {
-	var that      = new SmalltalkPackage();
-	that.pkgName  = spec.pkgName;
-	that.properties = spec.properties || [];
-	return that;
-    };
-
-    /* Smalltalk class creation. A class is an instance of an automatically 
-       created metaclass object. Newly created classes (not their metaclass) 
-       should be added to the smalltalk object, see smalltalk.addClass().
-       Superclass linking is *not* handled here, see smalltalk.init()  */
-
-    function klass(spec) {
-	var spec = spec || {};
-	var that;
-	if(spec.meta) {
-	    that = new SmalltalkMetaclass();
-	} else {
-	    that = new (klass({meta: true})).fn;
-	    that.klass.instanceClass = that;
-	    that.className = spec.className;
-	    that.klass.className = that.className + ' class';
-	}
-	
-	that.fn = spec.fn || function(){};
-	that.superclass = spec.superclass;
-	that.iVarNames = spec.iVarNames || [];
-	if(that.superclass) {
-	    that.klass.superclass = that.superclass.klass;
-	}
-	that.pkg = spec.pkg;
-	that.fn.prototype.methods = {};
-	that.fn.prototype.inheritedMethods = {};
-	that.fn.prototype.klass = that;
-
-	return that;
-    };
-
-    /* Smalltalk method object. To add a method to a class,
-       use smalltalk.addMethod() */
-
-    st.method = function(spec) {
-	var that = new SmalltalkMethod();
-	that.selector          = spec.selector;
-	that.jsSelector        = spec.jsSelector;
-	that.args              = spec.args || {};
-	that.category          = spec.category;
-	that.source            = spec.source;
-	that.messageSends      = spec.messageSends || [];
-	that.referencedClasses = spec.referencedClasses || [];
-	that.fn                = spec.fn;
-	return that
-    };
-
-    /* Initialize a class in its class hierarchy. Handle both class and
-       metaclasses. */
-
-    st.init = function(klass) {
-	var subclasses = st.subclasses(klass);
-	var methods;
-
-	if(klass.superclass && klass.superclass !== nil) {
-	    methods = st.methods(klass.superclass);
-
-	    //Methods linking
-	    for(var i in methods) {
-		if(!klass.fn.prototype.methods[i]) {
-		    klass.fn.prototype.inheritedMethods[i] = methods[i];
-		    klass.fn.prototype[methods[i].jsSelector] = methods[i].fn;
+	var st = this;
+
+	/* This is the current call context object. While it is publicly available,
+	   Use smalltalk.getThisContext() instead which will answer a safe copy of 
+	   the current context */
+
+	st.thisContext = undefined;
+
+	/* List of all reserved words in JavaScript. They may not be used as variables
+	   in Smalltalk. */
+
+	st.reservedWords = ['break', 'case', 'catch', 'char', 'class', 'continue', 'debugger', 
+		'default', 'delete', 'do', 'else', 'finally', 'for', 'function', 
+		'if', 'in', 'instanceof', 'new', 'private', 'protected', 
+		'public', 'return', 'static', 'switch', 'this', 'throw',
+		'try', 'typeof', 'var', 'void', 'while', 'with', 'yield'];
+
+	/* We hold all Packages in a separate Object */
+
+	st.packages = {};
+
+	/* Smalltalk package creation. To add a Package, use smalltalk.addPackage() */
+
+	function pkg(spec) {
+		var that      = new SmalltalkPackage();
+		that.pkgName  = spec.pkgName;
+		that.properties = spec.properties || [];
+		return that;
+	};
+
+	/* Smalltalk class creation. A class is an instance of an automatically 
+	   created metaclass object. Newly created classes (not their metaclass) 
+	   should be added to the smalltalk object, see smalltalk.addClass().
+	   Superclass linking is *not* handled here, see smalltalk.init()  */
+
+	function klass(spec) {
+		var spec = spec || {};
+		var that;
+		if(spec.meta) {
+			that = new SmalltalkMetaclass();
+		} else {
+			that = new (klass({meta: true})).fn;
+			that.klass.instanceClass = that;
+			that.className = spec.className;
+			that.klass.className = that.className + ' class';
 		}
-	    }
-	}
 
-	for(var i=0;i<subclasses.length;i++) {
-     	    st.init(subclasses[i]);
-	}
-	if(klass.klass && !klass.meta) {
-	    st.init(klass.klass);
-	}
-    };
+		that.fn = spec.fn || function(){};
+		that.superclass = spec.superclass;
+		that.iVarNames = spec.iVarNames || [];
+		if(that.superclass) {
+			that.klass.superclass = that.superclass.klass;
+		}
+		that.pkg = spec.pkg;
+		that.fn.prototype.methods = {};
+		that.fn.prototype.inheritedMethods = {};
+		that.fn.prototype.klass = that;
+
+		return that;
+	};
+
+	/* Smalltalk method object. To add a method to a class,
+	   use smalltalk.addMethod() */
+
+	st.method = function(spec) {
+		var that = new SmalltalkMethod();
+		that.selector          = spec.selector;
+		that.jsSelector        = spec.jsSelector;
+		that.args              = spec.args || {};
+		that.category          = spec.category;
+		that.source            = spec.source;
+		that.messageSends      = spec.messageSends || [];
+		that.referencedClasses = spec.referencedClasses || [];
+		that.fn                = spec.fn;
+		return that
+	};
+
+	/* Initialize a class in its class hierarchy. Handle both class and
+	   metaclasses. */
+
+	st.init = function(klass) {
+		var subclasses = st.subclasses(klass);
+		var methods;
+
+		if(klass.superclass && klass.superclass !== nil) {
+			methods = st.methods(klass.superclass);
+
+			//Methods linking
+			for(var i in methods) {
+				if(!klass.fn.prototype.methods[i]) {
+					klass.fn.prototype.inheritedMethods[i] = methods[i];
+					klass.fn.prototype[methods[i].jsSelector] = methods[i].fn;
+				}
+			}
+		}
 
-    /* Answer all registered Packages as Array */
+		for(var i=0;i<subclasses.length;i++) {
+			st.init(subclasses[i]);
+		}
+		if(klass.klass && !klass.meta) {
+			st.init(klass.klass);
+		}
+	};
 
-    st.packages.all = function() {
-	var packages = [];
-	for(var i in st.packages) {
-          if (!st.packages.hasOwnProperty(i) || typeof(st.packages[i]) === "function") continue;
-	    packages.push(st.packages[i]);
-	}
-	return packages
-    };
+	/* Answer all registered Packages as Array */
 
-    /* Answer all registered Smalltalk classes */
+	st.packages.all = function() {
+		var packages = [];
+		for(var i in st.packages) {
+			if (!st.packages.hasOwnProperty(i) || typeof(st.packages[i]) === "function") continue;
+			packages.push(st.packages[i]);
+		}
+		return packages
+	};
 
-    st.classes = function() {
-	var classes = [];
-	for(var i in st) {
-	    if(i.search(/^[A-Z]/g) != -1) {
-		classes.push(st[i]);
-	    }
-	}
-	return classes
-    };
+	/* Answer all registered Smalltalk classes */
+
+	st.classes = function() {
+		var classes = [];
+		for(var i in st) {
+			if(i.search(/^[A-Z]/g) != -1) {
+				classes.push(st[i]);
+			}
+		}
+		return classes
+	};
 
-    /* Answer all methods (included inherited ones) of klass. */
+	/* Answer all methods (included inherited ones) of klass. */
 
-    st.methods = function(klass) {
-	var methods = {};
-	for(var i in klass.fn.prototype.methods) {
-	    methods[i] = klass.fn.prototype.methods[i]
-	}
-	for(var i in klass.fn.prototype.inheritedMethods) {
-	    methods[i] = klass.fn.prototype.inheritedMethods[i]
-	}
-	return methods;
-    }
-
-    /* Answer the direct subclasses of klass. */
-
-    st.subclasses = function(klass) {
-	var subclasses = [];
-	var classes = st.classes();
-	for(var i in classes) {
-	    if(classes[i].fn) {
-		//Metaclasses
-		if(classes[i].klass && classes[i].klass.superclass === klass) {
-		    subclasses.push(classes[i].klass);
+	st.methods = function(klass) {
+		var methods = {};
+		for(var i in klass.fn.prototype.methods) {
+			methods[i] = klass.fn.prototype.methods[i]
 		}
-		//Classes
-		if(classes[i].superclass === klass) {
-		    subclasses.push(classes[i]);
+		for(var i in klass.fn.prototype.inheritedMethods) {
+			methods[i] = klass.fn.prototype.inheritedMethods[i]
 		}
-	    }
-	}
-	return subclasses;
-    };
-
-    /* Create a new class wrapping a JavaScript constructor, and add it to the 
-       global smalltalk object. Package is lazily created if it does not exist with given name. */
-
-    st.mapClassName = function(className, pkgName, fn, superclass) {
-	var pkg = st.addPackage(pkgName, null);
-	st[className] = klass({
-	    className:  className, 
-	    superclass: superclass,
-	    pkg:        pkg, 
-	    fn:         fn
-	});
-    };
-
-    /* Add a package to the smalltalk.packages object, creating a new one if needed.
-       If pkgName is null or empty we return nil, which is an allowed package for a class.
-       If package already exists we still update the properties of it. */
-
-    st.addPackage = function(pkgName, properties) {
-	if(!pkgName) {return nil;}
-	if(!(st.packages[pkgName])) {
-	    st.packages[pkgName] = pkg({
-		pkgName: pkgName,
-		properties: properties
-	    });
-	} else {
-	    if(properties) {
-		st.packages[pkgName].properties = properties;
-	    }	
-	}
-	return st.packages[pkgName];
-    };
-
-    /* Add a class to the smalltalk object, creating a new one if needed.
-       Package is lazily created if it does not exist with given name.*/
-
-    st.addClass = function(className, superclass, iVarNames, pkgName) {
-	var pkg = st.addPackage(pkgName, null);
-	if(st[className]) {
-	    st[className].superclass = superclass;
-	    st[className].iVarNames = iVarNames;
-	    st[className].pkg = pkg || st[className].pkg;
-	} else {    
-	    st[className] = klass({
-		className: className, 
-		superclass: superclass,
-		pkg: pkg,
-		iVarNames: iVarNames
-	    });
+		return methods;
 	}
-    };
 
-    /* Add a method to a class */
+	/* Answer the direct subclasses of klass. */
+
+	st.subclasses = function(klass) {
+		var subclasses = [];
+		var classes = st.classes();
+		for(var i in classes) {
+			if(classes[i].fn) {
+				//Metaclasses
+				if(classes[i].klass && classes[i].klass.superclass === klass) {
+					subclasses.push(classes[i].klass);
+				}
+				//Classes
+				if(classes[i].superclass === klass) {
+					subclasses.push(classes[i]);
+				}
+			}
+		}
+		return subclasses;
+	};
+
+	/* Create a new class wrapping a JavaScript constructor, and add it to the 
+	   global smalltalk object. Package is lazily created if it does not exist with given name. */
+
+	st.mapClassName = function(className, pkgName, fn, superclass) {
+		var pkg = st.addPackage(pkgName, null);
+		st[className] = klass({
+			className:  className, 
+			superclass: superclass,
+			pkg:        pkg, 
+			fn:         fn
+		});
+	};
+
+	/* Add a package to the smalltalk.packages object, creating a new one if needed.
+	   If pkgName is null or empty we return nil, which is an allowed package for a class.
+	   If package already exists we still update the properties of it. */
+
+	st.addPackage = function(pkgName, properties) {
+		if(!pkgName) {return nil;}
+		if(!(st.packages[pkgName])) {
+			st.packages[pkgName] = pkg({
+				pkgName: pkgName,
+				properties: properties
+			});
+		} else {
+			if(properties) {
+				st.packages[pkgName].properties = properties;
+			}	
+		}
+		return st.packages[pkgName];
+	};
+
+	/* Add a class to the smalltalk object, creating a new one if needed.
+	   Package is lazily created if it does not exist with given name.*/
+
+	st.addClass = function(className, superclass, iVarNames, pkgName) {
+		var pkg = st.addPackage(pkgName, null);
+		if(st[className]) {
+			st[className].superclass = superclass;
+			st[className].iVarNames = iVarNames;
+			st[className].pkg = pkg || st[className].pkg;
+		} else {    
+			st[className] = klass({
+				className: className, 
+				superclass: superclass,
+				pkg: pkg,
+				iVarNames: iVarNames
+			});
+		}
+	};
 
-    st.addMethod = function(jsSelector, method, klass) {
-	klass.fn.prototype[jsSelector] = method.fn;
-	klass.fn.prototype.methods[method.selector] = method;
-	method.methodClass = klass;
-	method.jsSelector = jsSelector;
-    };
+	/* Add a method to a class */
 
-    /* Handles Smalltalk message send. Automatically converts undefined to the nil object.
-       If the receiver does not understand the selector, call its #doesNotUnderstand: method */
+	st.addMethod = function(jsSelector, method, klass) {
+		klass.fn.prototype[jsSelector] = method.fn;
+		klass.fn.prototype.methods[method.selector] = method;
+		method.methodClass = klass;
+		method.jsSelector = jsSelector;
+	};
 
-    sendWithoutContext = function(receiver, selector, args, klass) {
-	if(receiver === undefined || receiver === null) {
-	    receiver = nil;
-	}
-	if(!klass && receiver.klass && receiver[selector]) {
-	    return receiver[selector].apply(receiver, args);
-	} else if(klass && klass.fn.prototype[selector]) {
-	    return klass.fn.prototype[selector].apply(receiver, args)
-	}
-	return messageNotUnderstood(receiver, selector, args);
-    };
+	/* Handles Smalltalk message send. Automatically converts undefined to the nil object.
+	   If the receiver does not understand the selector, call its #doesNotUnderstand: method */
 
+	sendWithoutContext = function(receiver, selector, args, klass) {
+		if(receiver === undefined || receiver === null) {
+			receiver = nil;
+		}
+		if(!klass && receiver.klass && receiver[selector]) {
+			return receiver[selector].apply(receiver, args);
+		} else if(klass && klass.fn.prototype[selector]) {
+			return klass.fn.prototype[selector].apply(receiver, args)
+		}
+		return messageNotUnderstood(receiver, selector, args);
+	};
 
-    /* Handles unhandled errors during message sends */
 
-    sendWithContext = function(receiver, selector, args, klass) {
-	if(st.thisContext) {
-	     return withContextSend(receiver, selector, args, klass);
-	} else {
-	    try {return withContextSend(receiver, selector, args, klass)}
-	    catch(error) {
-		// Reset the context stack in any case
-		st.thisContext = undefined;
-		if(error.smalltalkError) {
-		    handleError(error);
+	/* Handles unhandled errors during message sends */
+
+	sendWithContext = function(receiver, selector, args, klass) {
+		if(st.thisContext) {
+			return withContextSend(receiver, selector, args, klass);
 		} else {
-		    throw(error);
+			try {return withContextSend(receiver, selector, args, klass)}
+			catch(error) {
+				// Reset the context stack in any case
+				st.thisContext = undefined;
+				if(error.smalltalkError) {
+					handleError(error);
+				} else {
+					throw(error);
+				}
+			}
 		}
-	    }
-	}
-    };
+	};
 
-    /* Same as sendWithoutContext but creates a methodContext. */
+	/* Same as sendWithoutContext but creates a methodContext. */
 
-    withContextSend = function(receiver, selector, args, klass) {
-	var call, context;
-	if(receiver === undefined || receiver === null) {
-	    receiver = nil;
-	}
-	if(!klass && receiver.klass && receiver[selector]) {
-	    context = pushContext(receiver, selector, args);
-	    call = receiver[selector].apply(receiver, args);
-	    popContext(context);
-	    return call;
-	} else if(klass && klass.fn.prototype[selector]) {
-	    context = pushContext(receiver, selector, args);
-	    call = klass.fn.prototype[selector].apply(receiver, args);
-	    popContext(context);
-	    return call;
+	withContextSend = function(receiver, selector, args, klass) {
+		var call, context;
+		if(receiver === undefined || receiver === null) {
+			receiver = nil;
+		}
+		if(!klass && receiver.klass && receiver[selector]) {
+			context = pushContext(receiver, selector, args);
+			call = receiver[selector].apply(receiver, args);
+			popContext(context);
+			return call;
+		} else if(klass && klass.fn.prototype[selector]) {
+			context = pushContext(receiver, selector, args);
+			call = klass.fn.prototype[selector].apply(receiver, args);
+			popContext(context);
+			return call;
+		}
+		return messageNotUnderstood(receiver, selector, args);
+	};
+
+	/* Handles Smalltalk errors. Triggers the registered ErrorHandler 
+	   (See the Smalltalk class ErrorHandler and its subclasses */
+
+	function handleError(error) {
+		st.thisContext = undefined;
+		smalltalk.ErrorHandler._current()._handleError_(error);
 	}
-	return messageNotUnderstood(receiver, selector, args);
-    };
 
-    /* Handles Smalltalk errors. Triggers the registered ErrorHandler 
-       (See the Smalltalk class ErrorHandler and its subclasses */
-    
-    function handleError(error) {
-	st.thisContext = undefined;
-	smalltalk.ErrorHandler._current()._handleError_(error);
-    }
+	/* Handles #dnu: *and* JavaScript method calls.
+	   if the receiver has no klass, we consider it a JS object (outside of the
+	   Amber system). Else assume that the receiver understands #doesNotUnderstand: */
+
+	function messageNotUnderstood(receiver, selector, args) {
+		/* Handles JS method calls. */
+		if(receiver.klass === undefined || receiver.allowJavaScriptCalls) {
+			return callJavaScriptMethod(receiver, selector, args);
+		}
 
-    /* Handles #dnu: *and* JavaScript method calls.
-       if the receiver has no klass, we consider it a JS object (outside of the
-       Amber system). Else assume that the receiver understands #doesNotUnderstand: */
+		/* Handles not understood messages. Also see the Amber counter-part 
+		   Object>>doesNotUnderstand: */
 
-    function messageNotUnderstood(receiver, selector, args) {
-	/* Handles JS method calls. */
-	if(receiver.klass === undefined || receiver.allowJavaScriptCalls) {
-	    return callJavaScriptMethod(receiver, selector, args);
-	}
+		return receiver._doesNotUnderstand_(
+				st.Message._new()
+				._selector_(st.convertSelector(selector))
+				._arguments_(args)
+				);
+	};
 
-	/* Handles not understood messages. Also see the Amber counter-part 
-	   Object>>doesNotUnderstand: */
-	
-	return receiver._doesNotUnderstand_(
-	    st.Message._new()
-		._selector_(st.convertSelector(selector))
-		._arguments_(args)
-	);
-    };
-
-    function callJavaScriptMethod(receiver, selector, args) {
 	/* Call a method of a JS object, or answer a property if it exists.
 	   Else try wrapping a JSObjectProxy around the receiver.
- 
+
 	   Converts keyword-based selectors by using the first
 	   keyword only, but keeping all message arguments.
 
 	   Example:
 	   "self do: aBlock with: anObject" -> "self.do(aBlock, anObject)" */
 
-	var jsSelector = selector._asJavaScriptSelector();
-	var jsProperty = receiver[jsSelector];
-	if(typeof jsProperty === "function") {
-	    return jsProperty.apply(receiver, args);
-	} else if(jsProperty !== undefined) {
-	    if(args[0]) {
-		receiver[jsSelector] = args[0];
-		return nil;
-	    } else {
-		return jsProperty
-	    }
-	}
-	
-	return st.send(st.JSObjectProxy._on_(receiver), selector, args);
-    };
+	function callJavaScriptMethod(receiver, selector, args) {
+		var jsSelector = selector._asJavaScriptSelector();
+		var jsProperty = receiver[jsSelector];
+		if(typeof jsProperty === "function") {
+			return jsProperty.apply(receiver, args);
+		} else if(jsProperty !== undefined) {
+			if(args[0]) {
+				receiver[jsSelector] = args[0];
+				return nil;
+			} else {
+				return jsProperty
+			}
+		}
 
+		return st.send(st.JSObjectProxy._on_(receiver), selector, args);
+	};
 
-    /* Reuse old contexts stored in oldContexts */
 
-    st.oldContexts = [];
+	/* Reuse old contexts stored in oldContexts */
 
-	
-    /* Handle thisContext pseudo variable */
-    
-    st.getThisContext = function() {
-	if(st.thisContext) {
-	    return st.thisContext.copy();
-	} else {
-	    return undefined;
-	}
-    }
+	st.oldContexts = [];
 
-    pushContext = function(receiver, selector, temps) {
-	if(st.thisContext) {
-	    return st.thisContext = st.thisContext.newContext(receiver, selector, temps);
-	} else {
-	    return st.thisContext = new SmalltalkMethodContext(receiver, selector, temps);
-	}
-    };
 
-    popContext = function(context) {
-	if(context) {
-	    context.removeYourself();
+	/* Handle thisContext pseudo variable */
+
+	st.getThisContext = function() {
+		if(st.thisContext) {
+			return st.thisContext.copy();
+		} else {
+			return undefined;
+		}
 	}
-    };
 
-    /* Convert a string to a valid smalltalk selector.
-       if you modify the following functions, also change String>>asSelector
-       accordingly */
+	pushContext = function(receiver, selector, temps) {
+		if(st.thisContext) {
+			return st.thisContext = st.thisContext.newContext(receiver, selector, temps);
+		} else {
+			return st.thisContext = new SmalltalkMethodContext(receiver, selector, temps);
+		}
+	};
 
-    st.convertSelector = function(selector) {
-	if(selector.match(/__/)) {
-	    return convertBinarySelector(selector);
-	} else {
-	    return convertKeywordSelector(selector);
-	}
-    };
-
-    function convertKeywordSelector(selector) {
-	return selector.replace(/^_/, '').replace(/_/g, ':');
-    };
-
-    function convertBinarySelector(selector) {
-	return selector
-	    .replace(/^_/, '')
-	    .replace(/_plus/, '+')
-	    .replace(/_minus/, '-')
-	    .replace(/_star/, '*')
-	    .replace(/_slash/, '/')
-	    .replace(/_gt/, '>')
-	    .replace(/_lt/, '<')
-	    .replace(/_eq/, '=')
-	    .replace(/_comma/, ',')
-	    .replace(/_at/, '@')
-    };
-
-    /* Converts a JavaScript object to valid Smalltalk Object */
-    st.readJSObject = function(js) {
-	var object = js;
-	var readObject = (js.constructor === Object);
-	var readArray = (js.constructor === Array);
-	
-	if(readObject) {
-	    object = smalltalk.Dictionary._new();
-	}
-	for(var i in js) {
-	    if(readObject) {
-		object._at_put_(i, st.readJSObject(js[i]));
-	    } 
-	    if(readArray) {
-		object[i] = st.readJSObject(js[i]);
-	    }
-	}
-	return object;
-    };
+	popContext = function(context) {
+		if(context) {
+			context.removeYourself();
+		}
+	};
 
-    /* Toggle deployment mode (no context will be handled during message send */
-    st.setDeploymentMode = function() {
-	st.send = sendWithoutContext;
-    };
+	/* Convert a string to a valid smalltalk selector.
+	   if you modify the following functions, also change String>>asSelector
+	   accordingly */
 
-    st.setDevelopmentMode = function() {
-	st.send = sendWithContext;
-    }
+	st.convertSelector = function(selector) {
+		if(selector.match(/__/)) {
+			return convertBinarySelector(selector);
+		} else {
+			return convertKeywordSelector(selector);
+		}
+	};
+
+	function convertKeywordSelector(selector) {
+		return selector.replace(/^_/, '').replace(/_/g, ':');
+	};
+
+	function convertBinarySelector(selector) {
+		return selector
+			.replace(/^_/, '')
+			.replace(/_plus/, '+')
+			.replace(/_minus/, '-')
+			.replace(/_star/, '*')
+			.replace(/_slash/, '/')
+			.replace(/_gt/, '>')
+			.replace(/_lt/, '<')
+			.replace(/_eq/, '=')
+			.replace(/_comma/, ',')
+			.replace(/_at/, '@')
+	};
+
+	/* Converts a JavaScript object to valid Smalltalk Object */
+	st.readJSObject = function(js) {
+		var object = js;
+		var readObject = (js.constructor === Object);
+		var readArray = (js.constructor === Array);
+
+		if(readObject) {
+			object = smalltalk.Dictionary._new();
+		}
+		for(var i in js) {
+			if(readObject) {
+				object._at_put_(i, st.readJSObject(js[i]));
+			} 
+			if(readArray) {
+				object[i] = st.readJSObject(js[i]);
+			}
+		}
+		return object;
+	};
 
-    /* Set development mode by default */
-    st.setDevelopmentMode();
+	/* Toggle deployment mode (no context will be handled during message send */
+	st.setDeploymentMode = function() {
+		st.send = sendWithoutContext;
+	};
+
+	st.setDevelopmentMode = function() {
+		st.send = sendWithContext;
+	}
+
+	/* Set development mode by default */
+	st.setDevelopmentMode();
 }
 
 function SmalltalkMethodContext(receiver, selector, temps, home) {
-    var that = this;
-    that.receiver = receiver;
-    that.selector = selector;
-    that.temps = temps || {};
-    that.homeContext = home;
-
-    that.copy = function() {
-	var home = that.homeContext;
-	if(home) {home = home.copy()}
-	return new SmalltalkMethodContext(
-	    that.receiver, 
-	    that.selector, 
-	    that.temps, 
-	    home
-	);
-    }
-
-    that.newContext = function(receiver, selector, temps) {
-	var c = smalltalk.oldContexts.pop();
-	if(c) {
-	    c.homeContext = that;
-	    c.receiver = receiver;
-	    c.selector = selector;
-	    c.temps = temps || {};
-	} else {
-	    c = new SmalltalkMethodContext(receiver, selector, temps, that);
+	var that = this;
+	that.receiver = receiver;
+	that.selector = selector;
+	that.temps = temps || {};
+	that.homeContext = home;
+
+	that.copy = function() {
+		var home = that.homeContext;
+		if(home) {home = home.copy()}
+		return new SmalltalkMethodContext(
+				that.receiver, 
+				that.selector, 
+				that.temps, 
+				home
+				);
+	}
+
+	that.newContext = function(receiver, selector, temps) {
+		var c = smalltalk.oldContexts.pop();
+		if(c) {
+			c.homeContext = that;
+			c.receiver = receiver;
+			c.selector = selector;
+			c.temps = temps || {};
+		} else {
+			c = new SmalltalkMethodContext(receiver, selector, temps, that);
+		}
+		return c;
+	}
+
+	that.removeYourself = function() {
+		smalltalk.thisContext = that.homeContext;
+		that.homeContext = undefined;
+		smalltalk.oldContexts.push(that);
 	}
-	return c;
-    }
-
-    that.removeYourself = function() {
-	smalltalk.thisContext = that.homeContext;
-	that.homeContext = undefined;
-	smalltalk.oldContexts.push(that);
-    }
 }
 
 /* Global Smalltalk objects. */
@@ -527,7 +527,7 @@ var nil = new SmalltalkNil();
 var smalltalk = new Smalltalk();
 
 if(this.jQuery) {
-    this.jQuery.allowJavaScriptCalls = true;
+	this.jQuery.allowJavaScriptCalls = true;
 }
 
 /****************************************************************************************/