浏览代码

First stab at adding the concept of Module instead of plain class categories.

Göran Krampe 13 年之前
父节点
当前提交
ac9ae60a8c
共有 7 个文件被更改,包括 434 次插入132 次删除
  1. 1 1
      js/Compiler.deploy.js
  2. 4 4
      js/Compiler.js
  3. 123 32
      js/Kernel.deploy.js
  4. 183 60
      js/Kernel.js
  5. 59 14
      js/boot.js
  6. 0 0
      st/Compiler.st
  7. 64 21
      st/Kernel.st

+ 1 - 1
js/Compiler.deploy.js

@@ -1547,7 +1547,7 @@ smalltalk.method({
 selector: 'recompileAll',
 selector: 'recompileAll',
 fn: function (){
 fn: function (){
 var self=this;
 var self=this;
-smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_classes", []), "_do_", [(function(each){(function($rec){smalltalk.send($rec, "_show_", [each]);return smalltalk.send($rec, "_cr", []);})((smalltalk.Transcript || Transcript));return smalltalk.send((function(){return smalltalk.send(self, "_recompile_", [each]);}), "_valueWithTimeout_", [(1)]);})]);
+smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_classes", []), "_do_", [(function(each){(function($rec){smalltalk.send($rec, "_show_", [each]);return smalltalk.send($rec, "_cr", []);})((smalltalk.Transcript || Transcript));return smalltalk.send((function(){return smalltalk.send(self, "_recompile_", [each]);}), "_valueWithTimeout_", [(100)]);})]);
 return self;}
 return self;}
 }),
 }),
 smalltalk.Compiler);
 smalltalk.Compiler);

+ 4 - 4
js/Compiler.js

@@ -1523,7 +1523,7 @@ return smalltalk.send((smalltalk.SmalltalkParser || SmalltalkParser), "_new", []
 return self;},
 return self;},
 source: unescape('parser%0A%09%5ESmalltalkParser%20new'),
 source: unescape('parser%0A%09%5ESmalltalkParser%20new'),
 messageSends: ["new"],
 messageSends: ["new"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: []
 }),
 }),
 smalltalk.Compiler);
 smalltalk.Compiler);
 
 
@@ -1939,7 +1939,7 @@ fn: function (aString){
 var self=this;
 var self=this;
 return smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_parse_", [aString]);
 return smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_parse_", [aString]);
 return self;},
 return self;},
-source: unescape('parse%3A%20aString%0A%20%20%20%20%5ESmalltalk%20current%20parse%3A%20aString%20'),
+source: unescape('parse%3A%20aString%0A%20%20%20%20%5ESmalltalk%20current%20parse%3A%20aString'),
 messageSends: ["parse:", "current"],
 messageSends: ["parse:", "current"],
 referencedClasses: [smalltalk.Smalltalk]
 referencedClasses: [smalltalk.Smalltalk]
 }),
 }),
@@ -2044,11 +2044,11 @@ selector: 'recompileAll',
 category: 'compiling',
 category: 'compiling',
 fn: function (){
 fn: function (){
 var self=this;
 var self=this;
-smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_classes", []), "_do_", [(function(each){(function($rec){smalltalk.send($rec, "_show_", [each]);return smalltalk.send($rec, "_cr", []);})((smalltalk.Transcript || Transcript));return smalltalk.send((function(){return smalltalk.send(self, "_recompile_", [each]);}), "_valueWithTimeout_", [(1)]);})]);
+smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_classes", []), "_do_", [(function(each){(function($rec){smalltalk.send($rec, "_show_", [each]);return smalltalk.send($rec, "_cr", []);})((smalltalk.Transcript || Transcript));return smalltalk.send((function(){return smalltalk.send(self, "_recompile_", [each]);}), "_valueWithTimeout_", [(100)]);})]);
 return self;},
 return self;},
 source: unescape('recompileAll%0A%09Smalltalk%20current%20classes%20do%3A%20%5B%3Aeach%20%7C%0A%09%09Transcript%20show%3A%20each%3B%20cr.%0A%09%09%5Bself%20recompile%3A%20each%5D%20valueWithTimeout%3A%20100%5D'),
 source: unescape('recompileAll%0A%09Smalltalk%20current%20classes%20do%3A%20%5B%3Aeach%20%7C%0A%09%09Transcript%20show%3A%20each%3B%20cr.%0A%09%09%5Bself%20recompile%3A%20each%5D%20valueWithTimeout%3A%20100%5D'),
 messageSends: ["do:", "classes", "current", "show:", "cr", "valueWithTimeout:", "recompile:"],
 messageSends: ["do:", "classes", "current", "show:", "cr", "valueWithTimeout:", "recompile:"],
-referencedClasses: [smalltalk.Smalltalk,smalltalk.nil]
+referencedClasses: [smalltalk.Smalltalk]
 }),
 }),
 smalltalk.Compiler);
 smalltalk.Compiler);
 
 

+ 123 - 32
js/Kernel.deploy.js

@@ -647,6 +647,17 @@ return self;}
 }),
 }),
 smalltalk.Smalltalk);
 smalltalk.Smalltalk);
 
 
+smalltalk.addMethod(
+'_modules',
+smalltalk.method({
+selector: 'modules',
+fn: function (){
+var self=this;
+return self.modules.all();
+return self;}
+}),
+smalltalk.Smalltalk);
+
 
 
 smalltalk.Smalltalk.klass.iVarNames = ['current'];
 smalltalk.Smalltalk.klass.iVarNames = ['current'];
 smalltalk.addMethod(
 smalltalk.addMethod(
@@ -661,6 +672,42 @@ return self;}
 smalltalk.Smalltalk.klass);
 smalltalk.Smalltalk.klass);
 
 
 
 
+smalltalk.addClass('Module', smalltalk.Object, [], 'Kernel');
+smalltalk.addMethod(
+'_name',
+smalltalk.method({
+selector: 'name',
+fn: function (){
+var self=this;
+return self.moduleName || nil;
+return self;}
+}),
+smalltalk.Module);
+
+smalltalk.addMethod(
+'_requires',
+smalltalk.method({
+selector: 'requires',
+fn: function (){
+var self=this;
+return self.requires || nil;
+return self;}
+}),
+smalltalk.Module);
+
+smalltalk.addMethod(
+'_name_',
+smalltalk.method({
+selector: 'name:',
+fn: function (aString){
+var self=this;
+return self.moduleName = aString;
+return self;}
+}),
+smalltalk.Module);
+
+
+
 smalltalk.addClass('Behavior', smalltalk.Object, [], 'Kernel');
 smalltalk.addClass('Behavior', smalltalk.Object, [], 'Kernel');
 smalltalk.addMethod(
 smalltalk.addMethod(
 '_new',
 '_new',
@@ -970,18 +1017,7 @@ smalltalk.method({
 selector: 'category',
 selector: 'category',
 fn: function (){
 fn: function (){
 var self=this;
 var self=this;
-return self.category;
-return self;}
-}),
-smalltalk.Class);
-
-smalltalk.addMethod(
-'_category_',
-smalltalk.method({
-selector: 'category:',
-fn: function (aString){
-var self=this;
-self.category = aString;
+return (($receiver = smalltalk.send(self, "_module", [])) == nil || $receiver == undefined) ? (function(){return "unclassified";})() : (function(){return smalltalk.send(smalltalk.send(self, "_module", []), "_name", []);})();
 return self;}
 return self;}
 }),
 }),
 smalltalk.Class);
 smalltalk.Class);
