Browse Source

Merge branch 'message_send' of github.com:NicolasPetton/amber into message_send

Conflicts:
	js/boot.js
Nicolas Petton 12 years ago
parent
commit
7b81628251
1 changed files with 98 additions and 109 deletions
  1. 98 109
      js/boot.js

+ 98 - 109
js/boot.js

@@ -35,7 +35,7 @@
 
 /* Make sure that console is defined */
 
-if (typeof console === "undefined") {
+if(typeof console === "undefined") {
 	this.console = {
 		log: function() {},
 		warn: function() {},
@@ -48,8 +48,8 @@ if (typeof console === "undefined") {
 /* Array extensions */
 
 Array.prototype.addElement = function(el) {
-    if(typeof el === 'undefined') { return false; };
-    if(this.indexOf(el) == -1) {
+	if(typeof el === 'undefined') { return false; }
+	if(this.indexOf(el) == -1) {
         this.push(el);
     }
 };
@@ -66,45 +66,39 @@ Array.prototype.removeElement = function(el) {
 
 /* Smalltalk constructors definition */
 
-function SmalltalkObject(){};
-function SmalltalkBehavior(){};
-function SmalltalkClass(){};
-function SmalltalkMetaclass(){
+function SmalltalkObject() {}
+function SmalltalkBehavior() {}
+function SmalltalkClass() {}
+function SmalltalkMetaclass() {
 	this.meta = true;
-};
-
-function SmalltalkPackage(){};
-function SmalltalkMethod(){};
-function SmalltalkNil(){};
-
-function SmalltalkSymbol(string){
+}
+function SmalltalkPackage() {}
+function SmalltalkMethod() {}
+function SmalltalkNil() {}
+function SmalltalkSymbol(string) {
 	this.value = string;
-};
-
+}
 function SmalltalkOrganizer() {
     this.elements = [];
-};
-
-SmalltalkBehavior.prototype  = new SmalltalkObject();
-SmalltalkClass.prototype     = new SmalltalkBehavior();
-SmalltalkMetaclass.prototype = new SmalltalkBehavior();
-
-SmalltalkNil.prototype       = new SmalltalkObject();
-SmalltalkMethod.prototype    = new SmalltalkObject();
-SmalltalkPackage.prototype   = new SmalltalkObject();
-SmalltalkOrganizer.prototype = new SmalltalkObject();
+}
 
-SmalltalkBehavior.prototype.constructor  = SmalltalkBehavior;
-SmalltalkClass.prototype.constructor     = SmalltalkClass;
-SmalltalkMetaclass.prototype.constructor = SmalltalkMetaclass;
+function inherits(child, parent) {
+	child.prototype = Object.create(parent.prototype, {
+		constructor: { value: child,
+			enumerable: false, configurable: true, writable: true }
+	});
+}
 
-SmalltalkNil.prototype.constructor       = SmalltalkNil;
-SmalltalkMethod.prototype.constructor    = SmalltalkMethod;
-SmalltalkPackage.prototype.constructor   = SmalltalkPackage;
-SmalltalkOrganizer.prototype.constructor = SmalltalkOrganizer;
+inherits(SmalltalkBehavior, SmalltalkObject);
+inherits(SmalltalkClass, SmalltalkBehavior);
+inherits(SmalltalkMetaclass, SmalltalkBehavior);
+inherits(SmalltalkNil, SmalltalkObject);
+inherits(SmalltalkMethod, SmalltalkObject);
+inherits(SmalltalkPackage, SmalltalkObject);
+inherits(SmalltalkOrganizer, SmalltalkObject);
 
 
-function Smalltalk(){
+function Smalltalk() {
 
 	var st = this;
 
@@ -134,35 +128,35 @@ function Smalltalk(){
 
     var dnuHandlers = [];
 
-    var addDnuHandler = function(string) {
+    function addDnuHandler(string) {
         if(dnuHandlers.indexOf(string) == -1) {
             dnuHandlers.push(string);
         }
-    };
+	}
 
-    /* Dnu handler method */
+	/* Dnu handler method */
 
-    var dnu = function(selector) {
+    function dnu(selector) {
         return function() {
             var args = Array.prototype.slice.call(arguments);
             return messageNotUnderstood(this, selector, args);
         };
-    };
+	}
 
 	/* The symbol table ensures symbol unicity */
 
-	symbolTable = {};
+	var symbolTable = {};
 	st.symbolFor = function(string) {
 		if(symbolTable[string] === undefined) {
 			symbolTable[string] = new SmalltalkSymbol(string);
-		};
+		}
 
 		return symbolTable[string];
 	};
 
 	/* Unique ID number generator */
 
-	oid = 0;
+	var oid = 0;
 	st.nextId = function() {
 		oid += 1;
 		return oid;
@@ -180,10 +174,10 @@ function Smalltalk(){
         that.organization = new SmalltalkOrganizer();
 		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)
+	   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()  */
 
@@ -217,8 +211,7 @@ function Smalltalk(){
 		var that = new SmalltalkMetaclass();
         that.fn            = function() {};
         that.organization  = new SmalltalkOrganizer();
-        that.fn.prototype  = new superConstructor();
-        that.fn.prototype.constructor = that.fn;
+        inherits(that.fn, superConstructor);
 
         setupClass(that);
 
@@ -229,7 +222,7 @@ function Smalltalk(){
 	function setupClass(klass, spec) {
         spec = spec || {};
         if(!klass.fn) {
-		    klass.fn = spec.fn || function(){};
+		    klass.fn = spec.fn || function() {};
         }
 		klass.iVarNames = spec.iVarNames || [];
 		klass.pkg = spec.pkg;
@@ -256,7 +249,7 @@ function Smalltalk(){
                 writable: true 
             }
 		});
-	};
+	}
 
 	/* Smalltalk method object. To add a method to a class,
 	   use smalltalk.addMethod() */
@@ -297,21 +290,20 @@ function Smalltalk(){
         }
     };
 
-    var installSuperclass = function(klass) {
+    function installSuperclass(klass) {
         // only if the klass has not been initialized yet.
-        if(klass.fn.prototype._yourself) { return false; };
+		if(klass.fn.prototype._yourself) { return false; }
 
-        if(klass.superclass && klass.superclass !== nil) {
-            klass.fn.prototype = new klass.superclass.fn();
-            klass.fn.prototype.constructor = klass.fn;
+		if(klass.superclass && klass.superclass !== nil) {
+            inherits(klass.fn, klass.superclass.fn);
             Object.defineProperties(klass.fn.prototype, {
 			    klass: { value: klass, enumerable: false, configurable: true, writable: true }
 		    });
             reinstallMethods(klass);
         }
-    };
+	}
 
-    var copySuperclass = function(klass, superclass) {
+	function copySuperclass(klass, superclass) {
         superclass = superclass || klass.superclass;
         if(superclass && superclass !== nil) {
 			for(var keys = Object.keys(superclass.methods), i=0; i<keys.length; i++) {
@@ -324,44 +316,44 @@ function Smalltalk(){
                 copySuperclass(klass, superclass.superclass);
             }
         }
-    };
+	}
 
-    var installMethod = function(method, klass) {
+	function installMethod(method, klass) {
         Object.defineProperty(klass.fn.prototype, method.jsSelector, {
 			value: method.fn, configurable: true, writable: true
 		});
-    };
+	}
 
-    var reinstallMethods = function(klass) {
+	function reinstallMethods(klass) {
         for(var keys = Object.keys(klass.methods), i=0; i<keys.length; i++) {
             installMethod(klass.methods[keys[i]], klass);
 		}
-    };
+	}
 
-    var installDnuHandlers = function(klass) {
+	function installDnuHandlers(klass) {
         for(var i=0; i<dnuHandlers.length; i++) {
             installDnuHandler(dnuHandlers[i], klass);
         }
-    };
+	}
 
-    var installDnuHandler = function(string, klass) {
+	function installDnuHandler(string, klass) {
         var selector = st.selector(string);
         if(!klass.fn.prototype[selector]) {
             Object.defineProperty(klass.fn.prototype, selector, {
                 value: dnu(selector), configurable: true, writable: true
             });
         }
-    };
+	}
 
-    var installNewDnuHandler = function(string) {
+	function installNewDnuHandler(string) {
         if(dnuHandlers.indexOf(string) === -1) {
             addDnuHandler(string);
             installDnuHandler(string, smalltalk.Object);
             for(var i=0; i<wrappedClasses.length; i++) {
                 installDnuHandler(string, wrappedClasses[i]);
-            };
-        }
-    };
+			}
+		}
+	}
 
 	/* Answer all registered Packages as Array */
     // TODO: Remove this hack
@@ -369,7 +361,7 @@ function Smalltalk(){
 	st.packages.all = function() {
 		var packages = [];
 		for(var i in st.packages) {
-			if (!st.packages.hasOwnProperty(i) || typeof(st.packages[i]) === "function") continue;
+			if(!st.packages.hasOwnProperty(i) || typeof(st.packages[i]) === "function") continue;
 			packages.push(st.packages[i]);
 		}
 		return packages
@@ -425,15 +417,15 @@ function Smalltalk(){
 		});
 
         classes.addElement(st[className]);
-        if(wrapped) {wrappedClasses.addElement(st[className])};
-        pkg.organization.elements.addElement(st[className]);
+		if(wrapped) {wrappedClasses.addElement(st[className])}
+		pkg.organization.elements.addElement(st[className]);
 	};
 
 	/* Create an alias for an existing class */
 
 	st.alias = function(klass, alias) {
 		st[alias] = klass;
-	}
+	};
 
 	/* 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.
@@ -466,7 +458,7 @@ function Smalltalk(){
 		} else {
             if(st[className]) {
                 st.removeClass(st[className]);
-            };
+			}
 			st[className] = klass({
 				className: className,
 				superclass: superclass,
@@ -502,8 +494,8 @@ function Smalltalk(){
             addDnuHandler(method.messageSends[i]);
             if(initialized) {
                 installNewDnuHandler(method.messageSends[i]);
-            };
-        };
+			}
+		}
 	};
 
     st.removeMethod = function(method) {
@@ -517,12 +509,12 @@ function Smalltalk(){
         for(var i=0; i<klass.methods; i++) {
             if(klass.methods[i].category == protocol) {
                 shouldDeleteProtocol = true;
-            };
-        };
-        if(shouldDeleteProtocol) {
+			}
+		}
+		if(shouldDeleteProtocol) {
             klass.organization.elements.removeElement(protocol);
-        };
-    };
+		}
+	};
 
 	/* Handles unhandled errors during message sends */
 
@@ -557,7 +549,7 @@ function Smalltalk(){
 		} else {
 			return messageNotUnderstood(receiver, selector, args);
 		}
-	};
+	}
 
 	st.withContext = function(fn, receiver, selector, args) {
 		if(st.thisContext) {
@@ -581,15 +573,14 @@ function Smalltalk(){
 		var result = fn();
 		popContext(context);
 		return result;
-	};
-
+	}
 
 	/* Handles Smalltalk errors. Triggers the registered ErrorHandler
 	   (See the Smalltalk class ErrorHandler and its subclasses */
 
 	function handleError(error) {
         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
@@ -609,7 +600,7 @@ function Smalltalk(){
 				._selector_(st.convertSelector(selector))
 				._arguments_(args)
 				);
-	};
+	}
 
 	/* Call a method of a JS object, or answer a property if it exists.
 	   Else try wrapping a JSObjectProxy around the receiver.
@@ -639,8 +630,7 @@ function Smalltalk(){
 		}
 
 		return st.send(st.JSObjectProxy._on_(receiver), selector, args);
-	};
-
+	}
 
 	/* Reuse one old context stored in oldContext */
 
@@ -657,8 +647,9 @@ function Smalltalk(){
 
 	function pushContext(receiver, selector, temps) {
 		var c = st.oldContext, tc = st.thisContext;
-		if (!c) {
+		if(!c) {
 			return st.thisContext = new SmalltalkMethodContext(receiver, selector, temps, tc);
+
 		}
 		st.oldContext = null;
 		c.homeContext = tc;
@@ -667,15 +658,15 @@ function Smalltalk(){
         c.selector    = selector || "";
 		c.temps       = temps || {};
 		return st.thisContext = c;
-	};
+	}
 
 	function popContext(context) {
 		st.thisContext = context.homeContext;
 		context.homeContext = undefined;
 		st.oldContext = context;
-	};
+	}
 
-    /* Convert a Smalltalk selector into a JS selector */
+	/* Convert a Smalltalk selector into a JS selector */
 
     st.selector = function(string) {
         var selector = '_' + string;
@@ -710,7 +701,7 @@ function Smalltalk(){
 
 	function convertKeywordSelector(selector) {
 		return selector.replace(/^_/, '').replace(/_/g, ':');
-	};
+	}
 
 	function convertBinarySelector(selector) {
 		return selector
@@ -753,19 +744,19 @@ function Smalltalk(){
     /* Boolean assertion */
 
     st.assert = function(boolean) {
-        if(boolean.klass === smalltalk.Boolean) {
-            return boolean;
-        } else {
-            smalltalk.NonBooleanReceiver._new()._object_(boolean)._signal();
-        }
-    }
+		if(boolean.klass === smalltalk.Boolean) {
+			return boolean;
+		} else {
+			smalltalk.NonBooleanReceiver._new()._object_(boolean)._signal();
+		}
+	};
 
     /* Smalltalk initialization. Called on page load */
 
     st.initialize = function() {
-        if(initialized) {return false};
+		if(initialized) {return false}
 
-        classes.forEach(function(klass) {
+		classes.forEach(function(klass) {
             st.init(klass);
         });
         classes.forEach(function(klass) {
@@ -774,10 +765,9 @@ function Smalltalk(){
 
         initialized = true;
     };
-};
+}
 
-Smalltalk.prototype = new SmalltalkObject();
-Smalltalk.prototype.constructor = Smalltalk;
+inherits(Smalltalk, SmalltalkObject);
 
 function SmalltalkMethodContext(receiver, selector, temps, home) {
 	this.receiver    = receiver;
@@ -793,8 +783,7 @@ function SmalltalkMethodContext(receiver, selector, temps, home) {
     // };
 };
 
-SmalltalkMethodContext.prototype = new SmalltalkObject();
-SmalltalkMethodContext.prototype.constructor = SmalltalkMethodContext;
+inherits(SmalltalkMethodContext, SmalltalkObject);
 
 SmalltalkMethodContext.prototype.copy = function() {
 	var home = this.homeContext;
@@ -822,10 +811,10 @@ var smalltalk = new Smalltalk();
  */
 
 var _st = function(o) {
-    if(typeof o === 'undefined') {return nil};
-    if(o.klass) {return o};
-    return smalltalk.JSObjectProxy._on_(o);
-};
+	if(typeof o === 'undefined') {return nil}
+	if(o.klass) {return o}
+	return smalltalk.JSObjectProxy._on_(o);
+}; 
 
 
 /***************************************** BOOTSTRAP ******************************************/