@@ -992,7 +1028,7 @@ smalltalk.method({
 selector: 'subclass:instanceVariableNames:',
 selector: 'subclass:instanceVariableNames:',
 fn: function (aString, anotherString){
 fn: function (aString, anotherString){
 var self=this;
 var self=this;
-return smalltalk.send(self, "_subclass_instanceVariableNames_category_", [aString, anotherString, nil]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, anotherString, nil]);
 return self;}
 return self;}
 }),
 }),
 smalltalk.Class);
 smalltalk.Class);
@@ -1003,7 +1039,7 @@ smalltalk.method({
 selector: 'subclass:instanceVariableNames:category:',
 selector: 'subclass:instanceVariableNames:category:',
 fn: function (aString, aString2, aString3){
 fn: function (aString, aString2, aString3){
 var self=this;
 var self=this;
-return smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_superclass_subclass_instanceVariableNames_category_", [self, aString, aString2, aString3]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, aString2, aString3]);
 return self;}
 return self;}
 }),
 }),
 smalltalk.Class);
 smalltalk.Class);
@@ -1051,7 +1087,40 @@ smalltalk.method({
 selector: 'subclass:instanceVariableNames:classVariableNames:poolDictionaries:category:',
 selector: 'subclass:instanceVariableNames:classVariableNames:poolDictionaries:category:',
 fn: function (aString, aString2, classVars, pools, aString3){
 fn: function (aString, aString2, classVars, pools, aString3){
 var self=this;
 var self=this;
-return smalltalk.send(self, "_subclass_instanceVariableNames_category_", [aString, aString2, aString3]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, aString2, aString3]);
+return self;}
+}),
+smalltalk.Class);
+
+smalltalk.addMethod(
+'_module',
+smalltalk.method({
+selector: 'module',
+fn: function (){
+var self=this;
+return self.module;
+return self;}
+}),
+smalltalk.Class);
+
+smalltalk.addMethod(
+'_module_',
+smalltalk.method({
+selector: 'module:',
+fn: function (aModule){
+var self=this;
+self.module = aModule;
+return self;}
+}),
+smalltalk.Class);
+
+smalltalk.addMethod(
+'_subclass_instanceVariableNames_module_',
+smalltalk.method({
+selector: 'subclass:instanceVariableNames:module:',
+fn: function (aString, aString2, aString3){
+var self=this;
+return smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_superclass_subclass_instanceVariableNames_module_", [self, aString, aString2, aString3]);
 return self;}
 return self;}
 }),
 }),
 smalltalk.Class);
 smalltalk.Class);
@@ -2405,7 +2474,7 @@ smalltalk.method({
 selector: 'subclass:instanceVariableNames:',
 selector: 'subclass:instanceVariableNames:',
 fn: function (aString, anotherString){
 fn: function (aString, anotherString){
 var self=this;
 var self=this;
-return smalltalk.send(self, "_subclass_instanceVariableNames_category_", [aString, anotherString, nil]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, anotherString, nil]);
 return self;}
 return self;}
 }),
 }),
 smalltalk.UndefinedObject);
 smalltalk.UndefinedObject);
@@ -2416,7 +2485,7 @@ smalltalk.method({
 selector: 'subclass:instanceVariableNames:category:',
 selector: 'subclass:instanceVariableNames:category:',
 fn: function (aString, aString2, aString3){
 fn: function (aString, aString2, aString3){
 var self=this;
 var self=this;
-return smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_superclass_subclass_instanceVariableNames_category_", [self, aString, aString2, aString3]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, aString2, aString3]);
 return self;}
 return self;}
 }),
 }),
 smalltalk.UndefinedObject);
 smalltalk.UndefinedObject);
@@ -2520,6 +2589,17 @@ return self;}
 }),
 }),
 smalltalk.UndefinedObject);
 smalltalk.UndefinedObject);
 
 
+smalltalk.addMethod(
+'_subclass_instanceVariableNames_module_',
+smalltalk.method({
+selector: 'subclass:instanceVariableNames:module:',
+fn: function (aString, aString2, aString3){
+var self=this;
+return smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_superclass_subclass_instanceVariableNames_module_", [self, aString, aString2, aString3]);
+return self;}
+}),
+smalltalk.UndefinedObject);
+
 
 
 smalltalk.addMethod(
 smalltalk.addMethod(
 '_new',
 '_new',
@@ -4593,21 +4673,7 @@ smalltalk.method({
 selector: 'superclass:subclass:',
 selector: 'superclass:subclass:',
 fn: function (aClass, aString){
 fn: function (aClass, aString){
 var self=this;
 var self=this;
-smalltalk.send(self, "_superclass_subclass_instanceVariableNames_category_", [aClass, aString, "", nil]);
-return self;}
-}),
-smalltalk.ClassBuilder);
-
-smalltalk.addMethod(
-'_superclass_subclass_instanceVariableNames_category_',
-smalltalk.method({
-selector: 'superclass:subclass:instanceVariableNames:category:',
-fn: function (aClass, aString, aString2, aString3){
-var self=this;
-var newClass=nil;
-newClass=smalltalk.send(self, "_addSubclassOf_named_instanceVariableNames_", [aClass, aString, smalltalk.send(self, "_instanceVariableNamesFor_", [aString2])]);
-smalltalk.send(self, "_setupClass_", [newClass]);
-smalltalk.send(newClass, "_category_", [(($receiver = aString3) == nil || $receiver == undefined) ? (function(){return "unclassified";})() : $receiver]);
+return smalltalk.send(self, "_superclass_subclass_instanceVariableNames_module_", [aClass, aString, "", nil]);
 return self;}
 return self;}
 }),
 }),
 smalltalk.ClassBuilder);
 smalltalk.ClassBuilder);
@@ -4659,6 +4725,31 @@ return self;}
 }),
 }),
 smalltalk.ClassBuilder);
 smalltalk.ClassBuilder);
 
 
+smalltalk.addMethod(
+'_superclass_subclass_instanceVariableNames_module_',
+smalltalk.method({
+selector: 'superclass:subclass:instanceVariableNames:module:',
+fn: function (aClass, aString, aString2, aString3){
+var self=this;
+var newClass=nil;
+newClass=smalltalk.send(self, "_addSubclassOf_named_instanceVariableNames_module_", [aClass, aString, smalltalk.send(self, "_instanceVariableNamesFor_", [aString2]), (($receiver = aString3) == nil || $receiver == undefined) ? (function(){return "unclassified";})() : $receiver]);
+smalltalk.send(self, "_setupClass_", [newClass]);
+return self;}
+}),
+smalltalk.ClassBuilder);
+
+smalltalk.addMethod(
+'_addSubclassOf_named_instanceVariableNames_module_',
+smalltalk.method({
+selector: 'addSubclassOf:named:instanceVariableNames:module:',
+fn: function (aClass, aString, aCollection, moduleName){
+var self=this;
+smalltalk.addClass(aString, aClass, aCollection, moduleName);
+	    return smalltalk[aString];
+return self;}
+}),
+smalltalk.ClassBuilder);
+
 
 
 
 
 smalltalk.addClass('ClassCategoryReader', smalltalk.Object, ['class', 'category', 'chunkParser'], 'Kernel');
 smalltalk.addClass('ClassCategoryReader', smalltalk.Object, ['class', 'category', 'chunkParser'], 'Kernel');

+ 183 - 60
js/Kernel.js

@@ -354,7 +354,7 @@ fn: function (aBlock, anotherBlock){
 var self=this;
 var self=this;
 try{aBlock()} catch(e) {anotherBlock(e)};
 try{aBlock()} catch(e) {anotherBlock(e)};
 return self;},
 return self;},
-source: unescape('try%3A%20aBlock%20catch%3A%20anotherBlock%0A%09%3Ctry%7BaBlock%28%29%7D%20catch%28e%29%20%7BanotherBlock%28e%29%7D%3E%20'),
+source: unescape('try%3A%20aBlock%20catch%3A%20anotherBlock%0A%09%3Ctry%7BaBlock%28%29%7D%20catch%28e%29%20%7BanotherBlock%28e%29%7D%3E'),
 messageSends: [],
 messageSends: [],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -704,7 +704,7 @@ var result=nil;
 smalltalk.send((typeof console == 'undefined' ? nil : console), "_log_", [smalltalk.send(smalltalk.send(aString, "__comma", [" time: "]), "__comma", [smalltalk.send(smalltalk.send((smalltalk.Date || Date), "_millisecondsToRun_", [(function(){return result=smalltalk.send(aBlock, "_value", []);})]), "_printString", [])])]);
 smalltalk.send((typeof console == 'undefined' ? nil : console), "_log_", [smalltalk.send(smalltalk.send(aString, "__comma", [" time: "]), "__comma", [smalltalk.send(smalltalk.send((smalltalk.Date || Date), "_millisecondsToRun_", [(function(){return result=smalltalk.send(aBlock, "_value", []);})]), "_printString", [])])]);
 return result;
 return result;
 return self;},
 return self;},
-source: unescape('log%3A%20aString%20block%3A%20aBlock%0A%0A%09%7C%20result%20%7C%0A%09console%20log%3A%20%20aString%2C%20%20%27%20time%3A%20%27%2C%20%28Date%20millisecondsToRun%3A%20%5Bresult%20%3A%3D%20aBlock%20value%5D%29%20printString.%0A%09%5Eresult%0A%0A'),
+source: unescape('log%3A%20aString%20block%3A%20aBlock%0A%0A%09%7C%20result%20%7C%0A%09console%20log%3A%20%20aString%2C%20%20%27%20time%3A%20%27%2C%20%28Date%20millisecondsToRun%3A%20%5Bresult%20%3A%3D%20aBlock%20value%5D%29%20printString.%0A%09%5Eresult'),
 messageSends: ["log:", unescape("%2C"), "printString", "millisecondsToRun:", "value"],
 messageSends: ["log:", unescape("%2C"), "printString", "millisecondsToRun:", "value"],
 referencedClasses: [smalltalk.Date]
 referencedClasses: [smalltalk.Date]
 }),
 }),
@@ -861,12 +861,27 @@ smalltalk.send(lines, "_at_put_", [row, badLine]);
 code=smalltalk.send((smalltalk.String || String), "_streamContents_", [(function(s){return smalltalk.send(lines, "_withIndexDo_", [(function(l, i){return smalltalk.send(s, "_nextPutAll_", [smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(i, "_asString", []), "__comma", [": "]), "__comma", [l]), "__comma", [smalltalk.send((smalltalk.String || String), "_lf", [])])]);})]);})]);
 code=smalltalk.send((smalltalk.String || String), "_streamContents_", [(function(s){return smalltalk.send(lines, "_withIndexDo_", [(function(l, i){return smalltalk.send(s, "_nextPutAll_", [smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(i, "_asString", []), "__comma", [": "]), "__comma", [l]), "__comma", [smalltalk.send((smalltalk.String || String), "_lf", [])])]);})]);})]);
 return smalltalk.send(smalltalk.send((smalltalk.Error || Error), "_new", []), "_messageText_", [smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send("Parse error on line ", "__comma", [row]), "__comma", [" column "]), "__comma", [col]), "__comma", [" : "]), "__comma", [message]), "__comma", [unescape("%20Below%20is%20code%20with%20line%20numbers%20and%20%3D%3D%3D%3E%20marker%20inserted%3A")]), "__comma", [smalltalk.send((smalltalk.String || String), "_lf", [])]), "__comma", [code])]);
 return smalltalk.send(smalltalk.send((smalltalk.Error || Error), "_new", []), "_messageText_", [smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send("Parse error on line ", "__comma", [row]), "__comma", [" column "]), "__comma", [col]), "__comma", [" : "]), "__comma", [message]), "__comma", [unescape("%20Below%20is%20code%20with%20line%20numbers%20and%20%3D%3D%3D%3E%20marker%20inserted%3A")]), "__comma", [smalltalk.send((smalltalk.String || String), "_lf", [])]), "__comma", [code])]);
 return self;},
 return self;},
-source: unescape('parseError%3A%20anException%20parsing%3A%20aString%0A%09%7C%20row%20col%20message%20lines%20badLine%20code%20%7C%0A%09%3Crow%20%3D%20anException.line%3B%0A%09col%20%3D%20anException.column%3B%0A%09message%20%3D%20anException.message%3B%3E.%0A%09lines%20%3A%3D%20aString%20lines.%0A%09badLine%20%3A%3D%20lines%20at%3A%20row.%0A%09badLine%20%3A%3D%20%28badLine%20copyFrom%3A%201%20to%3A%20col%20-%201%29%2C%20%27%20%3D%3D%3D%3E%27%2C%20%28badLine%20copyFrom%3A%20%20col%20to%3A%20badLine%20size%29.%0A%09lines%20at%3A%20row%20put%3A%20badLine.%0A%09code%20%3A%3D%20String%20streamContents%3A%20%5B%3As%20%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lines%20withIndexDo%3A%20%5B%3Al%20%3Ai%20%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20s%20nextPutAll%3A%20i%20asString%2C%20%27%3A%20%27%2C%20l%2C%20String%20lf%5D%5D.%0A%09%5E%20Error%20new%20messageText%3A%20%28%27Parse%20error%20on%20line%20%27%20%2C%20row%20%2C%20%27%20column%20%27%20%2C%20col%20%2C%20%27%20%3A%20%27%20%2C%20message%20%2C%20%27%20Below%20is%20code%20with%20line%20numbers%20and%20%3D%3D%3D%3E%20marker%20inserted%3A%27%20%2C%20String%20lf%2C%20code%29'),
+source: unescape('parseError%3A%20anException%20parsing%3A%20aString%0A%09%7C%20row%20col%20message%20lines%20badLine%20code%20%7C%0A%09%3Crow%20%3D%20anException.line%3B%0A%09col%20%3D%20anException.column%3B%0A%09message%20%3D%20anException.message%3B%3E.%0A%09lines%20%3A%3D%20aString%20lines.%0A%09badLine%20%3A%3D%20lines%20at%3A%20row.%0A%09badLine%20%3A%3D%20%28badLine%20copyFrom%3A%201%20to%3A%20col%20-%201%29%2C%20%27%20%3D%3D%3D%3E%27%2C%20%28badLine%20copyFrom%3A%20%20col%20to%3A%20badLine%20size%29.%0A%09lines%20at%3A%20row%20put%3A%20badLine.%0A%09code%20%3A%3D%20String%20streamContents%3A%20%5B%3As%20%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lines%20withIndexDo%3A%20%5B%3Al%20%3Ai%20%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20s%20nextPutAll%3A%20i%20asString%2C%20%27%3A%20%27%2C%20l%2C%20String%20lf%5D%5D.%0A%09%5E%20Error%20new%20messageText%3A%20%28%27Parse%20error%20on%20line%20%27%20%2C%20row%20%2C%20%27%20column%20%27%20%2C%20col%20%2C%20%27%20%3A%20%27%20%2C%20message%20%2C%20%27%20Below%20is%20code%20with%20line%20numbers%20and%20%3D%3D%3D%3E%20marker%20inserted%3A%27%20%2C%20String%20lf%2C%20code%29'),
 messageSends: ["lines", "at:", unescape("%2C"), "copyFrom:to:", unescape("-"), "size", "at:put:", "streamContents:", "withIndexDo:", "nextPutAll:", "asString", "lf", "messageText:", "new"],
 messageSends: ["lines", "at:", unescape("%2C"), "copyFrom:to:", unescape("-"), "size", "at:put:", "streamContents:", "withIndexDo:", "nextPutAll:", "asString", "lf", "messageText:", "new"],
 referencedClasses: [smalltalk.String,smalltalk.Error]
 referencedClasses: [smalltalk.String,smalltalk.Error]
 }),
 }),
 smalltalk.Smalltalk);
 smalltalk.Smalltalk);
 
 
+smalltalk.addMethod(
+'_modules',
+smalltalk.method({
+selector: 'modules',
+category: 'accessing',
+fn: function (){
+var self=this;
+return self.modules.all();
+return self;},
+source: unescape('modules%0A%09%3Creturn%20self.modules.all%28%29%3E'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Smalltalk);
+
 
 
 smalltalk.Smalltalk.klass.iVarNames = ['current'];
 smalltalk.Smalltalk.klass.iVarNames = ['current'];
 smalltalk.addMethod(
 smalltalk.addMethod(
@@ -885,6 +900,54 @@ referencedClasses: []
 smalltalk.Smalltalk.klass);
 smalltalk.Smalltalk.klass);
 
 
 
 
+smalltalk.addClass('Module', smalltalk.Object, [], 'Kernel');
+smalltalk.addMethod(
+'_name',
+smalltalk.method({
+selector: 'name',
+category: 'accessing',
+fn: function (){
+var self=this;
+return self.moduleName || nil;
+return self;},
+source: unescape('name%0A%09%3Creturn%20self.moduleName%20%7C%7C%20nil%3E'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Module);
+
+smalltalk.addMethod(
+'_requires',
+smalltalk.method({
+selector: 'requires',
+category: 'accessing',
+fn: function (){
+var self=this;
+return self.requires || nil;
+return self;},
+source: unescape('requires%0A%09%3Creturn%20self.requires%20%7C%7C%20nil%3E'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Module);
+
+smalltalk.addMethod(
+'_name_',
+smalltalk.method({
+selector: 'name:',
+category: 'accessing',
+fn: function (aString){
+var self=this;
+return self.moduleName = aString;
+return self;},
+source: unescape('name%3A%20aString%0A%09%3Creturn%20self.moduleName%20%3D%20aString%3E'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Module);
+
+
+
 smalltalk.addClass('Behavior', smalltalk.Object, [], 'Kernel');
 smalltalk.addClass('Behavior', smalltalk.Object, [], 'Kernel');
 smalltalk.addMethod(
 smalltalk.addMethod(
 '_new',
 '_new',
@@ -1281,7 +1344,7 @@ smalltalk.send(self, "_addCompiledMethod_", [method]);
 return self;},
 return self;},
 source: unescape('compile%3A%20aString%20category%3A%20anotherString%0A%09%7C%20method%20%7C%0A%09method%20%3A%3D%20Compiler%20new%20load%3A%20aString%20forClass%3A%20self.%0A%09method%20category%3A%20anotherString.%0A%09self%20addCompiledMethod%3A%20method'),
 source: unescape('compile%3A%20aString%20category%3A%20anotherString%0A%09%7C%20method%20%7C%0A%09method%20%3A%3D%20Compiler%20new%20load%3A%20aString%20forClass%3A%20self.%0A%09method%20category%3A%20anotherString.%0A%09self%20addCompiledMethod%3A%20method'),
 messageSends: ["load:forClass:", "new", "category:", "addCompiledMethod:"],
 messageSends: ["load:forClass:", "new", "category:", "addCompiledMethod:"],
-referencedClasses: [smalltalk.Compiler]
+referencedClasses: [smalltalk.nil]
 }),
 }),
 smalltalk.Behavior);
 smalltalk.Behavior);
 
 
@@ -1295,25 +1358,10 @@ selector: 'category',
 category: 'accessing',
 category: 'accessing',
 fn: function (){
 fn: function (){
 var self=this;
 var self=this;
-return self.category;
-return self;},
-source: unescape('category%0A%09%3Creturn%20self.category%3E'),
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.Class);
-
-smalltalk.addMethod(
-'_category_',
-smalltalk.method({
-selector: 'category:',
-category: 'accessing',
-fn: function (aString){
-var self=this;
-self.category = aString;
+return (($receiver = smalltalk.send(self, "_module", [])) == nil || $receiver == undefined) ? (function(){return "unclassified";})() : (function(){return smalltalk.send(smalltalk.send(self, "_module", []), "_name", []);})();
 return self;},
 return self;},
-source: unescape('category%3A%20aString%0A%09%3Cself.category%20%3D%20aString%3E'),
-messageSends: [],
+source: unescape('category%0A%09%5Eself%20module%20ifNil%3A%20%5B%27unclassified%27%5D%20ifNotNil%3A%20%5Bself%20module%20name%5D'),
+messageSends: ["ifNil:ifNotNil:", "module", "name"],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
 smalltalk.Class);
 smalltalk.Class);
@@ -1325,10 +1373,10 @@ selector: 'subclass:instanceVariableNames:',
 category: 'class creation',
 category: 'class creation',
 fn: function (aString, anotherString){
 fn: function (aString, anotherString){
 var self=this;
 var self=this;
-return smalltalk.send(self, "_subclass_instanceVariableNames_category_", [aString, anotherString, nil]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, anotherString, nil]);
 return self;},
 return self;},
-source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20anotherString%0A%09%5Eself%20subclass%3A%20aString%20instanceVariableNames%3A%20anotherString%20category%3A%20nil'),
-messageSends: ["subclass:instanceVariableNames:category:"],
+source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20anotherString%0A%09%22Kept%20for%20compatibility.%22%0A%09%5Eself%20subclass%3A%20aString%20instanceVariableNames%3A%20anotherString%20module%3A%20nil'),
+messageSends: ["subclass:instanceVariableNames:module:"],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
 smalltalk.Class);
 smalltalk.Class);
@@ -1340,11 +1388,11 @@ selector: 'subclass:instanceVariableNames:category:',
 category: 'class creation',
 category: 'class creation',
 fn: function (aString, aString2, aString3){
 fn: function (aString, aString2, aString3){
 var self=this;
 var self=this;
-return smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_superclass_subclass_instanceVariableNames_category_", [self, aString, aString2, aString3]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, aString2, aString3]);
 return self;},
 return self;},
-source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20category%3A%20aString3%0A%09%5EClassBuilder%20new%0A%09%20%20%20%20superclass%3A%20self%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20category%3A%20aString3'),
-messageSends: ["superclass:subclass:instanceVariableNames:category:", "new"],
-referencedClasses: [smalltalk.nil]
+source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20category%3A%20aString3%0A%09%22Kept%20for%20compatibility.%22%0A%09%5Eself%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20module%3A%20aString3'),
+messageSends: ["subclass:instanceVariableNames:module:"],
+referencedClasses: []
 }),
 }),
 smalltalk.Class);
 smalltalk.Class);
 
 
@@ -1404,14 +1452,59 @@ selector: 'subclass:instanceVariableNames:classVariableNames:poolDictionaries:ca
 category: 'class creation',
 category: 'class creation',
 fn: function (aString, aString2, classVars, pools, aString3){
 fn: function (aString, aString2, classVars, pools, aString3){
 var self=this;
 var self=this;
-return smalltalk.send(self, "_subclass_instanceVariableNames_category_", [aString, aString2, aString3]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, aString2, aString3]);
+return self;},
+source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20classVariableNames%3A%20classVars%20poolDictionaries%3A%20pools%20category%3A%20aString3%0A%09%22Just%20ignore%20class%20variables%20and%20pools.%20Added%20for%20compatibility.%22%0A%09%5Eself%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20module%3A%20aString3'),
+messageSends: ["subclass:instanceVariableNames:module:"],
+referencedClasses: []
+}),
+smalltalk.Class);
+
+smalltalk.addMethod(
+'_module',
+smalltalk.method({
+selector: 'module',
+category: 'accessing',
+fn: function (){
+var self=this;
+return self.module;
 return self;},
 return self;},
-source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20classVariableNames%3A%20classVars%20poolDictionaries%3A%20pools%20category%3A%20aString3%0A%09%22Just%20ignore%20class%20variables%20and%20pools.%20Added%20for%20compatibility.%22%0A%09%5Eself%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20category%3A%20aString3'),
-messageSends: ["subclass:instanceVariableNames:category:"],
+source: unescape('module%0A%09%3Creturn%20self.module%3E'),
+messageSends: [],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
 smalltalk.Class);
 smalltalk.Class);
 
 
+smalltalk.addMethod(
+'_module_',
+smalltalk.method({
+selector: 'module:',
+category: 'accessing',
+fn: function (aModule){
+var self=this;
+self.module = aModule;
+return self;},
+source: unescape('module%3A%20aModule%0A%09%3Cself.module%20%3D%20aModule%3E'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Class);
+
+smalltalk.addMethod(
+'_subclass_instanceVariableNames_module_',
+smalltalk.method({
+selector: 'subclass:instanceVariableNames:module:',
+category: 'class creation',
+fn: function (aString, aString2, aString3){
+var self=this;
+return smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_superclass_subclass_instanceVariableNames_module_", [self, aString, aString2, aString3]);
+return self;},
+source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20module%3A%20aString3%0A%09%5EClassBuilder%20new%0A%09%20%20%20%20superclass%3A%20self%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20module%3A%20aString3'),
+messageSends: ["superclass:subclass:instanceVariableNames:module:", "new"],
+referencedClasses: [smalltalk.ClassBuilder]
+}),
+smalltalk.Class);
+
 
 
 
 
 smalltalk.addClass('Metaclass', smalltalk.Behavior, [], 'Kernel');
 smalltalk.addClass('Metaclass', smalltalk.Behavior, [], 'Kernel');
@@ -3231,10 +3324,10 @@ selector: 'subclass:instanceVariableNames:',
 category: 'class creation',
 category: 'class creation',
 fn: function (aString, anotherString){
 fn: function (aString, anotherString){
 var self=this;
 var self=this;
-return smalltalk.send(self, "_subclass_instanceVariableNames_category_", [aString, anotherString, nil]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, anotherString, nil]);
 return self;},
 return self;},
-source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20anotherString%0A%09%5Eself%20subclass%3A%20aString%20instanceVariableNames%3A%20anotherString%20category%3A%20nil'),
-messageSends: ["subclass:instanceVariableNames:category:"],
+source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20anotherString%0A%09%5Eself%20subclass%3A%20aString%20instanceVariableNames%3A%20anotherString%20module%3A%20nil'),
+messageSends: ["subclass:instanceVariableNames:module:"],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
 smalltalk.UndefinedObject);
 smalltalk.UndefinedObject);
@@ -3246,11 +3339,11 @@ selector: 'subclass:instanceVariableNames:category:',
 category: 'class creation',
 category: 'class creation',
 fn: function (aString, aString2, aString3){
 fn: function (aString, aString2, aString3){
 var self=this;
 var self=this;
-return smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_superclass_subclass_instanceVariableNames_category_", [self, aString, aString2, aString3]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, aString2, aString3]);
 return self;},
 return self;},
-source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20category%3A%20aString3%0A%09%5EClassBuilder%20new%0A%09%20%20%20%20superclass%3A%20self%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20category%3A%20aString3'),
-messageSends: ["superclass:subclass:instanceVariableNames:category:", "new"],
-referencedClasses: [smalltalk.nil]
+source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20category%3A%20aString3%0A%09%22Kept%20for%20compatibility.%22%0A%09%5Eself%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20module%3A%20aString3'),
+messageSends: ["subclass:instanceVariableNames:module:"],
+referencedClasses: []
 }),
 }),
 smalltalk.UndefinedObject);
 smalltalk.UndefinedObject);
 
 
@@ -3389,6 +3482,21 @@ referencedClasses: []
 }),
 }),
 smalltalk.UndefinedObject);
 smalltalk.UndefinedObject);
 
 
+smalltalk.addMethod(
+'_subclass_instanceVariableNames_module_',
+smalltalk.method({
+selector: 'subclass:instanceVariableNames:module:',
+category: 'class creation',
+fn: function (aString, aString2, aString3){
+var self=this;
+return smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_superclass_subclass_instanceVariableNames_module_", [self, aString, aString2, aString3]);
+return self;},
+source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20module%3A%20aString3%0A%09%5EClassBuilder%20new%0A%09%20%20%20%20superclass%3A%20self%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20module%3A%20aString3'),
+messageSends: ["superclass:subclass:instanceVariableNames:module:", "new"],
+referencedClasses: [smalltalk.ClassBuilder]
+}),
+smalltalk.UndefinedObject);
+
 
 
 smalltalk.addMethod(
 smalltalk.addMethod(
 '_new',
 '_new',
@@ -6155,28 +6263,10 @@ selector: 'superclass:subclass:',
 category: 'class creation',
 category: 'class creation',
 fn: function (aClass, aString){
 fn: function (aClass, aString){
 var self=this;
 var self=this;
-smalltalk.send(self, "_superclass_subclass_instanceVariableNames_category_", [aClass, aString, "", nil]);
+return smalltalk.send(self, "_superclass_subclass_instanceVariableNames_module_", [aClass, aString, "", nil]);
 return self;},
 return self;},
-source: unescape('superclass%3A%20aClass%20subclass%3A%20aString%0A%09self%20superclass%3A%20aClass%20subclass%3A%20aString%20instanceVariableNames%3A%20%27%27%20category%3A%20nil'),
-messageSends: ["superclass:subclass:instanceVariableNames:category:"],
-referencedClasses: []
-}),
-smalltalk.ClassBuilder);
-
-smalltalk.addMethod(
-'_superclass_subclass_instanceVariableNames_category_',
-smalltalk.method({
-selector: 'superclass:subclass:instanceVariableNames:category:',
-category: 'class creation',
-fn: function (aClass, aString, aString2, aString3){
-var self=this;
-var newClass=nil;
-newClass=smalltalk.send(self, "_addSubclassOf_named_instanceVariableNames_", [aClass, aString, smalltalk.send(self, "_instanceVariableNamesFor_", [aString2])]);
-smalltalk.send(self, "_setupClass_", [newClass]);
-smalltalk.send(newClass, "_category_", [(($receiver = aString3) == nil || $receiver == undefined) ? (function(){return "unclassified";})() : $receiver]);
-return self;},
-source: unescape('superclass%3A%20aClass%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20category%3A%20aString3%0A%09%7C%20newClass%20%7C%0A%09newClass%20%3A%3D%20self%20addSubclassOf%3A%20aClass%20named%3A%20aString%20instanceVariableNames%3A%20%28self%20instanceVariableNamesFor%3A%20aString2%29.%0A%09self%20setupClass%3A%20newClass.%0A%09newClass%20category%3A%20%28aString3%20ifNil%3A%20%5B%27unclassified%27%5D%29'),
-messageSends: ["addSubclassOf:named:instanceVariableNames:", "instanceVariableNamesFor:", "setupClass:", "category:", "ifNil:"],
+source: unescape('superclass%3A%20aClass%20subclass%3A%20aString%0A%09%5Eself%20superclass%3A%20aClass%20subclass%3A%20aString%20instanceVariableNames%3A%20%27%27%20module%3A%20nil'),
+messageSends: ["superclass:subclass:instanceVariableNames:module:"],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
 smalltalk.ClassBuilder);
 smalltalk.ClassBuilder);
@@ -6244,6 +6334,39 @@ referencedClasses: []
 }),
 }),
 smalltalk.ClassBuilder);
 smalltalk.ClassBuilder);
 
 
+smalltalk.addMethod(
+'_superclass_subclass_instanceVariableNames_module_',
+smalltalk.method({
+selector: 'superclass:subclass:instanceVariableNames:module:',
+category: 'class creation',
+fn: function (aClass, aString, aString2, aString3){
+var self=this;
+var newClass=nil;
+newClass=smalltalk.send(self, "_addSubclassOf_named_instanceVariableNames_module_", [aClass, aString, smalltalk.send(self, "_instanceVariableNamesFor_", [aString2]), (($receiver = aString3) == nil || $receiver == undefined) ? (function(){return "unclassified";})() : $receiver]);
+smalltalk.send(self, "_setupClass_", [newClass]);
+return self;},
+source: unescape('superclass%3A%20aClass%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20module%3A%20aString3%0A%09%7C%20newClass%20%7C%0A%09newClass%20%3A%3D%20self%20addSubclassOf%3A%20aClass%0A%09%09%09%09named%3A%20aString%20instanceVariableNames%3A%20%28self%20instanceVariableNamesFor%3A%20aString2%29%0A%09%09%09%09module%3A%20%28aString3%20ifNil%3A%20%5B%27unclassified%27%5D%29.%0A%09self%20setupClass%3A%20newClass'),
+messageSends: ["addSubclassOf:named:instanceVariableNames:module:", "instanceVariableNamesFor:", "ifNil:", "setupClass:"],
+referencedClasses: []
+}),
+smalltalk.ClassBuilder);
+
+smalltalk.addMethod(
+'_addSubclassOf_named_instanceVariableNames_module_',
+smalltalk.method({
+selector: 'addSubclassOf:named:instanceVariableNames:module:',
+category: 'private',
+fn: function (aClass, aString, aCollection, moduleName){
+var self=this;
+smalltalk.addClass(aString, aClass, aCollection, moduleName);
+	    return smalltalk[aString];
+return self;},
+source: unescape('addSubclassOf%3A%20aClass%20named%3A%20aString%20instanceVariableNames%3A%20aCollection%20module%3A%20moduleName%0A%09%3Csmalltalk.addClass%28aString%2C%20aClass%2C%20aCollection%2C%20moduleName%29%3B%0A%09%20%20%20%20return%20smalltalk%5BaString%5D%3E'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ClassBuilder);
+
 
 
 
 
 smalltalk.addClass('ClassCategoryReader', smalltalk.Object, ['class', 'category', 'chunkParser'], 'Kernel');
 smalltalk.addClass('ClassCategoryReader', smalltalk.Object, ['class', 'category', 'chunkParser'], 'Kernel');

+ 59 - 14
js/boot.js

@@ -38,6 +38,7 @@
 function SmalltalkObject(){};
 function SmalltalkObject(){};
 function SmalltalkBehavior(){};
 function SmalltalkBehavior(){};
 function SmalltalkClass(){};
 function SmalltalkClass(){};
+function SmalltalkModule(){};
 function SmalltalkMetaclass(){
 function SmalltalkMetaclass(){
     this.meta = true;
     this.meta = true;
 };
 };
@@ -48,6 +49,20 @@ function Smalltalk(){
 
 
     var st = this;
     var st = this;
 
 
+    
+    /* We hold all Modules in a separate Object */
+    st.modules = {};
+
+    /* Smalltalk Module object. To add a Module, use smalltalk.addModule() */
+
+    function mod(spec) {
+	var that = new SmalltalkModule();
+	that.moduleName        = spec.moduleName;
+	that.requires          = spec.requires || [];
+	that.fn                = spec.fn || function(){};
+	return that;
+    };
+
     /* Smalltalk class creation. A class is an instance of an automatically 
     /* 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().
        should be added to the smalltalk object, see smalltalk.addClass().
@@ -71,7 +86,11 @@ function Smalltalk(){
 	if(that.superclass) {
 	if(that.superclass) {
 	    that.klass.superclass = that.superclass.klass;
 	    that.klass.superclass = that.superclass.klass;
 	}
 	}
-	that.category = spec.category || "";
+	that.module = spec.module;
+        // For a while we keep the category attribute...
+        if(!(spec.module === undefined)) {
+	    that.category = spec.module.moduleName;
+	}
 	that.fn.prototype.methods = {};
 	that.fn.prototype.methods = {};
 	that.fn.prototype.inheritedMethods = {};
 	that.fn.prototype.inheritedMethods = {};
 	that.fn.prototype.klass = that;
 	that.fn.prototype.klass = that;
@@ -121,6 +140,16 @@ function Smalltalk(){
 	}
 	}
     };
     };
 
 
+    /* Answer all registered Modules */
+
+    st.modules.all = function() {
+	var modules = [];
+	for(var i in st.modules) {
+	    modules.push(st.modules[i]);
+	}
+	return modules
+    };
+
     /* Answer all registered Smalltalk classes */
     /* Answer all registered Smalltalk classes */
 
 
     st.classes = function() {
     st.classes = function() {
@@ -129,7 +158,6 @@ function Smalltalk(){
 	    if(i.search(/^[A-Z]/g) != -1) {
 	    if(i.search(/^[A-Z]/g) != -1) {
 		classes.push(st[i]);
 		classes.push(st[i]);
 	    }
 	    }
-
 	}
 	}
 	return classes
 	return classes
     };
     };
@@ -168,31 +196,47 @@ function Smalltalk(){
     };
     };
 
 
     /* Create a new class wrapping a JavaScript constructor, and add it to the 
     /* Create a new class wrapping a JavaScript constructor, and add it to the 
-       global smalltalk object. */
+       global smalltalk object. Module is lazily created if it does not exist with given name. */
 
 
-    st.mapClassName = function(className, category, fn, superclass) {
+    st.mapClassName = function(className, moduleName, fn, superclass) {
+	modul = st.addModule(moduleName);
 	st[className] = klass({
 	st[className] = klass({
 	    className:  className, 
 	    className:  className, 
-	    category:   category, 
+	    module:     modul, 
 	    superclass: superclass,
 	    superclass: superclass,
 	    fn:         fn
 	    fn:         fn
 	});
 	});
     };
     };
 
 
-    /* Add a class to the smalltalk object, creating a new one if needed. */
+    /* Add a module to the smalltalk.modules object, creating a new one if needed.
+       If moduleName is nil or empty we return nil, which is an allowed module for a class. */
 
 
-    st.addClass = function(className, superclass, iVarNames, category) {
+    st.addModule = function(moduleName) {
+	if(!moduleName) {return nil;}
+	if(!(st.modules[moduleName])) {
+	    st.modules[moduleName] = mod({
+		moduleName: moduleName
+	    });
+	}
+	return st.modules[moduleName];
+    };
+
+    /* Add a class to the smalltalk object, creating a new one if needed.
+       Module is lazily created if it does not exist with given name.*/
+
+    st.addClass = function(className, superclass, iVarNames, moduleName) {
+	modul = st.addModule(moduleName);
 	if(st[className]) {
 	if(st[className]) {
 	    st[className].superclass = superclass;
 	    st[className].superclass = superclass;
 	    st[className].iVarNames = iVarNames;
 	    st[className].iVarNames = iVarNames;
-	    st[className].category = category || st[className].category;
-	} else {
+	    st[className].module = modul || st[className].module;
+	} else {    
 	    st[className] = klass({
 	    st[className] = klass({
 		className: className, 
 		className: className, 
 		iVarNames: iVarNames,
 		iVarNames: iVarNames,
-		superclass: superclass
+		superclass: superclass,
+		module: modul
 	    });
 	    });
-	    st[className].category = category || '';
 	}
 	}
     };
     };
 
 
@@ -446,12 +490,13 @@ if(this.jQuery) {
 
 
 smalltalk.mapClassName("Object", "Kernel", SmalltalkObject);
 smalltalk.mapClassName("Object", "Kernel", SmalltalkObject);
 smalltalk.mapClassName("Smalltalk", "Kernel", Smalltalk, smalltalk.Object);
 smalltalk.mapClassName("Smalltalk", "Kernel", Smalltalk, smalltalk.Object);
+smalltalk.mapClassName("Module", "Kernel", SmalltalkModule, smalltalk.Object);
 smalltalk.mapClassName("Behavior", "Kernel", SmalltalkBehavior, smalltalk.Object);
 smalltalk.mapClassName("Behavior", "Kernel", SmalltalkBehavior, smalltalk.Object);
 smalltalk.mapClassName("Class", "Kernel", SmalltalkClass, smalltalk.Behavior);
 smalltalk.mapClassName("Class", "Kernel", SmalltalkClass, smalltalk.Behavior);
 smalltalk.mapClassName("Metaclass", "Kernel", SmalltalkMetaclass, smalltalk.Behavior);
 smalltalk.mapClassName("Metaclass", "Kernel", SmalltalkMetaclass, smalltalk.Behavior);
 smalltalk.mapClassName("CompiledMethod", "Kernel", SmalltalkMethod, smalltalk.Object);
 smalltalk.mapClassName("CompiledMethod", "Kernel", SmalltalkMethod, smalltalk.Object);
 
 
-smalltalk.Object.klass.superclass = smalltalk.Class
+smalltalk.Object.klass.superclass = smalltalk.Class;
 
 
 smalltalk.mapClassName("Number", "Kernel", Number, smalltalk.Object);
 smalltalk.mapClassName("Number", "Kernel", Number, smalltalk.Object);
 smalltalk.mapClassName("BlockClosure", "Kernel", Function, smalltalk.Object);
 smalltalk.mapClassName("BlockClosure", "Kernel", Function, smalltalk.Object);
@@ -469,5 +514,5 @@ smalltalk.mapClassName("Error", "Kernel", Error, smalltalk.Object);
 smalltalk.mapClassName("MethodContext", "Kernel", SmalltalkMethodContext, smalltalk.Object);
 smalltalk.mapClassName("MethodContext", "Kernel", SmalltalkMethodContext, smalltalk.Object);
 
 
 if(this.CanvasRenderingContext2D) {
 if(this.CanvasRenderingContext2D) {
-    smalltalk.mapClassName("CanvasRenderingContext", "Canvas", CanvasRenderingContext2D, smalltalk.Object);
-}
+    smalltalk.mapClassName("CanvasRenderingContext", 'Canvas', CanvasRenderingContext2D, smalltalk.Object);
+}

+ 0 - 0
st/Compiler.st


+ 64 - 21
st/Kernel.st

@@ -292,9 +292,13 @@ parseError: anException parsing: aString
 	badLine := (badLine copyFrom: 1 to: col - 1), ' ===>', (badLine copyFrom:  col to: badLine size).
 	badLine := (badLine copyFrom: 1 to: col - 1), ' ===>', (badLine copyFrom:  col to: badLine size).
 	lines at: row put: badLine.
 	lines at: row put: badLine.
 	code := String streamContents: [:s |
 	code := String streamContents: [:s |
-                                        lines withIndexDo: [:l :i |
-                                                   s nextPutAll: i asString, ': ', l, String lf]].
+                  lines withIndexDo: [:l :i |
+                     s nextPutAll: i asString, ': ', l, String lf]].
 	^ Error new messageText: ('Parse error on line ' , row , ' column ' , col , ' : ' , message , ' Below is code with line numbers and ===> marker inserted:' , String lf, code)
 	^ Error new messageText: ('Parse error on line ' , row , ' column ' , col , ' : ' , message , ' Below is code with line numbers and ===> marker inserted:' , String lf, code)
+!
+
+modules
+	<return self.modules.all()>
 ! !
 ! !
 
 
 Smalltalk class instanceVariableNames: 'current'!
 Smalltalk class instanceVariableNames: 'current'!
@@ -305,6 +309,24 @@ current
 	<return smalltalk>
 	<return smalltalk>
 ! !
 ! !
 
 
+Object subclass: #Module
+	instanceVariableNames: ''
+	category: 'Kernel'!
+
+!Module methodsFor: 'accessing'!
+
+name
+	<return self.moduleName || nil>
+!
+
+requires
+	<return self.requires || nil>
+!
+
+name: aString
+	<return self.moduleName = aString>
+! !
+
 Object subclass: #Behavior
 Object subclass: #Behavior
 	instanceVariableNames: ''
 	instanceVariableNames: ''
 	category: 'Kernel'!
 	category: 'Kernel'!
@@ -461,11 +483,7 @@ Behavior subclass: #Class
 !Class methodsFor: 'accessing'!
 !Class methodsFor: 'accessing'!
 
 
 category
 category
-	<return self.category>
-!
-
-category: aString
-	<self.category = aString>
+	^self module ifNil: ['unclassified'] ifNotNil: [self module name]
 !
 !
 
 
 rename: aString
 rename: aString
@@ -474,22 +492,36 @@ rename: aString
 		delete smalltalk[self.className];
 		delete smalltalk[self.className];
 		self.className = aString;
 		self.className = aString;
 	>
 	>
+!
+
+module
+	<return self.module>
+!
+
+module: aModule
+	<self.module = aModule>
 ! !
 ! !
 
 
 !Class methodsFor: 'class creation'!
 !Class methodsFor: 'class creation'!
 
 
 subclass: aString instanceVariableNames: anotherString
 subclass: aString instanceVariableNames: anotherString
-	^self subclass: aString instanceVariableNames: anotherString category: nil
+	"Kept for compatibility."
+	^self subclass: aString instanceVariableNames: anotherString module: nil
 !
 !
 
 
 subclass: aString instanceVariableNames: aString2 category: aString3
 subclass: aString instanceVariableNames: aString2 category: aString3
-	^ClassBuilder new
-	    superclass: self subclass: aString instanceVariableNames: aString2 category: aString3
+	"Kept for compatibility."
+	^self subclass: aString instanceVariableNames: aString2 module: aString3
 !
 !
 
 
 subclass: aString instanceVariableNames: aString2 classVariableNames: classVars poolDictionaries: pools category: aString3
 subclass: aString instanceVariableNames: aString2 classVariableNames: classVars poolDictionaries: pools category: aString3
 	"Just ignore class variables and pools. Added for compatibility."
 	"Just ignore class variables and pools. Added for compatibility."
-	^self subclass: aString instanceVariableNames: aString2 category: aString3
+	^self subclass: aString instanceVariableNames: aString2 module: aString3
+!
+
+subclass: aString instanceVariableNames: aString2 module: aString3
+	^ClassBuilder new
+	    superclass: self subclass: aString instanceVariableNames: aString2 module: aString3
 ! !
 ! !
 
 
 !Class methodsFor: 'printing'!
 !Class methodsFor: 'printing'!
@@ -1129,12 +1161,17 @@ Object subclass: #UndefinedObject
 !UndefinedObject methodsFor: 'class creation'!
 !UndefinedObject methodsFor: 'class creation'!
 
 
 subclass: aString instanceVariableNames: anotherString
 subclass: aString instanceVariableNames: anotherString
-	^self subclass: aString instanceVariableNames: anotherString category: nil
+	^self subclass: aString instanceVariableNames: anotherString module: nil
 !
 !
 
 
 subclass: aString instanceVariableNames: aString2 category: aString3
 subclass: aString instanceVariableNames: aString2 category: aString3
+	"Kept for compatibility."
+	^self subclass: aString instanceVariableNames: aString2 module: aString3
+!
+
+subclass: aString instanceVariableNames: aString2 module: aString3
 	^ClassBuilder new
 	^ClassBuilder new
-	    superclass: self subclass: aString instanceVariableNames: aString2 category: aString3
+	    superclass: self subclass: aString instanceVariableNames: aString2 module: aString3
 ! !
 ! !
 
 
 !UndefinedObject methodsFor: 'copying'!
 !UndefinedObject methodsFor: 'copying'!
@@ -2249,20 +2286,21 @@ Object subclass: #ClassBuilder
 !ClassBuilder methodsFor: 'class creation'!
 !ClassBuilder methodsFor: 'class creation'!
 
 
 superclass: aClass subclass: aString
 superclass: aClass subclass: aString
-	self superclass: aClass subclass: aString instanceVariableNames: '' category: nil
-!
-
-superclass: aClass subclass: aString instanceVariableNames: aString2 category: aString3
-	| newClass |
-	newClass := self addSubclassOf: aClass named: aString instanceVariableNames: (self instanceVariableNamesFor: aString2).
-	self setupClass: newClass.
-	newClass category: (aString3 ifNil: ['unclassified'])
+	^self superclass: aClass subclass: aString instanceVariableNames: '' module: nil
 !
 !
 
 
 class: aClass instanceVariableNames: aString
 class: aClass instanceVariableNames: aString
 	aClass isMetaclass ifFalse: [self error: aClass name, ' is not a metaclass'].
 	aClass isMetaclass ifFalse: [self error: aClass name, ' is not a metaclass'].
 	aClass basicAt: 'iVarNames' put: (self instanceVariableNamesFor: aString).
 	aClass basicAt: 'iVarNames' put: (self instanceVariableNamesFor: aString).
 	self setupClass: aClass
 	self setupClass: aClass
+!
+
+superclass: aClass subclass: aString instanceVariableNames: aString2 module: aString3
+	| newClass |
+	newClass := self addSubclassOf: aClass
+				named: aString instanceVariableNames: (self instanceVariableNamesFor: aString2)
+				module: (aString3 ifNil: ['unclassified']).
+	self setupClass: newClass
 ! !
 ! !
 
 
 !ClassBuilder methodsFor: 'private'!
 !ClassBuilder methodsFor: 'private'!
@@ -2278,6 +2316,11 @@ addSubclassOf: aClass named: aString instanceVariableNames: aCollection
 
 
 setupClass: aClass
 setupClass: aClass
 	<smalltalk.init(aClass);>
 	<smalltalk.init(aClass);>
+!
+
+addSubclassOf: aClass named: aString instanceVariableNames: aCollection module: moduleName
+	<smalltalk.addClass(aString, aClass, aCollection, moduleName);
+	    return smalltalk[aString]>
 ! !
 ! !
 
 
 Object subclass: #ClassCategoryReader
 Object subclass: #ClassCategoryReader