Browse Source

Add untracked files

Nicolas Petton 13 years ago
parent
commit
e59f182a9a

+ 1051 - 0
js/Compiler-AST.deploy.js

@@ -0,0 +1,1051 @@
+smalltalk.addPackage('Compiler-AST', {});
+smalltalk.addClass('Node', smalltalk.Object, ['nodes', 'used', 'alias'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitNode_", [self]);
+return self;}
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_addNode_",
+smalltalk.method({
+selector: "addNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_nodes", []), "_add_", [aNode]);
+return self;}
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_alias",
+smalltalk.method({
+selector: "alias",
+fn: function () {
+var self=this;
+return self['@alias'];
+return self;}
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_alias_",
+smalltalk.method({
+selector: "alias:",
+fn: function (aString) {
+var self=this;
+(self['@alias']=aString);
+return self;}
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_beUsed",
+smalltalk.method({
+selector: "beUsed",
+fn: function () {
+var self=this;
+(self['@used']=true);
+return self;}
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_canAliasChildren",
+smalltalk.method({
+selector: "canAliasChildren",
+fn: function () {
+var self=this;
+return true;
+return self;}
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_isAliased",
+smalltalk.method({
+selector: "isAliased",
+fn: function () {
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_alias", []), "_notNil", []);
+return self;}
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_isBlockNode",
+smalltalk.method({
+selector: "isBlockNode",
+fn: function () {
+var self=this;
+return false;
+return self;}
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_isBlockSequenceNode",
+smalltalk.method({
+selector: "isBlockSequenceNode",
+fn: function () {
+var self=this;
+return false;
+return self;}
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_isSendNode",
+smalltalk.method({
+selector: "isSendNode",
+fn: function () {
+var self=this;
+return false;
+return self;}
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_isUsed",
+smalltalk.method({
+selector: "isUsed",
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_used", []);
+return self;}
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_isValueNode",
+smalltalk.method({
+selector: "isValueNode",
+fn: function () {
+var self=this;
+return false;
+return self;}
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_nodes",
+smalltalk.method({
+selector: "nodes",
+fn: function () {
+var self=this;
+return (($receiver = self['@nodes']) == nil || $receiver == undefined) ? (function(){return (self['@nodes']=smalltalk.send((smalltalk.Array || Array), "_new", []));})() : $receiver;
+return self;}
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_nodes_",
+smalltalk.method({
+selector: "nodes:",
+fn: function (aCollection) {
+var self=this;
+(self['@nodes']=aCollection);
+return self;}
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_shouldBeAliased",
+smalltalk.method({
+selector: "shouldBeAliased",
+fn: function () {
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_isUsed", []), "_and_", [(function(){return smalltalk.send(smalltalk.send(self, "_alias", []), "_isNil", []);})]);
+return self;}
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_used",
+smalltalk.method({
+selector: "used",
+fn: function () {
+var self=this;
+return (($receiver = self['@used']) == nil || $receiver == undefined) ? (function(){return false;})() : $receiver;
+return self;}
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_used_",
+smalltalk.method({
+selector: "used:",
+fn: function (aBoolean) {
+var self=this;
+(self['@used']=aBoolean);
+return self;}
+}),
+smalltalk.Node);
+
+
+
+smalltalk.addClass('AssignmentNode', smalltalk.Node, ['left', 'right'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitAssignmentNode_", [self]);
+return self;}
+}),
+smalltalk.AssignmentNode);
+
+smalltalk.addMethod(
+"_left",
+smalltalk.method({
+selector: "left",
+fn: function () {
+var self=this;
+return self['@left'];
+return self;}
+}),
+smalltalk.AssignmentNode);
+
+smalltalk.addMethod(
+"_left_",
+smalltalk.method({
+selector: "left:",
+fn: function (aNode) {
+var self=this;
+(self['@left']=aNode);
+smalltalk.send(self['@left'], "_assigned_", [true]);
+return self;}
+}),
+smalltalk.AssignmentNode);
+
+smalltalk.addMethod(
+"_nodes",
+smalltalk.method({
+selector: "nodes",
+fn: function () {
+var self=this;
+return smalltalk.send((smalltalk.Array || Array), "_with_with_", [smalltalk.send(self, "_left", []), smalltalk.send(self, "_right", [])]);
+return self;}
+}),
+smalltalk.AssignmentNode);
+
+smalltalk.addMethod(
+"_right",
+smalltalk.method({
+selector: "right",
+fn: function () {
+var self=this;
+return self['@right'];
+return self;}
+}),
+smalltalk.AssignmentNode);
+
+smalltalk.addMethod(
+"_right_",
+smalltalk.method({
+selector: "right:",
+fn: function (aNode) {
+var self=this;
+(self['@right']=aNode);
+return self;}
+}),
+smalltalk.AssignmentNode);
+
+
+
+smalltalk.addClass('BlockNode', smalltalk.Node, ['parameters', 'scope', 'inlined'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitBlockNode_", [self]);
+return self;}
+}),
+smalltalk.BlockNode);
+
+smalltalk.addMethod(
+"_inlined",
+smalltalk.method({
+selector: "inlined",
+fn: function () {
+var self=this;
+return (($receiver = self['@inlined']) == nil || $receiver == undefined) ? (function(){return false;})() : $receiver;
+return self;}
+}),
+smalltalk.BlockNode);
+
+smalltalk.addMethod(
+"_inlined_",
+smalltalk.method({
+selector: "inlined:",
+fn: function (aBoolean) {
+var self=this;
+(self['@inlined']=aBoolean);
+return self;}
+}),
+smalltalk.BlockNode);
+
+smalltalk.addMethod(
+"_isBlockNode",
+smalltalk.method({
+selector: "isBlockNode",
+fn: function () {
+var self=this;
+return true;
+return self;}
+}),
+smalltalk.BlockNode);
+
+smalltalk.addMethod(
+"_parameters",
+smalltalk.method({
+selector: "parameters",
+fn: function () {
+var self=this;
+return (($receiver = self['@parameters']) == nil || $receiver == undefined) ? (function(){return (self['@parameters']=smalltalk.send((smalltalk.Array || Array), "_new", []));})() : $receiver;
+return self;}
+}),
+smalltalk.BlockNode);
+
+smalltalk.addMethod(
+"_parameters_",
+smalltalk.method({
+selector: "parameters:",
+fn: function (aCollection) {
+var self=this;
+(self['@parameters']=aCollection);
+return self;}
+}),
+smalltalk.BlockNode);
+
+smalltalk.addMethod(
+"_scope",
+smalltalk.method({
+selector: "scope",
+fn: function () {
+var self=this;
+return self['@scope'];
+return self;}
+}),
+smalltalk.BlockNode);
+
+smalltalk.addMethod(
+"_scope_",
+smalltalk.method({
+selector: "scope:",
+fn: function (aLexicalScope) {
+var self=this;
+(self['@scope']=aLexicalScope);
+return self;}
+}),
+smalltalk.BlockNode);
+
+
+
+smalltalk.addClass('CascadeNode', smalltalk.Node, ['receiver'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitCascadeNode_", [self]);
+return self;}
+}),
+smalltalk.CascadeNode);
+
+smalltalk.addMethod(
+"_receiver",
+smalltalk.method({
+selector: "receiver",
+fn: function () {
+var self=this;
+return self['@receiver'];
+return self;}
+}),
+smalltalk.CascadeNode);
+
+smalltalk.addMethod(
+"_receiver_",
+smalltalk.method({
+selector: "receiver:",
+fn: function (aNode) {
+var self=this;
+(self['@receiver']=aNode);
+return self;}
+}),
+smalltalk.CascadeNode);
+
+
+
+smalltalk.addClass('DynamicArrayNode', smalltalk.Node, [], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitDynamicArrayNode_", [self]);
+return self;}
+}),
+smalltalk.DynamicArrayNode);
+
+
+
+smalltalk.addClass('DynamicDictionaryNode', smalltalk.Node, [], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitDynamicDictionaryNode_", [self]);
+return self;}
+}),
+smalltalk.DynamicDictionaryNode);
+
+
+
+smalltalk.addClass('JSStatementNode', smalltalk.Node, ['source'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitJSStatementNode_", [self]);
+return self;}
+}),
+smalltalk.JSStatementNode);
+
+smalltalk.addMethod(
+"_source",
+smalltalk.method({
+selector: "source",
+fn: function () {
+var self=this;
+return (($receiver = self['@source']) == nil || $receiver == undefined) ? (function(){return "";})() : $receiver;
+return self;}
+}),
+smalltalk.JSStatementNode);
+
+smalltalk.addMethod(
+"_source_",
+smalltalk.method({
+selector: "source:",
+fn: function (aString) {
+var self=this;
+(self['@source']=aString);
+return self;}
+}),
+smalltalk.JSStatementNode);
+
+
+
+smalltalk.addClass('MethodNode', smalltalk.Node, ['selector', 'arguments', 'source', 'scope', 'classReferences', 'messageSends'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitMethodNode_", [self]);
+return self;}
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_arguments",
+smalltalk.method({
+selector: "arguments",
+fn: function () {
+var self=this;
+return (($receiver = self['@arguments']) == nil || $receiver == undefined) ? (function(){return [];})() : $receiver;
+return self;}
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_arguments_",
+smalltalk.method({
+selector: "arguments:",
+fn: function (aCollection) {
+var self=this;
+(self['@arguments']=aCollection);
+return self;}
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_canAliasChildren",
+smalltalk.method({
+selector: "canAliasChildren",
+fn: function () {
+var self=this;
+return false;
+return self;}
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_classReferences",
+smalltalk.method({
+selector: "classReferences",
+fn: function () {
+var self=this;
+return self['@classReferences'];
+return self;}
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_classReferences_",
+smalltalk.method({
+selector: "classReferences:",
+fn: function (aCollection) {
+var self=this;
+(self['@classReferences']=aCollection);
+return self;}
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_hasNonLocalReturn",
+smalltalk.method({
+selector: "hasNonLocalReturn",
+fn: function () {
+var self=this;
+return (($receiver = smalltalk.send(self, "_scope", [])) == nil || $receiver == undefined) ? (function(){return false;})() : (function(){return smalltalk.send(smalltalk.send(self, "_scope", []), "_hasNonLocalReturn", []);})();
+return self;}
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_messageSends",
+smalltalk.method({
+selector: "messageSends",
+fn: function () {
+var self=this;
+return self['@messageSends'];
+return self;}
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_messageSends_",
+smalltalk.method({
+selector: "messageSends:",
+fn: function (aCollection) {
+var self=this;
+(self['@messageSends']=aCollection);
+return self;}
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_scope",
+smalltalk.method({
+selector: "scope",
+fn: function () {
+var self=this;
+return self['@scope'];
+return self;}
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_scope_",
+smalltalk.method({
+selector: "scope:",
+fn: function (aMethodScope) {
+var self=this;
+(self['@scope']=aMethodScope);
+return self;}
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_selector",
+smalltalk.method({
+selector: "selector",
+fn: function () {
+var self=this;
+return self['@selector'];
+return self;}
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_selector_",
+smalltalk.method({
+selector: "selector:",
+fn: function (aString) {
+var self=this;
+(self['@selector']=aString);
+return self;}
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_source",
+smalltalk.method({
+selector: "source",
+fn: function () {
+var self=this;
+return self['@source'];
+return self;}
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_source_",
+smalltalk.method({
+selector: "source:",
+fn: function (aString) {
+var self=this;
+(self['@source']=aString);
+return self;}
+}),
+smalltalk.MethodNode);
+
+
+
+smalltalk.addClass('ReturnNode', smalltalk.Node, ['nonLocalReturn'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitReturnNode_", [self]);
+return self;}
+}),
+smalltalk.ReturnNode);
+
+smalltalk.addMethod(
+"_nonLocalReturn",
+smalltalk.method({
+selector: "nonLocalReturn",
+fn: function () {
+var self=this;
+return (($receiver = self['@nonLocalReturn']) == nil || $receiver == undefined) ? (function(){return false;})() : $receiver;
+return self;}
+}),
+smalltalk.ReturnNode);
+
+smalltalk.addMethod(
+"_nonLocalReturn_",
+smalltalk.method({
+selector: "nonLocalReturn:",
+fn: function (aBoolean) {
+var self=this;
+(self['@nonLocalReturn']=aBoolean);
+return self;}
+}),
+smalltalk.ReturnNode);
+
+smalltalk.addMethod(
+"_shouldBeAliased",
+smalltalk.method({
+selector: "shouldBeAliased",
+fn: function () {
+var self=this;
+return false;
+return self;}
+}),
+smalltalk.ReturnNode);
+
+
+
+smalltalk.addClass('SendNode', smalltalk.Node, ['selector', 'arguments', 'receiver'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitSendNode_", [self]);
+return self;}
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_arguments",
+smalltalk.method({
+selector: "arguments",
+fn: function () {
+var self=this;
+return (($receiver = self['@arguments']) == nil || $receiver == undefined) ? (function(){return (self['@arguments']=[]);})() : $receiver;
+return self;}
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_arguments_",
+smalltalk.method({
+selector: "arguments:",
+fn: function (aCollection) {
+var self=this;
+(self['@arguments']=aCollection);
+return self;}
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_cascadeNodeWithMessages_",
+smalltalk.method({
+selector: "cascadeNodeWithMessages:",
+fn: function (aCollection) {
+var self=this;
+var first=nil;
+(first=(function($rec){smalltalk.send($rec, "_selector_", [smalltalk.send(self, "_selector", [])]);smalltalk.send($rec, "_arguments_", [smalltalk.send(self, "_arguments", [])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.SendNode || SendNode), "_new", [])));
+return (function($rec){smalltalk.send($rec, "_receiver_", [smalltalk.send(self, "_receiver", [])]);smalltalk.send($rec, "_nodes_", [smalltalk.send(smalltalk.send((smalltalk.Array || Array), "_with_", [first]), "__comma", [aCollection])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.CascadeNode || CascadeNode), "_new", []));
+return self;}
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_isSendNode",
+smalltalk.method({
+selector: "isSendNode",
+fn: function () {
+var self=this;
+return true;
+return self;}
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_nodes",
+smalltalk.method({
+selector: "nodes",
+fn: function () {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_add_", [smalltalk.send(self, "_receiver", [])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.Array || Array), "_withAll_", [smalltalk.send(self, "_arguments", [])]));
+return self;}
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_receiver",
+smalltalk.method({
+selector: "receiver",
+fn: function () {
+var self=this;
+return self['@receiver'];
+return self;}
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_receiver_",
+smalltalk.method({
+selector: "receiver:",
+fn: function (aNode) {
+var self=this;
+(self['@receiver']=aNode);
+return self;}
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_selector",
+smalltalk.method({
+selector: "selector",
+fn: function () {
+var self=this;
+return self['@selector'];
+return self;}
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_selector_",
+smalltalk.method({
+selector: "selector:",
+fn: function (aString) {
+var self=this;
+(self['@selector']=aString);
+return self;}
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_valueForReceiver_",
+smalltalk.method({
+selector: "valueForReceiver:",
+fn: function (anObject) {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_receiver_", [(($receiver = smalltalk.send(self, "_receiver", [])) == nil || $receiver == undefined) ? (function(){return anObject;})() : (function(){return smalltalk.send(smalltalk.send(self, "_receiver", []), "_valueForReceiver_", [anObject]);})()]);smalltalk.send($rec, "_selector_", [smalltalk.send(self, "_selector", [])]);smalltalk.send($rec, "_arguments_", [smalltalk.send(self, "_arguments", [])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.SendNode || SendNode), "_new", []));
+return self;}
+}),
+smalltalk.SendNode);
+
+
+
+smalltalk.addClass('SequenceNode', smalltalk.Node, ['temps', 'scope'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitSequenceNode_", [self]);
+return self;}
+}),
+smalltalk.SequenceNode);
+
+smalltalk.addMethod(
+"_asBlockSequenceNode",
+smalltalk.method({
+selector: "asBlockSequenceNode",
+fn: function () {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_nodes_", [smalltalk.send(self, "_nodes", [])]);smalltalk.send($rec, "_temps_", [smalltalk.send(self, "_temps", [])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.BlockSequenceNode || BlockSequenceNode), "_new", []));
+return self;}
+}),
+smalltalk.SequenceNode);
+
+smalltalk.addMethod(
+"_canAliasChildren",
+smalltalk.method({
+selector: "canAliasChildren",
+fn: function () {
+var self=this;
+return false;
+return self;}
+}),
+smalltalk.SequenceNode);
+
+smalltalk.addMethod(
+"_scope",
+smalltalk.method({
+selector: "scope",
+fn: function () {
+var self=this;
+return self['@scope'];
+return self;}
+}),
+smalltalk.SequenceNode);
+
+smalltalk.addMethod(
+"_scope_",
+smalltalk.method({
+selector: "scope:",
+fn: function (aLexicalScope) {
+var self=this;
+(self['@scope']=aLexicalScope);
+return self;}
+}),
+smalltalk.SequenceNode);
+
+smalltalk.addMethod(
+"_temps",
+smalltalk.method({
+selector: "temps",
+fn: function () {
+var self=this;
+return (($receiver = self['@temps']) == nil || $receiver == undefined) ? (function(){return [];})() : $receiver;
+return self;}
+}),
+smalltalk.SequenceNode);
+
+smalltalk.addMethod(
+"_temps_",
+smalltalk.method({
+selector: "temps:",
+fn: function (aCollection) {
+var self=this;
+(self['@temps']=aCollection);
+return self;}
+}),
+smalltalk.SequenceNode);
+
+
+
+smalltalk.addClass('BlockSequenceNode', smalltalk.SequenceNode, [], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitBlockSequenceNode_", [self]);
+return self;}
+}),
+smalltalk.BlockSequenceNode);
+
+smalltalk.addMethod(
+"_isBlockSequenceNode",
+smalltalk.method({
+selector: "isBlockSequenceNode",
+fn: function () {
+var self=this;
+return true;
+return self;}
+}),
+smalltalk.BlockSequenceNode);
+
+
+
+smalltalk.addClass('ValueNode', smalltalk.Node, ['value'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitValueNode_", [self]);
+return self;}
+}),
+smalltalk.ValueNode);
+
+smalltalk.addMethod(
+"_isValueNode",
+smalltalk.method({
+selector: "isValueNode",
+fn: function () {
+var self=this;
+return true;
+return self;}
+}),
+smalltalk.ValueNode);
+
+smalltalk.addMethod(
+"_shouldBeAliased",
+smalltalk.method({
+selector: "shouldBeAliased",
+fn: function () {
+var self=this;
+return false;
+return self;}
+}),
+smalltalk.ValueNode);
+
+smalltalk.addMethod(
+"_value",
+smalltalk.method({
+selector: "value",
+fn: function () {
+var self=this;
+return self['@value'];
+return self;}
+}),
+smalltalk.ValueNode);
+
+smalltalk.addMethod(
+"_value_",
+smalltalk.method({
+selector: "value:",
+fn: function (anObject) {
+var self=this;
+(self['@value']=anObject);
+return self;}
+}),
+smalltalk.ValueNode);
+
+
+
+smalltalk.addClass('VariableNode', smalltalk.ValueNode, ['assigned', 'binding'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitVariableNode_", [self]);
+return self;}
+}),
+smalltalk.VariableNode);
+
+smalltalk.addMethod(
+"_alias",
+smalltalk.method({
+selector: "alias",
+fn: function () {
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_binding", []), "_alias", []);
+return self;}
+}),
+smalltalk.VariableNode);
+
+smalltalk.addMethod(
+"_assigned",
+smalltalk.method({
+selector: "assigned",
+fn: function () {
+var self=this;
+return (($receiver = self['@assigned']) == nil || $receiver == undefined) ? (function(){return false;})() : $receiver;
+return self;}
+}),
+smalltalk.VariableNode);
+
+smalltalk.addMethod(
+"_assigned_",
+smalltalk.method({
+selector: "assigned:",
+fn: function (aBoolean) {
+var self=this;
+(self['@assigned']=aBoolean);
+return self;}
+}),
+smalltalk.VariableNode);
+
+smalltalk.addMethod(
+"_beAssigned",
+smalltalk.method({
+selector: "beAssigned",
+fn: function () {
+var self=this;
+(self['@assigned']=true);
+return self;}
+}),
+smalltalk.VariableNode);
+
+smalltalk.addMethod(
+"_binding",
+smalltalk.method({
+selector: "binding",
+fn: function () {
+var self=this;
+return self['@binding'];
+return self;}
+}),
+smalltalk.VariableNode);
+
+smalltalk.addMethod(
+"_binding_",
+smalltalk.method({
+selector: "binding:",
+fn: function (aScopeVar) {
+var self=this;
+((($receiver = smalltalk.send(aScopeVar, "_isKindOf_", [(smalltalk.SemanticAnalyzer || SemanticAnalyzer)])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_halt", []);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(self, "_halt", []);})]));
+(self['@binding']=aScopeVar);
+return self;}
+}),
+smalltalk.VariableNode);
+
+
+
+smalltalk.addClass('ClassReferenceNode', smalltalk.VariableNode, [], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitClassReferenceNode_", [self]);
+return self;}
+}),
+smalltalk.ClassReferenceNode);
+
+
+

+ 1507 - 0
js/Compiler-AST.js

@@ -0,0 +1,1507 @@
+smalltalk.addPackage('Compiler-AST', {});
+smalltalk.addClass('Node', smalltalk.Object, ['nodes', 'used', 'alias'], 'Compiler-AST');
+smalltalk.Node.comment="I am the abstract root class of the abstract syntax tree."
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+category: 'visiting',
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitNode_", [self]);
+return self;},
+args: ["aVisitor"],
+source: "accept: aVisitor\x0a\x09aVisitor visitNode: self",
+messageSends: ["visitNode:"],
+referencedClasses: []
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_addNode_",
+smalltalk.method({
+selector: "addNode:",
+category: 'accessing',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_nodes", []), "_add_", [aNode]);
+return self;},
+args: ["aNode"],
+source: "addNode: aNode\x0a\x09self nodes add: aNode",
+messageSends: ["add:", "nodes"],
+referencedClasses: []
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_alias",
+smalltalk.method({
+selector: "alias",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@alias'];
+return self;},
+args: [],
+source: "alias\x0a\x09^ alias",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_alias_",
+smalltalk.method({
+selector: "alias:",
+category: 'accessing',
+fn: function (aString) {
+var self=this;
+(self['@alias']=aString);
+return self;},
+args: ["aString"],
+source: "alias: aString\x0a\x09alias := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_beUsed",
+smalltalk.method({
+selector: "beUsed",
+category: 'accessing',
+fn: function () {
+var self=this;
+(self['@used']=true);
+return self;},
+args: [],
+source: "beUsed\x0a\x09used := true",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_canAliasChildren",
+smalltalk.method({
+selector: "canAliasChildren",
+category: 'testing',
+fn: function () {
+var self=this;
+return true;
+return self;},
+args: [],
+source: "canAliasChildren\x0a\x09^ true",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_isAliased",
+smalltalk.method({
+selector: "isAliased",
+category: 'testing',
+fn: function () {
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_alias", []), "_notNil", []);
+return self;},
+args: [],
+source: "isAliased\x0a\x09^ self alias notNil",
+messageSends: ["notNil", "alias"],
+referencedClasses: []
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_isBlockNode",
+smalltalk.method({
+selector: "isBlockNode",
+category: 'testing',
+fn: function () {
+var self=this;
+return false;
+return self;},
+args: [],
+source: "isBlockNode\x0a\x09^false",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_isBlockSequenceNode",
+smalltalk.method({
+selector: "isBlockSequenceNode",
+category: 'testing',
+fn: function () {
+var self=this;
+return false;
+return self;},
+args: [],
+source: "isBlockSequenceNode\x0a\x09^false",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_isSendNode",
+smalltalk.method({
+selector: "isSendNode",
+category: 'testing',
+fn: function () {
+var self=this;
+return false;
+return self;},
+args: [],
+source: "isSendNode\x0a\x09^false",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_isUsed",
+smalltalk.method({
+selector: "isUsed",
+category: 'testing',
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_used", []);
+return self;},
+args: [],
+source: "isUsed\x0a\x09^ self used",
+messageSends: ["used"],
+referencedClasses: []
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_isValueNode",
+smalltalk.method({
+selector: "isValueNode",
+category: 'testing',
+fn: function () {
+var self=this;
+return false;
+return self;},
+args: [],
+source: "isValueNode\x0a\x09^false",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_nodes",
+smalltalk.method({
+selector: "nodes",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@nodes']) == nil || $receiver == undefined) ? (function(){return (self['@nodes']=smalltalk.send((smalltalk.Array || Array), "_new", []));})() : $receiver;
+return self;},
+args: [],
+source: "nodes\x0a\x09^nodes ifNil: [nodes := Array new]",
+messageSends: ["ifNil:", "new"],
+referencedClasses: ["Array"]
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_nodes_",
+smalltalk.method({
+selector: "nodes:",
+category: 'building',
+fn: function (aCollection) {
+var self=this;
+(self['@nodes']=aCollection);
+return self;},
+args: ["aCollection"],
+source: "nodes: aCollection\x0a\x09nodes := aCollection",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_shouldBeAliased",
+smalltalk.method({
+selector: "shouldBeAliased",
+category: 'testing',
+fn: function () {
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_isUsed", []), "_and_", [(function(){return smalltalk.send(smalltalk.send(self, "_alias", []), "_isNil", []);})]);
+return self;},
+args: [],
+source: "shouldBeAliased\x0a\x09^ self isUsed and: [ self alias isNil ]",
+messageSends: ["and:", "isUsed", "isNil", "alias"],
+referencedClasses: []
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_used",
+smalltalk.method({
+selector: "used",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@used']) == nil || $receiver == undefined) ? (function(){return false;})() : $receiver;
+return self;},
+args: [],
+source: "used\x0a\x09^ used ifNil: [ false ]",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_used_",
+smalltalk.method({
+selector: "used:",
+category: 'accessing',
+fn: function (aBoolean) {
+var self=this;
+(self['@used']=aBoolean);
+return self;},
+args: ["aBoolean"],
+source: "used: aBoolean\x0a\x09used := aBoolean",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Node);
+
+
+
+smalltalk.addClass('AssignmentNode', smalltalk.Node, ['left', 'right'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+category: 'visiting',
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitAssignmentNode_", [self]);
+return self;},
+args: ["aVisitor"],
+source: "accept: aVisitor\x0a\x09aVisitor visitAssignmentNode: self",
+messageSends: ["visitAssignmentNode:"],
+referencedClasses: []
+}),
+smalltalk.AssignmentNode);
+
+smalltalk.addMethod(
+"_left",
+smalltalk.method({
+selector: "left",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@left'];
+return self;},
+args: [],
+source: "left\x0a\x09^left",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.AssignmentNode);
+
+smalltalk.addMethod(
+"_left_",
+smalltalk.method({
+selector: "left:",
+category: 'accessing',
+fn: function (aNode) {
+var self=this;
+(self['@left']=aNode);
+smalltalk.send(self['@left'], "_assigned_", [true]);
+return self;},
+args: ["aNode"],
+source: "left: aNode\x0a\x09left := aNode.\x0a\x09left assigned: true",
+messageSends: ["assigned:"],
+referencedClasses: []
+}),
+smalltalk.AssignmentNode);
+
+smalltalk.addMethod(
+"_nodes",
+smalltalk.method({
+selector: "nodes",
+category: 'accessing',
+fn: function () {
+var self=this;
+return smalltalk.send((smalltalk.Array || Array), "_with_with_", [smalltalk.send(self, "_left", []), smalltalk.send(self, "_right", [])]);
+return self;},
+args: [],
+source: "nodes\x0a\x09^ Array with: self left with: self right",
+messageSends: ["with:with:", "left", "right"],
+referencedClasses: ["Array"]
+}),
+smalltalk.AssignmentNode);
+
+smalltalk.addMethod(
+"_right",
+smalltalk.method({
+selector: "right",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@right'];
+return self;},
+args: [],
+source: "right\x0a\x09^right",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.AssignmentNode);
+
+smalltalk.addMethod(
+"_right_",
+smalltalk.method({
+selector: "right:",
+category: 'accessing',
+fn: function (aNode) {
+var self=this;
+(self['@right']=aNode);
+return self;},
+args: ["aNode"],
+source: "right: aNode\x0a\x09right := aNode",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.AssignmentNode);
+
+
+
+smalltalk.addClass('BlockNode', smalltalk.Node, ['parameters', 'scope', 'inlined'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+category: 'visiting',
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitBlockNode_", [self]);
+return self;},
+args: ["aVisitor"],
+source: "accept: aVisitor\x0a\x09aVisitor visitBlockNode: self",
+messageSends: ["visitBlockNode:"],
+referencedClasses: []
+}),
+smalltalk.BlockNode);
+
+smalltalk.addMethod(
+"_inlined",
+smalltalk.method({
+selector: "inlined",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@inlined']) == nil || $receiver == undefined) ? (function(){return false;})() : $receiver;
+return self;},
+args: [],
+source: "inlined\x0a\x09^inlined ifNil: [false]",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.BlockNode);
+
+smalltalk.addMethod(
+"_inlined_",
+smalltalk.method({
+selector: "inlined:",
+category: 'accessing',
+fn: function (aBoolean) {
+var self=this;
+(self['@inlined']=aBoolean);
+return self;},
+args: ["aBoolean"],
+source: "inlined: aBoolean\x0a\x09inlined := aBoolean",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.BlockNode);
+
+smalltalk.addMethod(
+"_isBlockNode",
+smalltalk.method({
+selector: "isBlockNode",
+category: 'testing',
+fn: function () {
+var self=this;
+return true;
+return self;},
+args: [],
+source: "isBlockNode\x0a\x09^true",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.BlockNode);
+
+smalltalk.addMethod(
+"_parameters",
+smalltalk.method({
+selector: "parameters",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@parameters']) == nil || $receiver == undefined) ? (function(){return (self['@parameters']=smalltalk.send((smalltalk.Array || Array), "_new", []));})() : $receiver;
+return self;},
+args: [],
+source: "parameters\x0a\x09^parameters ifNil: [parameters := Array new]",
+messageSends: ["ifNil:", "new"],
+referencedClasses: ["Array"]
+}),
+smalltalk.BlockNode);
+
+smalltalk.addMethod(
+"_parameters_",
+smalltalk.method({
+selector: "parameters:",
+category: 'accessing',
+fn: function (aCollection) {
+var self=this;
+(self['@parameters']=aCollection);
+return self;},
+args: ["aCollection"],
+source: "parameters: aCollection\x0a\x09parameters := aCollection",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.BlockNode);
+
+smalltalk.addMethod(
+"_scope",
+smalltalk.method({
+selector: "scope",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@scope'];
+return self;},
+args: [],
+source: "scope\x0a\x09^ scope",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.BlockNode);
+
+smalltalk.addMethod(
+"_scope_",
+smalltalk.method({
+selector: "scope:",
+category: 'accessing',
+fn: function (aLexicalScope) {
+var self=this;
+(self['@scope']=aLexicalScope);
+return self;},
+args: ["aLexicalScope"],
+source: "scope: aLexicalScope\x0a\x09scope := aLexicalScope",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.BlockNode);
+
+
+
+smalltalk.addClass('CascadeNode', smalltalk.Node, ['receiver'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+category: 'visiting',
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitCascadeNode_", [self]);
+return self;},
+args: ["aVisitor"],
+source: "accept: aVisitor\x0a\x09aVisitor visitCascadeNode: self",
+messageSends: ["visitCascadeNode:"],
+referencedClasses: []
+}),
+smalltalk.CascadeNode);
+
+smalltalk.addMethod(
+"_receiver",
+smalltalk.method({
+selector: "receiver",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@receiver'];
+return self;},
+args: [],
+source: "receiver\x0a\x09^receiver",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.CascadeNode);
+
+smalltalk.addMethod(
+"_receiver_",
+smalltalk.method({
+selector: "receiver:",
+category: 'accessing',
+fn: function (aNode) {
+var self=this;
+(self['@receiver']=aNode);
+return self;},
+args: ["aNode"],
+source: "receiver: aNode\x0a\x09receiver := aNode",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.CascadeNode);
+
+
+
+smalltalk.addClass('DynamicArrayNode', smalltalk.Node, [], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+category: 'visiting',
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitDynamicArrayNode_", [self]);
+return self;},
+args: ["aVisitor"],
+source: "accept: aVisitor\x0a\x09aVisitor visitDynamicArrayNode: self",
+messageSends: ["visitDynamicArrayNode:"],
+referencedClasses: []
+}),
+smalltalk.DynamicArrayNode);
+
+
+
+smalltalk.addClass('DynamicDictionaryNode', smalltalk.Node, [], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+category: 'visiting',
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitDynamicDictionaryNode_", [self]);
+return self;},
+args: ["aVisitor"],
+source: "accept: aVisitor\x0a\x09aVisitor visitDynamicDictionaryNode: self",
+messageSends: ["visitDynamicDictionaryNode:"],
+referencedClasses: []
+}),
+smalltalk.DynamicDictionaryNode);
+
+
+
+smalltalk.addClass('JSStatementNode', smalltalk.Node, ['source'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+category: 'visiting',
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitJSStatementNode_", [self]);
+return self;},
+args: ["aVisitor"],
+source: "accept: aVisitor\x0a\x09aVisitor visitJSStatementNode: self",
+messageSends: ["visitJSStatementNode:"],
+referencedClasses: []
+}),
+smalltalk.JSStatementNode);
+
+smalltalk.addMethod(
+"_source",
+smalltalk.method({
+selector: "source",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@source']) == nil || $receiver == undefined) ? (function(){return "";})() : $receiver;
+return self;},
+args: [],
+source: "source\x0a\x09^source ifNil: ['']",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.JSStatementNode);
+
+smalltalk.addMethod(
+"_source_",
+smalltalk.method({
+selector: "source:",
+category: 'accessing',
+fn: function (aString) {
+var self=this;
+(self['@source']=aString);
+return self;},
+args: ["aString"],
+source: "source: aString\x0a\x09source := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.JSStatementNode);
+
+
+
+smalltalk.addClass('MethodNode', smalltalk.Node, ['selector', 'arguments', 'source', 'scope', 'classReferences', 'messageSends'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+category: 'visiting',
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitMethodNode_", [self]);
+return self;},
+args: ["aVisitor"],
+source: "accept: aVisitor\x0a\x09aVisitor visitMethodNode: self",
+messageSends: ["visitMethodNode:"],
+referencedClasses: []
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_arguments",
+smalltalk.method({
+selector: "arguments",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@arguments']) == nil || $receiver == undefined) ? (function(){return [];})() : $receiver;
+return self;},
+args: [],
+source: "arguments\x0a\x09^arguments ifNil: [#()]",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_arguments_",
+smalltalk.method({
+selector: "arguments:",
+category: 'accessing',
+fn: function (aCollection) {
+var self=this;
+(self['@arguments']=aCollection);
+return self;},
+args: ["aCollection"],
+source: "arguments: aCollection\x0a\x09arguments := aCollection",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_canAliasChildren",
+smalltalk.method({
+selector: "canAliasChildren",
+category: 'testing',
+fn: function () {
+var self=this;
+return false;
+return self;},
+args: [],
+source: "canAliasChildren\x0a\x09^ false",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_classReferences",
+smalltalk.method({
+selector: "classReferences",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@classReferences'];
+return self;},
+args: [],
+source: "classReferences\x0a\x09^ classReferences",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_classReferences_",
+smalltalk.method({
+selector: "classReferences:",
+category: 'accessing',
+fn: function (aCollection) {
+var self=this;
+(self['@classReferences']=aCollection);
+return self;},
+args: ["aCollection"],
+source: "classReferences: aCollection\x0a\x09classReferences := aCollection",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_hasNonLocalReturn",
+smalltalk.method({
+selector: "hasNonLocalReturn",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = smalltalk.send(self, "_scope", [])) == nil || $receiver == undefined) ? (function(){return false;})() : (function(){return smalltalk.send(smalltalk.send(self, "_scope", []), "_hasNonLocalReturn", []);})();
+return self;},
+args: [],
+source: "hasNonLocalReturn\x0a\x09^ self scope\x0a\x09\x09ifNil: [ false ]\x0a\x09\x09ifNotNil: [ self scope hasNonLocalReturn ]",
+messageSends: ["ifNil:ifNotNil:", "scope", "hasNonLocalReturn"],
+referencedClasses: []
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_messageSends",
+smalltalk.method({
+selector: "messageSends",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@messageSends'];
+return self;},
+args: [],
+source: "messageSends\x0a\x09^ messageSends",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_messageSends_",
+smalltalk.method({
+selector: "messageSends:",
+category: 'accessing',
+fn: function (aCollection) {
+var self=this;
+(self['@messageSends']=aCollection);
+return self;},
+args: ["aCollection"],
+source: "messageSends: aCollection\x0a\x09messageSends := aCollection",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_scope",
+smalltalk.method({
+selector: "scope",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@scope'];
+return self;},
+args: [],
+source: "scope\x0a\x09^ scope",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_scope_",
+smalltalk.method({
+selector: "scope:",
+category: 'accessing',
+fn: function (aMethodScope) {
+var self=this;
+(self['@scope']=aMethodScope);
+return self;},
+args: ["aMethodScope"],
+source: "scope: aMethodScope\x0a\x09scope := aMethodScope",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_selector",
+smalltalk.method({
+selector: "selector",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@selector'];
+return self;},
+args: [],
+source: "selector\x0a\x09^selector",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_selector_",
+smalltalk.method({
+selector: "selector:",
+category: 'accessing',
+fn: function (aString) {
+var self=this;
+(self['@selector']=aString);
+return self;},
+args: ["aString"],
+source: "selector: aString\x0a\x09selector := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_source",
+smalltalk.method({
+selector: "source",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@source'];
+return self;},
+args: [],
+source: "source\x0a\x09^source",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.MethodNode);
+
+smalltalk.addMethod(
+"_source_",
+smalltalk.method({
+selector: "source:",
+category: 'accessing',
+fn: function (aString) {
+var self=this;
+(self['@source']=aString);
+return self;},
+args: ["aString"],
+source: "source: aString\x0a\x09source := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.MethodNode);
+
+
+
+smalltalk.addClass('ReturnNode', smalltalk.Node, ['nonLocalReturn'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+category: 'visiting',
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitReturnNode_", [self]);
+return self;},
+args: ["aVisitor"],
+source: "accept: aVisitor\x0a\x09aVisitor visitReturnNode: self",
+messageSends: ["visitReturnNode:"],
+referencedClasses: []
+}),
+smalltalk.ReturnNode);
+
+smalltalk.addMethod(
+"_nonLocalReturn",
+smalltalk.method({
+selector: "nonLocalReturn",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@nonLocalReturn']) == nil || $receiver == undefined) ? (function(){return false;})() : $receiver;
+return self;},
+args: [],
+source: "nonLocalReturn\x0a\x09^ nonLocalReturn ifNil: [ false ]",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.ReturnNode);
+
+smalltalk.addMethod(
+"_nonLocalReturn_",
+smalltalk.method({
+selector: "nonLocalReturn:",
+category: 'accessing',
+fn: function (aBoolean) {
+var self=this;
+(self['@nonLocalReturn']=aBoolean);
+return self;},
+args: ["aBoolean"],
+source: "nonLocalReturn: aBoolean\x0a\x09nonLocalReturn := aBoolean",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ReturnNode);
+
+smalltalk.addMethod(
+"_shouldBeAliased",
+smalltalk.method({
+selector: "shouldBeAliased",
+category: 'testing',
+fn: function () {
+var self=this;
+return false;
+return self;},
+args: [],
+source: "shouldBeAliased\x0a\x09^ false",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ReturnNode);
+
+
+
+smalltalk.addClass('SendNode', smalltalk.Node, ['selector', 'arguments', 'receiver'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+category: 'visiting',
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitSendNode_", [self]);
+return self;},
+args: ["aVisitor"],
+source: "accept: aVisitor\x0a\x09aVisitor visitSendNode: self",
+messageSends: ["visitSendNode:"],
+referencedClasses: []
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_arguments",
+smalltalk.method({
+selector: "arguments",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@arguments']) == nil || $receiver == undefined) ? (function(){return (self['@arguments']=[]);})() : $receiver;
+return self;},
+args: [],
+source: "arguments\x0a\x09^arguments ifNil: [arguments := #()]",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_arguments_",
+smalltalk.method({
+selector: "arguments:",
+category: 'accessing',
+fn: function (aCollection) {
+var self=this;
+(self['@arguments']=aCollection);
+return self;},
+args: ["aCollection"],
+source: "arguments: aCollection\x0a\x09arguments := aCollection",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_cascadeNodeWithMessages_",
+smalltalk.method({
+selector: "cascadeNodeWithMessages:",
+category: 'accessing',
+fn: function (aCollection) {
+var self=this;
+var first=nil;
+(first=(function($rec){smalltalk.send($rec, "_selector_", [smalltalk.send(self, "_selector", [])]);smalltalk.send($rec, "_arguments_", [smalltalk.send(self, "_arguments", [])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.SendNode || SendNode), "_new", [])));
+return (function($rec){smalltalk.send($rec, "_receiver_", [smalltalk.send(self, "_receiver", [])]);smalltalk.send($rec, "_nodes_", [smalltalk.send(smalltalk.send((smalltalk.Array || Array), "_with_", [first]), "__comma", [aCollection])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.CascadeNode || CascadeNode), "_new", []));
+return self;},
+args: ["aCollection"],
+source: "cascadeNodeWithMessages: aCollection\x0a\x09| first |\x0a\x09first := SendNode new\x0a\x09    selector: self selector;\x0a\x09    arguments: self arguments;\x0a\x09    yourself.\x0a\x09^CascadeNode new\x0a\x09    receiver: self receiver;\x0a\x09    nodes: (Array with: first), aCollection;\x0a\x09    yourself",
+messageSends: ["selector:", "selector", "arguments:", "arguments", "yourself", "new", "receiver:", "receiver", "nodes:", ",", "with:"],
+referencedClasses: ["SendNode", "Array", "CascadeNode"]
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_isSendNode",
+smalltalk.method({
+selector: "isSendNode",
+category: 'testing',
+fn: function () {
+var self=this;
+return true;
+return self;},
+args: [],
+source: "isSendNode\x0a\x09^ true",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_nodes",
+smalltalk.method({
+selector: "nodes",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_add_", [smalltalk.send(self, "_receiver", [])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.Array || Array), "_withAll_", [smalltalk.send(self, "_arguments", [])]));
+return self;},
+args: [],
+source: "nodes\x0a\x09^ (Array withAll: self arguments)\x0a\x09\x09add: self receiver;\x0a\x09\x09yourself",
+messageSends: ["add:", "receiver", "yourself", "withAll:", "arguments"],
+referencedClasses: ["Array"]
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_receiver",
+smalltalk.method({
+selector: "receiver",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@receiver'];
+return self;},
+args: [],
+source: "receiver\x0a\x09^receiver",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_receiver_",
+smalltalk.method({
+selector: "receiver:",
+category: 'accessing',
+fn: function (aNode) {
+var self=this;
+(self['@receiver']=aNode);
+return self;},
+args: ["aNode"],
+source: "receiver: aNode\x0a\x09receiver := aNode",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_selector",
+smalltalk.method({
+selector: "selector",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@selector'];
+return self;},
+args: [],
+source: "selector\x0a\x09^selector",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_selector_",
+smalltalk.method({
+selector: "selector:",
+category: 'accessing',
+fn: function (aString) {
+var self=this;
+(self['@selector']=aString);
+return self;},
+args: ["aString"],
+source: "selector: aString\x0a\x09selector := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_valueForReceiver_",
+smalltalk.method({
+selector: "valueForReceiver:",
+category: 'accessing',
+fn: function (anObject) {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_receiver_", [(($receiver = smalltalk.send(self, "_receiver", [])) == nil || $receiver == undefined) ? (function(){return anObject;})() : (function(){return smalltalk.send(smalltalk.send(self, "_receiver", []), "_valueForReceiver_", [anObject]);})()]);smalltalk.send($rec, "_selector_", [smalltalk.send(self, "_selector", [])]);smalltalk.send($rec, "_arguments_", [smalltalk.send(self, "_arguments", [])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.SendNode || SendNode), "_new", []));
+return self;},
+args: ["anObject"],
+source: "valueForReceiver: anObject\x0a\x09^SendNode new\x0a\x09    receiver: (self receiver \x0a\x09\x09ifNil: [anObject]\x0a\x09\x09ifNotNil: [self receiver valueForReceiver: anObject]);\x0a\x09    selector: self selector;\x0a\x09    arguments: self arguments;\x0a\x09    yourself",
+messageSends: ["receiver:", "ifNil:ifNotNil:", "receiver", "valueForReceiver:", "selector:", "selector", "arguments:", "arguments", "yourself", "new"],
+referencedClasses: ["SendNode"]
+}),
+smalltalk.SendNode);
+
+
+
+smalltalk.addClass('SequenceNode', smalltalk.Node, ['temps', 'scope'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+category: 'visiting',
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitSequenceNode_", [self]);
+return self;},
+args: ["aVisitor"],
+source: "accept: aVisitor\x0a\x09aVisitor visitSequenceNode: self",
+messageSends: ["visitSequenceNode:"],
+referencedClasses: []
+}),
+smalltalk.SequenceNode);
+
+smalltalk.addMethod(
+"_asBlockSequenceNode",
+smalltalk.method({
+selector: "asBlockSequenceNode",
+category: 'testing',
+fn: function () {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_nodes_", [smalltalk.send(self, "_nodes", [])]);smalltalk.send($rec, "_temps_", [smalltalk.send(self, "_temps", [])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.BlockSequenceNode || BlockSequenceNode), "_new", []));
+return self;},
+args: [],
+source: "asBlockSequenceNode\x0a\x09^BlockSequenceNode new\x0a\x09    nodes: self nodes;\x0a\x09    temps: self temps;\x0a\x09    yourself",
+messageSends: ["nodes:", "nodes", "temps:", "temps", "yourself", "new"],
+referencedClasses: ["BlockSequenceNode"]
+}),
+smalltalk.SequenceNode);
+
+smalltalk.addMethod(
+"_canAliasChildren",
+smalltalk.method({
+selector: "canAliasChildren",
+category: 'testing',
+fn: function () {
+var self=this;
+return false;
+return self;},
+args: [],
+source: "canAliasChildren\x0a\x09^ false",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.SequenceNode);
+
+smalltalk.addMethod(
+"_scope",
+smalltalk.method({
+selector: "scope",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@scope'];
+return self;},
+args: [],
+source: "scope\x0a\x09^ scope",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.SequenceNode);
+
+smalltalk.addMethod(
+"_scope_",
+smalltalk.method({
+selector: "scope:",
+category: 'accessing',
+fn: function (aLexicalScope) {
+var self=this;
+(self['@scope']=aLexicalScope);
+return self;},
+args: ["aLexicalScope"],
+source: "scope: aLexicalScope\x0a\x09scope := aLexicalScope",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.SequenceNode);
+
+smalltalk.addMethod(
+"_temps",
+smalltalk.method({
+selector: "temps",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@temps']) == nil || $receiver == undefined) ? (function(){return [];})() : $receiver;
+return self;},
+args: [],
+source: "temps\x0a\x09^temps ifNil: [#()]",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.SequenceNode);
+
+smalltalk.addMethod(
+"_temps_",
+smalltalk.method({
+selector: "temps:",
+category: 'accessing',
+fn: function (aCollection) {
+var self=this;
+(self['@temps']=aCollection);
+return self;},
+args: ["aCollection"],
+source: "temps: aCollection\x0a\x09temps := aCollection",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.SequenceNode);
+
+
+
+smalltalk.addClass('BlockSequenceNode', smalltalk.SequenceNode, [], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+category: 'visiting',
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitBlockSequenceNode_", [self]);
+return self;},
+args: ["aVisitor"],
+source: "accept: aVisitor\x0a\x09aVisitor visitBlockSequenceNode: self",
+messageSends: ["visitBlockSequenceNode:"],
+referencedClasses: []
+}),
+smalltalk.BlockSequenceNode);
+
+smalltalk.addMethod(
+"_isBlockSequenceNode",
+smalltalk.method({
+selector: "isBlockSequenceNode",
+category: 'testing',
+fn: function () {
+var self=this;
+return true;
+return self;},
+args: [],
+source: "isBlockSequenceNode\x0a\x09^true",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.BlockSequenceNode);
+
+
+
+smalltalk.addClass('ValueNode', smalltalk.Node, ['value'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+category: 'visiting',
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitValueNode_", [self]);
+return self;},
+args: ["aVisitor"],
+source: "accept: aVisitor\x0a\x09aVisitor visitValueNode: self",
+messageSends: ["visitValueNode:"],
+referencedClasses: []
+}),
+smalltalk.ValueNode);
+
+smalltalk.addMethod(
+"_isValueNode",
+smalltalk.method({
+selector: "isValueNode",
+category: 'testing',
+fn: function () {
+var self=this;
+return true;
+return self;},
+args: [],
+source: "isValueNode\x0a\x09^true",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ValueNode);
+
+smalltalk.addMethod(
+"_shouldBeAliased",
+smalltalk.method({
+selector: "shouldBeAliased",
+category: 'testing',
+fn: function () {
+var self=this;
+return false;
+return self;},
+args: [],
+source: "shouldBeAliased\x0a\x09^ false",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ValueNode);
+
+smalltalk.addMethod(
+"_value",
+smalltalk.method({
+selector: "value",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@value'];
+return self;},
+args: [],
+source: "value\x0a\x09^value",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ValueNode);
+
+smalltalk.addMethod(
+"_value_",
+smalltalk.method({
+selector: "value:",
+category: 'accessing',
+fn: function (anObject) {
+var self=this;
+(self['@value']=anObject);
+return self;},
+args: ["anObject"],
+source: "value: anObject\x0a\x09value := anObject",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ValueNode);
+
+
+
+smalltalk.addClass('VariableNode', smalltalk.ValueNode, ['assigned', 'binding'], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+category: 'visiting',
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitVariableNode_", [self]);
+return self;},
+args: ["aVisitor"],
+source: "accept: aVisitor\x0a\x09aVisitor visitVariableNode: self",
+messageSends: ["visitVariableNode:"],
+referencedClasses: []
+}),
+smalltalk.VariableNode);
+
+smalltalk.addMethod(
+"_alias",
+smalltalk.method({
+selector: "alias",
+category: 'accessing',
+fn: function () {
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_binding", []), "_alias", []);
+return self;},
+args: [],
+source: "alias\x0a\x09^ self binding alias",
+messageSends: ["alias", "binding"],
+referencedClasses: []
+}),
+smalltalk.VariableNode);
+
+smalltalk.addMethod(
+"_assigned",
+smalltalk.method({
+selector: "assigned",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@assigned']) == nil || $receiver == undefined) ? (function(){return false;})() : $receiver;
+return self;},
+args: [],
+source: "assigned\x0a\x09^assigned ifNil: [false]",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.VariableNode);
+
+smalltalk.addMethod(
+"_assigned_",
+smalltalk.method({
+selector: "assigned:",
+category: 'accessing',
+fn: function (aBoolean) {
+var self=this;
+(self['@assigned']=aBoolean);
+return self;},
+args: ["aBoolean"],
+source: "assigned: aBoolean\x0a\x09assigned := aBoolean",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.VariableNode);
+
+smalltalk.addMethod(
+"_beAssigned",
+smalltalk.method({
+selector: "beAssigned",
+category: 'accessing',
+fn: function () {
+var self=this;
+(self['@assigned']=true);
+return self;},
+args: [],
+source: "beAssigned\x0a\x09assigned := true",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.VariableNode);
+
+smalltalk.addMethod(
+"_binding",
+smalltalk.method({
+selector: "binding",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@binding'];
+return self;},
+args: [],
+source: "binding\x0a\x09^ binding",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.VariableNode);
+
+smalltalk.addMethod(
+"_binding_",
+smalltalk.method({
+selector: "binding:",
+category: 'accessing',
+fn: function (aScopeVar) {
+var self=this;
+((($receiver = smalltalk.send(aScopeVar, "_isKindOf_", [(smalltalk.SemanticAnalyzer || SemanticAnalyzer)])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_halt", []);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(self, "_halt", []);})]));
+(self['@binding']=aScopeVar);
+return self;},
+args: ["aScopeVar"],
+source: "binding: aScopeVar\x0a\x09(aScopeVar isKindOf: SemanticAnalyzer) ifTrue: [ self halt ].\x0a\x09binding := aScopeVar",
+messageSends: ["ifTrue:", "isKindOf:", "halt"],
+referencedClasses: ["SemanticAnalyzer"]
+}),
+smalltalk.VariableNode);
+
+
+
+smalltalk.addClass('ClassReferenceNode', smalltalk.VariableNode, [], 'Compiler-AST');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+category: 'visiting',
+fn: function (aVisitor) {
+var self=this;
+smalltalk.send(aVisitor, "_visitClassReferenceNode_", [self]);
+return self;},
+args: ["aVisitor"],
+source: "accept: aVisitor\x0a\x09aVisitor visitClassReferenceNode: self",
+messageSends: ["visitClassReferenceNode:"],
+referencedClasses: []
+}),
+smalltalk.ClassReferenceNode);
+
+
+

+ 666 - 0
js/Compiler-Core.deploy.js

@@ -0,0 +1,666 @@
+smalltalk.addPackage('Compiler-Core', {});
+smalltalk.addClass('Compiler', smalltalk.Object, ['currentClass', 'source', 'unknownVariables', 'codeGeneratorClass'], 'Compiler-Core');
+smalltalk.addMethod(
+"_codeGeneratorClass",
+smalltalk.method({
+selector: "codeGeneratorClass",
+fn: function () {
+var self=this;
+return (($receiver = self['@codeGeneratorClass']) == nil || $receiver == undefined) ? (function(){return (smalltalk.FunCodeGenerator || FunCodeGenerator);})() : $receiver;
+return self;}
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_codeGeneratorClass_",
+smalltalk.method({
+selector: "codeGeneratorClass:",
+fn: function (aClass) {
+var self=this;
+(self['@codeGeneratorClass']=aClass);
+return self;}
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_compile_",
+smalltalk.method({
+selector: "compile:",
+fn: function (aString) {
+var self=this;
+return smalltalk.send(self, "_compileNode_", [smalltalk.send(self, "_parse_", [aString])]);
+return self;}
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_compile_forClass_",
+smalltalk.method({
+selector: "compile:forClass:",
+fn: function (aString, aClass) {
+var self=this;
+smalltalk.send(self, "_currentClass_", [aClass]);
+smalltalk.send(self, "_source_", [aString]);
+return smalltalk.send(self, "_compile_", [aString]);
+return self;}
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_compileExpression_",
+smalltalk.method({
+selector: "compileExpression:",
+fn: function (aString) {
+var self=this;
+smalltalk.send(self, "_currentClass_", [(smalltalk.DoIt || DoIt)]);
+smalltalk.send(self, "_source_", [smalltalk.send(smalltalk.send("doIt ^[", "__comma", [aString]), "__comma", ["] value"])]);
+return smalltalk.send(self, "_compileNode_", [smalltalk.send(self, "_parse_", [smalltalk.send(self, "_source", [])])]);
+return self;}
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_compileNode_",
+smalltalk.method({
+selector: "compileNode:",
+fn: function (aNode) {
+var self=this;
+var generator=nil;
+var result=nil;
+(generator=smalltalk.send(smalltalk.send(self, "_codeGeneratorClass", []), "_new", []));
+(function($rec){smalltalk.send($rec, "_source_", [smalltalk.send(self, "_source", [])]);return smalltalk.send($rec, "_currentClass_", [smalltalk.send(self, "_currentClass", [])]);})(generator);
+(result=smalltalk.send(generator, "_compileNode_", [aNode]));
+smalltalk.send(self, "_unknownVariables_", [[]]);
+return result;
+return self;}
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_currentClass",
+smalltalk.method({
+selector: "currentClass",
+fn: function () {
+var self=this;
+return self['@currentClass'];
+return self;}
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_currentClass_",
+smalltalk.method({
+selector: "currentClass:",
+fn: function (aClass) {
+var self=this;
+(self['@currentClass']=aClass);
+return self;}
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_eval_",
+smalltalk.method({
+selector: "eval:",
+fn: function (aString) {
+var self=this;
+return eval(aString);
+return self;}
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_evaluateExpression_",
+smalltalk.method({
+selector: "evaluateExpression:",
+fn: function (aString) {
+var self=this;
+var result=nil;
+smalltalk.send((smalltalk.DoIt || DoIt), "_addCompiledMethod_", [smalltalk.send(self, "_eval_", [smalltalk.send(self, "_compileExpression_", [aString])])]);
+(result=smalltalk.send(smalltalk.send((smalltalk.DoIt || DoIt), "_new", []), "_doIt", []));
+smalltalk.send((smalltalk.DoIt || DoIt), "_removeCompiledMethod_", [smalltalk.send(smalltalk.send((smalltalk.DoIt || DoIt), "_methodDictionary", []), "_at_", ["doIt"])]);
+return result;
+return self;}
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_parse_",
+smalltalk.method({
+selector: "parse:",
+fn: function (aString) {
+var self=this;
+return smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_parse_", [aString]);
+return self;}
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_parseExpression_",
+smalltalk.method({
+selector: "parseExpression:",
+fn: function (aString) {
+var self=this;
+return smalltalk.send(self, "_parse_", [smalltalk.send(smalltalk.send("doIt ^[", "__comma", [aString]), "__comma", ["] value"])]);
+return self;}
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_recompile_",
+smalltalk.method({
+selector: "recompile:",
+fn: function (aClass) {
+var self=this;
+smalltalk.send(smalltalk.send(aClass, "_methodDictionary", []), "_do_", [(function(each){return smalltalk.send(self, "_install_forClass_category_", [smalltalk.send(each, "_source", []), aClass, smalltalk.send(each, "_category", [])]);})]);
+smalltalk.send(self, "_setupClass_", [aClass]);
+((($receiver = smalltalk.send(aClass, "_isMetaclass", [])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(self, "_recompile_", [smalltalk.send(aClass, "_class", [])]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(self, "_recompile_", [smalltalk.send(aClass, "_class", [])]);})]));
+return self;}
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_recompileAll",
+smalltalk.method({
+selector: "recompileAll",
+fn: function () {
+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_", [(100)]);})]);
+return self;}
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_setupClass_",
+smalltalk.method({
+selector: "setupClass:",
+fn: function (aClass) {
+var self=this;
+smalltalk.init(aClass);
+return self;}
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_source",
+smalltalk.method({
+selector: "source",
+fn: function () {
+var self=this;
+return (($receiver = self['@source']) == nil || $receiver == undefined) ? (function(){return "";})() : $receiver;
+return self;}
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_source_",
+smalltalk.method({
+selector: "source:",
+fn: function (aString) {
+var self=this;
+(self['@source']=aString);
+return self;}
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_unknownVariables",
+smalltalk.method({
+selector: "unknownVariables",
+fn: function () {
+var self=this;
+return self['@unknownVariables'];
+return self;}
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_unknownVariables_",
+smalltalk.method({
+selector: "unknownVariables:",
+fn: function (aCollection) {
+var self=this;
+(self['@unknownVariables']=aCollection);
+return self;}
+}),
+smalltalk.Compiler);
+
+
+smalltalk.addMethod(
+"_recompile_",
+smalltalk.method({
+selector: "recompile:",
+fn: function (aClass) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_new", []), "_recompile_", [aClass]);
+return self;}
+}),
+smalltalk.Compiler.klass);
+
+smalltalk.addMethod(
+"_recompileAll",
+smalltalk.method({
+selector: "recompileAll",
+fn: function () {
+var self=this;
+smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_classes", []), "_do_", [(function(each){return smalltalk.send(self, "_recompile_", [each]);})]);
+return self;}
+}),
+smalltalk.Compiler.klass);
+
+
+smalltalk.addClass('DoIt', smalltalk.Object, [], 'Compiler-Core');
+
+
+smalltalk.addClass('JSStream', smalltalk.Object, ['stream'], 'Compiler-Core');
+smalltalk.addMethod(
+"_contents",
+smalltalk.method({
+selector: "contents",
+fn: function () {
+var self=this;
+return smalltalk.send(self['@stream'], "_contents", []);
+return self;}
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+fn: function () {
+var self=this;
+smalltalk.send(self, "_initialize", [], smalltalk.JSStream.superclass || nil);
+(self['@stream']=smalltalk.send("", "_writeStream", []));
+return self;}
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_lf",
+smalltalk.method({
+selector: "lf",
+fn: function () {
+var self=this;
+smalltalk.send(self['@stream'], "_lf", []);
+return self;}
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPut_",
+smalltalk.method({
+selector: "nextPut:",
+fn: function (aString) {
+var self=this;
+smalltalk.send(self['@stream'], "_nextPut_", [aString]);
+return self;}
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutAll_",
+smalltalk.method({
+selector: "nextPutAll:",
+fn: function (aString) {
+var self=this;
+smalltalk.send(self['@stream'], "_nextPutAll_", [aString]);
+return self;}
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutAssignment_to_",
+smalltalk.method({
+selector: "nextPutAssignment:to:",
+fn: function (varInstruction, valueInstruction) {
+var self=this;
+smalltalk.send(varInstruction, "_emitOn_", [self]);
+smalltalk.send(self['@stream'], "_nextPutAll_", ["="]);
+smalltalk.send(valueInstruction, "_emitOn_", [self]);
+return self;}
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutClosureWith_arguments_",
+smalltalk.method({
+selector: "nextPutClosureWith:arguments:",
+fn: function (aBlock, anArray) {
+var self=this;
+smalltalk.send(self['@stream'], "_nextPutAll_", ["(function("]);
+smalltalk.send(anArray, "_do_separatedBy_", [(function(each){return smalltalk.send(self['@stream'], "_nextPutAll_", [each]);}), (function(){return smalltalk.send(self['@stream'], "_nextPut_", [","]);})]);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["){"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+smalltalk.send(aBlock, "_value", []);
+smalltalk.send(self['@stream'], "_nextPutAll_", ["})"]);
+return self;}
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutFunctionWith_arguments_",
+smalltalk.method({
+selector: "nextPutFunctionWith:arguments:",
+fn: function (aBlock, anArray) {
+var self=this;
+smalltalk.send(self['@stream'], "_nextPutAll_", ["fn: function("]);
+smalltalk.send(anArray, "_do_separatedBy_", [(function(each){return smalltalk.send(self['@stream'], "_nextPutAll_", [each]);}), (function(){return smalltalk.send(self['@stream'], "_nextPut_", [","]);})]);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["){"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+smalltalk.send(self, "_nextPutVar_", ["$return"]);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["var self=this;"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+smalltalk.send(aBlock, "_value", []);
+smalltalk.send(self['@stream'], "_nextPutAll_", ["return $return || self;}"]);
+return self;}
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutMethodDeclaration_with_",
+smalltalk.method({
+selector: "nextPutMethodDeclaration:with:",
+fn: function (aMethod, aBlock) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["smalltalk.method({"]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("selector: \x22", "__comma", [smalltalk.send(aMethod, "_selector", [])]), "__comma", ["\x22,"])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("source: ", "__comma", [smalltalk.send(smalltalk.send(aMethod, "_source", []), "_asJavascript", [])]), "__comma", [","])]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+smalltalk.send(aBlock, "_value", []);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(",", "__comma", [smalltalk.send((smalltalk.String || String), "_lf", [])]), "__comma", ["messageSends: "])]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aMethod, "_messageSends", []), "_asArray", []), "_asJavascript", []), "__comma", [","])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("args: ", "__comma", [smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aMethod, "_arguments", []), "_collect_", [(function(each){return smalltalk.send(each, "_value", []);})]), "_asArray", []), "_asJavascript", [])]), "__comma", [","])]);smalltalk.send($rec, "_lf", []);return smalltalk.send($rec, "_nextPutAll_", ["referencedClasses: ["]);})(self['@stream']);
+smalltalk.send(smalltalk.send(aMethod, "_classReferences", []), "_do_separatedBy_", [(function(each){return smalltalk.send(self['@stream'], "_nextPutAll_", [smalltalk.send(each, "_asJavascript", [])]);}), (function(){return smalltalk.send(self['@stream'], "_nextPutAll_", [","]);})]);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["]"]);return smalltalk.send($rec, "_nextPutAll_", ["})"]);})(self['@stream']);
+return self;}
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutNonLocalReturnHandlingWith_",
+smalltalk.method({
+selector: "nextPutNonLocalReturnHandlingWith:",
+fn: function (aBlock) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["var $early={};"]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", ["try {"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+smalltalk.send(aBlock, "_value", []);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["}"]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", ["catch(e) {if(e===$early)return e[0]; throw e}"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+return self;}
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutNonLocalReturnWith_",
+smalltalk.method({
+selector: "nextPutNonLocalReturnWith:",
+fn: function (aBlock) {
+var self=this;
+smalltalk.send(self['@stream'], "_nextPutAll_", ["(function(){throw $early=["]);
+smalltalk.send(aBlock, "_value", []);
+smalltalk.send(self['@stream'], "_nextPutAll_", ["]})()"]);
+return self;}
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutReturnWith_",
+smalltalk.method({
+selector: "nextPutReturnWith:",
+fn: function (aBlock) {
+var self=this;
+smalltalk.send(self['@stream'], "_nextPutAll_", ["$return="]);
+smalltalk.send(aBlock, "_value", []);
+return self;}
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutSendTo_selector_arguments_",
+smalltalk.method({
+selector: "nextPutSendTo:selector:arguments:",
+fn: function (receiver, selector, arguments) {
+var self=this;
+smalltalk.send(self['@stream'], "_nextPutAll_", ["smalltalk.send("]);
+smalltalk.send(receiver, "_emitOn_", [self]);
+smalltalk.send(self['@stream'], "_nextPutAll_", [smalltalk.send(smalltalk.send(",\x22", "__comma", [smalltalk.send(selector, "_asSelector", [])]), "__comma", ["\x22,["])]);
+smalltalk.send(arguments, "_do_separatedBy_", [(function(each){return smalltalk.send(each, "_emitOn_", [self]);}), (function(){return smalltalk.send(self['@stream'], "_nextPutAll_", [","]);})]);
+smalltalk.send(self['@stream'], "_nextPutAll_", ["])"]);
+return self;}
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutSequenceWith_",
+smalltalk.method({
+selector: "nextPutSequenceWith:",
+fn: function (aBlock) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["switch(smalltalk.thisContext.pc){"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+smalltalk.send(aBlock, "_value", []);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["};"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+return self;}
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutStatement_with_",
+smalltalk.method({
+selector: "nextPutStatement:with:",
+fn: function (anInteger, aBlock) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("case ", "__comma", [smalltalk.send(anInteger, "_asString", [])]), "__comma", [":"])]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+smalltalk.send(aBlock, "_value", []);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", [";"]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("smalltalk.thisContext.pc=", "__comma", [smalltalk.send(((($receiver = anInteger).klass === smalltalk.Number) ? $receiver +(1) : smalltalk.send($receiver, "__plus", [(1)])), "_asString", [])]), "__comma", [";"])]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+return self;}
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutVar_",
+smalltalk.method({
+selector: "nextPutVar:",
+fn: function (aString) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("var ", "__comma", [aString]), "__comma", [";"])]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+return self;}
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutVars_",
+smalltalk.method({
+selector: "nextPutVars:",
+fn: function (aCollection) {
+var self=this;
+smalltalk.send(self['@stream'], "_nextPutAll_", ["var "]);
+smalltalk.send(aCollection, "_do_separatedBy_", [(function(each){return smalltalk.send(self['@stream'], "_nextPutAll_", [each]);}), (function(){return smalltalk.send(self['@stream'], "_nextPutAll_", [","]);})]);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", [";"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+return self;}
+}),
+smalltalk.JSStream);
+
+
+
+smalltalk.addClass('NodeVisitor', smalltalk.Object, [], 'Compiler-Core');
+smalltalk.addMethod(
+"_visit_",
+smalltalk.method({
+selector: "visit:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(aNode, "_accept_", [self]);
+return self;}
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitAll_",
+smalltalk.method({
+selector: "visitAll:",
+fn: function (aCollection) {
+var self=this;
+smalltalk.send(aCollection, "_do_", [(function(each){return smalltalk.send(self, "_visit_", [each]);})]);
+return self;}
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitAssignmentNode_",
+smalltalk.method({
+selector: "visitAssignmentNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;}
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitBlockNode_",
+smalltalk.method({
+selector: "visitBlockNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;}
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitBlockSequenceNode_",
+smalltalk.method({
+selector: "visitBlockSequenceNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitSequenceNode_", [aNode]);
+return self;}
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitCascadeNode_",
+smalltalk.method({
+selector: "visitCascadeNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;}
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitClassReferenceNode_",
+smalltalk.method({
+selector: "visitClassReferenceNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;}
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitDynamicArrayNode_",
+smalltalk.method({
+selector: "visitDynamicArrayNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;}
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitDynamicDictionaryNode_",
+smalltalk.method({
+selector: "visitDynamicDictionaryNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;}
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitJSStatementNode_",
+smalltalk.method({
+selector: "visitJSStatementNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;}
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitMethodNode_",
+smalltalk.method({
+selector: "visitMethodNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;}
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitNode_",
+smalltalk.method({
+selector: "visitNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(smalltalk.send(aNode, "_nodes", []), "_do_", [(function(each){return smalltalk.send(self, "_visit_", [each]);})]);
+return self;}
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitReturnNode_",
+smalltalk.method({
+selector: "visitReturnNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;}
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitSendNode_",
+smalltalk.method({
+selector: "visitSendNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;}
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitSequenceNode_",
+smalltalk.method({
+selector: "visitSequenceNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;}
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitValueNode_",
+smalltalk.method({
+selector: "visitValueNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;}
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitVariableNode_",
+smalltalk.method({
+selector: "visitVariableNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;}
+}),
+smalltalk.NodeVisitor);
+
+
+

+ 941 - 0
js/Compiler-Core.js

@@ -0,0 +1,941 @@
+smalltalk.addPackage('Compiler-Core', {});
+smalltalk.addClass('Compiler', smalltalk.Object, ['currentClass', 'source', 'unknownVariables', 'codeGeneratorClass'], 'Compiler-Core');
+smalltalk.addMethod(
+"_codeGeneratorClass",
+smalltalk.method({
+selector: "codeGeneratorClass",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@codeGeneratorClass']) == nil || $receiver == undefined) ? (function(){return (smalltalk.FunCodeGenerator || FunCodeGenerator);})() : $receiver;
+return self;},
+args: [],
+source: "codeGeneratorClass\x0a\x09^codeGeneratorClass ifNil: [FunCodeGenerator]",
+messageSends: ["ifNil:"],
+referencedClasses: ["FunCodeGenerator"]
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_codeGeneratorClass_",
+smalltalk.method({
+selector: "codeGeneratorClass:",
+category: 'accessing',
+fn: function (aClass) {
+var self=this;
+(self['@codeGeneratorClass']=aClass);
+return self;},
+args: ["aClass"],
+source: "codeGeneratorClass: aClass\x0a\x09codeGeneratorClass := aClass",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_compile_",
+smalltalk.method({
+selector: "compile:",
+category: 'compiling',
+fn: function (aString) {
+var self=this;
+return smalltalk.send(self, "_compileNode_", [smalltalk.send(self, "_parse_", [aString])]);
+return self;},
+args: ["aString"],
+source: "compile: aString\x0a\x09^self compileNode: (self parse: aString)",
+messageSends: ["compileNode:", "parse:"],
+referencedClasses: []
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_compile_forClass_",
+smalltalk.method({
+selector: "compile:forClass:",
+category: 'compiling',
+fn: function (aString, aClass) {
+var self=this;
+smalltalk.send(self, "_currentClass_", [aClass]);
+smalltalk.send(self, "_source_", [aString]);
+return smalltalk.send(self, "_compile_", [aString]);
+return self;},
+args: ["aString", "aClass"],
+source: "compile: aString forClass: aClass\x0a\x09self currentClass: aClass.\x0a\x09self source: aString.\x0a\x09^self compile: aString",
+messageSends: ["currentClass:", "source:", "compile:"],
+referencedClasses: []
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_compileExpression_",
+smalltalk.method({
+selector: "compileExpression:",
+category: 'compiling',
+fn: function (aString) {
+var self=this;
+smalltalk.send(self, "_currentClass_", [(smalltalk.DoIt || DoIt)]);
+smalltalk.send(self, "_source_", [smalltalk.send(smalltalk.send("doIt ^[", "__comma", [aString]), "__comma", ["] value"])]);
+return smalltalk.send(self, "_compileNode_", [smalltalk.send(self, "_parse_", [smalltalk.send(self, "_source", [])])]);
+return self;},
+args: ["aString"],
+source: "compileExpression: aString\x0a\x09self currentClass: DoIt.\x0a\x09self source: 'doIt ^[', aString, '] value'.\x0a\x09^self compileNode: (self parse: self source)",
+messageSends: ["currentClass:", "source:", ",", "compileNode:", "parse:", "source"],
+referencedClasses: ["DoIt"]
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_compileNode_",
+smalltalk.method({
+selector: "compileNode:",
+category: 'compiling',
+fn: function (aNode) {
+var self=this;
+var generator=nil;
+var result=nil;
+(generator=smalltalk.send(smalltalk.send(self, "_codeGeneratorClass", []), "_new", []));
+(function($rec){smalltalk.send($rec, "_source_", [smalltalk.send(self, "_source", [])]);return smalltalk.send($rec, "_currentClass_", [smalltalk.send(self, "_currentClass", [])]);})(generator);
+(result=smalltalk.send(generator, "_compileNode_", [aNode]));
+smalltalk.send(self, "_unknownVariables_", [[]]);
+return result;
+return self;},
+args: ["aNode"],
+source: "compileNode: aNode\x0a\x09| generator result |\x0a\x09generator := self codeGeneratorClass new.\x0a\x09generator\x0a\x09\x09source: self source;\x0a\x09\x09currentClass: self currentClass.\x0a\x09result := generator compileNode: aNode.\x0a\x09self unknownVariables: #().\x0a\x09^result",
+messageSends: ["new", "codeGeneratorClass", "source:", "source", "currentClass:", "currentClass", "compileNode:", "unknownVariables:"],
+referencedClasses: []
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_currentClass",
+smalltalk.method({
+selector: "currentClass",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@currentClass'];
+return self;},
+args: [],
+source: "currentClass\x0a\x09^currentClass",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_currentClass_",
+smalltalk.method({
+selector: "currentClass:",
+category: 'accessing',
+fn: function (aClass) {
+var self=this;
+(self['@currentClass']=aClass);
+return self;},
+args: ["aClass"],
+source: "currentClass: aClass\x0a\x09currentClass := aClass",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_eval_",
+smalltalk.method({
+selector: "eval:",
+category: 'compiling',
+fn: function (aString) {
+var self=this;
+return eval(aString);
+return self;},
+args: ["aString"],
+source: "eval: aString\x0a\x09<return eval(aString)>",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_evaluateExpression_",
+smalltalk.method({
+selector: "evaluateExpression:",
+category: 'compiling',
+fn: function (aString) {
+var self=this;
+var result=nil;
+smalltalk.send((smalltalk.DoIt || DoIt), "_addCompiledMethod_", [smalltalk.send(self, "_eval_", [smalltalk.send(self, "_compileExpression_", [aString])])]);
+(result=smalltalk.send(smalltalk.send((smalltalk.DoIt || DoIt), "_new", []), "_doIt", []));
+smalltalk.send((smalltalk.DoIt || DoIt), "_removeCompiledMethod_", [smalltalk.send(smalltalk.send((smalltalk.DoIt || DoIt), "_methodDictionary", []), "_at_", ["doIt"])]);
+return result;
+return self;},
+args: ["aString"],
+source: "evaluateExpression: aString\x0a\x09\x22Unlike #eval: evaluate a Smalltalk expression and answer the returned object\x22\x0a\x09| result |\x0a\x09DoIt addCompiledMethod: (self eval: (self compileExpression: aString)).\x0a\x09result := DoIt new doIt.\x0a\x09DoIt removeCompiledMethod: (DoIt methodDictionary at: 'doIt').\x0a\x09^result",
+messageSends: ["addCompiledMethod:", "eval:", "compileExpression:", "doIt", "new", "removeCompiledMethod:", "at:", "methodDictionary"],
+referencedClasses: ["DoIt"]
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_parse_",
+smalltalk.method({
+selector: "parse:",
+category: 'compiling',
+fn: function (aString) {
+var self=this;
+return smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_parse_", [aString]);
+return self;},
+args: ["aString"],
+source: "parse: aString\x0a    ^Smalltalk current parse: aString",
+messageSends: ["parse:", "current"],
+referencedClasses: ["Smalltalk"]
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_parseExpression_",
+smalltalk.method({
+selector: "parseExpression:",
+category: 'compiling',
+fn: function (aString) {
+var self=this;
+return smalltalk.send(self, "_parse_", [smalltalk.send(smalltalk.send("doIt ^[", "__comma", [aString]), "__comma", ["] value"])]);
+return self;},
+args: ["aString"],
+source: "parseExpression: aString\x0a    ^self parse: 'doIt ^[', aString, '] value'",
+messageSends: ["parse:", ","],
+referencedClasses: []
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_recompile_",
+smalltalk.method({
+selector: "recompile:",
+category: 'compiling',
+fn: function (aClass) {
+var self=this;
+smalltalk.send(smalltalk.send(aClass, "_methodDictionary", []), "_do_", [(function(each){return smalltalk.send(self, "_install_forClass_category_", [smalltalk.send(each, "_source", []), aClass, smalltalk.send(each, "_category", [])]);})]);
+smalltalk.send(self, "_setupClass_", [aClass]);
+((($receiver = smalltalk.send(aClass, "_isMetaclass", [])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(self, "_recompile_", [smalltalk.send(aClass, "_class", [])]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(self, "_recompile_", [smalltalk.send(aClass, "_class", [])]);})]));
+return self;},
+args: ["aClass"],
+source: "recompile: aClass\x0a\x09aClass methodDictionary do: [:each |\x0a\x09\x09self install: each source forClass: aClass category: each category].\x0a\x09self setupClass: aClass.\x0a\x09aClass isMetaclass ifFalse: [self recompile: aClass class]",
+messageSends: ["do:", "methodDictionary", "install:forClass:category:", "source", "category", "setupClass:", "ifFalse:", "isMetaclass", "recompile:", "class"],
+referencedClasses: []
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_recompileAll",
+smalltalk.method({
+selector: "recompileAll",
+category: 'compiling',
+fn: function () {
+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_", [(100)]);})]);
+return self;},
+args: [],
+source: "recompileAll\x0a\x09Smalltalk current classes do: [:each |\x0a\x09\x09Transcript show: each; cr.\x0a\x09\x09[self recompile: each] valueWithTimeout: 100]",
+messageSends: ["do:", "classes", "current", "show:", "cr", "valueWithTimeout:", "recompile:"],
+referencedClasses: ["Smalltalk", "Transcript"]
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_setupClass_",
+smalltalk.method({
+selector: "setupClass:",
+category: 'compiling',
+fn: function (aClass) {
+var self=this;
+smalltalk.init(aClass);
+return self;},
+args: ["aClass"],
+source: "setupClass: aClass\x0a\x09<smalltalk.init(aClass)>",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_source",
+smalltalk.method({
+selector: "source",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@source']) == nil || $receiver == undefined) ? (function(){return "";})() : $receiver;
+return self;},
+args: [],
+source: "source\x0a\x09^source ifNil: ['']",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_source_",
+smalltalk.method({
+selector: "source:",
+category: 'accessing',
+fn: function (aString) {
+var self=this;
+(self['@source']=aString);
+return self;},
+args: ["aString"],
+source: "source: aString\x0a\x09source := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_unknownVariables",
+smalltalk.method({
+selector: "unknownVariables",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@unknownVariables'];
+return self;},
+args: [],
+source: "unknownVariables\x0a\x09^unknownVariables",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_unknownVariables_",
+smalltalk.method({
+selector: "unknownVariables:",
+category: 'accessing',
+fn: function (aCollection) {
+var self=this;
+(self['@unknownVariables']=aCollection);
+return self;},
+args: ["aCollection"],
+source: "unknownVariables: aCollection\x0a\x09unknownVariables := aCollection",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Compiler);
+
+
+smalltalk.addMethod(
+"_recompile_",
+smalltalk.method({
+selector: "recompile:",
+category: 'compiling',
+fn: function (aClass) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_new", []), "_recompile_", [aClass]);
+return self;},
+args: ["aClass"],
+source: "recompile: aClass\x0a\x09self new recompile: aClass",
+messageSends: ["recompile:", "new"],
+referencedClasses: []
+}),
+smalltalk.Compiler.klass);
+
+smalltalk.addMethod(
+"_recompileAll",
+smalltalk.method({
+selector: "recompileAll",
+category: 'compiling',
+fn: function () {
+var self=this;
+smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_classes", []), "_do_", [(function(each){return smalltalk.send(self, "_recompile_", [each]);})]);
+return self;},
+args: [],
+source: "recompileAll\x0a\x09Smalltalk current classes do: [:each |\x0a\x09\x09self recompile: each]",
+messageSends: ["do:", "classes", "current", "recompile:"],
+referencedClasses: ["Smalltalk"]
+}),
+smalltalk.Compiler.klass);
+
+
+smalltalk.addClass('DoIt', smalltalk.Object, [], 'Compiler-Core');
+
+
+smalltalk.addClass('JSStream', smalltalk.Object, ['stream'], 'Compiler-Core');
+smalltalk.addMethod(
+"_contents",
+smalltalk.method({
+selector: "contents",
+category: 'accessing',
+fn: function () {
+var self=this;
+return smalltalk.send(self['@stream'], "_contents", []);
+return self;},
+args: [],
+source: "contents\x0a\x09^ stream contents",
+messageSends: ["contents"],
+referencedClasses: []
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+category: 'initialization',
+fn: function () {
+var self=this;
+smalltalk.send(self, "_initialize", [], smalltalk.JSStream.superclass || nil);
+(self['@stream']=smalltalk.send("", "_writeStream", []));
+return self;},
+args: [],
+source: "initialize\x0a\x09super initialize.\x0a\x09stream := '' writeStream.",
+messageSends: ["initialize", "writeStream"],
+referencedClasses: []
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_lf",
+smalltalk.method({
+selector: "lf",
+category: 'streaming',
+fn: function () {
+var self=this;
+smalltalk.send(self['@stream'], "_lf", []);
+return self;},
+args: [],
+source: "lf\x0a\x09stream lf",
+messageSends: ["lf"],
+referencedClasses: []
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPut_",
+smalltalk.method({
+selector: "nextPut:",
+category: 'streaming',
+fn: function (aString) {
+var self=this;
+smalltalk.send(self['@stream'], "_nextPut_", [aString]);
+return self;},
+args: ["aString"],
+source: "nextPut: aString\x0a\x09stream nextPut: aString",
+messageSends: ["nextPut:"],
+referencedClasses: []
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutAll_",
+smalltalk.method({
+selector: "nextPutAll:",
+category: 'streaming',
+fn: function (aString) {
+var self=this;
+smalltalk.send(self['@stream'], "_nextPutAll_", [aString]);
+return self;},
+args: ["aString"],
+source: "nextPutAll: aString\x0a\x09stream nextPutAll: aString",
+messageSends: ["nextPutAll:"],
+referencedClasses: []
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutAssignment_to_",
+smalltalk.method({
+selector: "nextPutAssignment:to:",
+category: 'streaming',
+fn: function (varInstruction, valueInstruction) {
+var self=this;
+smalltalk.send(varInstruction, "_emitOn_", [self]);
+smalltalk.send(self['@stream'], "_nextPutAll_", ["="]);
+smalltalk.send(valueInstruction, "_emitOn_", [self]);
+return self;},
+args: ["varInstruction", "valueInstruction"],
+source: "nextPutAssignment: varInstruction to: valueInstruction\x0a\x09varInstruction emitOn: self.\x0a\x09stream nextPutAll: '='.\x0a\x09valueInstruction emitOn: self",
+messageSends: ["emitOn:", "nextPutAll:"],
+referencedClasses: []
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutClosureWith_arguments_",
+smalltalk.method({
+selector: "nextPutClosureWith:arguments:",
+category: 'streaming',
+fn: function (aBlock, anArray) {
+var self=this;
+smalltalk.send(self['@stream'], "_nextPutAll_", ["(function("]);
+smalltalk.send(anArray, "_do_separatedBy_", [(function(each){return smalltalk.send(self['@stream'], "_nextPutAll_", [each]);}), (function(){return smalltalk.send(self['@stream'], "_nextPut_", [","]);})]);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["){"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+smalltalk.send(aBlock, "_value", []);
+smalltalk.send(self['@stream'], "_nextPutAll_", ["})"]);
+return self;},
+args: ["aBlock", "anArray"],
+source: "nextPutClosureWith: aBlock arguments: anArray\x0a\x09stream nextPutAll: '(function('.\x0a\x09anArray \x0a\x09\x09do: [ :each | stream nextPutAll: each ]\x0a\x09\x09separatedBy: [ stream nextPut: ',' ].\x0a\x09stream nextPutAll: '){'; lf.\x0a\x09aBlock value.\x0a\x09stream nextPutAll: '})'",
+messageSends: ["nextPutAll:", "do:separatedBy:", "nextPut:", "lf", "value"],
+referencedClasses: []
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutFunctionWith_arguments_",
+smalltalk.method({
+selector: "nextPutFunctionWith:arguments:",
+category: 'streaming',
+fn: function (aBlock, anArray) {
+var self=this;
+smalltalk.send(self['@stream'], "_nextPutAll_", ["fn: function("]);
+smalltalk.send(anArray, "_do_separatedBy_", [(function(each){return smalltalk.send(self['@stream'], "_nextPutAll_", [each]);}), (function(){return smalltalk.send(self['@stream'], "_nextPut_", [","]);})]);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["){"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+smalltalk.send(self, "_nextPutVar_", ["$return"]);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["var self=this;"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+smalltalk.send(aBlock, "_value", []);
+smalltalk.send(self['@stream'], "_nextPutAll_", ["return $return || self;}"]);
+return self;},
+args: ["aBlock", "anArray"],
+source: "nextPutFunctionWith: aBlock arguments: anArray\x0a\x09stream nextPutAll: 'fn: function('.\x0a\x09anArray \x0a\x09\x09do: [ :each | stream nextPutAll: each ]\x0a\x09\x09separatedBy: [ stream nextPut: ',' ].\x0a\x09stream nextPutAll: '){'; lf.\x0a\x09self nextPutVar: '$return'.\x0a\x09stream nextPutAll: 'var self=this;'; lf.\x0a\x09aBlock value.\x0a\x09stream nextPutAll: 'return $return || self;}'",
+messageSends: ["nextPutAll:", "do:separatedBy:", "nextPut:", "lf", "nextPutVar:", "value"],
+referencedClasses: []
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutMethodDeclaration_with_",
+smalltalk.method({
+selector: "nextPutMethodDeclaration:with:",
+category: 'streaming',
+fn: function (aMethod, aBlock) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["smalltalk.method({"]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("selector: \x22", "__comma", [smalltalk.send(aMethod, "_selector", [])]), "__comma", ["\x22,"])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("source: ", "__comma", [smalltalk.send(smalltalk.send(aMethod, "_source", []), "_asJavascript", [])]), "__comma", [","])]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+smalltalk.send(aBlock, "_value", []);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(",", "__comma", [smalltalk.send((smalltalk.String || String), "_lf", [])]), "__comma", ["messageSends: "])]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aMethod, "_messageSends", []), "_asArray", []), "_asJavascript", []), "__comma", [","])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("args: ", "__comma", [smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aMethod, "_arguments", []), "_collect_", [(function(each){return smalltalk.send(each, "_value", []);})]), "_asArray", []), "_asJavascript", [])]), "__comma", [","])]);smalltalk.send($rec, "_lf", []);return smalltalk.send($rec, "_nextPutAll_", ["referencedClasses: ["]);})(self['@stream']);
+smalltalk.send(smalltalk.send(aMethod, "_classReferences", []), "_do_separatedBy_", [(function(each){return smalltalk.send(self['@stream'], "_nextPutAll_", [smalltalk.send(each, "_asJavascript", [])]);}), (function(){return smalltalk.send(self['@stream'], "_nextPutAll_", [","]);})]);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["]"]);return smalltalk.send($rec, "_nextPutAll_", ["})"]);})(self['@stream']);
+return self;},
+args: ["aMethod", "aBlock"],
+source: "nextPutMethodDeclaration: aMethod with: aBlock\x0a\x09stream \x0a\x09\x09nextPutAll: 'smalltalk.method({'; lf;\x0a\x09\x09nextPutAll: 'selector: \x22', aMethod selector, '\x22,'; lf;\x0a\x09\x09nextPutAll: 'source: ', aMethod source asJavascript, ',';lf.\x0a\x09aBlock value.\x0a\x09stream \x0a\x09\x09nextPutAll: ',', String lf, 'messageSends: ';\x0a\x09\x09nextPutAll: aMethod messageSends asArray asJavascript, ','; lf;\x0a          \x09nextPutAll: 'args: ', (aMethod arguments collect: [ :each | each value ]) asArray asJavascript, ','; lf;\x0a\x09\x09nextPutAll: 'referencedClasses: ['.\x0a\x09aMethod classReferences \x0a\x09\x09do: [:each | stream nextPutAll: each asJavascript]\x0a\x09\x09separatedBy: [stream nextPutAll: ','].\x0a\x09stream \x0a\x09\x09nextPutAll: ']';\x0a\x09\x09nextPutAll: '})'",
+messageSends: ["nextPutAll:", "lf", ",", "selector", "asJavascript", "source", "value", "asArray", "messageSends", "collect:", "arguments", "do:separatedBy:", "classReferences"],
+referencedClasses: ["String"]
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutNonLocalReturnHandlingWith_",
+smalltalk.method({
+selector: "nextPutNonLocalReturnHandlingWith:",
+category: 'streaming',
+fn: function (aBlock) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["var $early={};"]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", ["try {"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+smalltalk.send(aBlock, "_value", []);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["}"]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", ["catch(e) {if(e===$early)return e[0]; throw e}"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+return self;},
+args: ["aBlock"],
+source: "nextPutNonLocalReturnHandlingWith: aBlock\x0a\x09stream \x0a\x09\x09nextPutAll: 'var $early={};'; lf;\x0a\x09\x09nextPutAll: 'try {'; lf.\x0a\x09aBlock value.\x0a\x09stream \x0a\x09\x09nextPutAll: '}'; lf;\x0a\x09\x09nextPutAll: 'catch(e) {if(e===$early)return e[0]; throw e}'; lf",
+messageSends: ["nextPutAll:", "lf", "value"],
+referencedClasses: []
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutNonLocalReturnWith_",
+smalltalk.method({
+selector: "nextPutNonLocalReturnWith:",
+category: 'streaming',
+fn: function (aBlock) {
+var self=this;
+smalltalk.send(self['@stream'], "_nextPutAll_", ["(function(){throw $early=["]);
+smalltalk.send(aBlock, "_value", []);
+smalltalk.send(self['@stream'], "_nextPutAll_", ["]})()"]);
+return self;},
+args: ["aBlock"],
+source: "nextPutNonLocalReturnWith: aBlock\x0a\x09stream nextPutAll: '(function(){throw $early=['.\x0a\x09aBlock value.\x0a\x09stream nextPutAll: ']})()'",
+messageSends: ["nextPutAll:", "value"],
+referencedClasses: []
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutReturnWith_",
+smalltalk.method({
+selector: "nextPutReturnWith:",
+category: 'streaming',
+fn: function (aBlock) {
+var self=this;
+smalltalk.send(self['@stream'], "_nextPutAll_", ["$return="]);
+smalltalk.send(aBlock, "_value", []);
+return self;},
+args: ["aBlock"],
+source: "nextPutReturnWith: aBlock\x0a\x09stream nextPutAll: '$return='.\x0a\x09aBlock value",
+messageSends: ["nextPutAll:", "value"],
+referencedClasses: []
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutSendTo_selector_arguments_",
+smalltalk.method({
+selector: "nextPutSendTo:selector:arguments:",
+category: 'streaming',
+fn: function (receiver, selector, arguments) {
+var self=this;
+smalltalk.send(self['@stream'], "_nextPutAll_", ["smalltalk.send("]);
+smalltalk.send(receiver, "_emitOn_", [self]);
+smalltalk.send(self['@stream'], "_nextPutAll_", [smalltalk.send(smalltalk.send(",\x22", "__comma", [smalltalk.send(selector, "_asSelector", [])]), "__comma", ["\x22,["])]);
+smalltalk.send(arguments, "_do_separatedBy_", [(function(each){return smalltalk.send(each, "_emitOn_", [self]);}), (function(){return smalltalk.send(self['@stream'], "_nextPutAll_", [","]);})]);
+smalltalk.send(self['@stream'], "_nextPutAll_", ["])"]);
+return self;},
+args: ["receiver", "selector", "arguments"],
+source: "nextPutSendTo: receiver selector: selector arguments: arguments\x0a\x09stream nextPutAll: 'smalltalk.send('.\x0a\x09receiver emitOn: self. \x0a\x09stream nextPutAll: ',\x22', selector asSelector, '\x22,['.\x0a\x09arguments \x0a\x09\x09do: [ :each | each emitOn: self ]\x0a\x09\x09separatedBy: [ stream nextPutAll: ',' ].\x0a\x09stream nextPutAll: '])'",
+messageSends: ["nextPutAll:", "emitOn:", ",", "asSelector", "do:separatedBy:"],
+referencedClasses: []
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutSequenceWith_",
+smalltalk.method({
+selector: "nextPutSequenceWith:",
+category: 'streaming',
+fn: function (aBlock) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["switch(smalltalk.thisContext.pc){"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+smalltalk.send(aBlock, "_value", []);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["};"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+return self;},
+args: ["aBlock"],
+source: "nextPutSequenceWith: aBlock\x0a\x09stream \x0a\x09\x09nextPutAll: 'switch(smalltalk.thisContext.pc){'; lf.\x0a\x09aBlock value.\x0a\x09stream \x0a\x09\x09nextPutAll: '};'; lf",
+messageSends: ["nextPutAll:", "lf", "value"],
+referencedClasses: []
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutStatement_with_",
+smalltalk.method({
+selector: "nextPutStatement:with:",
+category: 'streaming',
+fn: function (anInteger, aBlock) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("case ", "__comma", [smalltalk.send(anInteger, "_asString", [])]), "__comma", [":"])]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+smalltalk.send(aBlock, "_value", []);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", [";"]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("smalltalk.thisContext.pc=", "__comma", [smalltalk.send(((($receiver = anInteger).klass === smalltalk.Number) ? $receiver +(1) : smalltalk.send($receiver, "__plus", [(1)])), "_asString", [])]), "__comma", [";"])]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+return self;},
+args: ["anInteger", "aBlock"],
+source: "nextPutStatement: anInteger with: aBlock\x0a\x09stream \x0a\x09\x09nextPutAll: 'case ', anInteger asString, ':'; lf.\x0a\x09aBlock value.\x0a\x09stream \x0a\x09\x09nextPutAll: ';'; lf;\x0a\x09\x09nextPutAll: 'smalltalk.thisContext.pc=', (anInteger + 1) asString, ';'; lf",
+messageSends: ["nextPutAll:", ",", "asString", "lf", "value", "+"],
+referencedClasses: []
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutVar_",
+smalltalk.method({
+selector: "nextPutVar:",
+category: 'streaming',
+fn: function (aString) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("var ", "__comma", [aString]), "__comma", [";"])]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+return self;},
+args: ["aString"],
+source: "nextPutVar: aString\x0a\x09stream nextPutAll: 'var ', aString, ';'; lf",
+messageSends: ["nextPutAll:", ",", "lf"],
+referencedClasses: []
+}),
+smalltalk.JSStream);
+
+smalltalk.addMethod(
+"_nextPutVars_",
+smalltalk.method({
+selector: "nextPutVars:",
+category: 'streaming',
+fn: function (aCollection) {
+var self=this;
+smalltalk.send(self['@stream'], "_nextPutAll_", ["var "]);
+smalltalk.send(aCollection, "_do_separatedBy_", [(function(each){return smalltalk.send(self['@stream'], "_nextPutAll_", [each]);}), (function(){return smalltalk.send(self['@stream'], "_nextPutAll_", [","]);})]);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", [";"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
+return self;},
+args: ["aCollection"],
+source: "nextPutVars: aCollection\x0a\x09stream nextPutAll: 'var '.\x0a\x09aCollection \x0a\x09\x09do: [ :each | stream nextPutAll: each ]\x0a\x09\x09separatedBy: [ stream nextPutAll: ',' ].\x0a\x09stream nextPutAll: ';'; lf",
+messageSends: ["nextPutAll:", "do:separatedBy:", "lf"],
+referencedClasses: []
+}),
+smalltalk.JSStream);
+
+
+
+smalltalk.addClass('NodeVisitor', smalltalk.Object, [], 'Compiler-Core');
+smalltalk.addMethod(
+"_visit_",
+smalltalk.method({
+selector: "visit:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(aNode, "_accept_", [self]);
+return self;},
+args: ["aNode"],
+source: "visit: aNode\x0a\x09aNode accept: self",
+messageSends: ["accept:"],
+referencedClasses: []
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitAll_",
+smalltalk.method({
+selector: "visitAll:",
+category: 'visiting',
+fn: function (aCollection) {
+var self=this;
+smalltalk.send(aCollection, "_do_", [(function(each){return smalltalk.send(self, "_visit_", [each]);})]);
+return self;},
+args: ["aCollection"],
+source: "visitAll: aCollection\x0a\x09aCollection do: [ :each | self visit: each ]",
+messageSends: ["do:", "visit:"],
+referencedClasses: []
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitAssignmentNode_",
+smalltalk.method({
+selector: "visitAssignmentNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;},
+args: ["aNode"],
+source: "visitAssignmentNode: aNode\x0a\x09self visitNode: aNode",
+messageSends: ["visitNode:"],
+referencedClasses: []
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitBlockNode_",
+smalltalk.method({
+selector: "visitBlockNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;},
+args: ["aNode"],
+source: "visitBlockNode: aNode\x0a\x09self visitNode: aNode",
+messageSends: ["visitNode:"],
+referencedClasses: []
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitBlockSequenceNode_",
+smalltalk.method({
+selector: "visitBlockSequenceNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitSequenceNode_", [aNode]);
+return self;},
+args: ["aNode"],
+source: "visitBlockSequenceNode: aNode\x0a\x09self visitSequenceNode: aNode",
+messageSends: ["visitSequenceNode:"],
+referencedClasses: []
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitCascadeNode_",
+smalltalk.method({
+selector: "visitCascadeNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;},
+args: ["aNode"],
+source: "visitCascadeNode: aNode\x0a\x09self visitNode: aNode",
+messageSends: ["visitNode:"],
+referencedClasses: []
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitClassReferenceNode_",
+smalltalk.method({
+selector: "visitClassReferenceNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;},
+args: ["aNode"],
+source: "visitClassReferenceNode: aNode\x0a\x09self visitNode: aNode",
+messageSends: ["visitNode:"],
+referencedClasses: []
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitDynamicArrayNode_",
+smalltalk.method({
+selector: "visitDynamicArrayNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;},
+args: ["aNode"],
+source: "visitDynamicArrayNode: aNode\x0a\x09self visitNode: aNode",
+messageSends: ["visitNode:"],
+referencedClasses: []
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitDynamicDictionaryNode_",
+smalltalk.method({
+selector: "visitDynamicDictionaryNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;},
+args: ["aNode"],
+source: "visitDynamicDictionaryNode: aNode\x0a\x09self visitNode: aNode",
+messageSends: ["visitNode:"],
+referencedClasses: []
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitJSStatementNode_",
+smalltalk.method({
+selector: "visitJSStatementNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;},
+args: ["aNode"],
+source: "visitJSStatementNode: aNode\x0a\x09self visitNode: aNode",
+messageSends: ["visitNode:"],
+referencedClasses: []
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitMethodNode_",
+smalltalk.method({
+selector: "visitMethodNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;},
+args: ["aNode"],
+source: "visitMethodNode: aNode\x0a\x09self visitNode: aNode",
+messageSends: ["visitNode:"],
+referencedClasses: []
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitNode_",
+smalltalk.method({
+selector: "visitNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(smalltalk.send(aNode, "_nodes", []), "_do_", [(function(each){return smalltalk.send(self, "_visit_", [each]);})]);
+return self;},
+args: ["aNode"],
+source: "visitNode: aNode\x0a\x09aNode nodes do: [ :each | self visit: each ]",
+messageSends: ["do:", "nodes", "visit:"],
+referencedClasses: []
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitReturnNode_",
+smalltalk.method({
+selector: "visitReturnNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;},
+args: ["aNode"],
+source: "visitReturnNode: aNode\x0a\x09self visitNode: aNode",
+messageSends: ["visitNode:"],
+referencedClasses: []
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitSendNode_",
+smalltalk.method({
+selector: "visitSendNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;},
+args: ["aNode"],
+source: "visitSendNode: aNode\x0a\x09self visitNode: aNode",
+messageSends: ["visitNode:"],
+referencedClasses: []
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitSequenceNode_",
+smalltalk.method({
+selector: "visitSequenceNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;},
+args: ["aNode"],
+source: "visitSequenceNode: aNode\x0a\x09self visitNode: aNode",
+messageSends: ["visitNode:"],
+referencedClasses: []
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitValueNode_",
+smalltalk.method({
+selector: "visitValueNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;},
+args: ["aNode"],
+source: "visitValueNode: aNode\x0a\x09self visitNode: aNode",
+messageSends: ["visitNode:"],
+referencedClasses: []
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+"_visitVariableNode_",
+smalltalk.method({
+selector: "visitVariableNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;},
+args: ["aNode"],
+source: "visitVariableNode: aNode\x0a\x09self visitNode: aNode",
+messageSends: ["visitNode:"],
+referencedClasses: []
+}),
+smalltalk.NodeVisitor);
+
+
+

+ 1128 - 0
js/Compiler-IR.deploy.js

@@ -0,0 +1,1128 @@
+smalltalk.addPackage('Compiler-IR', {});
+smalltalk.addClass('IRASTTranslator', smalltalk.NodeVisitor, ['builder', 'source'], 'Compiler-IR');
+smalltalk.addMethod(
+"_builder",
+smalltalk.method({
+selector: "builder",
+fn: function () {
+var self=this;
+return (($receiver = self['@builder']) == nil || $receiver == undefined) ? (function(){return (self['@builder']=smalltalk.send((smalltalk.IRBuilder || IRBuilder), "_new", []));})() : $receiver;
+return self;}
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_builder_",
+smalltalk.method({
+selector: "builder:",
+fn: function (aBuilder) {
+var self=this;
+(self['@builder']=aBuilder);
+return self;}
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_source",
+smalltalk.method({
+selector: "source",
+fn: function () {
+var self=this;
+return self['@source'];
+return self;}
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_source_",
+smalltalk.method({
+selector: "source:",
+fn: function (aString) {
+var self=this;
+(self['@source']=aString);
+return self;}
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_visitAssignmentNode_",
+smalltalk.method({
+selector: "visitAssignmentNode:",
+fn: function (aNode) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(self, "_visit_", [smalltalk.send(aNode, "_left", [])]);})]);return smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(self, "_visit_", [smalltalk.send(aNode, "_right", [])]);})]);})(smalltalk.send(smalltalk.send(self, "_builder", []), "_assignment", []));
+return self;}
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_visitBlockNode_",
+smalltalk.method({
+selector: "visitBlockNode:",
+fn: function (aNode) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(self, "_visitBlockNode_", [aNode], smalltalk.IRASTTranslator.superclass || nil);})]);return smalltalk.send($rec, "_arguments_", [smalltalk.send(aNode, "_parameters", [])]);})(smalltalk.send(smalltalk.send(self, "_builder", []), "_closure", []));
+return self;}
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_visitJSStatementNode_",
+smalltalk.method({
+selector: "visitJSStatementNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_builder", []), "_verbatim_", [smalltalk.send(aNode, "_source", [])]);
+return self;}
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_visitMethodNode_",
+smalltalk.method({
+selector: "visitMethodNode:",
+fn: function (aNode) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_source_", [smalltalk.send(self, "_source", [])]);smalltalk.send($rec, "_arguments_", [smalltalk.send(aNode, "_arguments", [])]);smalltalk.send($rec, "_selector_", [smalltalk.send(aNode, "_selector", [])]);smalltalk.send($rec, "_messageSends_", [smalltalk.send(aNode, "_messageSends", [])]);return smalltalk.send($rec, "_classReferences_", [smalltalk.send(aNode, "_classReferences", [])]);})(smalltalk.send(smalltalk.send(self, "_builder", []), "_method", []));
+smalltalk.send(smalltalk.send(smalltalk.send(aNode, "_scope", []), "_temps", []), "_do_", [(function(each){return smalltalk.send(smalltalk.send(smalltalk.send(self, "_builder", []), "_tempDeclaration", []), "_name_", [smalltalk.send(each, "_name", [])]);})]);
+((($receiver = smalltalk.send(aNode, "_hasNonLocalReturn", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send(smalltalk.send(self, "_builder", []), "_nonLocalReturnHandling", []), "_with_", [(function(){return smalltalk.send(self, "_visitMethodNode_", [aNode], smalltalk.IRASTTranslator.superclass || nil);})]);})() : (function(){return smalltalk.send(self, "_visitMethodNode_", [aNode], smalltalk.IRASTTranslator.superclass || nil);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(smalltalk.send(self, "_builder", []), "_nonLocalReturnHandling", []), "_with_", [(function(){return smalltalk.send(self, "_visitMethodNode_", [aNode], smalltalk.IRASTTranslator.superclass || nil);})]);}), (function(){return smalltalk.send(self, "_visitMethodNode_", [aNode], smalltalk.IRASTTranslator.superclass || nil);})]));
+return self;}
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_visitReturnNode_",
+smalltalk.method({
+selector: "visitReturnNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(((($receiver = smalltalk.send(aNode, "_nonLocalReturn", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send(self, "_builder", []), "_nonLocalReturn", []);})() : (function(){return smalltalk.send(smalltalk.send(self, "_builder", []), "_return", []);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(self, "_builder", []), "_nonLocalReturn", []);}), (function(){return smalltalk.send(smalltalk.send(self, "_builder", []), "_return", []);})])), "_with_", [(function(){return smalltalk.send(self, "_visitReturnNode_", [aNode], smalltalk.IRASTTranslator.superclass || nil);})]);
+return self;}
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_visitSendNode_",
+smalltalk.method({
+selector: "visitSendNode:",
+fn: function (aNode) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_selector_", [smalltalk.send(aNode, "_selector", [])]);return smalltalk.send($rec, "_with_", [(function(){smalltalk.send(self, "_visit_", [smalltalk.send(aNode, "_receiver", [])]);return smalltalk.send(smalltalk.send(aNode, "_arguments", []), "_do_", [(function(each){return smalltalk.send(self, "_visit_", [each]);})]);})]);})(smalltalk.send(smalltalk.send(self, "_builder", []), "_send", []));
+return self;}
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_visitSequenceNode_",
+smalltalk.method({
+selector: "visitSequenceNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(smalltalk.send(smalltalk.send(self, "_builder", []), "_sequence", []), "_with_", [(function(){return smalltalk.send(self, "_visitSequenceNode_", [aNode], smalltalk.IRASTTranslator.superclass || nil);})]);
+return self;}
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_visitValueNode_",
+smalltalk.method({
+selector: "visitValueNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_builder", []), "_value_", [smalltalk.send(aNode, "_value", [])]);
+return self;}
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_visitVariableNode_",
+smalltalk.method({
+selector: "visitVariableNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_builder", []), "_variable_", [smalltalk.send(aNode, "_binding", [])]);
+return self;}
+}),
+smalltalk.IRASTTranslator);
+
+
+
+smalltalk.addClass('IRASTResolver', smalltalk.IRASTTranslator, ['nextAlias'], 'Compiler-IR');
+smalltalk.addMethod(
+"_nextAlias",
+smalltalk.method({
+selector: "nextAlias",
+fn: function () {
+var self=this;
+(($receiver = self['@nextAlias']) == nil || $receiver == undefined) ? (function(){return (self['@nextAlias']=(0));})() : $receiver;
+(self['@nextAlias']=((($receiver = self['@nextAlias']).klass === smalltalk.Number) ? $receiver +(1) : smalltalk.send($receiver, "__plus", [(1)])));
+return smalltalk.send("$_", "__comma", [smalltalk.send(self['@nextAlias'], "_asString", [])]);
+return self;}
+}),
+smalltalk.IRASTResolver);
+
+smalltalk.addMethod(
+"_resolve_",
+smalltalk.method({
+selector: "resolve:",
+fn: function (aNode) {
+var self=this;
+((($receiver = smalltalk.send(aNode, "_isBlockSequenceNode", [])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(smalltalk.send(aNode, "_nodes", []), "_do_", [(function(each){return smalltalk.send(self, "_resolve_", [each]);})]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(aNode, "_nodes", []), "_do_", [(function(each){return smalltalk.send(self, "_resolve_", [each]);})]);})]));
+((($receiver = smalltalk.send(aNode, "_shouldBeAliased", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){var alias=nil;
+(alias=smalltalk.send(self, "_nextAlias", []));smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_builder", []), "_method", []), "_internalVariables", []), "_add_", [alias]);(function($rec){smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(smalltalk.send(self, "_builder", []), "_variable_", [smalltalk.send(smalltalk.send((smalltalk.AliasVar || AliasVar), "_new", []), "_name_", [alias])]);})]);return smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(self, "_visit_resolving_", [aNode, false]);})]);})(smalltalk.send(smalltalk.send(self, "_builder", []), "_assignment", []));return smalltalk.send(aNode, "_alias_", [alias]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){var alias=nil;
+(alias=smalltalk.send(self, "_nextAlias", []));smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_builder", []), "_method", []), "_internalVariables", []), "_add_", [alias]);(function($rec){smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(smalltalk.send(self, "_builder", []), "_variable_", [smalltalk.send(smalltalk.send((smalltalk.AliasVar || AliasVar), "_new", []), "_name_", [alias])]);})]);return smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(self, "_visit_resolving_", [aNode, false]);})]);})(smalltalk.send(smalltalk.send(self, "_builder", []), "_assignment", []));return smalltalk.send(aNode, "_alias_", [alias]);})]));
+return self;}
+}),
+smalltalk.IRASTResolver);
+
+smalltalk.addMethod(
+"_visit_",
+smalltalk.method({
+selector: "visit:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visit_resolving_", [aNode, smalltalk.send(aNode, "_canAliasChildren", [])]);
+return self;}
+}),
+smalltalk.IRASTResolver);
+
+smalltalk.addMethod(
+"_visit_resolving_",
+smalltalk.method({
+selector: "visit:resolving:",
+fn: function (aNode, aBoolean) {
+var self=this;
+((($receiver = aBoolean).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_resolve_", [aNode]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(self, "_resolve_", [aNode]);})]));
+((($receiver = smalltalk.send(aNode, "_isAliased", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_visitAliased_", [aNode]);})() : (function(){return smalltalk.send(self, "_visit_", [aNode], smalltalk.IRASTResolver.superclass || nil);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(self, "_visitAliased_", [aNode]);}), (function(){return smalltalk.send(self, "_visit_", [aNode], smalltalk.IRASTResolver.superclass || nil);})]));
+return self;}
+}),
+smalltalk.IRASTResolver);
+
+smalltalk.addMethod(
+"_visitAliased_",
+smalltalk.method({
+selector: "visitAliased:",
+fn: function (aNode) {
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_builder", []), "_variable_", [smalltalk.send(smalltalk.send((smalltalk.AliasVar || AliasVar), "_new", []), "_name_", [smalltalk.send(aNode, "_alias", [])])]);
+return self;}
+}),
+smalltalk.IRASTResolver);
+
+
+
+smalltalk.addClass('IRBuilder', smalltalk.Object, ['method', 'root', 'nextPc'], 'Compiler-IR');
+smalltalk.addMethod(
+"_add_",
+smalltalk.method({
+selector: "add:",
+fn: function (aClass) {
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_root", []), "_append_", [smalltalk.send(aClass, "_on_", [self])]);
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_append_",
+smalltalk.method({
+selector: "append:",
+fn: function (anObject) {
+var self=this;
+return smalltalk.send(self['@root'], "_append_", [anObject]);
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_assignment",
+smalltalk.method({
+selector: "assignment",
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRAssignment || IRAssignment)]);
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_closure",
+smalltalk.method({
+selector: "closure",
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRClosure || IRClosure)]);
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+fn: function (aStream) {
+var self=this;
+smalltalk.send(self['@method'], "_emitOn_", [aStream]);
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+fn: function () {
+var self=this;
+smalltalk.send(self, "_initialize", [], smalltalk.IRBuilder.superclass || nil);
+(self['@root']=(self['@method']=smalltalk.send((smalltalk.IRMethod || IRMethod), "_on_", [self])));
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_method",
+smalltalk.method({
+selector: "method",
+fn: function () {
+var self=this;
+return self['@method'];
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_nextPc",
+smalltalk.method({
+selector: "nextPc",
+fn: function () {
+var self=this;
+(($receiver = self['@nextPc']) == nil || $receiver == undefined) ? (function(){return (self['@nextPc']=(0));})() : $receiver;
+(self['@nextPc']=((($receiver = self['@nextPc']).klass === smalltalk.Number) ? $receiver +(1) : smalltalk.send($receiver, "__plus", [(1)])));
+return self['@nextPc'];
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_nonLocalReturn",
+smalltalk.method({
+selector: "nonLocalReturn",
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRNonLocalReturn || IRNonLocalReturn)]);
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_nonLocalReturnHandling",
+smalltalk.method({
+selector: "nonLocalReturnHandling",
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRNonLocalReturnHandling || IRNonLocalReturnHandling)]);
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_return",
+smalltalk.method({
+selector: "return",
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRReturn || IRReturn)]);
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_root",
+smalltalk.method({
+selector: "root",
+fn: function () {
+var self=this;
+return self['@root'];
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_root_",
+smalltalk.method({
+selector: "root:",
+fn: function (anIRInstruction) {
+var self=this;
+(self['@root']=anIRInstruction);
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_send",
+smalltalk.method({
+selector: "send",
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRSend || IRSend)]);
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_sequence",
+smalltalk.method({
+selector: "sequence",
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRSequence || IRSequence)]);
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_statement",
+smalltalk.method({
+selector: "statement",
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRStatement || IRStatement)]);
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_tempDeclaration",
+smalltalk.method({
+selector: "tempDeclaration",
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRTempDeclaration || IRTempDeclaration)]);
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_value",
+smalltalk.method({
+selector: "value",
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRValue || IRValue)]);
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_value_",
+smalltalk.method({
+selector: "value:",
+fn: function (aString) {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_value_", [aString]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_value", []));
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_variable",
+smalltalk.method({
+selector: "variable",
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRVariable || IRVariable)]);
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_variable_",
+smalltalk.method({
+selector: "variable:",
+fn: function (aScopeVariable) {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_variable_", [aScopeVariable]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_variable", []));
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_verbatim_",
+smalltalk.method({
+selector: "verbatim:",
+fn: function (aString) {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_source_", [aString]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_add_", [(smalltalk.IRVerbatim || IRVerbatim)]));
+return self;}
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_with_",
+smalltalk.method({
+selector: "with:",
+fn: function (anObject) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_root", []), "_with_", [anObject]);
+return self;}
+}),
+smalltalk.IRBuilder);
+
+
+
+smalltalk.addClass('IRInstruction', smalltalk.Object, ['builder', 'instructions'], 'Compiler-IR');
+smalltalk.addMethod(
+"_append_",
+smalltalk.method({
+selector: "append:",
+fn: function (anObject) {
+var self=this;
+smalltalk.send(anObject, "_appendToInstruction_", [self]);
+return anObject;
+return self;}
+}),
+smalltalk.IRInstruction);
+
+smalltalk.addMethod(
+"_appendBlock_",
+smalltalk.method({
+selector: "appendBlock:",
+fn: function (aBlock) {
+var self=this;
+var root=nil;
+(root=smalltalk.send(smalltalk.send(self, "_builder", []), "_root", []));
+smalltalk.send(smalltalk.send(self, "_builder", []), "_root_", [self]);
+smalltalk.send(aBlock, "_value", []);
+smalltalk.send(smalltalk.send(self, "_builder", []), "_root_", [root]);
+return self;}
+}),
+smalltalk.IRInstruction);
+
+smalltalk.addMethod(
+"_appendInstruction_",
+smalltalk.method({
+selector: "appendInstruction:",
+fn: function (anIRInstruction) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_instructions", []), "_add_", [anIRInstruction]);
+return self;}
+}),
+smalltalk.IRInstruction);
+
+smalltalk.addMethod(
+"_appendString_",
+smalltalk.method({
+selector: "appendString:",
+fn: function (aString) {
+var self=this;
+smalltalk.send(self, "_append_", [smalltalk.send(smalltalk.send(self, "_builder", []), "_value_", [aString])]);
+return self;}
+}),
+smalltalk.IRInstruction);
+
+smalltalk.addMethod(
+"_appendToInstruction_",
+smalltalk.method({
+selector: "appendToInstruction:",
+fn: function (anIRInstruction) {
+var self=this;
+smalltalk.send(anIRInstruction, "_appendInstruction_", [self]);
+return self;}
+}),
+smalltalk.IRInstruction);
+
+smalltalk.addMethod(
+"_builder",
+smalltalk.method({
+selector: "builder",
+fn: function () {
+var self=this;
+return self['@builder'];
+return self;}
+}),
+smalltalk.IRInstruction);
+
+smalltalk.addMethod(
+"_builder_",
+smalltalk.method({
+selector: "builder:",
+fn: function (aBuilder) {
+var self=this;
+(self['@builder']=aBuilder);
+return self;}
+}),
+smalltalk.IRInstruction);
+
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+fn: function (aStream) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_instructions", []), "_do_", [(function(each){return smalltalk.send(each, "_emitOn_", [aStream]);})]);
+return self;}
+}),
+smalltalk.IRInstruction);
+
+smalltalk.addMethod(
+"_instructions",
+smalltalk.method({
+selector: "instructions",
+fn: function () {
+var self=this;
+return (($receiver = self['@instructions']) == nil || $receiver == undefined) ? (function(){return (self['@instructions']=smalltalk.send((smalltalk.OrderedCollection || OrderedCollection), "_new", []));})() : $receiver;
+return self;}
+}),
+smalltalk.IRInstruction);
+
+smalltalk.addMethod(
+"_with_",
+smalltalk.method({
+selector: "with:",
+fn: function (anObject) {
+var self=this;
+smalltalk.send(anObject, "_appendToInstruction_", [self]);
+return self;}
+}),
+smalltalk.IRInstruction);
+
+
+smalltalk.addMethod(
+"_on_",
+smalltalk.method({
+selector: "on:",
+fn: function (aBuilder) {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_builder_", [aBuilder]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_new", []));
+return self;}
+}),
+smalltalk.IRInstruction.klass);
+
+
+smalltalk.addClass('IRAssignment', smalltalk.IRInstruction, ['left', 'right'], 'Compiler-IR');
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutAssignment_to_", [smalltalk.send(smalltalk.send(self, "_instructions", []), "_first", []), smalltalk.send(smalltalk.send(self, "_instructions", []), "_second", [])]);
+return self;}
+}),
+smalltalk.IRAssignment);
+
+
+
+smalltalk.addClass('IRClosure', smalltalk.IRInstruction, ['arguments'], 'Compiler-IR');
+smalltalk.addMethod(
+"_arguments",
+smalltalk.method({
+selector: "arguments",
+fn: function () {
+var self=this;
+return self['@arguments'];
+return self;}
+}),
+smalltalk.IRClosure);
+
+smalltalk.addMethod(
+"_arguments_",
+smalltalk.method({
+selector: "arguments:",
+fn: function (aCollection) {
+var self=this;
+(self['@arguments']=aCollection);
+return self;}
+}),
+smalltalk.IRClosure);
+
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutClosureWith_arguments_", [(function(){return smalltalk.send(self, "_emitOn_", [aStream], smalltalk.IRClosure.superclass || nil);}), smalltalk.send(smalltalk.send(self, "_arguments", []), "_collect_", [(function(each){return smalltalk.send(each, "_asVariableName", []);})])]);
+return self;}
+}),
+smalltalk.IRClosure);
+
+
+
+smalltalk.addClass('IRMethod', smalltalk.IRInstruction, ['source', 'selector', 'classReferences', 'messageSends', 'arguments', 'internalVariables', 'source'], 'Compiler-IR');
+smalltalk.addMethod(
+"_arguments",
+smalltalk.method({
+selector: "arguments",
+fn: function () {
+var self=this;
+return self['@arguments'];
+return self;}
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_arguments_",
+smalltalk.method({
+selector: "arguments:",
+fn: function (aCollection) {
+var self=this;
+(self['@arguments']=aCollection);
+return self;}
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_classReferences",
+smalltalk.method({
+selector: "classReferences",
+fn: function () {
+var self=this;
+return self['@classReferences'];
+return self;}
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_classReferences_",
+smalltalk.method({
+selector: "classReferences:",
+fn: function (aCollection) {
+var self=this;
+(self['@classReferences']=aCollection);
+return self;}
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutMethodDeclaration_with_", [self, (function(){return smalltalk.send(aStream, "_nextPutFunctionWith_arguments_", [(function(){((($receiver = smalltalk.send(smalltalk.send(self, "_internalVariables", []), "_notEmpty", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(aStream, "_nextPutVars_", [smalltalk.send(self, "_internalVariables", [])]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(aStream, "_nextPutVars_", [smalltalk.send(self, "_internalVariables", [])]);})]));return smalltalk.send(self, "_emitOn_", [aStream], smalltalk.IRMethod.superclass || nil);}), smalltalk.send(smalltalk.send(self, "_arguments", []), "_collect_", [(function(each){return smalltalk.send(each, "_asVariableName", []);})])]);})]);
+return self;}
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_internalVariables",
+smalltalk.method({
+selector: "internalVariables",
+fn: function () {
+var self=this;
+return (($receiver = self['@internalVariables']) == nil || $receiver == undefined) ? (function(){return (self['@internalVariables']=smalltalk.send((smalltalk.Set || Set), "_new", []));})() : $receiver;
+return self;}
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_messageSends",
+smalltalk.method({
+selector: "messageSends",
+fn: function () {
+var self=this;
+return self['@messageSends'];
+return self;}
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_messageSends_",
+smalltalk.method({
+selector: "messageSends:",
+fn: function (aCollection) {
+var self=this;
+(self['@messageSends']=aCollection);
+return self;}
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_selector",
+smalltalk.method({
+selector: "selector",
+fn: function () {
+var self=this;
+return self['@selector'];
+return self;}
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_selector_",
+smalltalk.method({
+selector: "selector:",
+fn: function (aString) {
+var self=this;
+(self['@selector']=aString);
+return self;}
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_source",
+smalltalk.method({
+selector: "source",
+fn: function () {
+var self=this;
+return self['@source'];
+return self;}
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_source_",
+smalltalk.method({
+selector: "source:",
+fn: function (aString) {
+var self=this;
+(self['@source']=aString);
+return self;}
+}),
+smalltalk.IRMethod);
+
+
+
+smalltalk.addClass('IRNonLocalReturn', smalltalk.IRInstruction, [], 'Compiler-IR');
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutNonLocalReturnWith_", [(function(){return smalltalk.send(self, "_emitOn_", [aStream], smalltalk.IRNonLocalReturn.superclass || nil);})]);
+return self;}
+}),
+smalltalk.IRNonLocalReturn);
+
+
+
+smalltalk.addClass('IRNonLocalReturnHandling', smalltalk.IRInstruction, [], 'Compiler-IR');
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutNonLocalReturnHandlingWith_", [(function(){return smalltalk.send(self, "_emitOn_", [aStream], smalltalk.IRNonLocalReturnHandling.superclass || nil);})]);
+return self;}
+}),
+smalltalk.IRNonLocalReturnHandling);
+
+
+
+smalltalk.addClass('IRReturn', smalltalk.IRInstruction, [], 'Compiler-IR');
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutReturnWith_", [(function(){return smalltalk.send(self, "_emitOn_", [aStream], smalltalk.IRReturn.superclass || nil);})]);
+return self;}
+}),
+smalltalk.IRReturn);
+
+
+
+smalltalk.addClass('IRSend', smalltalk.IRInstruction, ['selector', 'superSend'], 'Compiler-IR');
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutAll_", ["smalltalk.send("]);
+smalltalk.send(smalltalk.send(smalltalk.send(self, "_instructions", []), "_first", []), "_emitOn_", [aStream]);
+smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send(smalltalk.send(",\x22", "__comma", [smalltalk.send(smalltalk.send(self, "_selector", []), "_asSelector", [])]), "__comma", ["\x22, ["])]);
+smalltalk.send(smalltalk.send(smalltalk.send(self, "_instructions", []), "_allButFirst", []), "_do_separatedBy_", [(function(each){return smalltalk.send(each, "_emitOn_", [aStream]);}), (function(){return smalltalk.send(aStream, "_nextPutAll_", [","]);})]);
+smalltalk.send(aStream, "_nextPutAll_", ["])"]);
+return self;}
+}),
+smalltalk.IRSend);
+
+smalltalk.addMethod(
+"_selector",
+smalltalk.method({
+selector: "selector",
+fn: function () {
+var self=this;
+return self['@selector'];
+return self;}
+}),
+smalltalk.IRSend);
+
+smalltalk.addMethod(
+"_selector_",
+smalltalk.method({
+selector: "selector:",
+fn: function (aString) {
+var self=this;
+(self['@selector']=aString);
+return self;}
+}),
+smalltalk.IRSend);
+
+smalltalk.addMethod(
+"_superSend",
+smalltalk.method({
+selector: "superSend",
+fn: function () {
+var self=this;
+return (($receiver = self['@superSend']) == nil || $receiver == undefined) ? (function(){return false;})() : $receiver;
+return self;}
+}),
+smalltalk.IRSend);
+
+smalltalk.addMethod(
+"_superSend_",
+smalltalk.method({
+selector: "superSend:",
+fn: function (aBoolean) {
+var self=this;
+(self['@superSend']=aBoolean);
+return self;}
+}),
+smalltalk.IRSend);
+
+
+
+smalltalk.addClass('IRSequence', smalltalk.IRInstruction, [], 'Compiler-IR');
+smalltalk.addMethod(
+"_appendInstruction_",
+smalltalk.method({
+selector: "appendInstruction:",
+fn: function (anIRInstruction) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_instructions", []), "_add_", [smalltalk.send(smalltalk.send((smalltalk.IRStatement || IRStatement), "_on_", [smalltalk.send(self, "_builder", [])]), "_with_", [anIRInstruction])]);
+return self;}
+}),
+smalltalk.IRSequence);
+
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutSequenceWith_", [(function(){return smalltalk.send(self, "_emitOn_", [aStream], smalltalk.IRSequence.superclass || nil);})]);
+return self;}
+}),
+smalltalk.IRSequence);
+
+
+
+smalltalk.addClass('IRStatement', smalltalk.IRInstruction, ['pc'], 'Compiler-IR');
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutStatement_with_", [smalltalk.send(self, "_pc", []), (function(){return smalltalk.send(self, "_emitOn_", [aStream], smalltalk.IRStatement.superclass || nil);})]);
+return self;}
+}),
+smalltalk.IRStatement);
+
+smalltalk.addMethod(
+"_pc",
+smalltalk.method({
+selector: "pc",
+fn: function () {
+var self=this;
+return (($receiver = self['@pc']) == nil || $receiver == undefined) ? (function(){return (self['@pc']=smalltalk.send(smalltalk.send(self, "_builder", []), "_nextPc", []));})() : $receiver;
+return self;}
+}),
+smalltalk.IRStatement);
+
+
+
+smalltalk.addClass('IRTempDeclaration', smalltalk.IRInstruction, ['name'], 'Compiler-IR');
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutVar_", [smalltalk.send(smalltalk.send(self, "_name", []), "_asVariableName", [])]);
+return self;}
+}),
+smalltalk.IRTempDeclaration);
+
+smalltalk.addMethod(
+"_name",
+smalltalk.method({
+selector: "name",
+fn: function () {
+var self=this;
+return self['@name'];
+return self;}
+}),
+smalltalk.IRTempDeclaration);
+
+smalltalk.addMethod(
+"_name_",
+smalltalk.method({
+selector: "name:",
+fn: function (aString) {
+var self=this;
+(self['@name']=aString);
+return self;}
+}),
+smalltalk.IRTempDeclaration);
+
+
+
+smalltalk.addClass('IRValue', smalltalk.IRInstruction, ['value'], 'Compiler-IR');
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send(smalltalk.send(self, "_value", []), "_asJavascript", [])]);
+return self;}
+}),
+smalltalk.IRValue);
+
+smalltalk.addMethod(
+"_value",
+smalltalk.method({
+selector: "value",
+fn: function () {
+var self=this;
+return self['@value'];
+return self;}
+}),
+smalltalk.IRValue);
+
+smalltalk.addMethod(
+"_value_",
+smalltalk.method({
+selector: "value:",
+fn: function (aString) {
+var self=this;
+(self['@value']=aString);
+return self;}
+}),
+smalltalk.IRValue);
+
+
+
+smalltalk.addClass('IRVariable', smalltalk.IRInstruction, ['variable'], 'Compiler-IR');
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send(smalltalk.send(self, "_variable", []), "_alias", [])]);
+return self;}
+}),
+smalltalk.IRVariable);
+
+smalltalk.addMethod(
+"_variable",
+smalltalk.method({
+selector: "variable",
+fn: function () {
+var self=this;
+return self['@variable'];
+return self;}
+}),
+smalltalk.IRVariable);
+
+smalltalk.addMethod(
+"_variable_",
+smalltalk.method({
+selector: "variable:",
+fn: function (aScopeVariable) {
+var self=this;
+(self['@variable']=aScopeVariable);
+return self;}
+}),
+smalltalk.IRVariable);
+
+
+
+smalltalk.addClass('IRVerbatim', smalltalk.IRInstruction, ['source'], 'Compiler-IR');
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send(smalltalk.send(self, "_source", []), "__comma", [";"])]);
+return self;}
+}),
+smalltalk.IRVerbatim);
+
+smalltalk.addMethod(
+"_source",
+smalltalk.method({
+selector: "source",
+fn: function () {
+var self=this;
+return self['@source'];
+return self;}
+}),
+smalltalk.IRVerbatim);
+
+smalltalk.addMethod(
+"_source_",
+smalltalk.method({
+selector: "source:",
+fn: function (aString) {
+var self=this;
+(self['@source']=aString);
+return self;}
+}),
+smalltalk.IRVerbatim);
+
+
+
+smalltalk.addMethod(
+"_appendToInstruction_",
+smalltalk.method({
+selector: "appendToInstruction:",
+fn: function (anIRInstruction) {
+var self=this;
+smalltalk.send(anIRInstruction, "_appendBlock_", [self]);
+return self;}
+}),
+smalltalk.BlockClosure);
+
+smalltalk.addMethod(
+"_appendToInstruction_",
+smalltalk.method({
+selector: "appendToInstruction:",
+fn: function (anInstruction) {
+var self=this;
+smalltalk.send(anInstruction, "_appendString_", [self]);
+return self;}
+}),
+smalltalk.String);
+
+smalltalk.addMethod(
+"_asVariableName",
+smalltalk.method({
+selector: "asVariableName",
+fn: function () {
+var self=this;
+return ((($receiver = smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_reservedWords", []), "_includes_", [self])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "__comma", ["_"]);})() : (function(){return self;})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(self, "__comma", ["_"]);}), (function(){return self;})]));
+return self;}
+}),
+smalltalk.String);
+
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutAll_", [self]);
+return self;}
+}),
+smalltalk.String);
+

+ 1619 - 0
js/Compiler-IR.js

@@ -0,0 +1,1619 @@
+smalltalk.addPackage('Compiler-IR', {});
+smalltalk.addClass('IRASTTranslator', smalltalk.NodeVisitor, ['builder', 'source'], 'Compiler-IR');
+smalltalk.IRASTTranslator.comment="I an the AST (abstract syntax tree) visitor responsible for building the intermediate representation graph.\x0aI rely on a builder object, instance of IRBuilder."
+smalltalk.addMethod(
+"_builder",
+smalltalk.method({
+selector: "builder",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@builder']) == nil || $receiver == undefined) ? (function(){return (self['@builder']=smalltalk.send((smalltalk.IRBuilder || IRBuilder), "_new", []));})() : $receiver;
+return self;},
+args: [],
+source: "builder\x0a\x09^ builder ifNil: [ builder := IRBuilder new ]",
+messageSends: ["ifNil:", "new"],
+referencedClasses: ["IRBuilder"]
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_builder_",
+smalltalk.method({
+selector: "builder:",
+category: 'accessing',
+fn: function (aBuilder) {
+var self=this;
+(self['@builder']=aBuilder);
+return self;},
+args: ["aBuilder"],
+source: "builder: aBuilder\x0a\x09builder := aBuilder",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_source",
+smalltalk.method({
+selector: "source",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@source'];
+return self;},
+args: [],
+source: "source\x0a\x09^ source",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_source_",
+smalltalk.method({
+selector: "source:",
+category: 'accessing',
+fn: function (aString) {
+var self=this;
+(self['@source']=aString);
+return self;},
+args: ["aString"],
+source: "source: aString\x0a\x09source := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_visitAssignmentNode_",
+smalltalk.method({
+selector: "visitAssignmentNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(self, "_visit_", [smalltalk.send(aNode, "_left", [])]);})]);return smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(self, "_visit_", [smalltalk.send(aNode, "_right", [])]);})]);})(smalltalk.send(smalltalk.send(self, "_builder", []), "_assignment", []));
+return self;},
+args: ["aNode"],
+source: "visitAssignmentNode: aNode\x0a\x09self builder assignment \x0a\x09\x09with: [ self visit: aNode left ];\x0a\x09\x09with: [ self visit: aNode right ]",
+messageSends: ["with:", "visit:", "left", "right", "assignment", "builder"],
+referencedClasses: []
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_visitBlockNode_",
+smalltalk.method({
+selector: "visitBlockNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(self, "_visitBlockNode_", [aNode], smalltalk.IRASTTranslator.superclass || nil);})]);return smalltalk.send($rec, "_arguments_", [smalltalk.send(aNode, "_parameters", [])]);})(smalltalk.send(smalltalk.send(self, "_builder", []), "_closure", []));
+return self;},
+args: ["aNode"],
+source: "visitBlockNode: aNode\x0a\x09self builder closure \x0a\x09\x09with: [ super visitBlockNode: aNode ];\x0a\x09\x09arguments: aNode parameters",
+messageSends: ["with:", "visitBlockNode:", "arguments:", "parameters", "closure", "builder"],
+referencedClasses: []
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_visitJSStatementNode_",
+smalltalk.method({
+selector: "visitJSStatementNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_builder", []), "_verbatim_", [smalltalk.send(aNode, "_source", [])]);
+return self;},
+args: ["aNode"],
+source: "visitJSStatementNode: aNode\x0a\x09self builder verbatim: aNode source",
+messageSends: ["verbatim:", "builder", "source"],
+referencedClasses: []
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_visitMethodNode_",
+smalltalk.method({
+selector: "visitMethodNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_source_", [smalltalk.send(self, "_source", [])]);smalltalk.send($rec, "_arguments_", [smalltalk.send(aNode, "_arguments", [])]);smalltalk.send($rec, "_selector_", [smalltalk.send(aNode, "_selector", [])]);smalltalk.send($rec, "_messageSends_", [smalltalk.send(aNode, "_messageSends", [])]);return smalltalk.send($rec, "_classReferences_", [smalltalk.send(aNode, "_classReferences", [])]);})(smalltalk.send(smalltalk.send(self, "_builder", []), "_method", []));
+smalltalk.send(smalltalk.send(smalltalk.send(aNode, "_scope", []), "_temps", []), "_do_", [(function(each){return smalltalk.send(smalltalk.send(smalltalk.send(self, "_builder", []), "_tempDeclaration", []), "_name_", [smalltalk.send(each, "_name", [])]);})]);
+((($receiver = smalltalk.send(aNode, "_hasNonLocalReturn", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send(smalltalk.send(self, "_builder", []), "_nonLocalReturnHandling", []), "_with_", [(function(){return smalltalk.send(self, "_visitMethodNode_", [aNode], smalltalk.IRASTTranslator.superclass || nil);})]);})() : (function(){return smalltalk.send(self, "_visitMethodNode_", [aNode], smalltalk.IRASTTranslator.superclass || nil);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(smalltalk.send(self, "_builder", []), "_nonLocalReturnHandling", []), "_with_", [(function(){return smalltalk.send(self, "_visitMethodNode_", [aNode], smalltalk.IRASTTranslator.superclass || nil);})]);}), (function(){return smalltalk.send(self, "_visitMethodNode_", [aNode], smalltalk.IRASTTranslator.superclass || nil);})]));
+return self;},
+args: ["aNode"],
+source: "visitMethodNode: aNode\x0a\x09self builder method \x0a\x09\x09source: self source;\x0a\x09\x09arguments: aNode arguments;\x0a\x09\x09selector: aNode selector;\x0a\x09\x09messageSends: aNode messageSends;\x0a\x09\x09classReferences: aNode classReferences.\x0a\x0a\x09aNode scope temps do: [ :each |\x0a\x09\x09self builder tempDeclaration name: each name ].\x0a\x09aNode hasNonLocalReturn \x0a\x09\x09ifTrue: [ self builder nonLocalReturnHandling with: [\x0a\x09\x09\x09super visitMethodNode: aNode ]]\x0a\x09\x09ifFalse: [ super visitMethodNode: aNode ]",
+messageSends: ["source:", "source", "arguments:", "arguments", "selector:", "selector", "messageSends:", "messageSends", "classReferences:", "classReferences", "method", "builder", "do:", "temps", "scope", "name:", "tempDeclaration", "name", "ifTrue:ifFalse:", "hasNonLocalReturn", "with:", "nonLocalReturnHandling", "visitMethodNode:"],
+referencedClasses: []
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_visitReturnNode_",
+smalltalk.method({
+selector: "visitReturnNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(((($receiver = smalltalk.send(aNode, "_nonLocalReturn", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send(self, "_builder", []), "_nonLocalReturn", []);})() : (function(){return smalltalk.send(smalltalk.send(self, "_builder", []), "_return", []);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(self, "_builder", []), "_nonLocalReturn", []);}), (function(){return smalltalk.send(smalltalk.send(self, "_builder", []), "_return", []);})])), "_with_", [(function(){return smalltalk.send(self, "_visitReturnNode_", [aNode], smalltalk.IRASTTranslator.superclass || nil);})]);
+return self;},
+args: ["aNode"],
+source: "visitReturnNode: aNode\x0a\x09(aNode nonLocalReturn \x0a\x09\x09ifTrue: [ self builder nonLocalReturn ]\x0a\x09\x09ifFalse: [ self builder return ]) with: [ super visitReturnNode: aNode ]",
+messageSends: ["with:", "ifTrue:ifFalse:", "nonLocalReturn", "builder", "return", "visitReturnNode:"],
+referencedClasses: []
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_visitSendNode_",
+smalltalk.method({
+selector: "visitSendNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_selector_", [smalltalk.send(aNode, "_selector", [])]);return smalltalk.send($rec, "_with_", [(function(){smalltalk.send(self, "_visit_", [smalltalk.send(aNode, "_receiver", [])]);return smalltalk.send(smalltalk.send(aNode, "_arguments", []), "_do_", [(function(each){return smalltalk.send(self, "_visit_", [each]);})]);})]);})(smalltalk.send(smalltalk.send(self, "_builder", []), "_send", []));
+return self;},
+args: ["aNode"],
+source: "visitSendNode: aNode\x0a\x09self builder send\x0a\x09\x09selector: aNode selector;\x0a\x09\x09with: [\x0a\x09\x09\x09self visit: aNode receiver.\x0a\x09\x09\x09(aNode arguments do: [ :each | self visit: each ]) ]",
+messageSends: ["selector:", "selector", "with:", "visit:", "receiver", "do:", "arguments", "send", "builder"],
+referencedClasses: []
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_visitSequenceNode_",
+smalltalk.method({
+selector: "visitSequenceNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(smalltalk.send(smalltalk.send(self, "_builder", []), "_sequence", []), "_with_", [(function(){return smalltalk.send(self, "_visitSequenceNode_", [aNode], smalltalk.IRASTTranslator.superclass || nil);})]);
+return self;},
+args: ["aNode"],
+source: "visitSequenceNode: aNode\x0a\x09self builder sequence with: [\x0a\x09\x09super visitSequenceNode: aNode ]",
+messageSends: ["with:", "sequence", "builder", "visitSequenceNode:"],
+referencedClasses: []
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_visitValueNode_",
+smalltalk.method({
+selector: "visitValueNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_builder", []), "_value_", [smalltalk.send(aNode, "_value", [])]);
+return self;},
+args: ["aNode"],
+source: "visitValueNode: aNode\x0a\x09self builder value: aNode value",
+messageSends: ["value:", "builder", "value"],
+referencedClasses: []
+}),
+smalltalk.IRASTTranslator);
+
+smalltalk.addMethod(
+"_visitVariableNode_",
+smalltalk.method({
+selector: "visitVariableNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_builder", []), "_variable_", [smalltalk.send(aNode, "_binding", [])]);
+return self;},
+args: ["aNode"],
+source: "visitVariableNode: aNode\x0a\x09self builder variable: aNode binding",
+messageSends: ["variable:", "builder", "binding"],
+referencedClasses: []
+}),
+smalltalk.IRASTTranslator);
+
+
+
+smalltalk.addClass('IRASTResolver', smalltalk.IRASTTranslator, ['nextAlias'], 'Compiler-IR');
+smalltalk.IRASTResolver.comment="I resolve nodes by creating an alias variable when appropriate, to flatten the AST.\x0aNodes referenced in other nodes are aliased, except for some specific nodes such as variable or value nodes."
+smalltalk.addMethod(
+"_nextAlias",
+smalltalk.method({
+selector: "nextAlias",
+category: 'accessing',
+fn: function () {
+var self=this;
+(($receiver = self['@nextAlias']) == nil || $receiver == undefined) ? (function(){return (self['@nextAlias']=(0));})() : $receiver;
+(self['@nextAlias']=((($receiver = self['@nextAlias']).klass === smalltalk.Number) ? $receiver +(1) : smalltalk.send($receiver, "__plus", [(1)])));
+return smalltalk.send("$_", "__comma", [smalltalk.send(self['@nextAlias'], "_asString", [])]);
+return self;},
+args: [],
+source: "nextAlias\x0a\x09\x22Message sends are assigned, or 'aliased', to internal variables.\x0a\x09Internal variable names are unique, and attached to the annotated send node\x22\x0a\x0a\x09nextAlias ifNil: [nextAlias := 0].\x0a\x09nextAlias := nextAlias + 1.\x0a\x09^ '$_', nextAlias asString",
+messageSends: ["ifNil:", "+", ",", "asString"],
+referencedClasses: []
+}),
+smalltalk.IRASTResolver);
+
+smalltalk.addMethod(
+"_resolve_",
+smalltalk.method({
+selector: "resolve:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+((($receiver = smalltalk.send(aNode, "_isBlockSequenceNode", [])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(smalltalk.send(aNode, "_nodes", []), "_do_", [(function(each){return smalltalk.send(self, "_resolve_", [each]);})]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(aNode, "_nodes", []), "_do_", [(function(each){return smalltalk.send(self, "_resolve_", [each]);})]);})]));
+((($receiver = smalltalk.send(aNode, "_shouldBeAliased", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){var alias=nil;
+(alias=smalltalk.send(self, "_nextAlias", []));smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_builder", []), "_method", []), "_internalVariables", []), "_add_", [alias]);(function($rec){smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(smalltalk.send(self, "_builder", []), "_variable_", [smalltalk.send(smalltalk.send((smalltalk.AliasVar || AliasVar), "_new", []), "_name_", [alias])]);})]);return smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(self, "_visit_resolving_", [aNode, false]);})]);})(smalltalk.send(smalltalk.send(self, "_builder", []), "_assignment", []));return smalltalk.send(aNode, "_alias_", [alias]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){var alias=nil;
+(alias=smalltalk.send(self, "_nextAlias", []));smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_builder", []), "_method", []), "_internalVariables", []), "_add_", [alias]);(function($rec){smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(smalltalk.send(self, "_builder", []), "_variable_", [smalltalk.send(smalltalk.send((smalltalk.AliasVar || AliasVar), "_new", []), "_name_", [alias])]);})]);return smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(self, "_visit_resolving_", [aNode, false]);})]);})(smalltalk.send(smalltalk.send(self, "_builder", []), "_assignment", []));return smalltalk.send(aNode, "_alias_", [alias]);})]));
+return self;},
+args: ["aNode"],
+source: "resolve: aNode\x0a\x09aNode isBlockSequenceNode ifFalse: [\x0a\x09\x09aNode nodes do: [ :each | self resolve: each ]].\x0a\x09aNode shouldBeAliased ifTrue: [\x0a\x09\x09| alias |\x0a\x09\x09alias := self nextAlias.\x0a\x09\x09self builder method internalVariables add: alias.\x0a\x09\x09self builder assignment\x0a\x09\x09\x09with: [ self builder variable: (AliasVar new name: alias) ];\x0a\x09\x09\x09with: [ self visit: aNode resolving: false ].\x0a\x09\x09\x09aNode alias: alias ]",
+messageSends: ["ifFalse:", "isBlockSequenceNode", "do:", "nodes", "resolve:", "ifTrue:", "shouldBeAliased", "nextAlias", "add:", "internalVariables", "method", "builder", "with:", "variable:", "name:", "new", "visit:resolving:", "assignment", "alias:"],
+referencedClasses: ["AliasVar"]
+}),
+smalltalk.IRASTResolver);
+
+smalltalk.addMethod(
+"_visit_",
+smalltalk.method({
+selector: "visit:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_visit_resolving_", [aNode, smalltalk.send(aNode, "_canAliasChildren", [])]);
+return self;},
+args: ["aNode"],
+source: "visit: aNode\x0a\x09self visit: aNode resolving: aNode canAliasChildren ",
+messageSends: ["visit:resolving:", "canAliasChildren"],
+referencedClasses: []
+}),
+smalltalk.IRASTResolver);
+
+smalltalk.addMethod(
+"_visit_resolving_",
+smalltalk.method({
+selector: "visit:resolving:",
+category: 'visiting',
+fn: function (aNode, aBoolean) {
+var self=this;
+((($receiver = aBoolean).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_resolve_", [aNode]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(self, "_resolve_", [aNode]);})]));
+((($receiver = smalltalk.send(aNode, "_isAliased", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_visitAliased_", [aNode]);})() : (function(){return smalltalk.send(self, "_visit_", [aNode], smalltalk.IRASTResolver.superclass || nil);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(self, "_visitAliased_", [aNode]);}), (function(){return smalltalk.send(self, "_visit_", [aNode], smalltalk.IRASTResolver.superclass || nil);})]));
+return self;},
+args: ["aNode", "aBoolean"],
+source: "visit: aNode resolving: aBoolean\x0a\x09aBoolean ifTrue: [ self resolve: aNode ].\x0a\x09aNode isAliased \x0a\x09\x09ifTrue: [ self visitAliased: aNode ]\x0a\x09\x09ifFalse: [ super visit: aNode ]",
+messageSends: ["ifTrue:", "resolve:", "ifTrue:ifFalse:", "isAliased", "visitAliased:", "visit:"],
+referencedClasses: []
+}),
+smalltalk.IRASTResolver);
+
+smalltalk.addMethod(
+"_visitAliased_",
+smalltalk.method({
+selector: "visitAliased:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_builder", []), "_variable_", [smalltalk.send(smalltalk.send((smalltalk.AliasVar || AliasVar), "_new", []), "_name_", [smalltalk.send(aNode, "_alias", [])])]);
+return self;},
+args: ["aNode"],
+source: "visitAliased: aNode\x0a\x09^ self builder variable: (AliasVar new name: aNode alias)",
+messageSends: ["variable:", "builder", "name:", "new", "alias"],
+referencedClasses: ["AliasVar"]
+}),
+smalltalk.IRASTResolver);
+
+
+
+smalltalk.addClass('IRBuilder', smalltalk.Object, ['method', 'root', 'nextPc'], 'Compiler-IR');
+smalltalk.IRBuilder.comment="I am responsible for building the IR (Intermatiate Representation) graph, composed of IRInstruction objects."
+smalltalk.addMethod(
+"_add_",
+smalltalk.method({
+selector: "add:",
+category: 'building',
+fn: function (aClass) {
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_root", []), "_append_", [smalltalk.send(aClass, "_on_", [self])]);
+return self;},
+args: ["aClass"],
+source: "add: aClass\x0a\x09^ self root append: (aClass on: self)",
+messageSends: ["append:", "root", "on:"],
+referencedClasses: []
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_append_",
+smalltalk.method({
+selector: "append:",
+category: 'building',
+fn: function (anObject) {
+var self=this;
+return smalltalk.send(self['@root'], "_append_", [anObject]);
+return self;},
+args: ["anObject"],
+source: "append: anObject\x0a\x09^root append: anObject",
+messageSends: ["append:"],
+referencedClasses: []
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_assignment",
+smalltalk.method({
+selector: "assignment",
+category: 'building',
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRAssignment || IRAssignment)]);
+return self;},
+args: [],
+source: "assignment\x0a\x09^ self add: IRAssignment",
+messageSends: ["add:"],
+referencedClasses: ["IRAssignment"]
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_closure",
+smalltalk.method({
+selector: "closure",
+category: 'building',
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRClosure || IRClosure)]);
+return self;},
+args: [],
+source: "closure\x0a\x09^ self add: IRClosure",
+messageSends: ["add:"],
+referencedClasses: ["IRClosure"]
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+category: 'emiting',
+fn: function (aStream) {
+var self=this;
+smalltalk.send(self['@method'], "_emitOn_", [aStream]);
+return self;},
+args: ["aStream"],
+source: "emitOn: aStream\x0a\x09method emitOn: aStream",
+messageSends: ["emitOn:"],
+referencedClasses: []
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+category: 'initialization',
+fn: function () {
+var self=this;
+smalltalk.send(self, "_initialize", [], smalltalk.IRBuilder.superclass || nil);
+(self['@root']=(self['@method']=smalltalk.send((smalltalk.IRMethod || IRMethod), "_on_", [self])));
+return self;},
+args: [],
+source: "initialize\x0a\x09super initialize.\x0a\x09root := method := IRMethod on: self",
+messageSends: ["initialize", "on:"],
+referencedClasses: ["IRMethod"]
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_method",
+smalltalk.method({
+selector: "method",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@method'];
+return self;},
+args: [],
+source: "method\x0a\x09^ method",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_nextPc",
+smalltalk.method({
+selector: "nextPc",
+category: 'accessing',
+fn: function () {
+var self=this;
+(($receiver = self['@nextPc']) == nil || $receiver == undefined) ? (function(){return (self['@nextPc']=(0));})() : $receiver;
+(self['@nextPc']=((($receiver = self['@nextPc']).klass === smalltalk.Number) ? $receiver +(1) : smalltalk.send($receiver, "__plus", [(1)])));
+return self['@nextPc'];
+return self;},
+args: [],
+source: "nextPc\x0a\x09nextPc ifNil: [ nextPc := 0 ].\x0a\x09nextPc := nextPc + 1.\x0a\x09^ nextPc",
+messageSends: ["ifNil:", "+"],
+referencedClasses: []
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_nonLocalReturn",
+smalltalk.method({
+selector: "nonLocalReturn",
+category: 'building',
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRNonLocalReturn || IRNonLocalReturn)]);
+return self;},
+args: [],
+source: "nonLocalReturn\x0a\x09^ self add: IRNonLocalReturn",
+messageSends: ["add:"],
+referencedClasses: ["IRNonLocalReturn"]
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_nonLocalReturnHandling",
+smalltalk.method({
+selector: "nonLocalReturnHandling",
+category: 'building',
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRNonLocalReturnHandling || IRNonLocalReturnHandling)]);
+return self;},
+args: [],
+source: "nonLocalReturnHandling\x0a\x09^ self add: IRNonLocalReturnHandling",
+messageSends: ["add:"],
+referencedClasses: ["IRNonLocalReturnHandling"]
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_return",
+smalltalk.method({
+selector: "return",
+category: 'building',
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRReturn || IRReturn)]);
+return self;},
+args: [],
+source: "return\x0a\x09^ self add: IRReturn",
+messageSends: ["add:"],
+referencedClasses: ["IRReturn"]
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_root",
+smalltalk.method({
+selector: "root",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@root'];
+return self;},
+args: [],
+source: "root\x0a\x09^ root",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_root_",
+smalltalk.method({
+selector: "root:",
+category: 'accessing',
+fn: function (anIRInstruction) {
+var self=this;
+(self['@root']=anIRInstruction);
+return self;},
+args: ["anIRInstruction"],
+source: "root: anIRInstruction\x0a\x09root := anIRInstruction",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_send",
+smalltalk.method({
+selector: "send",
+category: 'building',
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRSend || IRSend)]);
+return self;},
+args: [],
+source: "send\x0a\x09^ self add: IRSend",
+messageSends: ["add:"],
+referencedClasses: ["IRSend"]
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_sequence",
+smalltalk.method({
+selector: "sequence",
+category: 'building',
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRSequence || IRSequence)]);
+return self;},
+args: [],
+source: "sequence\x0a\x09^ self add: IRSequence",
+messageSends: ["add:"],
+referencedClasses: ["IRSequence"]
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_statement",
+smalltalk.method({
+selector: "statement",
+category: 'building',
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRStatement || IRStatement)]);
+return self;},
+args: [],
+source: "statement\x0a\x09^ self add: IRStatement",
+messageSends: ["add:"],
+referencedClasses: ["IRStatement"]
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_tempDeclaration",
+smalltalk.method({
+selector: "tempDeclaration",
+category: 'building',
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRTempDeclaration || IRTempDeclaration)]);
+return self;},
+args: [],
+source: "tempDeclaration\x0a\x09^ self add: IRTempDeclaration",
+messageSends: ["add:"],
+referencedClasses: ["IRTempDeclaration"]
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_value",
+smalltalk.method({
+selector: "value",
+category: 'building',
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRValue || IRValue)]);
+return self;},
+args: [],
+source: "value\x0a\x09^ self add: IRValue",
+messageSends: ["add:"],
+referencedClasses: ["IRValue"]
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_value_",
+smalltalk.method({
+selector: "value:",
+category: 'building',
+fn: function (aString) {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_value_", [aString]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_value", []));
+return self;},
+args: ["aString"],
+source: "value: aString\x0a\x09^ self value\x0a\x09\x09value: aString;\x0a\x09\x09yourself",
+messageSends: ["value:", "yourself", "value"],
+referencedClasses: []
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_variable",
+smalltalk.method({
+selector: "variable",
+category: 'building',
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_add_", [(smalltalk.IRVariable || IRVariable)]);
+return self;},
+args: [],
+source: "variable\x0a\x09^ self add: IRVariable",
+messageSends: ["add:"],
+referencedClasses: ["IRVariable"]
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_variable_",
+smalltalk.method({
+selector: "variable:",
+category: 'building',
+fn: function (aScopeVariable) {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_variable_", [aScopeVariable]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_variable", []));
+return self;},
+args: ["aScopeVariable"],
+source: "variable: aScopeVariable\x0a\x09^ self variable\x0a\x09\x09variable: aScopeVariable;\x0a\x09\x09yourself",
+messageSends: ["variable:", "yourself", "variable"],
+referencedClasses: []
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_verbatim_",
+smalltalk.method({
+selector: "verbatim:",
+category: 'building',
+fn: function (aString) {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_source_", [aString]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_add_", [(smalltalk.IRVerbatim || IRVerbatim)]));
+return self;},
+args: ["aString"],
+source: "verbatim: aString\x0a\x09^(self add: IRVerbatim)\x0a\x09\x09source: aString;\x0a\x09\x09yourself",
+messageSends: ["source:", "yourself", "add:"],
+referencedClasses: ["IRVerbatim"]
+}),
+smalltalk.IRBuilder);
+
+smalltalk.addMethod(
+"_with_",
+smalltalk.method({
+selector: "with:",
+category: 'building',
+fn: function (anObject) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_root", []), "_with_", [anObject]);
+return self;},
+args: ["anObject"],
+source: "with: anObject\x0a\x09self root with: anObject",
+messageSends: ["with:", "root"],
+referencedClasses: []
+}),
+smalltalk.IRBuilder);
+
+
+
+smalltalk.addClass('IRInstruction', smalltalk.Object, ['builder', 'instructions'], 'Compiler-IR');
+smalltalk.IRInstruction.comment="I am the abstract root class of the IR (intermediate representation) instructions class hierarchy.\x0aThe IR graph is used to emit JavaScript code using a JSStream. "
+smalltalk.addMethod(
+"_append_",
+smalltalk.method({
+selector: "append:",
+category: 'building',
+fn: function (anObject) {
+var self=this;
+smalltalk.send(anObject, "_appendToInstruction_", [self]);
+return anObject;
+return self;},
+args: ["anObject"],
+source: "append: anObject\x0a\x09anObject appendToInstruction: self.\x0a\x09^ anObject",
+messageSends: ["appendToInstruction:"],
+referencedClasses: []
+}),
+smalltalk.IRInstruction);
+
+smalltalk.addMethod(
+"_appendBlock_",
+smalltalk.method({
+selector: "appendBlock:",
+category: 'building',
+fn: function (aBlock) {
+var self=this;
+var root=nil;
+(root=smalltalk.send(smalltalk.send(self, "_builder", []), "_root", []));
+smalltalk.send(smalltalk.send(self, "_builder", []), "_root_", [self]);
+smalltalk.send(aBlock, "_value", []);
+smalltalk.send(smalltalk.send(self, "_builder", []), "_root_", [root]);
+return self;},
+args: ["aBlock"],
+source: "appendBlock: aBlock\x0a\x09| root |\x0a\x09root := self builder root.\x0a\x09self builder root: self.\x0a\x09aBlock value.\x0a\x09self builder root: root",
+messageSends: ["root", "builder", "root:", "value"],
+referencedClasses: []
+}),
+smalltalk.IRInstruction);
+
+smalltalk.addMethod(
+"_appendInstruction_",
+smalltalk.method({
+selector: "appendInstruction:",
+category: 'building',
+fn: function (anIRInstruction) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_instructions", []), "_add_", [anIRInstruction]);
+return self;},
+args: ["anIRInstruction"],
+source: "appendInstruction: anIRInstruction\x0a\x09self instructions add: anIRInstruction",
+messageSends: ["add:", "instructions"],
+referencedClasses: []
+}),
+smalltalk.IRInstruction);
+
+smalltalk.addMethod(
+"_appendString_",
+smalltalk.method({
+selector: "appendString:",
+category: 'building',
+fn: function (aString) {
+var self=this;
+smalltalk.send(self, "_append_", [smalltalk.send(smalltalk.send(self, "_builder", []), "_value_", [aString])]);
+return self;},
+args: ["aString"],
+source: "appendString: aString\x0a\x09self append: (self builder value: aString)",
+messageSends: ["append:", "value:", "builder"],
+referencedClasses: []
+}),
+smalltalk.IRInstruction);
+
+smalltalk.addMethod(
+"_appendToInstruction_",
+smalltalk.method({
+selector: "appendToInstruction:",
+category: 'building',
+fn: function (anIRInstruction) {
+var self=this;
+smalltalk.send(anIRInstruction, "_appendInstruction_", [self]);
+return self;},
+args: ["anIRInstruction"],
+source: "appendToInstruction: anIRInstruction\x0a\x09anIRInstruction appendInstruction: self",
+messageSends: ["appendInstruction:"],
+referencedClasses: []
+}),
+smalltalk.IRInstruction);
+
+smalltalk.addMethod(
+"_builder",
+smalltalk.method({
+selector: "builder",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@builder'];
+return self;},
+args: [],
+source: "builder\x0a\x09^ builder",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRInstruction);
+
+smalltalk.addMethod(
+"_builder_",
+smalltalk.method({
+selector: "builder:",
+category: 'accessing',
+fn: function (aBuilder) {
+var self=this;
+(self['@builder']=aBuilder);
+return self;},
+args: ["aBuilder"],
+source: "builder: aBuilder\x0a\x09builder := aBuilder",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRInstruction);
+
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+category: 'emiting',
+fn: function (aStream) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_instructions", []), "_do_", [(function(each){return smalltalk.send(each, "_emitOn_", [aStream]);})]);
+return self;},
+args: ["aStream"],
+source: "emitOn: aStream\x0a\x09\x22Just emit all sub instructions to aStream.\x0a\x09Subclasses should not forget to call `super emitOn:`\x22\x0a\x0a\x09self instructions do: [ :each |\x0a\x09\x09each emitOn: aStream ]",
+messageSends: ["do:", "instructions", "emitOn:"],
+referencedClasses: []
+}),
+smalltalk.IRInstruction);
+
+smalltalk.addMethod(
+"_instructions",
+smalltalk.method({
+selector: "instructions",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@instructions']) == nil || $receiver == undefined) ? (function(){return (self['@instructions']=smalltalk.send((smalltalk.OrderedCollection || OrderedCollection), "_new", []));})() : $receiver;
+return self;},
+args: [],
+source: "instructions\x0a\x09^ instructions ifNil: [ instructions := OrderedCollection new ]",
+messageSends: ["ifNil:", "new"],
+referencedClasses: ["OrderedCollection"]
+}),
+smalltalk.IRInstruction);
+
+smalltalk.addMethod(
+"_with_",
+smalltalk.method({
+selector: "with:",
+category: 'building',
+fn: function (anObject) {
+var self=this;
+smalltalk.send(anObject, "_appendToInstruction_", [self]);
+return self;},
+args: ["anObject"],
+source: "with: anObject\x0a\x09anObject appendToInstruction: self",
+messageSends: ["appendToInstruction:"],
+referencedClasses: []
+}),
+smalltalk.IRInstruction);
+
+
+smalltalk.addMethod(
+"_on_",
+smalltalk.method({
+selector: "on:",
+category: 'instance creation',
+fn: function (aBuilder) {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_builder_", [aBuilder]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_new", []));
+return self;},
+args: ["aBuilder"],
+source: "on: aBuilder\x0a\x09^ self new\x0a\x09\x09builder: aBuilder;\x0a\x09\x09yourself",
+messageSends: ["builder:", "yourself", "new"],
+referencedClasses: []
+}),
+smalltalk.IRInstruction.klass);
+
+
+smalltalk.addClass('IRAssignment', smalltalk.IRInstruction, ['left', 'right'], 'Compiler-IR');
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+category: 'emiting',
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutAssignment_to_", [smalltalk.send(smalltalk.send(self, "_instructions", []), "_first", []), smalltalk.send(smalltalk.send(self, "_instructions", []), "_second", [])]);
+return self;},
+args: ["aStream"],
+source: "emitOn: aStream\x0a\x09aStream \x0a\x09\x09nextPutAssignment: self instructions first\x0a\x09\x09to: self instructions second",
+messageSends: ["nextPutAssignment:to:", "first", "instructions", "second"],
+referencedClasses: []
+}),
+smalltalk.IRAssignment);
+
+
+
+smalltalk.addClass('IRClosure', smalltalk.IRInstruction, ['arguments'], 'Compiler-IR');
+smalltalk.addMethod(
+"_arguments",
+smalltalk.method({
+selector: "arguments",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@arguments'];
+return self;},
+args: [],
+source: "arguments\x0a\x09^ arguments",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRClosure);
+
+smalltalk.addMethod(
+"_arguments_",
+smalltalk.method({
+selector: "arguments:",
+category: 'accessing',
+fn: function (aCollection) {
+var self=this;
+(self['@arguments']=aCollection);
+return self;},
+args: ["aCollection"],
+source: "arguments: aCollection\x0a\x09arguments := aCollection",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRClosure);
+
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+category: 'emiting',
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutClosureWith_arguments_", [(function(){return smalltalk.send(self, "_emitOn_", [aStream], smalltalk.IRClosure.superclass || nil);}), smalltalk.send(smalltalk.send(self, "_arguments", []), "_collect_", [(function(each){return smalltalk.send(each, "_asVariableName", []);})])]);
+return self;},
+args: ["aStream"],
+source: "emitOn: aStream\x0a\x09aStream \x0a\x09\x09nextPutClosureWith: [ super emitOn: aStream ]\x0a\x09\x09arguments: (self arguments collect: [ :each | each asVariableName ])",
+messageSends: ["nextPutClosureWith:arguments:", "emitOn:", "collect:", "arguments", "asVariableName"],
+referencedClasses: []
+}),
+smalltalk.IRClosure);
+
+
+
+smalltalk.addClass('IRMethod', smalltalk.IRInstruction, ['source', 'selector', 'classReferences', 'messageSends', 'arguments', 'internalVariables', 'source'], 'Compiler-IR');
+smalltalk.IRMethod.comment="I am a method instruction"
+smalltalk.addMethod(
+"_arguments",
+smalltalk.method({
+selector: "arguments",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@arguments'];
+return self;},
+args: [],
+source: "arguments\x0a\x09^ arguments",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_arguments_",
+smalltalk.method({
+selector: "arguments:",
+category: 'accessing',
+fn: function (aCollection) {
+var self=this;
+(self['@arguments']=aCollection);
+return self;},
+args: ["aCollection"],
+source: "arguments: aCollection\x0a\x09arguments := aCollection",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_classReferences",
+smalltalk.method({
+selector: "classReferences",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@classReferences'];
+return self;},
+args: [],
+source: "classReferences\x0a\x09^ classReferences",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_classReferences_",
+smalltalk.method({
+selector: "classReferences:",
+category: 'accessing',
+fn: function (aCollection) {
+var self=this;
+(self['@classReferences']=aCollection);
+return self;},
+args: ["aCollection"],
+source: "classReferences: aCollection\x0a\x09classReferences := aCollection",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+category: 'emiting',
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutMethodDeclaration_with_", [self, (function(){return smalltalk.send(aStream, "_nextPutFunctionWith_arguments_", [(function(){((($receiver = smalltalk.send(smalltalk.send(self, "_internalVariables", []), "_notEmpty", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(aStream, "_nextPutVars_", [smalltalk.send(self, "_internalVariables", [])]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(aStream, "_nextPutVars_", [smalltalk.send(self, "_internalVariables", [])]);})]));return smalltalk.send(self, "_emitOn_", [aStream], smalltalk.IRMethod.superclass || nil);}), smalltalk.send(smalltalk.send(self, "_arguments", []), "_collect_", [(function(each){return smalltalk.send(each, "_asVariableName", []);})])]);})]);
+return self;},
+args: ["aStream"],
+source: "emitOn: aStream\x0a\x09aStream \x0a\x09\x09nextPutMethodDeclaration: self\x0a\x09\x09with: [\x0a\x09\x09\x09aStream \x0a\x09\x09\x09\x09nextPutFunctionWith: [ \x0a\x09\x09\x09\x09\x09self internalVariables notEmpty ifTrue: [\x0a\x09\x09\x09\x09\x09\x09aStream nextPutVars: self internalVariables ].\x0a\x09\x09\x09\x09\x09super emitOn: aStream ]\x0a\x09\x09\x09\x09arguments: (self arguments collect: [ :each | each asVariableName ]) ]",
+messageSends: ["nextPutMethodDeclaration:with:", "nextPutFunctionWith:arguments:", "ifTrue:", "notEmpty", "internalVariables", "nextPutVars:", "emitOn:", "collect:", "arguments", "asVariableName"],
+referencedClasses: []
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_internalVariables",
+smalltalk.method({
+selector: "internalVariables",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@internalVariables']) == nil || $receiver == undefined) ? (function(){return (self['@internalVariables']=smalltalk.send((smalltalk.Set || Set), "_new", []));})() : $receiver;
+return self;},
+args: [],
+source: "internalVariables\x0a\x09^ internalVariables ifNil: [ internalVariables := Set new ]",
+messageSends: ["ifNil:", "new"],
+referencedClasses: ["Set"]
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_messageSends",
+smalltalk.method({
+selector: "messageSends",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@messageSends'];
+return self;},
+args: [],
+source: "messageSends\x0a\x09^ messageSends",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_messageSends_",
+smalltalk.method({
+selector: "messageSends:",
+category: 'accessing',
+fn: function (aCollection) {
+var self=this;
+(self['@messageSends']=aCollection);
+return self;},
+args: ["aCollection"],
+source: "messageSends: aCollection\x0a\x09messageSends := aCollection",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_selector",
+smalltalk.method({
+selector: "selector",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@selector'];
+return self;},
+args: [],
+source: "selector\x0a\x09^ selector",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_selector_",
+smalltalk.method({
+selector: "selector:",
+category: 'accessing',
+fn: function (aString) {
+var self=this;
+(self['@selector']=aString);
+return self;},
+args: ["aString"],
+source: "selector: aString\x0a\x09selector := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_source",
+smalltalk.method({
+selector: "source",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@source'];
+return self;},
+args: [],
+source: "source\x0a\x09^ source",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRMethod);
+
+smalltalk.addMethod(
+"_source_",
+smalltalk.method({
+selector: "source:",
+category: 'accessing',
+fn: function (aString) {
+var self=this;
+(self['@source']=aString);
+return self;},
+args: ["aString"],
+source: "source: aString\x0a\x09source := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRMethod);
+
+
+
+smalltalk.addClass('IRNonLocalReturn', smalltalk.IRInstruction, [], 'Compiler-IR');
+smalltalk.IRNonLocalReturn.comment="I am a non local return instruction.\x0aNon local returns are handled using a try/catch JS statement.\x0a\x0aSee IRNonLocalReturnHandling class"
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+category: 'emiting',
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutNonLocalReturnWith_", [(function(){return smalltalk.send(self, "_emitOn_", [aStream], smalltalk.IRNonLocalReturn.superclass || nil);})]);
+return self;},
+args: ["aStream"],
+source: "emitOn: aStream\x0a\x09aStream nextPutNonLocalReturnWith: [\x0a\x09\x09super emitOn: aStream ]",
+messageSends: ["nextPutNonLocalReturnWith:", "emitOn:"],
+referencedClasses: []
+}),
+smalltalk.IRNonLocalReturn);
+
+
+
+smalltalk.addClass('IRNonLocalReturnHandling', smalltalk.IRInstruction, [], 'Compiler-IR');
+smalltalk.IRNonLocalReturnHandling.comment="I represent a non local return handling instruction.\x0aNon local returns are handled with a try/catch statement"
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+category: 'emiting',
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutNonLocalReturnHandlingWith_", [(function(){return smalltalk.send(self, "_emitOn_", [aStream], smalltalk.IRNonLocalReturnHandling.superclass || nil);})]);
+return self;},
+args: ["aStream"],
+source: "emitOn: aStream\x0a\x09aStream nextPutNonLocalReturnHandlingWith: [\x0a\x09\x09super emitOn: aStream ]",
+messageSends: ["nextPutNonLocalReturnHandlingWith:", "emitOn:"],
+referencedClasses: []
+}),
+smalltalk.IRNonLocalReturnHandling);
+
+
+
+smalltalk.addClass('IRReturn', smalltalk.IRInstruction, [], 'Compiler-IR');
+smalltalk.IRReturn.comment="I am a local return instruction."
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+category: 'emiting',
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutReturnWith_", [(function(){return smalltalk.send(self, "_emitOn_", [aStream], smalltalk.IRReturn.superclass || nil);})]);
+return self;},
+args: ["aStream"],
+source: "emitOn: aStream\x0a\x09aStream nextPutReturnWith: [\x0a\x09\x09super emitOn: aStream ]",
+messageSends: ["nextPutReturnWith:", "emitOn:"],
+referencedClasses: []
+}),
+smalltalk.IRReturn);
+
+
+
+smalltalk.addClass('IRSend', smalltalk.IRInstruction, ['selector', 'superSend'], 'Compiler-IR');
+smalltalk.IRSend.comment="I am a message send instruction. "
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+category: 'accessing',
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutAll_", ["smalltalk.send("]);
+smalltalk.send(smalltalk.send(smalltalk.send(self, "_instructions", []), "_first", []), "_emitOn_", [aStream]);
+smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send(smalltalk.send(",\x22", "__comma", [smalltalk.send(smalltalk.send(self, "_selector", []), "_asSelector", [])]), "__comma", ["\x22, ["])]);
+smalltalk.send(smalltalk.send(smalltalk.send(self, "_instructions", []), "_allButFirst", []), "_do_separatedBy_", [(function(each){return smalltalk.send(each, "_emitOn_", [aStream]);}), (function(){return smalltalk.send(aStream, "_nextPutAll_", [","]);})]);
+smalltalk.send(aStream, "_nextPutAll_", ["])"]);
+return self;},
+args: ["aStream"],
+source: "emitOn: aStream\x0a\x0a\x09aStream nextPutAll: 'smalltalk.send('.\x0a\x09self instructions first emitOn: aStream.\x0a\x09aStream nextPutAll:  ',\x22', self selector asSelector, '\x22, ['.\x0a\x09self instructions allButFirst\x0a\x09\x09do: [ :each | each emitOn: aStream ]\x0a\x09\x09separatedBy: [ aStream nextPutAll: ',' ].\x0a\x09aStream nextPutAll: '])'",
+messageSends: ["nextPutAll:", "emitOn:", "first", "instructions", ",", "asSelector", "selector", "do:separatedBy:", "allButFirst"],
+referencedClasses: []
+}),
+smalltalk.IRSend);
+
+smalltalk.addMethod(
+"_selector",
+smalltalk.method({
+selector: "selector",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@selector'];
+return self;},
+args: [],
+source: "selector\x0a\x09^ selector",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRSend);
+
+smalltalk.addMethod(
+"_selector_",
+smalltalk.method({
+selector: "selector:",
+category: 'accessing',
+fn: function (aString) {
+var self=this;
+(self['@selector']=aString);
+return self;},
+args: ["aString"],
+source: "selector: aString\x0a\x09selector := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRSend);
+
+smalltalk.addMethod(
+"_superSend",
+smalltalk.method({
+selector: "superSend",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@superSend']) == nil || $receiver == undefined) ? (function(){return false;})() : $receiver;
+return self;},
+args: [],
+source: "superSend\x0a\x09^ superSend ifNil: [ false ]",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.IRSend);
+
+smalltalk.addMethod(
+"_superSend_",
+smalltalk.method({
+selector: "superSend:",
+category: 'accessing',
+fn: function (aBoolean) {
+var self=this;
+(self['@superSend']=aBoolean);
+return self;},
+args: ["aBoolean"],
+source: "superSend: aBoolean\x0a\x09superSend := aBoolean",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRSend);
+
+
+
+smalltalk.addClass('IRSequence', smalltalk.IRInstruction, [], 'Compiler-IR');
+smalltalk.addMethod(
+"_appendInstruction_",
+smalltalk.method({
+selector: "appendInstruction:",
+category: 'emiting',
+fn: function (anIRInstruction) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_instructions", []), "_add_", [smalltalk.send(smalltalk.send((smalltalk.IRStatement || IRStatement), "_on_", [smalltalk.send(self, "_builder", [])]), "_with_", [anIRInstruction])]);
+return self;},
+args: ["anIRInstruction"],
+source: "appendInstruction: anIRInstruction\x0a\x09self instructions add: ((IRStatement on: self builder) with: anIRInstruction)",
+messageSends: ["add:", "instructions", "with:", "on:", "builder"],
+referencedClasses: ["IRStatement"]
+}),
+smalltalk.IRSequence);
+
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+category: 'emiting',
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutSequenceWith_", [(function(){return smalltalk.send(self, "_emitOn_", [aStream], smalltalk.IRSequence.superclass || nil);})]);
+return self;},
+args: ["aStream"],
+source: "emitOn: aStream\x0a\x09aStream nextPutSequenceWith: [\x0a\x09\x09\x22self instructions do: [ :each |\x0a\x09\x09\x09((IRStatement on: self builder)\x0a\x09\x09\x09\x09pc: self builder nextPc;\x0a\x09\x09\x09\x09with: each;\x0a\x09\x09\x09\x09yourself) emitOn: aStream ]\x22\x0a\x09\x09super emitOn: aStream ]",
+messageSends: ["nextPutSequenceWith:", "emitOn:"],
+referencedClasses: []
+}),
+smalltalk.IRSequence);
+
+
+
+smalltalk.addClass('IRStatement', smalltalk.IRInstruction, ['pc'], 'Compiler-IR');
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+category: 'emiting',
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutStatement_with_", [smalltalk.send(self, "_pc", []), (function(){return smalltalk.send(self, "_emitOn_", [aStream], smalltalk.IRStatement.superclass || nil);})]);
+return self;},
+args: ["aStream"],
+source: "emitOn: aStream\x0a\x09aStream nextPutStatement: self pc with: [\x0a\x09\x09super emitOn: aStream ]",
+messageSends: ["nextPutStatement:with:", "pc", "emitOn:"],
+referencedClasses: []
+}),
+smalltalk.IRStatement);
+
+smalltalk.addMethod(
+"_pc",
+smalltalk.method({
+selector: "pc",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@pc']) == nil || $receiver == undefined) ? (function(){return (self['@pc']=smalltalk.send(smalltalk.send(self, "_builder", []), "_nextPc", []));})() : $receiver;
+return self;},
+args: [],
+source: "pc\x0a\x09^ pc ifNil: [pc := self builder nextPc]",
+messageSends: ["ifNil:", "nextPc", "builder"],
+referencedClasses: []
+}),
+smalltalk.IRStatement);
+
+
+
+smalltalk.addClass('IRTempDeclaration', smalltalk.IRInstruction, ['name'], 'Compiler-IR');
+smalltalk.IRTempDeclaration.comment="I am a temporary variable declaration instruction"
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+category: 'emiting',
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutVar_", [smalltalk.send(smalltalk.send(self, "_name", []), "_asVariableName", [])]);
+return self;},
+args: ["aStream"],
+source: "emitOn: aStream\x0a\x09aStream nextPutVar: self name asVariableName",
+messageSends: ["nextPutVar:", "asVariableName", "name"],
+referencedClasses: []
+}),
+smalltalk.IRTempDeclaration);
+
+smalltalk.addMethod(
+"_name",
+smalltalk.method({
+selector: "name",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@name'];
+return self;},
+args: [],
+source: "name\x0a\x09^ name",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRTempDeclaration);
+
+smalltalk.addMethod(
+"_name_",
+smalltalk.method({
+selector: "name:",
+category: 'accessing',
+fn: function (aString) {
+var self=this;
+(self['@name']=aString);
+return self;},
+args: ["aString"],
+source: "name: aString\x0a\x09name := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRTempDeclaration);
+
+
+
+smalltalk.addClass('IRValue', smalltalk.IRInstruction, ['value'], 'Compiler-IR');
+smalltalk.IRValue.comment="I am the simplest possible instruction. I represent a value."
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+category: 'emiting',
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send(smalltalk.send(self, "_value", []), "_asJavascript", [])]);
+return self;},
+args: ["aStream"],
+source: "emitOn: aStream\x0a\x09aStream nextPutAll: self value asJavascript",
+messageSends: ["nextPutAll:", "asJavascript", "value"],
+referencedClasses: []
+}),
+smalltalk.IRValue);
+
+smalltalk.addMethod(
+"_value",
+smalltalk.method({
+selector: "value",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@value'];
+return self;},
+args: [],
+source: "value\x0a\x09^value",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRValue);
+
+smalltalk.addMethod(
+"_value_",
+smalltalk.method({
+selector: "value:",
+category: 'accessing',
+fn: function (aString) {
+var self=this;
+(self['@value']=aString);
+return self;},
+args: ["aString"],
+source: "value: aString\x0a\x09value := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRValue);
+
+
+
+smalltalk.addClass('IRVariable', smalltalk.IRInstruction, ['variable'], 'Compiler-IR');
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+category: 'emiting',
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send(smalltalk.send(self, "_variable", []), "_alias", [])]);
+return self;},
+args: ["aStream"],
+source: "emitOn: aStream\x0a\x09aStream nextPutAll: self variable alias",
+messageSends: ["nextPutAll:", "alias", "variable"],
+referencedClasses: []
+}),
+smalltalk.IRVariable);
+
+smalltalk.addMethod(
+"_variable",
+smalltalk.method({
+selector: "variable",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@variable'];
+return self;},
+args: [],
+source: "variable\x0a\x09^ variable",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRVariable);
+
+smalltalk.addMethod(
+"_variable_",
+smalltalk.method({
+selector: "variable:",
+category: 'accessing',
+fn: function (aScopeVariable) {
+var self=this;
+(self['@variable']=aScopeVariable);
+return self;},
+args: ["aScopeVariable"],
+source: "variable: aScopeVariable\x0a\x09variable := aScopeVariable",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRVariable);
+
+
+
+smalltalk.addClass('IRVerbatim', smalltalk.IRInstruction, ['source'], 'Compiler-IR');
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+category: 'emiting',
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send(smalltalk.send(self, "_source", []), "__comma", [";"])]);
+return self;},
+args: ["aStream"],
+source: "emitOn: aStream\x0a\x09aStream nextPutAll: self source, ';'",
+messageSends: ["nextPutAll:", ",", "source"],
+referencedClasses: []
+}),
+smalltalk.IRVerbatim);
+
+smalltalk.addMethod(
+"_source",
+smalltalk.method({
+selector: "source",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@source'];
+return self;},
+args: [],
+source: "source\x0a\x09^ source",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRVerbatim);
+
+smalltalk.addMethod(
+"_source_",
+smalltalk.method({
+selector: "source:",
+category: 'accessing',
+fn: function (aString) {
+var self=this;
+(self['@source']=aString);
+return self;},
+args: ["aString"],
+source: "source: aString\x0a\x09source := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRVerbatim);
+
+
+
+smalltalk.addMethod(
+"_appendToInstruction_",
+smalltalk.method({
+selector: "appendToInstruction:",
+category: '*Compiler-IR',
+fn: function (anIRInstruction) {
+var self=this;
+smalltalk.send(anIRInstruction, "_appendBlock_", [self]);
+return self;},
+args: ["anIRInstruction"],
+source: "appendToInstruction: anIRInstruction\x0a    anIRInstruction appendBlock: self",
+messageSends: ["appendBlock:"],
+referencedClasses: []
+}),
+smalltalk.BlockClosure);
+
+smalltalk.addMethod(
+"_appendToInstruction_",
+smalltalk.method({
+selector: "appendToInstruction:",
+category: '*Compiler-IR',
+fn: function (anInstruction) {
+var self=this;
+smalltalk.send(anInstruction, "_appendString_", [self]);
+return self;},
+args: ["anInstruction"],
+source: "appendToInstruction: anInstruction\x0a\x09anInstruction appendString: self",
+messageSends: ["appendString:"],
+referencedClasses: []
+}),
+smalltalk.String);
+
+smalltalk.addMethod(
+"_asVariableName",
+smalltalk.method({
+selector: "asVariableName",
+category: '*Compiler-IR',
+fn: function () {
+var self=this;
+return ((($receiver = smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_reservedWords", []), "_includes_", [self])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "__comma", ["_"]);})() : (function(){return self;})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(self, "__comma", ["_"]);}), (function(){return self;})]));
+return self;},
+args: [],
+source: "asVariableName\x0a\x09^ (Smalltalk current reservedWords includes: self)\x0a\x09\x09ifTrue: [ self, '_' ]\x0a\x09\x09ifFalse: [ self ]",
+messageSends: ["ifTrue:ifFalse:", "includes:", "reservedWords", "current", ","],
+referencedClasses: ["Smalltalk"]
+}),
+smalltalk.String);
+
+smalltalk.addMethod(
+"_emitOn_",
+smalltalk.method({
+selector: "emitOn:",
+category: '*Compiler-IR',
+fn: function (aStream) {
+var self=this;
+smalltalk.send(aStream, "_nextPutAll_", [self]);
+return self;},
+args: ["aStream"],
+source: "emitOn: aStream\x0a\x09aStream nextPutAll: self",
+messageSends: ["nextPutAll:"],
+referencedClasses: []
+}),
+smalltalk.String);
+

+ 807 - 0
js/Compiler-Semantic.deploy.js

@@ -0,0 +1,807 @@
+smalltalk.addPackage('Compiler-Semantic', {});
+smalltalk.addClass('LexicalScope', smalltalk.Object, ['temps', 'args', 'outerScope'], 'Compiler-Semantic');
+smalltalk.addMethod(
+"_addArg_",
+smalltalk.method({
+selector: "addArg:",
+fn: function (aString) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_args", []), "_at_put_", [aString, smalltalk.send((smalltalk.ArgVar || ArgVar), "_on_", [aString])]);
+smalltalk.send(smalltalk.send(smalltalk.send(self, "_args", []), "_at_", [aString]), "_scope_", [self]);
+return self;}
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_addTemp_",
+smalltalk.method({
+selector: "addTemp:",
+fn: function (aString) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_temps", []), "_at_put_", [aString, smalltalk.send((smalltalk.TempVar || TempVar), "_on_", [aString])]);
+smalltalk.send(smalltalk.send(smalltalk.send(self, "_temps", []), "_at_", [aString]), "_scope_", [self]);
+return self;}
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_allVariableNames",
+smalltalk.method({
+selector: "allVariableNames",
+fn: function () {
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(self, "_args", []), "_keys", []), "__comma", [smalltalk.send(smalltalk.send(self, "_temps", []), "_keys", [])]);
+return self;}
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_args",
+smalltalk.method({
+selector: "args",
+fn: function () {
+var self=this;
+return (($receiver = self['@args']) == nil || $receiver == undefined) ? (function(){return (self['@args']=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));})() : $receiver;
+return self;}
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_bindingFor_",
+smalltalk.method({
+selector: "bindingFor:",
+fn: function (aStringOrNode) {
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_args", []), "_at_ifAbsent_", [smalltalk.send(aStringOrNode, "_value", []), (function(){return smalltalk.send(smalltalk.send(self, "_temps", []), "_at_ifAbsent_", [smalltalk.send(aStringOrNode, "_value", []), (function(){return nil;})]);})]);
+return self;}
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_isMethodScope",
+smalltalk.method({
+selector: "isMethodScope",
+fn: function () {
+var self=this;
+return false;
+return self;}
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_lookupVariable_",
+smalltalk.method({
+selector: "lookupVariable:",
+fn: function (aNode) {
+var self=this;
+var lookup=nil;
+(lookup=smalltalk.send(self, "_bindingFor_", [aNode]));
+(($receiver = lookup) == nil || $receiver == undefined) ? (function(){return (lookup=(($receiver = smalltalk.send(self, "_outerScope", [])) != nil && $receiver != undefined) ? (function(){return smalltalk.send(smalltalk.send(self, "_outerScope", []), "_lookupVariable_", [aNode]);})() : nil);})() : $receiver;
+return lookup;
+return self;}
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_methodScope",
+smalltalk.method({
+selector: "methodScope",
+fn: function () {
+var self=this;
+return (($receiver = smalltalk.send(self, "_outerScope", [])) != nil && $receiver != undefined) ? (function(){return smalltalk.send(smalltalk.send(self, "_outerScope", []), "_methodScope", []);})() : nil;
+return self;}
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_outerScope",
+smalltalk.method({
+selector: "outerScope",
+fn: function () {
+var self=this;
+return self['@outerScope'];
+return self;}
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_outerScope_",
+smalltalk.method({
+selector: "outerScope:",
+fn: function (aLexicalScope) {
+var self=this;
+(self['@outerScope']=aLexicalScope);
+return self;}
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_temps",
+smalltalk.method({
+selector: "temps",
+fn: function () {
+var self=this;
+return (($receiver = self['@temps']) == nil || $receiver == undefined) ? (function(){return (self['@temps']=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));})() : $receiver;
+return self;}
+}),
+smalltalk.LexicalScope);
+
+
+
+smalltalk.addClass('MethodLexicalScope', smalltalk.LexicalScope, ['iVars', 'unknownVariables', 'nonLocalReturn'], 'Compiler-Semantic');
+smalltalk.addMethod(
+"_addIvar_",
+smalltalk.method({
+selector: "addIvar:",
+fn: function (aString) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_iVars", []), "_at_put_", [aString, smalltalk.send((smalltalk.InstanceVar || InstanceVar), "_on_", [aString])]);
+smalltalk.send(smalltalk.send(smalltalk.send(self, "_iVars", []), "_at_", [aString]), "_scope_", [self]);
+return self;}
+}),
+smalltalk.MethodLexicalScope);
+
+smalltalk.addMethod(
+"_allVariableNames",
+smalltalk.method({
+selector: "allVariableNames",
+fn: function () {
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_allVariableNames", [], smalltalk.MethodLexicalScope.superclass || nil), "__comma", [smalltalk.send(smalltalk.send(self, "_iVars", []), "_keys", [])]);
+return self;}
+}),
+smalltalk.MethodLexicalScope);
+
+smalltalk.addMethod(
+"_bindingFor_",
+smalltalk.method({
+selector: "bindingFor:",
+fn: function (aNode) {
+var self=this;
+return (($receiver = smalltalk.send(self, "_bindingFor_", [aNode], smalltalk.MethodLexicalScope.superclass || nil)) == nil || $receiver == undefined) ? (function(){return smalltalk.send(smalltalk.send(self, "_iVars", []), "_at_ifAbsent_", [smalltalk.send(aNode, "_value", []), (function(){return nil;})]);})() : $receiver;
+return self;}
+}),
+smalltalk.MethodLexicalScope);
+
+smalltalk.addMethod(
+"_hasNonLocalReturn",
+smalltalk.method({
+selector: "hasNonLocalReturn",
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_nonLocalReturn", []);
+return self;}
+}),
+smalltalk.MethodLexicalScope);
+
+smalltalk.addMethod(
+"_iVars",
+smalltalk.method({
+selector: "iVars",
+fn: function () {
+var self=this;
+return (($receiver = self['@iVars']) == nil || $receiver == undefined) ? (function(){return (self['@iVars']=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));})() : $receiver;
+return self;}
+}),
+smalltalk.MethodLexicalScope);
+
+smalltalk.addMethod(
+"_isMethodScope",
+smalltalk.method({
+selector: "isMethodScope",
+fn: function () {
+var self=this;
+return true;
+return self;}
+}),
+smalltalk.MethodLexicalScope);
+
+smalltalk.addMethod(
+"_methodScope",
+smalltalk.method({
+selector: "methodScope",
+fn: function () {
+var self=this;
+return self;
+return self;}
+}),
+smalltalk.MethodLexicalScope);
+
+smalltalk.addMethod(
+"_nonLocalReturn",
+smalltalk.method({
+selector: "nonLocalReturn",
+fn: function () {
+var self=this;
+return (($receiver = self['@nonLocalReturn']) == nil || $receiver == undefined) ? (function(){return false;})() : $receiver;
+return self;}
+}),
+smalltalk.MethodLexicalScope);
+
+smalltalk.addMethod(
+"_nonLocalReturn_",
+smalltalk.method({
+selector: "nonLocalReturn:",
+fn: function (aBoolean) {
+var self=this;
+(self['@nonLocalReturn']=aBoolean);
+return self;}
+}),
+smalltalk.MethodLexicalScope);
+
+smalltalk.addMethod(
+"_unknownVariables",
+smalltalk.method({
+selector: "unknownVariables",
+fn: function () {
+var self=this;
+return (($receiver = self['@unknownVariables']) == nil || $receiver == undefined) ? (function(){return (self['@unknownVariables']=smalltalk.send((smalltalk.OrderedCollection || OrderedCollection), "_new", []));})() : $receiver;
+return self;}
+}),
+smalltalk.MethodLexicalScope);
+
+
+
+smalltalk.addClass('ScopeVar', smalltalk.Object, ['scope', 'name'], 'Compiler-Semantic');
+smalltalk.addMethod(
+"_alias",
+smalltalk.method({
+selector: "alias",
+fn: function () {
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_name", []), "_asVariableName", []);
+return self;}
+}),
+smalltalk.ScopeVar);
+
+smalltalk.addMethod(
+"_isArgVar",
+smalltalk.method({
+selector: "isArgVar",
+fn: function () {
+var self=this;
+return false;
+return self;}
+}),
+smalltalk.ScopeVar);
+
+smalltalk.addMethod(
+"_isInstanceVar",
+smalltalk.method({
+selector: "isInstanceVar",
+fn: function () {
+var self=this;
+return false;
+return self;}
+}),
+smalltalk.ScopeVar);
+
+smalltalk.addMethod(
+"_isTempVar",
+smalltalk.method({
+selector: "isTempVar",
+fn: function () {
+var self=this;
+return false;
+return self;}
+}),
+smalltalk.ScopeVar);
+
+smalltalk.addMethod(
+"_isUnknownVar",
+smalltalk.method({
+selector: "isUnknownVar",
+fn: function () {
+var self=this;
+return false;
+return self;}
+}),
+smalltalk.ScopeVar);
+
+smalltalk.addMethod(
+"_name",
+smalltalk.method({
+selector: "name",
+fn: function () {
+var self=this;
+return self['@name'];
+return self;}
+}),
+smalltalk.ScopeVar);
+
+smalltalk.addMethod(
+"_name_",
+smalltalk.method({
+selector: "name:",
+fn: function (aString) {
+var self=this;
+(self['@name']=aString);
+return self;}
+}),
+smalltalk.ScopeVar);
+
+smalltalk.addMethod(
+"_scope",
+smalltalk.method({
+selector: "scope",
+fn: function () {
+var self=this;
+return self['@scope'];
+return self;}
+}),
+smalltalk.ScopeVar);
+
+smalltalk.addMethod(
+"_scope_",
+smalltalk.method({
+selector: "scope:",
+fn: function (aScope) {
+var self=this;
+(self['@scope']=aScope);
+return self;}
+}),
+smalltalk.ScopeVar);
+
+
+smalltalk.addMethod(
+"_on_",
+smalltalk.method({
+selector: "on:",
+fn: function (aString) {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_name_", [aString]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_new", []));
+return self;}
+}),
+smalltalk.ScopeVar.klass);
+
+
+smalltalk.addClass('AliasVar', smalltalk.ScopeVar, [], 'Compiler-Semantic');
+
+
+smalltalk.addClass('ArgVar', smalltalk.ScopeVar, [], 'Compiler-Semantic');
+smalltalk.addMethod(
+"_isArgVar",
+smalltalk.method({
+selector: "isArgVar",
+fn: function () {
+var self=this;
+return true;
+return self;}
+}),
+smalltalk.ArgVar);
+
+
+
+smalltalk.addClass('ClassRefVar', smalltalk.ScopeVar, [], 'Compiler-Semantic');
+smalltalk.addMethod(
+"_alias",
+smalltalk.method({
+selector: "alias",
+fn: function () {
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send("(Smalltalk.", "__comma", [smalltalk.send(self, "_name", [])]), "__comma", [" || "]), "__comma", [smalltalk.send(self, "_name", [])]), "__comma", [")"]);
+return self;}
+}),
+smalltalk.ClassRefVar);
+
+
+
+smalltalk.addClass('InstanceVar', smalltalk.ScopeVar, [], 'Compiler-Semantic');
+smalltalk.addMethod(
+"_alias",
+smalltalk.method({
+selector: "alias",
+fn: function () {
+var self=this;
+return smalltalk.send(smalltalk.send("self[\x22@", "__comma", [smalltalk.send(self, "_name", [])]), "__comma", ["]"]);
+return self;}
+}),
+smalltalk.InstanceVar);
+
+smalltalk.addMethod(
+"_isInstanceVar",
+smalltalk.method({
+selector: "isInstanceVar",
+fn: function () {
+var self=this;
+return true;
+return self;}
+}),
+smalltalk.InstanceVar);
+
+
+
+smalltalk.addClass('TempVar', smalltalk.ScopeVar, [], 'Compiler-Semantic');
+smalltalk.addMethod(
+"_isTempVar",
+smalltalk.method({
+selector: "isTempVar",
+fn: function () {
+var self=this;
+return true;
+return self;}
+}),
+smalltalk.TempVar);
+
+
+
+smalltalk.addClass('UnknownVar', smalltalk.ScopeVar, [], 'Compiler-Semantic');
+smalltalk.addMethod(
+"_isUnknownVar",
+smalltalk.method({
+selector: "isUnknownVar",
+fn: function () {
+var self=this;
+return true;
+return self;}
+}),
+smalltalk.UnknownVar);
+
+
+
+smalltalk.addClass('SemanticAnalyzer', smalltalk.NodeVisitor, ['currentScope', 'theClass', 'classReferences', 'messageSends'], 'Compiler-Semantic');
+smalltalk.addMethod(
+"_allowUnknownVariables",
+smalltalk.method({
+selector: "allowUnknownVariables",
+fn: function () {
+var self=this;
+return true;
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_classReferences",
+smalltalk.method({
+selector: "classReferences",
+fn: function () {
+var self=this;
+return (($receiver = self['@classReferences']) == nil || $receiver == undefined) ? (function(){return (self['@classReferences']=smalltalk.send((smalltalk.Set || Set), "_new", []));})() : $receiver;
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_errorInvalidAssignment_",
+smalltalk.method({
+selector: "errorInvalidAssignment:",
+fn: function (aString) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_variableName_", [aString]);return smalltalk.send($rec, "_signal", []);})(smalltalk.send((smalltalk.InvalidAssignmentError || InvalidAssignmentError), "_new", []));
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_errorShadowingVariable_",
+smalltalk.method({
+selector: "errorShadowingVariable:",
+fn: function (aString) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_variableName_", [aString]);return smalltalk.send($rec, "_signal", []);})(smalltalk.send((smalltalk.ShadowingVariableError || ShadowingVariableError), "_new", []));
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_errorUnknownVariable_",
+smalltalk.method({
+selector: "errorUnknownVariable:",
+fn: function (aNode) {
+var self=this;
+((($receiver = smalltalk.send(self, "_allowUnknownVariables", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send(smalltalk.send(self['@currentScope'], "_methodScope", []), "_unknownVariables", []), "_add_", [smalltalk.send(aNode, "_value", [])]);})() : (function(){return (function($rec){smalltalk.send($rec, "_variableName_", [smalltalk.send(aNode, "_value", [])]);return smalltalk.send($rec, "_signal", []);})(smalltalk.send((smalltalk.UnknownVariableError || UnknownVariableError), "_new", []));})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(smalltalk.send(self['@currentScope'], "_methodScope", []), "_unknownVariables", []), "_add_", [smalltalk.send(aNode, "_value", [])]);}), (function(){return (function($rec){smalltalk.send($rec, "_variableName_", [smalltalk.send(aNode, "_value", [])]);return smalltalk.send($rec, "_signal", []);})(smalltalk.send((smalltalk.UnknownVariableError || UnknownVariableError), "_new", []));})]));
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_messageSends",
+smalltalk.method({
+selector: "messageSends",
+fn: function () {
+var self=this;
+return (($receiver = self['@messageSends']) == nil || $receiver == undefined) ? (function(){return (self['@messageSends']=smalltalk.send((smalltalk.Set || Set), "_new", []));})() : $receiver;
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_newBlockScope",
+smalltalk.method({
+selector: "newBlockScope",
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_newScopeOfClass_", [(smalltalk.LexicalScope || LexicalScope)]);
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_newMethodScope",
+smalltalk.method({
+selector: "newMethodScope",
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_newScopeOfClass_", [(smalltalk.MethodLexicalScope || MethodLexicalScope)]);
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_newScopeOfClass_",
+smalltalk.method({
+selector: "newScopeOfClass:",
+fn: function (aLexicalScopeClass) {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_outerScope_", [self['@currentScope']]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(aLexicalScopeClass, "_new", []));
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_popScope",
+smalltalk.method({
+selector: "popScope",
+fn: function () {
+var self=this;
+(($receiver = self['@currentScope']) != nil && $receiver != undefined) ? (function(){return (self['@currentScope']=smalltalk.send(self['@currentScope'], "_outerScope", []));})() : nil;
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_pseudoVariables",
+smalltalk.method({
+selector: "pseudoVariables",
+fn: function () {
+var self=this;
+return ["self", "super", "true", "false", "nil", "thisContext"];
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_pushScope_",
+smalltalk.method({
+selector: "pushScope:",
+fn: function (aScope) {
+var self=this;
+smalltalk.send(aScope, "_outerScope_", [self['@currentScope']]);
+(self['@currentScope']=aScope);
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_theClass",
+smalltalk.method({
+selector: "theClass",
+fn: function () {
+var self=this;
+return self['@theClass'];
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_theClass_",
+smalltalk.method({
+selector: "theClass:",
+fn: function (aClass) {
+var self=this;
+(self['@theClass']=aClass);
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_validateVariableScope_",
+smalltalk.method({
+selector: "validateVariableScope:",
+fn: function (aString) {
+var self=this;
+(($receiver = smalltalk.send(self['@currentScope'], "_lookupVariable_", [aString])) != nil && $receiver != undefined) ? (function(){return smalltalk.send(self, "_errorShadowingVariable_", [aString]);})() : nil;
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_visitAssignmentNode_",
+smalltalk.method({
+selector: "visitAssignmentNode:",
+fn: function (aNode) {
+var self=this;
+((($receiver = smalltalk.send(smalltalk.send(self, "_pseudoVariables", []), "_includes_", [smalltalk.send(smalltalk.send(aNode, "_left", []), "_value", [])])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_errorInvalidAssignment_", [smalltalk.send(aNode, "_left", [])]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(self, "_errorInvalidAssignment_", [smalltalk.send(aNode, "_left", [])]);})]));
+smalltalk.send(smalltalk.send(aNode, "_left", []), "_beAssigned", []);
+smalltalk.send(smalltalk.send(aNode, "_right", []), "_beUsed", []);
+smalltalk.send(self, "_visitAssignmentNode_", [aNode], smalltalk.SemanticAnalyzer.superclass || nil);
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_visitBlockNode_",
+smalltalk.method({
+selector: "visitBlockNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_pushScope_", [smalltalk.send(self, "_newBlockScope", [])]);
+smalltalk.send(aNode, "_scope_", [self['@currentScope']]);
+smalltalk.send(smalltalk.send(aNode, "_parameters", []), "_do_", [(function(each){smalltalk.send(self, "_validateVariableScope_", [each]);return smalltalk.send(self['@currentScope'], "_addArg_", [each]);})]);
+smalltalk.send(self, "_visitBlockNode_", [aNode], smalltalk.SemanticAnalyzer.superclass || nil);
+smalltalk.send(self, "_popScope", []);
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_visitClassReferenceNode_",
+smalltalk.method({
+selector: "visitClassReferenceNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_classReferences", []), "_add_", [smalltalk.send(aNode, "_value", [])]);
+smalltalk.send(aNode, "_binding_", [(function($rec){smalltalk.send($rec, "_name_", [smalltalk.send(aNode, "_value", [])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.ClassRefVar || ClassRefVar), "_new", []))]);
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_visitMethodNode_",
+smalltalk.method({
+selector: "visitMethodNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_pushScope_", [smalltalk.send(self, "_newMethodScope", [])]);
+smalltalk.send(aNode, "_scope_", [self['@currentScope']]);
+smalltalk.send(smalltalk.send(smalltalk.send(self, "_theClass", []), "_allInstanceVariableNames", []), "_do_", [(function(each){return smalltalk.send(self['@currentScope'], "_addIVar_", [each]);})]);
+smalltalk.send(smalltalk.send(aNode, "_arguments", []), "_do_", [(function(each){smalltalk.send(self, "_validateVariableScope_", [each]);return smalltalk.send(self['@currentScope'], "_addArg_", [each]);})]);
+smalltalk.send(self, "_visitMethodNode_", [aNode], smalltalk.SemanticAnalyzer.superclass || nil);
+(function($rec){smalltalk.send($rec, "_classReferences_", [smalltalk.send(self, "_classReferences", [])]);return smalltalk.send($rec, "_messageSends_", [smalltalk.send(self, "_messageSends", [])]);})(aNode);
+smalltalk.send(self, "_popScope", []);
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_visitReturnNode_",
+smalltalk.method({
+selector: "visitReturnNode:",
+fn: function (aNode) {
+var self=this;
+((($receiver = smalltalk.send(self['@currentScope'], "_isMethodScope", [])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){smalltalk.send(smalltalk.send(self['@currentScope'], "_methodScope", []), "_nonLocalReturn_", [true]);return smalltalk.send(aNode, "_nonLocalReturn_", [true]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){smalltalk.send(smalltalk.send(self['@currentScope'], "_methodScope", []), "_nonLocalReturn_", [true]);return smalltalk.send(aNode, "_nonLocalReturn_", [true]);})]));
+smalltalk.send(smalltalk.send(smalltalk.send(aNode, "_nodes", []), "_first", []), "_beUsed", []);
+smalltalk.send(self, "_visitReturnNode_", [aNode], smalltalk.SemanticAnalyzer.superclass || nil);
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_visitSendNode_",
+smalltalk.method({
+selector: "visitSendNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_messageSends", []), "_add_", [smalltalk.send(aNode, "_selector", [])]);
+smalltalk.send(smalltalk.send(aNode, "_receiver", []), "_beUsed", []);
+smalltalk.send(smalltalk.send(aNode, "_arguments", []), "_do_", [(function(each){return smalltalk.send(each, "_beUsed", []);})]);
+smalltalk.send(self, "_visitSendNode_", [aNode], smalltalk.SemanticAnalyzer.superclass || nil);
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_visitSequenceNode_",
+smalltalk.method({
+selector: "visitSequenceNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(smalltalk.send(aNode, "_temps", []), "_do_", [(function(each){smalltalk.send(self, "_validateVariableScope_", [each]);return smalltalk.send(self['@currentScope'], "_addTemp_", [each]);})]);
+smalltalk.send(self, "_visitSequenceNode_", [aNode], smalltalk.SemanticAnalyzer.superclass || nil);
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_visitVariableNode_",
+smalltalk.method({
+selector: "visitVariableNode:",
+fn: function (aNode) {
+var self=this;
+smalltalk.send(aNode, "_binding_", [(($receiver = smalltalk.send(self['@currentScope'], "_lookupVariable_", [aNode])) == nil || $receiver == undefined) ? (function(){smalltalk.send(self, "_errorUnknownVariable_", [aNode]);return (function($rec){smalltalk.send($rec, "_name_", [smalltalk.send(aNode, "_value", [])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.UnknownVar || UnknownVar), "_new", []));})() : $receiver]);
+return self;}
+}),
+smalltalk.SemanticAnalyzer);
+
+
+smalltalk.addMethod(
+"_on_",
+smalltalk.method({
+selector: "on:",
+fn: function (aClass) {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_theClass_", [aClass]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_new", []));
+return self;}
+}),
+smalltalk.SemanticAnalyzer.klass);
+
+
+smalltalk.addClass('SemanticError', smalltalk.Error, [], 'Compiler-Semantic');
+
+
+smalltalk.addClass('InvalidAssignmentError', smalltalk.SemanticError, ['variableName'], 'Compiler-Semantic');
+smalltalk.addMethod(
+"_variableName",
+smalltalk.method({
+selector: "variableName",
+fn: function () {
+var self=this;
+return self['@variableName'];
+return self;}
+}),
+smalltalk.InvalidAssignmentError);
+
+smalltalk.addMethod(
+"_variableName_",
+smalltalk.method({
+selector: "variableName:",
+fn: function (aString) {
+var self=this;
+(self['@variableName']=aString);
+return self;}
+}),
+smalltalk.InvalidAssignmentError);
+
+
+
+smalltalk.addClass('ShadowingVariableError', smalltalk.SemanticError, ['variableName'], 'Compiler-Semantic');
+smalltalk.addMethod(
+"_variableName",
+smalltalk.method({
+selector: "variableName",
+fn: function () {
+var self=this;
+return self['@variableName'];
+return self;}
+}),
+smalltalk.ShadowingVariableError);
+
+smalltalk.addMethod(
+"_variableName_",
+smalltalk.method({
+selector: "variableName:",
+fn: function (aString) {
+var self=this;
+(self['@variableName']=aString);
+return self;}
+}),
+smalltalk.ShadowingVariableError);
+
+
+
+smalltalk.addClass('UnknownVariableError', smalltalk.SemanticError, ['variableName'], 'Compiler-Semantic');
+smalltalk.addMethod(
+"_variableName",
+smalltalk.method({
+selector: "variableName",
+fn: function () {
+var self=this;
+return self['@variableName'];
+return self;}
+}),
+smalltalk.UnknownVariableError);
+
+smalltalk.addMethod(
+"_variableName_",
+smalltalk.method({
+selector: "variableName:",
+fn: function (aString) {
+var self=this;
+(self['@variableName']=aString);
+return self;}
+}),
+smalltalk.UnknownVariableError);
+
+
+

+ 1155 - 0
js/Compiler-Semantic.js

@@ -0,0 +1,1155 @@
+smalltalk.addPackage('Compiler-Semantic', {});
+smalltalk.addClass('LexicalScope', smalltalk.Object, ['temps', 'args', 'outerScope'], 'Compiler-Semantic');
+smalltalk.LexicalScope.comment="I represent a lexical scope where variable names are associated with ScopeVars\x0aInstances are used for block scopes. Method scopes are instances of MethodLexicalScope.\x0a\x0aI am attached to a ScopeVar and method/block nodes.\x0aEach context (method/closure) get a fresh scope that inherits from its outer scope."
+smalltalk.addMethod(
+"_addArg_",
+smalltalk.method({
+selector: "addArg:",
+category: 'adding',
+fn: function (aString) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_args", []), "_at_put_", [aString, smalltalk.send((smalltalk.ArgVar || ArgVar), "_on_", [aString])]);
+smalltalk.send(smalltalk.send(smalltalk.send(self, "_args", []), "_at_", [aString]), "_scope_", [self]);
+return self;},
+args: ["aString"],
+source: "addArg: aString\x0a\x09self args at: aString put: (ArgVar on: aString).\x0a\x09(self args at: aString) scope: self",
+messageSends: ["at:put:", "args", "on:", "scope:", "at:"],
+referencedClasses: ["ArgVar"]
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_addTemp_",
+smalltalk.method({
+selector: "addTemp:",
+category: 'adding',
+fn: function (aString) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_temps", []), "_at_put_", [aString, smalltalk.send((smalltalk.TempVar || TempVar), "_on_", [aString])]);
+smalltalk.send(smalltalk.send(smalltalk.send(self, "_temps", []), "_at_", [aString]), "_scope_", [self]);
+return self;},
+args: ["aString"],
+source: "addTemp: aString\x0a\x09self temps at: aString put: (TempVar on: aString).\x0a\x09(self temps at: aString) scope: self",
+messageSends: ["at:put:", "temps", "on:", "scope:", "at:"],
+referencedClasses: ["TempVar"]
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_allVariableNames",
+smalltalk.method({
+selector: "allVariableNames",
+category: 'accessing',
+fn: function () {
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(self, "_args", []), "_keys", []), "__comma", [smalltalk.send(smalltalk.send(self, "_temps", []), "_keys", [])]);
+return self;},
+args: [],
+source: "allVariableNames\x0a\x09^ self args keys, self temps keys",
+messageSends: [",", "keys", "args", "temps"],
+referencedClasses: []
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_args",
+smalltalk.method({
+selector: "args",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@args']) == nil || $receiver == undefined) ? (function(){return (self['@args']=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));})() : $receiver;
+return self;},
+args: [],
+source: "args\x0a\x09^ args ifNil: [ args := Dictionary new ]",
+messageSends: ["ifNil:", "new"],
+referencedClasses: ["Dictionary"]
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_bindingFor_",
+smalltalk.method({
+selector: "bindingFor:",
+category: 'accessing',
+fn: function (aStringOrNode) {
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_args", []), "_at_ifAbsent_", [smalltalk.send(aStringOrNode, "_value", []), (function(){return smalltalk.send(smalltalk.send(self, "_temps", []), "_at_ifAbsent_", [smalltalk.send(aStringOrNode, "_value", []), (function(){return nil;})]);})]);
+return self;},
+args: ["aStringOrNode"],
+source: "bindingFor: aStringOrNode\x0a\x09^ self args at: aStringOrNode value ifAbsent: [\x0a\x09\x09self temps at: aStringOrNode value ifAbsent: [ nil ]]",
+messageSends: ["at:ifAbsent:", "args", "value", "temps"],
+referencedClasses: []
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_isMethodScope",
+smalltalk.method({
+selector: "isMethodScope",
+category: 'testing',
+fn: function () {
+var self=this;
+return false;
+return self;},
+args: [],
+source: "isMethodScope\x0a\x09^ false",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_lookupVariable_",
+smalltalk.method({
+selector: "lookupVariable:",
+category: 'accessing',
+fn: function (aNode) {
+var self=this;
+var lookup=nil;
+(lookup=smalltalk.send(self, "_bindingFor_", [aNode]));
+(($receiver = lookup) == nil || $receiver == undefined) ? (function(){return (lookup=(($receiver = smalltalk.send(self, "_outerScope", [])) != nil && $receiver != undefined) ? (function(){return smalltalk.send(smalltalk.send(self, "_outerScope", []), "_lookupVariable_", [aNode]);})() : nil);})() : $receiver;
+return lookup;
+return self;},
+args: ["aNode"],
+source: "lookupVariable: aNode\x0a\x09| lookup |\x0a\x09lookup := (self bindingFor: aNode).\x0a\x09lookup ifNil: [\x0a\x09\x09lookup := self outerScope ifNotNil: [ \x0a\x09\x09\x09(self outerScope lookupVariable: aNode) ]].\x0a\x09^ lookup",
+messageSends: ["bindingFor:", "ifNil:", "ifNotNil:", "outerScope", "lookupVariable:"],
+referencedClasses: []
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_methodScope",
+smalltalk.method({
+selector: "methodScope",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = smalltalk.send(self, "_outerScope", [])) != nil && $receiver != undefined) ? (function(){return smalltalk.send(smalltalk.send(self, "_outerScope", []), "_methodScope", []);})() : nil;
+return self;},
+args: [],
+source: "methodScope\x0a\x09^ self outerScope ifNotNil: [\x0a\x09\x09self outerScope methodScope ]",
+messageSends: ["ifNotNil:", "outerScope", "methodScope"],
+referencedClasses: []
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_outerScope",
+smalltalk.method({
+selector: "outerScope",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@outerScope'];
+return self;},
+args: [],
+source: "outerScope\x0a\x09^ outerScope",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_outerScope_",
+smalltalk.method({
+selector: "outerScope:",
+category: 'accessing',
+fn: function (aLexicalScope) {
+var self=this;
+(self['@outerScope']=aLexicalScope);
+return self;},
+args: ["aLexicalScope"],
+source: "outerScope: aLexicalScope\x0a\x09outerScope := aLexicalScope",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.LexicalScope);
+
+smalltalk.addMethod(
+"_temps",
+smalltalk.method({
+selector: "temps",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@temps']) == nil || $receiver == undefined) ? (function(){return (self['@temps']=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));})() : $receiver;
+return self;},
+args: [],
+source: "temps\x0a\x09^ temps ifNil: [ temps := Dictionary new ]",
+messageSends: ["ifNil:", "new"],
+referencedClasses: ["Dictionary"]
+}),
+smalltalk.LexicalScope);
+
+
+
+smalltalk.addClass('MethodLexicalScope', smalltalk.LexicalScope, ['iVars', 'unknownVariables', 'nonLocalReturn'], 'Compiler-Semantic');
+smalltalk.MethodLexicalScope.comment="I represent a method scope."
+smalltalk.addMethod(
+"_addIvar_",
+smalltalk.method({
+selector: "addIvar:",
+category: 'adding',
+fn: function (aString) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_iVars", []), "_at_put_", [aString, smalltalk.send((smalltalk.InstanceVar || InstanceVar), "_on_", [aString])]);
+smalltalk.send(smalltalk.send(smalltalk.send(self, "_iVars", []), "_at_", [aString]), "_scope_", [self]);
+return self;},
+args: ["aString"],
+source: "addIvar: aString\x0a\x09self iVars at: aString put: (InstanceVar on: aString).\x0a\x09(self iVars at: aString) scope: self",
+messageSends: ["at:put:", "iVars", "on:", "scope:", "at:"],
+referencedClasses: ["InstanceVar"]
+}),
+smalltalk.MethodLexicalScope);
+
+smalltalk.addMethod(
+"_allVariableNames",
+smalltalk.method({
+selector: "allVariableNames",
+category: 'accessing',
+fn: function () {
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_allVariableNames", [], smalltalk.MethodLexicalScope.superclass || nil), "__comma", [smalltalk.send(smalltalk.send(self, "_iVars", []), "_keys", [])]);
+return self;},
+args: [],
+source: "allVariableNames\x0a\x09^ super allVariableNames, self iVars keys",
+messageSends: [",", "allVariableNames", "keys", "iVars"],
+referencedClasses: []
+}),
+smalltalk.MethodLexicalScope);
+
+smalltalk.addMethod(
+"_bindingFor_",
+smalltalk.method({
+selector: "bindingFor:",
+category: 'accessing',
+fn: function (aNode) {
+var self=this;
+return (($receiver = smalltalk.send(self, "_bindingFor_", [aNode], smalltalk.MethodLexicalScope.superclass || nil)) == nil || $receiver == undefined) ? (function(){return smalltalk.send(smalltalk.send(self, "_iVars", []), "_at_ifAbsent_", [smalltalk.send(aNode, "_value", []), (function(){return nil;})]);})() : $receiver;
+return self;},
+args: ["aNode"],
+source: "bindingFor: aNode\x0a\x09^ (super bindingFor: aNode) ifNil: [\x0a\x09\x09self iVars at: aNode value ifAbsent: [ nil ]]",
+messageSends: ["ifNil:", "bindingFor:", "at:ifAbsent:", "iVars", "value"],
+referencedClasses: []
+}),
+smalltalk.MethodLexicalScope);
+
+smalltalk.addMethod(
+"_hasNonLocalReturn",
+smalltalk.method({
+selector: "hasNonLocalReturn",
+category: 'testing',
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_nonLocalReturn", []);
+return self;},
+args: [],
+source: "hasNonLocalReturn\x0a\x09^ self nonLocalReturn",
+messageSends: ["nonLocalReturn"],
+referencedClasses: []
+}),
+smalltalk.MethodLexicalScope);
+
+smalltalk.addMethod(
+"_iVars",
+smalltalk.method({
+selector: "iVars",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@iVars']) == nil || $receiver == undefined) ? (function(){return (self['@iVars']=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));})() : $receiver;
+return self;},
+args: [],
+source: "iVars\x0a\x09^ iVars ifNil: [ iVars := Dictionary new ]",
+messageSends: ["ifNil:", "new"],
+referencedClasses: ["Dictionary"]
+}),
+smalltalk.MethodLexicalScope);
+
+smalltalk.addMethod(
+"_isMethodScope",
+smalltalk.method({
+selector: "isMethodScope",
+category: 'testing',
+fn: function () {
+var self=this;
+return true;
+return self;},
+args: [],
+source: "isMethodScope\x0a\x09^ true",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.MethodLexicalScope);
+
+smalltalk.addMethod(
+"_methodScope",
+smalltalk.method({
+selector: "methodScope",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self;
+return self;},
+args: [],
+source: "methodScope\x0a\x09^ self",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.MethodLexicalScope);
+
+smalltalk.addMethod(
+"_nonLocalReturn",
+smalltalk.method({
+selector: "nonLocalReturn",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@nonLocalReturn']) == nil || $receiver == undefined) ? (function(){return false;})() : $receiver;
+return self;},
+args: [],
+source: "nonLocalReturn\x0a\x09^ nonLocalReturn ifNil: [ false ]",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.MethodLexicalScope);
+
+smalltalk.addMethod(
+"_nonLocalReturn_",
+smalltalk.method({
+selector: "nonLocalReturn:",
+category: 'accessing',
+fn: function (aBoolean) {
+var self=this;
+(self['@nonLocalReturn']=aBoolean);
+return self;},
+args: ["aBoolean"],
+source: "nonLocalReturn: aBoolean\x0a\x09nonLocalReturn := aBoolean",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.MethodLexicalScope);
+
+smalltalk.addMethod(
+"_unknownVariables",
+smalltalk.method({
+selector: "unknownVariables",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@unknownVariables']) == nil || $receiver == undefined) ? (function(){return (self['@unknownVariables']=smalltalk.send((smalltalk.OrderedCollection || OrderedCollection), "_new", []));})() : $receiver;
+return self;},
+args: [],
+source: "unknownVariables\x0a\x09^ unknownVariables ifNil: [ unknownVariables := OrderedCollection new ]",
+messageSends: ["ifNil:", "new"],
+referencedClasses: ["OrderedCollection"]
+}),
+smalltalk.MethodLexicalScope);
+
+
+
+smalltalk.addClass('ScopeVar', smalltalk.Object, ['scope', 'name'], 'Compiler-Semantic');
+smalltalk.ScopeVar.comment="I am an entry in a LexicalScope that gets associated with variable nodes of the same name.  \x0aThere are 4 different subclasses of vars: temp vars, local vars, args, and unknown/global vars."
+smalltalk.addMethod(
+"_alias",
+smalltalk.method({
+selector: "alias",
+category: 'accessing',
+fn: function () {
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_name", []), "_asVariableName", []);
+return self;},
+args: [],
+source: "alias\x0a\x09^ self name asVariableName",
+messageSends: ["asVariableName", "name"],
+referencedClasses: []
+}),
+smalltalk.ScopeVar);
+
+smalltalk.addMethod(
+"_isArgVar",
+smalltalk.method({
+selector: "isArgVar",
+category: 'testing',
+fn: function () {
+var self=this;
+return false;
+return self;},
+args: [],
+source: "isArgVar\x0a\x09^ false",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ScopeVar);
+
+smalltalk.addMethod(
+"_isInstanceVar",
+smalltalk.method({
+selector: "isInstanceVar",
+category: 'testing',
+fn: function () {
+var self=this;
+return false;
+return self;},
+args: [],
+source: "isInstanceVar\x0a\x09^ false",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ScopeVar);
+
+smalltalk.addMethod(
+"_isTempVar",
+smalltalk.method({
+selector: "isTempVar",
+category: 'testing',
+fn: function () {
+var self=this;
+return false;
+return self;},
+args: [],
+source: "isTempVar\x0a\x09^ false",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ScopeVar);
+
+smalltalk.addMethod(
+"_isUnknownVar",
+smalltalk.method({
+selector: "isUnknownVar",
+category: 'testing',
+fn: function () {
+var self=this;
+return false;
+return self;},
+args: [],
+source: "isUnknownVar\x0a\x09^ false",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ScopeVar);
+
+smalltalk.addMethod(
+"_name",
+smalltalk.method({
+selector: "name",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@name'];
+return self;},
+args: [],
+source: "name\x0a\x09^ name",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ScopeVar);
+
+smalltalk.addMethod(
+"_name_",
+smalltalk.method({
+selector: "name:",
+category: 'accessing',
+fn: function (aString) {
+var self=this;
+(self['@name']=aString);
+return self;},
+args: ["aString"],
+source: "name: aString\x0a\x09name := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ScopeVar);
+
+smalltalk.addMethod(
+"_scope",
+smalltalk.method({
+selector: "scope",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@scope'];
+return self;},
+args: [],
+source: "scope\x0a\x09^ scope",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ScopeVar);
+
+smalltalk.addMethod(
+"_scope_",
+smalltalk.method({
+selector: "scope:",
+category: 'accessing',
+fn: function (aScope) {
+var self=this;
+(self['@scope']=aScope);
+return self;},
+args: ["aScope"],
+source: "scope: aScope\x0a\x09scope := aScope",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ScopeVar);
+
+
+smalltalk.addMethod(
+"_on_",
+smalltalk.method({
+selector: "on:",
+category: 'instance creation',
+fn: function (aString) {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_name_", [aString]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_new", []));
+return self;},
+args: ["aString"],
+source: "on: aString\x0a\x09^ self new \x0a\x09\x09name: aString;\x0a\x09\x09yourself",
+messageSends: ["name:", "yourself", "new"],
+referencedClasses: []
+}),
+smalltalk.ScopeVar.klass);
+
+
+smalltalk.addClass('AliasVar', smalltalk.ScopeVar, [], 'Compiler-Semantic');
+smalltalk.AliasVar.comment="I am an internally defined variable by the compiler"
+
+
+smalltalk.addClass('ArgVar', smalltalk.ScopeVar, [], 'Compiler-Semantic');
+smalltalk.ArgVar.comment="I am an argument of a method or block."
+smalltalk.addMethod(
+"_isArgVar",
+smalltalk.method({
+selector: "isArgVar",
+category: 'testing',
+fn: function () {
+var self=this;
+return true;
+return self;},
+args: [],
+source: "isArgVar\x0a\x09^ true",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ArgVar);
+
+
+
+smalltalk.addClass('ClassRefVar', smalltalk.ScopeVar, [], 'Compiler-Semantic');
+smalltalk.addMethod(
+"_alias",
+smalltalk.method({
+selector: "alias",
+category: 'accessing',
+fn: function () {
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send("(Smalltalk.", "__comma", [smalltalk.send(self, "_name", [])]), "__comma", [" || "]), "__comma", [smalltalk.send(self, "_name", [])]), "__comma", [")"]);
+return self;},
+args: [],
+source: "alias\x0a\x09^ '(Smalltalk.', self name, ' || ', self name, ')'",
+messageSends: [",", "name"],
+referencedClasses: []
+}),
+smalltalk.ClassRefVar);
+
+
+
+smalltalk.addClass('InstanceVar', smalltalk.ScopeVar, [], 'Compiler-Semantic');
+smalltalk.InstanceVar.comment="I am an instance variable of a method or block."
+smalltalk.addMethod(
+"_alias",
+smalltalk.method({
+selector: "alias",
+category: 'testing',
+fn: function () {
+var self=this;
+return smalltalk.send(smalltalk.send("self[\x22@", "__comma", [smalltalk.send(self, "_name", [])]), "__comma", ["]"]);
+return self;},
+args: [],
+source: "alias\x0a\x09^ 'self[\x22@', self name, ']'",
+messageSends: [",", "name"],
+referencedClasses: []
+}),
+smalltalk.InstanceVar);
+
+smalltalk.addMethod(
+"_isInstanceVar",
+smalltalk.method({
+selector: "isInstanceVar",
+category: 'testing',
+fn: function () {
+var self=this;
+return true;
+return self;},
+args: [],
+source: "isInstanceVar\x0a\x09^ true",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.InstanceVar);
+
+
+
+smalltalk.addClass('TempVar', smalltalk.ScopeVar, [], 'Compiler-Semantic');
+smalltalk.TempVar.comment="I am an temporary variable of a method or block."
+smalltalk.addMethod(
+"_isTempVar",
+smalltalk.method({
+selector: "isTempVar",
+category: 'testing',
+fn: function () {
+var self=this;
+return true;
+return self;},
+args: [],
+source: "isTempVar\x0a\x09^ true",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.TempVar);
+
+
+
+smalltalk.addClass('UnknownVar', smalltalk.ScopeVar, [], 'Compiler-Semantic');
+smalltalk.UnknownVar.comment="I am an unknown variable. Amber uses unknown variables as JavaScript globals"
+smalltalk.addMethod(
+"_isUnknownVar",
+smalltalk.method({
+selector: "isUnknownVar",
+category: 'testing',
+fn: function () {
+var self=this;
+return true;
+return self;},
+args: [],
+source: "isUnknownVar\x0a\x09^ true",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.UnknownVar);
+
+
+
+smalltalk.addClass('SemanticAnalyzer', smalltalk.NodeVisitor, ['currentScope', 'theClass', 'classReferences', 'messageSends'], 'Compiler-Semantic');
+smalltalk.SemanticAnalyzer.comment="I semantically analyze the abstract syntax tree and annotate it with informations such as non local returns and variable scopes."
+smalltalk.addMethod(
+"_allowUnknownVariables",
+smalltalk.method({
+selector: "allowUnknownVariables",
+category: 'testing',
+fn: function () {
+var self=this;
+return true;
+return self;},
+args: [],
+source: "allowUnknownVariables\x0a\x09^ true",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_classReferences",
+smalltalk.method({
+selector: "classReferences",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@classReferences']) == nil || $receiver == undefined) ? (function(){return (self['@classReferences']=smalltalk.send((smalltalk.Set || Set), "_new", []));})() : $receiver;
+return self;},
+args: [],
+source: "classReferences\x0a\x09^ classReferences ifNil: [ classReferences := Set new ]",
+messageSends: ["ifNil:", "new"],
+referencedClasses: ["Set"]
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_errorInvalidAssignment_",
+smalltalk.method({
+selector: "errorInvalidAssignment:",
+category: 'error handling',
+fn: function (aString) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_variableName_", [aString]);return smalltalk.send($rec, "_signal", []);})(smalltalk.send((smalltalk.InvalidAssignmentError || InvalidAssignmentError), "_new", []));
+return self;},
+args: ["aString"],
+source: "errorInvalidAssignment: aString\x0a\x09InvalidAssignmentError new\x0a\x09\x09variableName: aString;\x0a\x09\x09signal",
+messageSends: ["variableName:", "signal", "new"],
+referencedClasses: ["InvalidAssignmentError"]
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_errorShadowingVariable_",
+smalltalk.method({
+selector: "errorShadowingVariable:",
+category: 'error handling',
+fn: function (aString) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_variableName_", [aString]);return smalltalk.send($rec, "_signal", []);})(smalltalk.send((smalltalk.ShadowingVariableError || ShadowingVariableError), "_new", []));
+return self;},
+args: ["aString"],
+source: "errorShadowingVariable: aString\x0a\x09ShadowingVariableError new\x0a\x09\x09variableName: aString;\x0a\x09\x09signal",
+messageSends: ["variableName:", "signal", "new"],
+referencedClasses: ["ShadowingVariableError"]
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_errorUnknownVariable_",
+smalltalk.method({
+selector: "errorUnknownVariable:",
+category: 'error handling',
+fn: function (aNode) {
+var self=this;
+((($receiver = smalltalk.send(self, "_allowUnknownVariables", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send(smalltalk.send(self['@currentScope'], "_methodScope", []), "_unknownVariables", []), "_add_", [smalltalk.send(aNode, "_value", [])]);})() : (function(){return (function($rec){smalltalk.send($rec, "_variableName_", [smalltalk.send(aNode, "_value", [])]);return smalltalk.send($rec, "_signal", []);})(smalltalk.send((smalltalk.UnknownVariableError || UnknownVariableError), "_new", []));})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(smalltalk.send(self['@currentScope'], "_methodScope", []), "_unknownVariables", []), "_add_", [smalltalk.send(aNode, "_value", [])]);}), (function(){return (function($rec){smalltalk.send($rec, "_variableName_", [smalltalk.send(aNode, "_value", [])]);return smalltalk.send($rec, "_signal", []);})(smalltalk.send((smalltalk.UnknownVariableError || UnknownVariableError), "_new", []));})]));
+return self;},
+args: ["aNode"],
+source: "errorUnknownVariable: aNode\x0a\x09self allowUnknownVariables \x0a\x09\x09ifTrue: [ currentScope methodScope unknownVariables add: aNode value ]\x0a\x09\x09ifFalse: [ \x0a\x09\x09\x09UnknownVariableError new\x0a\x09\x09\x09\x09variableName: aNode value;\x0a\x09\x09\x09\x09signal ]",
+messageSends: ["ifTrue:ifFalse:", "allowUnknownVariables", "add:", "unknownVariables", "methodScope", "value", "variableName:", "signal", "new"],
+referencedClasses: ["UnknownVariableError"]
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_messageSends",
+smalltalk.method({
+selector: "messageSends",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@messageSends']) == nil || $receiver == undefined) ? (function(){return (self['@messageSends']=smalltalk.send((smalltalk.Set || Set), "_new", []));})() : $receiver;
+return self;},
+args: [],
+source: "messageSends\x0a\x09^ messageSends ifNil: [ messageSends := Set new ]",
+messageSends: ["ifNil:", "new"],
+referencedClasses: ["Set"]
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_newBlockScope",
+smalltalk.method({
+selector: "newBlockScope",
+category: 'factory',
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_newScopeOfClass_", [(smalltalk.LexicalScope || LexicalScope)]);
+return self;},
+args: [],
+source: "newBlockScope\x0a\x09^ self newScopeOfClass: LexicalScope",
+messageSends: ["newScopeOfClass:"],
+referencedClasses: ["LexicalScope"]
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_newMethodScope",
+smalltalk.method({
+selector: "newMethodScope",
+category: 'factory',
+fn: function () {
+var self=this;
+return smalltalk.send(self, "_newScopeOfClass_", [(smalltalk.MethodLexicalScope || MethodLexicalScope)]);
+return self;},
+args: [],
+source: "newMethodScope\x0a\x09^ self newScopeOfClass: MethodLexicalScope",
+messageSends: ["newScopeOfClass:"],
+referencedClasses: ["MethodLexicalScope"]
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_newScopeOfClass_",
+smalltalk.method({
+selector: "newScopeOfClass:",
+category: 'factory',
+fn: function (aLexicalScopeClass) {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_outerScope_", [self['@currentScope']]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(aLexicalScopeClass, "_new", []));
+return self;},
+args: ["aLexicalScopeClass"],
+source: "newScopeOfClass: aLexicalScopeClass\x0a\x09^ aLexicalScopeClass new \x0a\x09\x09outerScope: currentScope;\x0a\x09\x09yourself",
+messageSends: ["outerScope:", "yourself", "new"],
+referencedClasses: []
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_popScope",
+smalltalk.method({
+selector: "popScope",
+category: 'scope',
+fn: function () {
+var self=this;
+(($receiver = self['@currentScope']) != nil && $receiver != undefined) ? (function(){return (self['@currentScope']=smalltalk.send(self['@currentScope'], "_outerScope", []));})() : nil;
+return self;},
+args: [],
+source: "popScope\x0a\x09currentScope ifNotNil: [\x0a\x09\x09currentScope := currentScope outerScope ]",
+messageSends: ["ifNotNil:", "outerScope"],
+referencedClasses: []
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_pseudoVariables",
+smalltalk.method({
+selector: "pseudoVariables",
+category: 'accessing',
+fn: function () {
+var self=this;
+return ["self", "super", "true", "false", "nil", "thisContext"];
+return self;},
+args: [],
+source: "pseudoVariables\x0a\x09^#('self' 'super' 'true' 'false' 'nil' 'thisContext')",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_pushScope_",
+smalltalk.method({
+selector: "pushScope:",
+category: 'scope',
+fn: function (aScope) {
+var self=this;
+smalltalk.send(aScope, "_outerScope_", [self['@currentScope']]);
+(self['@currentScope']=aScope);
+return self;},
+args: ["aScope"],
+source: "pushScope: aScope\x0a\x09aScope outerScope: currentScope.\x0a\x09currentScope := aScope",
+messageSends: ["outerScope:"],
+referencedClasses: []
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_theClass",
+smalltalk.method({
+selector: "theClass",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@theClass'];
+return self;},
+args: [],
+source: "theClass\x0a\x09^ theClass",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_theClass_",
+smalltalk.method({
+selector: "theClass:",
+category: 'accessing',
+fn: function (aClass) {
+var self=this;
+(self['@theClass']=aClass);
+return self;},
+args: ["aClass"],
+source: "theClass: aClass\x0a\x09theClass := aClass",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_validateVariableScope_",
+smalltalk.method({
+selector: "validateVariableScope:",
+category: 'scope',
+fn: function (aString) {
+var self=this;
+(($receiver = smalltalk.send(self['@currentScope'], "_lookupVariable_", [aString])) != nil && $receiver != undefined) ? (function(){return smalltalk.send(self, "_errorShadowingVariable_", [aString]);})() : nil;
+return self;},
+args: ["aString"],
+source: "validateVariableScope: aString\x0a\x09\x22Validate the variable scope in by doing a recursive lookup, up to the method scope\x22\x0a\x0a\x09(currentScope lookupVariable: aString) ifNotNil: [\x0a\x09\x09self errorShadowingVariable: aString ]",
+messageSends: ["ifNotNil:", "lookupVariable:", "errorShadowingVariable:"],
+referencedClasses: []
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_visitAssignmentNode_",
+smalltalk.method({
+selector: "visitAssignmentNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+((($receiver = smalltalk.send(smalltalk.send(self, "_pseudoVariables", []), "_includes_", [smalltalk.send(smalltalk.send(aNode, "_left", []), "_value", [])])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_errorInvalidAssignment_", [smalltalk.send(aNode, "_left", [])]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(self, "_errorInvalidAssignment_", [smalltalk.send(aNode, "_left", [])]);})]));
+smalltalk.send(smalltalk.send(aNode, "_left", []), "_beAssigned", []);
+smalltalk.send(smalltalk.send(aNode, "_right", []), "_beUsed", []);
+smalltalk.send(self, "_visitAssignmentNode_", [aNode], smalltalk.SemanticAnalyzer.superclass || nil);
+return self;},
+args: ["aNode"],
+source: "visitAssignmentNode: aNode\x0a\x09(self pseudoVariables includes: aNode left value) ifTrue: [\x0a\x09\x09self errorInvalidAssignment: aNode left ].\x0a\x09aNode left beAssigned.\x0a\x09aNode right beUsed.\x0a\x09super visitAssignmentNode: aNode",
+messageSends: ["ifTrue:", "includes:", "pseudoVariables", "value", "left", "errorInvalidAssignment:", "beAssigned", "beUsed", "right", "visitAssignmentNode:"],
+referencedClasses: []
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_visitBlockNode_",
+smalltalk.method({
+selector: "visitBlockNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_pushScope_", [smalltalk.send(self, "_newBlockScope", [])]);
+smalltalk.send(aNode, "_scope_", [self['@currentScope']]);
+smalltalk.send(smalltalk.send(aNode, "_parameters", []), "_do_", [(function(each){smalltalk.send(self, "_validateVariableScope_", [each]);return smalltalk.send(self['@currentScope'], "_addArg_", [each]);})]);
+smalltalk.send(self, "_visitBlockNode_", [aNode], smalltalk.SemanticAnalyzer.superclass || nil);
+smalltalk.send(self, "_popScope", []);
+return self;},
+args: ["aNode"],
+source: "visitBlockNode: aNode\x0a\x09self pushScope: self newBlockScope.\x0a\x09aNode scope: currentScope.\x0a\x09\x0a\x09aNode parameters do: [ :each | \x0a\x09\x09self validateVariableScope: each.\x0a\x09\x09currentScope addArg: each ].\x0a\x0a\x09super visitBlockNode: aNode.\x0a\x09self popScope",
+messageSends: ["pushScope:", "newBlockScope", "scope:", "do:", "parameters", "validateVariableScope:", "addArg:", "visitBlockNode:", "popScope"],
+referencedClasses: []
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_visitClassReferenceNode_",
+smalltalk.method({
+selector: "visitClassReferenceNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_classReferences", []), "_add_", [smalltalk.send(aNode, "_value", [])]);
+smalltalk.send(aNode, "_binding_", [(function($rec){smalltalk.send($rec, "_name_", [smalltalk.send(aNode, "_value", [])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.ClassRefVar || ClassRefVar), "_new", []))]);
+return self;},
+args: ["aNode"],
+source: "visitClassReferenceNode: aNode\x0a\x09self classReferences add: aNode value.\x0a\x09aNode binding: (ClassRefVar new name: aNode value; yourself)",
+messageSends: ["add:", "classReferences", "value", "binding:", "name:", "yourself", "new"],
+referencedClasses: ["ClassRefVar"]
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_visitMethodNode_",
+smalltalk.method({
+selector: "visitMethodNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(self, "_pushScope_", [smalltalk.send(self, "_newMethodScope", [])]);
+smalltalk.send(aNode, "_scope_", [self['@currentScope']]);
+smalltalk.send(smalltalk.send(smalltalk.send(self, "_theClass", []), "_allInstanceVariableNames", []), "_do_", [(function(each){return smalltalk.send(self['@currentScope'], "_addIVar_", [each]);})]);
+smalltalk.send(smalltalk.send(aNode, "_arguments", []), "_do_", [(function(each){smalltalk.send(self, "_validateVariableScope_", [each]);return smalltalk.send(self['@currentScope'], "_addArg_", [each]);})]);
+smalltalk.send(self, "_visitMethodNode_", [aNode], smalltalk.SemanticAnalyzer.superclass || nil);
+(function($rec){smalltalk.send($rec, "_classReferences_", [smalltalk.send(self, "_classReferences", [])]);return smalltalk.send($rec, "_messageSends_", [smalltalk.send(self, "_messageSends", [])]);})(aNode);
+smalltalk.send(self, "_popScope", []);
+return self;},
+args: ["aNode"],
+source: "visitMethodNode: aNode\x0a\x09self pushScope: self newMethodScope.\x0a\x09aNode scope: currentScope.\x0a\x0a\x09self theClass allInstanceVariableNames do: [:each | \x0a\x09\x09currentScope addIVar: each ].\x0a\x09aNode arguments do: [ :each | \x0a\x09\x09self validateVariableScope: each.\x0a\x09\x09currentScope addArg: each ].\x0a\x0a\x09super visitMethodNode: aNode.\x0a\x0a\x09aNode \x0a\x09\x09classReferences: self classReferences;\x0a\x09\x09messageSends: self messageSends.\x0a\x09self popScope",
+messageSends: ["pushScope:", "newMethodScope", "scope:", "do:", "allInstanceVariableNames", "theClass", "addIVar:", "arguments", "validateVariableScope:", "addArg:", "visitMethodNode:", "classReferences:", "classReferences", "messageSends:", "messageSends", "popScope"],
+referencedClasses: []
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_visitReturnNode_",
+smalltalk.method({
+selector: "visitReturnNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+((($receiver = smalltalk.send(self['@currentScope'], "_isMethodScope", [])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){smalltalk.send(smalltalk.send(self['@currentScope'], "_methodScope", []), "_nonLocalReturn_", [true]);return smalltalk.send(aNode, "_nonLocalReturn_", [true]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){smalltalk.send(smalltalk.send(self['@currentScope'], "_methodScope", []), "_nonLocalReturn_", [true]);return smalltalk.send(aNode, "_nonLocalReturn_", [true]);})]));
+smalltalk.send(smalltalk.send(smalltalk.send(aNode, "_nodes", []), "_first", []), "_beUsed", []);
+smalltalk.send(self, "_visitReturnNode_", [aNode], smalltalk.SemanticAnalyzer.superclass || nil);
+return self;},
+args: ["aNode"],
+source: "visitReturnNode: aNode\x0a\x09currentScope isMethodScope ifFalse: [\x0a\x09\x09currentScope methodScope nonLocalReturn: true.\x0a\x09\x09aNode nonLocalReturn: true ].\x0a\x09aNode nodes first beUsed.\x0a\x09super visitReturnNode: aNode",
+messageSends: ["ifFalse:", "isMethodScope", "nonLocalReturn:", "methodScope", "beUsed", "first", "nodes", "visitReturnNode:"],
+referencedClasses: []
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_visitSendNode_",
+smalltalk.method({
+selector: "visitSendNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(smalltalk.send(self, "_messageSends", []), "_add_", [smalltalk.send(aNode, "_selector", [])]);
+smalltalk.send(smalltalk.send(aNode, "_receiver", []), "_beUsed", []);
+smalltalk.send(smalltalk.send(aNode, "_arguments", []), "_do_", [(function(each){return smalltalk.send(each, "_beUsed", []);})]);
+smalltalk.send(self, "_visitSendNode_", [aNode], smalltalk.SemanticAnalyzer.superclass || nil);
+return self;},
+args: ["aNode"],
+source: "visitSendNode: aNode\x0a\x09self messageSends add: aNode selector.\x0a\x09aNode receiver beUsed.\x0a\x09aNode arguments do: [ :each |\x0a\x09\x09each beUsed ].\x0a\x09super visitSendNode: aNode",
+messageSends: ["add:", "messageSends", "selector", "beUsed", "receiver", "do:", "arguments", "visitSendNode:"],
+referencedClasses: []
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_visitSequenceNode_",
+smalltalk.method({
+selector: "visitSequenceNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(smalltalk.send(aNode, "_temps", []), "_do_", [(function(each){smalltalk.send(self, "_validateVariableScope_", [each]);return smalltalk.send(self['@currentScope'], "_addTemp_", [each]);})]);
+smalltalk.send(self, "_visitSequenceNode_", [aNode], smalltalk.SemanticAnalyzer.superclass || nil);
+return self;},
+args: ["aNode"],
+source: "visitSequenceNode: aNode\x0a\x09aNode temps do: [ :each | \x0a\x09\x09self validateVariableScope: each.\x0a\x09\x09currentScope addTemp: each ].\x0a\x0a\x09super visitSequenceNode: aNode",
+messageSends: ["do:", "temps", "validateVariableScope:", "addTemp:", "visitSequenceNode:"],
+referencedClasses: []
+}),
+smalltalk.SemanticAnalyzer);
+
+smalltalk.addMethod(
+"_visitVariableNode_",
+smalltalk.method({
+selector: "visitVariableNode:",
+category: 'visiting',
+fn: function (aNode) {
+var self=this;
+smalltalk.send(aNode, "_binding_", [(($receiver = smalltalk.send(self['@currentScope'], "_lookupVariable_", [aNode])) == nil || $receiver == undefined) ? (function(){smalltalk.send(self, "_errorUnknownVariable_", [aNode]);return (function($rec){smalltalk.send($rec, "_name_", [smalltalk.send(aNode, "_value", [])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.UnknownVar || UnknownVar), "_new", []));})() : $receiver]);
+return self;},
+args: ["aNode"],
+source: "visitVariableNode: aNode\x0a\x09\x22Bind a ScopeVar to aNode by doing a lookup in the current scope.\x0a\x09If no ScopeVar is found, bind a UnknowVar and throw an error\x22\x0a\x0a\x09aNode binding: ((currentScope lookupVariable: aNode) ifNil: [ \x0a\x09\x09self errorUnknownVariable: aNode.\x0a\x09\x09UnknownVar new name: aNode value; yourself ])",
+messageSends: ["binding:", "ifNil:", "lookupVariable:", "errorUnknownVariable:", "name:", "value", "yourself", "new"],
+referencedClasses: ["UnknownVar"]
+}),
+smalltalk.SemanticAnalyzer);
+
+
+smalltalk.addMethod(
+"_on_",
+smalltalk.method({
+selector: "on:",
+category: 'instance creation',
+fn: function (aClass) {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_theClass_", [aClass]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_new", []));
+return self;},
+args: ["aClass"],
+source: "on: aClass\x0a\x09^ self new\x0a\x09\x09theClass: aClass;\x0a\x09\x09yourself",
+messageSends: ["theClass:", "yourself", "new"],
+referencedClasses: []
+}),
+smalltalk.SemanticAnalyzer.klass);
+
+
+smalltalk.addClass('SemanticError', smalltalk.Error, [], 'Compiler-Semantic');
+smalltalk.SemanticError.comment="I represent an abstract semantic error thrown by the SemanticAnalyzer.\x0aSemantic errors can be unknown variable errors, etc.\x0aSee my subclasses for concrete errors.\x0a\x0aThe IDE should catch instances of Semantic error to deal with them when compiling"
+
+
+smalltalk.addClass('InvalidAssignmentError', smalltalk.SemanticError, ['variableName'], 'Compiler-Semantic');
+smalltalk.InvalidAssignmentError.comment="I get signaled when a pseudo variable gets assigned."
+smalltalk.addMethod(
+"_variableName",
+smalltalk.method({
+selector: "variableName",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@variableName'];
+return self;},
+args: [],
+source: "variableName\x0a\x09^ variableName",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.InvalidAssignmentError);
+
+smalltalk.addMethod(
+"_variableName_",
+smalltalk.method({
+selector: "variableName:",
+category: 'accessing',
+fn: function (aString) {
+var self=this;
+(self['@variableName']=aString);
+return self;},
+args: ["aString"],
+source: "variableName: aString\x0a\x09variableName := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.InvalidAssignmentError);
+
+
+
+smalltalk.addClass('ShadowingVariableError', smalltalk.SemanticError, ['variableName'], 'Compiler-Semantic');
+smalltalk.ShadowingVariableError.comment="I get signaled when a variable in a block or method scope shadows a variable of the same name in an outer scope."
+smalltalk.addMethod(
+"_variableName",
+smalltalk.method({
+selector: "variableName",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@variableName'];
+return self;},
+args: [],
+source: "variableName\x0a\x09^ variableName",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ShadowingVariableError);
+
+smalltalk.addMethod(
+"_variableName_",
+smalltalk.method({
+selector: "variableName:",
+category: 'accessing',
+fn: function (aString) {
+var self=this;
+(self['@variableName']=aString);
+return self;},
+args: ["aString"],
+source: "variableName: aString\x0a\x09variableName := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ShadowingVariableError);
+
+
+
+smalltalk.addClass('UnknownVariableError', smalltalk.SemanticError, ['variableName'], 'Compiler-Semantic');
+smalltalk.UnknownVariableError.comment="I get signaled when a variable is not defined.\x0aThe default behavior is to allow it, as this is how Amber currently is able to seamlessly send messages to JavaScript objects."
+smalltalk.addMethod(
+"_variableName",
+smalltalk.method({
+selector: "variableName",
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@variableName'];
+return self;},
+args: [],
+source: "variableName\x0a\x09^ variableName",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.UnknownVariableError);
+
+smalltalk.addMethod(
+"_variableName_",
+smalltalk.method({
+selector: "variableName:",
+category: 'accessing',
+fn: function (aString) {
+var self=this;
+(self['@variableName']=aString);
+return self;},
+args: ["aString"],
+source: "variableName: aString\x0a\x09variableName := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.UnknownVariableError);
+
+
+

File diff suppressed because it is too large
+ 197 - 0
js/Compiler-Visitors.deploy.js


File diff suppressed because it is too large
+ 273 - 0
js/Compiler-Visitors.js


+ 331 - 0
js/Importer-Exporter.deploy.js

@@ -0,0 +1,331 @@
+smalltalk.addPackage('Importer-Exporter', {});
+smalltalk.addClass('ChunkParser', smalltalk.Object, ['stream'], 'Importer-Exporter');
+smalltalk.addMethod(
+"_nextChunk",
+smalltalk.method({
+selector: "nextChunk",
+fn: function () {
+var self=this;
+var $early={};
+try{var char_=nil;
+var result=nil;
+var chunk=nil;
+(result=smalltalk.send("", "_writeStream", []));
+(function(){while((function(){(char_=smalltalk.send(self['@stream'], "_next", []));return smalltalk.send(char_, "_notNil", []);})()) {(function(){((($receiver = smalltalk.send(char_, "__eq", ["!"])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return ((($receiver = smalltalk.send(smalltalk.send(self['@stream'], "_peek", []), "__eq", ["!"])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self['@stream'], "_next", []);})() : (function(){return (function(){throw $early=[smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])]})();})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(self['@stream'], "_next", []);}), (function(){return (function(){throw $early=[smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])]})();})]));})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return ((($receiver = smalltalk.send(smalltalk.send(self['@stream'], "_peek", []), "__eq", ["!"])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self['@stream'], "_next", []);})() : (function(){return (function(){throw $early=[smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])]})();})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(self['@stream'], "_next", []);}), (function(){return (function(){throw $early=[smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])]})();})]));})]));return smalltalk.send(result, "_nextPut_", [char_]);})()}})();
+return nil;
+return self;
+} catch(e) {if(e===$early)return e[0]; throw e}}
+}),
+smalltalk.ChunkParser);
+
+smalltalk.addMethod(
+"_stream_",
+smalltalk.method({
+selector: "stream:",
+fn: function (aStream) {
+var self=this;
+(self['@stream']=aStream);
+return self;}
+}),
+smalltalk.ChunkParser);
+
+
+smalltalk.addMethod(
+"_on_",
+smalltalk.method({
+selector: "on:",
+fn: function (aStream) {
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_new", []), "_stream_", [aStream]);
+return self;}
+}),
+smalltalk.ChunkParser.klass);
+
+
+smalltalk.addClass('Exporter', smalltalk.Object, [], 'Importer-Exporter');
+smalltalk.addMethod(
+"_classNameFor_",
+smalltalk.method({
+selector: "classNameFor:",
+fn: function (aClass) {
+var self=this;
+return ((($receiver = smalltalk.send(aClass, "_isMetaclass", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_instanceClass", []), "_name", []), "__comma", [".klass"]);})() : (function(){return ((($receiver = smalltalk.send(aClass, "_isNil", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return "nil";})() : (function(){return smalltalk.send(aClass, "_name", []);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return "nil";}), (function(){return smalltalk.send(aClass, "_name", []);})]));})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_instanceClass", []), "_name", []), "__comma", [".klass"]);}), (function(){return ((($receiver = smalltalk.send(aClass, "_isNil", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return "nil";})() : (function(){return smalltalk.send(aClass, "_name", []);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return "nil";}), (function(){return smalltalk.send(aClass, "_name", []);})]));})]));
+return self;}
+}),
+smalltalk.Exporter);
+
+smalltalk.addMethod(
+"_exportAll",
+smalltalk.method({
+selector: "exportAll",
+fn: function () {
+var self=this;
+return smalltalk.send((smalltalk.String || String), "_streamContents_", [(function(stream){return smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_packages", []), "_do_", [(function(pkg){return smalltalk.send(stream, "_nextPutAll_", [smalltalk.send(self, "_exportPackage_", [smalltalk.send(pkg, "_name", [])])]);})]);})]);
+return self;}
+}),
+smalltalk.Exporter);
+
+smalltalk.addMethod(
+"_exportClass_",
+smalltalk.method({
+selector: "exportClass:",
+fn: function (aClass) {
+var self=this;
+return smalltalk.send((smalltalk.String || String), "_streamContents_", [(function(stream){smalltalk.send(self, "_exportDefinitionOf_on_", [aClass, stream]);smalltalk.send(self, "_exportMethodsOf_on_", [aClass, stream]);smalltalk.send(self, "_exportMetaDefinitionOf_on_", [aClass, stream]);return smalltalk.send(self, "_exportMethodsOf_on_", [smalltalk.send(aClass, "_class", []), stream]);})]);
+return self;}
+}),
+smalltalk.Exporter);
+
+smalltalk.addMethod(
+"_exportDefinitionOf_on_",
+smalltalk.method({
+selector: "exportDefinitionOf:on:",
+fn: function (aClass, aStream) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["smalltalk.addClass("]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("'", "__comma", [smalltalk.send(self, "_classNameFor_", [aClass])]), "__comma", ["', "])]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send("smalltalk.", "__comma", [smalltalk.send(self, "_classNameFor_", [smalltalk.send(aClass, "_superclass", [])])])]);return smalltalk.send($rec, "_nextPutAll_", [", ["]);})(aStream);
+smalltalk.send(smalltalk.send(aClass, "_instanceVariableNames", []), "_do_separatedBy_", [(function(each){return smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send(smalltalk.send("'", "__comma", [each]), "__comma", ["'"])]);}), (function(){return smalltalk.send(aStream, "_nextPutAll_", [", "]);})]);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["], '"]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(aClass, "_category", []), "__comma", ["'"])]);return smalltalk.send($rec, "_nextPutAll_", [");"]);})(aStream);
+((($receiver = smalltalk.send(smalltalk.send(aClass, "_comment", []), "_notEmpty", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return (function($rec){smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", ["smalltalk."]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(self, "_classNameFor_", [aClass])]);smalltalk.send($rec, "_nextPutAll_", [".comment="]);return smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(aClass, "_comment", []), "_asJavascript", [])]);})(aStream);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return (function($rec){smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", ["smalltalk."]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(self, "_classNameFor_", [aClass])]);smalltalk.send($rec, "_nextPutAll_", [".comment="]);return smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(aClass, "_comment", []), "_asJavascript", [])]);})(aStream);})]));
+smalltalk.send(aStream, "_lf", []);
+return self;}
+}),
+smalltalk.Exporter);
+
+smalltalk.addMethod(
+"_exportMetaDefinitionOf_on_",
+smalltalk.method({
+selector: "exportMetaDefinitionOf:on:",
+fn: function (aClass, aStream) {
+var self=this;
+((($receiver = smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_class", []), "_instanceVariableNames", []), "_isEmpty", [])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send("smalltalk.", "__comma", [smalltalk.send(self, "_classNameFor_", [smalltalk.send(aClass, "_class", [])])])]);return smalltalk.send($rec, "_nextPutAll_", [".iVarNames = ["]);})(aStream);smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_class", []), "_instanceVariableNames", []), "_do_separatedBy_", [(function(each){return smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send(smalltalk.send("'", "__comma", [each]), "__comma", ["'"])]);}), (function(){return smalltalk.send(aStream, "_nextPutAll_", [","]);})]);return smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send("];", "__comma", [smalltalk.send((smalltalk.String || String), "_lf", [])])]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send("smalltalk.", "__comma", [smalltalk.send(self, "_classNameFor_", [smalltalk.send(aClass, "_class", [])])])]);return smalltalk.send($rec, "_nextPutAll_", [".iVarNames = ["]);})(aStream);smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_class", []), "_instanceVariableNames", []), "_do_separatedBy_", [(function(each){return smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send(smalltalk.send("'", "__comma", [each]), "__comma", ["'"])]);}), (function(){return smalltalk.send(aStream, "_nextPutAll_", [","]);})]);return smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send("];", "__comma", [smalltalk.send((smalltalk.String || String), "_lf", [])])]);})]));
+return self;}
+}),
+smalltalk.Exporter);
+
+smalltalk.addMethod(
+"_exportMethod_of_on_",
+smalltalk.method({
+selector: "exportMethod:of:on:",
+fn: function (aMethod, aClass, aStream) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["smalltalk.addMethod("]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aMethod, "_selector", []), "_asSelector", []), "_asJavascript", []), "__comma", [","])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", ["smalltalk.method({"]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("selector: ", "__comma", [smalltalk.send(smalltalk.send(aMethod, "_selector", []), "_asJavascript", [])]), "__comma", [","])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("category: '", "__comma", [smalltalk.send(aMethod, "_category", [])]), "__comma", ["',"])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("fn: ", "__comma", [smalltalk.send(smalltalk.send(aMethod, "_fn", []), "_compiledSource", [])]), "__comma", [","])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("args: ", "__comma", [smalltalk.send(smalltalk.send(aMethod, "_arguments", []), "_asJavascript", [])]), "__comma", [","])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("source: ", "__comma", [smalltalk.send(smalltalk.send(aMethod, "_source", []), "_asJavascript", [])]), "__comma", [","])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("messageSends: ", "__comma", [smalltalk.send(smalltalk.send(aMethod, "_messageSends", []), "_asJavascript", [])]), "__comma", [","])]);smalltalk.send($rec, "_lf", []);return smalltalk.send($rec, "_nextPutAll_", [smalltalk.send("referencedClasses: ", "__comma", [smalltalk.send(smalltalk.send(aMethod, "_referencedClasses", []), "_asJavascript", [])])]);})(aStream);
+(function($rec){smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", ["}),"]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send("smalltalk.", "__comma", [smalltalk.send(self, "_classNameFor_", [aClass])])]);smalltalk.send($rec, "_nextPutAll_", [");"]);smalltalk.send($rec, "_lf", []);return smalltalk.send($rec, "_lf", []);})(aStream);
+return self;}
+}),
+smalltalk.Exporter);
+
+smalltalk.addMethod(
+"_exportMethodsOf_on_",
+smalltalk.method({
+selector: "exportMethodsOf:on:",
+fn: function (aClass, aStream) {
+var self=this;
+smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_methodDictionary", []), "_values", []), "_sorted_", [(function(a, b){return ((($receiver = smalltalk.send(a, "_selector", [])).klass === smalltalk.Number) ? $receiver <=smalltalk.send(b, "_selector", []) : smalltalk.send($receiver, "__lt_eq", [smalltalk.send(b, "_selector", [])]));})]), "_do_", [(function(each){return ((($receiver = smalltalk.send(smalltalk.send(each, "_category", []), "_match_", ["^\x5c*"])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(self, "_exportMethod_of_on_", [each, aClass, aStream]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(self, "_exportMethod_of_on_", [each, aClass, aStream]);})]));})]);
+smalltalk.send(aStream, "_lf", []);
+return self;}
+}),
+smalltalk.Exporter);
+
+smalltalk.addMethod(
+"_exportPackage_",
+smalltalk.method({
+selector: "exportPackage:",
+fn: function (packageName) {
+var self=this;
+var package=nil;
+return smalltalk.send((smalltalk.String || String), "_streamContents_", [(function(stream){(package=smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_packageAt_", [packageName]));smalltalk.send(self, "_exportPackageDefinitionOf_on_", [package, stream]);smalltalk.send(smalltalk.send(smalltalk.send(package, "_sortedClasses", []), "_asSet", []), "_do_", [(function(each){return smalltalk.send(stream, "_nextPutAll_", [smalltalk.send(self, "_exportClass_", [each])]);})]);return smalltalk.send(self, "_exportPackageExtensionsOf_on_", [package, stream]);})]);
+return self;}
+}),
+smalltalk.Exporter);
+
+smalltalk.addMethod(
+"_exportPackageDefinitionOf_on_",
+smalltalk.method({
+selector: "exportPackageDefinitionOf:on:",
+fn: function (package, aStream) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["smalltalk.addPackage("]);return smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send("'", "__comma", [smalltalk.send(package, "_name", [])]), "__comma", ["', "]), "__comma", [smalltalk.send(package, "_propertiesAsJSON", [])]), "__comma", [");"])]);})(aStream);
+smalltalk.send(aStream, "_lf", []);
+return self;}
+}),
+smalltalk.Exporter);
+
+smalltalk.addMethod(
+"_exportPackageExtensionsOf_on_",
+smalltalk.method({
+selector: "exportPackageExtensionsOf:on:",
+fn: function (package, aStream) {
+var self=this;
+var name=nil;
+(name=smalltalk.send(package, "_name", []));
+smalltalk.send(smalltalk.send((smalltalk.Package || Package), "_sortedClasses_", [smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_classes", [])]), "_do_", [(function(each){return smalltalk.send([each,smalltalk.send(each, "_class", [])], "_do_", [(function(aClass){return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_methodDictionary", []), "_values", []), "_sorted_", [(function(a, b){return ((($receiver = smalltalk.send(a, "_selector", [])).klass === smalltalk.Number) ? $receiver <=smalltalk.send(b, "_selector", []) : smalltalk.send($receiver, "__lt_eq", [smalltalk.send(b, "_selector", [])]));})]), "_do_", [(function(method){return ((($receiver = smalltalk.send(smalltalk.send(method, "_category", []), "_match_", [smalltalk.send("^\x5c*", "__comma", [name])])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_exportMethod_of_on_", [method, aClass, aStream]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(self, "_exportMethod_of_on_", [method, aClass, aStream]);})]));})]);})]);})]);
+return self;}
+}),
+smalltalk.Exporter);
+
+
+
+smalltalk.addClass('ChunkExporter', smalltalk.Exporter, [], 'Importer-Exporter');
+smalltalk.addMethod(
+"_chunkEscape_",
+smalltalk.method({
+selector: "chunkEscape:",
+fn: function (aString) {
+var self=this;
+return smalltalk.send(smalltalk.send(aString, "_replace_with_", ["!", "!!"]), "_trimBoth", []);
+return self;}
+}),
+smalltalk.ChunkExporter);
+
+smalltalk.addMethod(
+"_classNameFor_",
+smalltalk.method({
+selector: "classNameFor:",
+fn: function (aClass) {
+var self=this;
+return ((($receiver = smalltalk.send(aClass, "_isMetaclass", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_instanceClass", []), "_name", []), "__comma", [" class"]);})() : (function(){return ((($receiver = smalltalk.send(aClass, "_isNil", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return "nil";})() : (function(){return smalltalk.send(aClass, "_name", []);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return "nil";}), (function(){return smalltalk.send(aClass, "_name", []);})]));})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_instanceClass", []), "_name", []), "__comma", [" class"]);}), (function(){return ((($receiver = smalltalk.send(aClass, "_isNil", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return "nil";})() : (function(){return smalltalk.send(aClass, "_name", []);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return "nil";}), (function(){return smalltalk.send(aClass, "_name", []);})]));})]));
+return self;}
+}),
+smalltalk.ChunkExporter);
+
+smalltalk.addMethod(
+"_exportDefinitionOf_on_",
+smalltalk.method({
+selector: "exportDefinitionOf:on:",
+fn: function (aClass, aStream) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(self, "_classNameFor_", [smalltalk.send(aClass, "_superclass", [])])]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(" subclass: #", "__comma", [smalltalk.send(self, "_classNameFor_", [aClass])])]);smalltalk.send($rec, "_lf", []);return smalltalk.send($rec, "_nextPutAll_", ["\x09instanceVariableNames: '"]);})(aStream);
+smalltalk.send(smalltalk.send(aClass, "_instanceVariableNames", []), "_do_separatedBy_", [(function(each){return smalltalk.send(aStream, "_nextPutAll_", [each]);}), (function(){return smalltalk.send(aStream, "_nextPutAll_", [" "]);})]);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["'"]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("\x09package: '", "__comma", [smalltalk.send(aClass, "_category", [])]), "__comma", ["'!"])]);return smalltalk.send($rec, "_lf", []);})(aStream);
+((($receiver = smalltalk.send(smalltalk.send(aClass, "_comment", []), "_notEmpty", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return (function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("!", "__comma", [smalltalk.send(self, "_classNameFor_", [aClass])]), "__comma", [" commentStamp!"])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(self, "_chunkEscape_", [smalltalk.send(aClass, "_comment", [])]), "__comma", ["!"])]);return smalltalk.send($rec, "_lf", []);})(aStream);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return (function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("!", "__comma", [smalltalk.send(self, "_classNameFor_", [aClass])]), "__comma", [" commentStamp!"])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(self, "_chunkEscape_", [smalltalk.send(aClass, "_comment", [])]), "__comma", ["!"])]);return smalltalk.send($rec, "_lf", []);})(aStream);})]));
+smalltalk.send(aStream, "_lf", []);
+return self;}
+}),
+smalltalk.ChunkExporter);
+
+smalltalk.addMethod(
+"_exportMetaDefinitionOf_on_",
+smalltalk.method({
+selector: "exportMetaDefinitionOf:on:",
+fn: function (aClass, aStream) {
+var self=this;
+((($receiver = smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_class", []), "_instanceVariableNames", []), "_isEmpty", [])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(self, "_classNameFor_", [smalltalk.send(aClass, "_class", [])])]);return smalltalk.send($rec, "_nextPutAll_", [" instanceVariableNames: '"]);})(aStream);smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_class", []), "_instanceVariableNames", []), "_do_separatedBy_", [(function(each){return smalltalk.send(aStream, "_nextPutAll_", [each]);}), (function(){return smalltalk.send(aStream, "_nextPutAll_", [" "]);})]);return (function($rec){smalltalk.send($rec, "_nextPutAll_", ["'!"]);smalltalk.send($rec, "_lf", []);return smalltalk.send($rec, "_lf", []);})(aStream);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(self, "_classNameFor_", [smalltalk.send(aClass, "_class", [])])]);return smalltalk.send($rec, "_nextPutAll_", [" instanceVariableNames: '"]);})(aStream);smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_class", []), "_instanceVariableNames", []), "_do_separatedBy_", [(function(each){return smalltalk.send(aStream, "_nextPutAll_", [each]);}), (function(){return smalltalk.send(aStream, "_nextPutAll_", [" "]);})]);return (function($rec){smalltalk.send($rec, "_nextPutAll_", ["'!"]);smalltalk.send($rec, "_lf", []);return smalltalk.send($rec, "_lf", []);})(aStream);})]));
+return self;}
+}),
+smalltalk.ChunkExporter);
+
+smalltalk.addMethod(
+"_exportMethod_of_on_",
+smalltalk.method({
+selector: "exportMethod:of:on:",
+fn: function (aMethod, aClass, aStream) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(self, "_chunkEscape_", [smalltalk.send(aMethod, "_source", [])])]);smalltalk.send($rec, "_lf", []);return smalltalk.send($rec, "_nextPutAll_", ["!"]);})(aStream);
+return self;}
+}),
+smalltalk.ChunkExporter);
+
+smalltalk.addMethod(
+"_exportMethods_category_of_on_",
+smalltalk.method({
+selector: "exportMethods:category:of:on:",
+fn: function (methods, category, aClass, aStream) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send("!", "__comma", [smalltalk.send(self, "_classNameFor_", [aClass])])]);return smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(" methodsFor: '", "__comma", [category]), "__comma", ["'!"])]);})(aStream);
+smalltalk.send(smalltalk.send(methods, "_sorted_", [(function(a, b){return ((($receiver = smalltalk.send(a, "_selector", [])).klass === smalltalk.Number) ? $receiver <=smalltalk.send(b, "_selector", []) : smalltalk.send($receiver, "__lt_eq", [smalltalk.send(b, "_selector", [])]));})]), "_do_", [(function(each){return smalltalk.send(self, "_exportMethod_of_on_", [each, aClass, aStream]);})]);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", [" !"]);smalltalk.send($rec, "_lf", []);return smalltalk.send($rec, "_lf", []);})(aStream);
+return self;}
+}),
+smalltalk.ChunkExporter);
+
+smalltalk.addMethod(
+"_exportMethodsOf_on_",
+smalltalk.method({
+selector: "exportMethodsOf:on:",
+fn: function (aClass, aStream) {
+var self=this;
+var map=nil;
+(map=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));
+smalltalk.send(aClass, "_protocolsDo_", [(function(category, methods){return ((($receiver = smalltalk.send(category, "_match_", ["^\x5c*"])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(map, "_at_put_", [category, methods]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(map, "_at_put_", [category, methods]);})]));})]);
+smalltalk.send(smalltalk.send(smalltalk.send(map, "_keys", []), "_sorted_", [(function(a, b){return ((($receiver = a).klass === smalltalk.Number) ? $receiver <=b : smalltalk.send($receiver, "__lt_eq", [b]));})]), "_do_", [(function(category){var methods=nil;
+(methods=smalltalk.send(map, "_at_", [category]));return smalltalk.send(self, "_exportMethods_category_of_on_", [methods, category, aClass, aStream]);})]);
+return self;}
+}),
+smalltalk.ChunkExporter);
+
+smalltalk.addMethod(
+"_exportPackageDefinitionOf_on_",
+smalltalk.method({
+selector: "exportPackageDefinitionOf:on:",
+fn: function (package, aStream) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send("Smalltalk current createPackage: '", "__comma", [smalltalk.send(package, "_name", [])]), "__comma", ["' properties: "]), "__comma", [smalltalk.send(smalltalk.send(package, "_properties", []), "_storeString", [])]), "__comma", ["!"])]);return smalltalk.send($rec, "_lf", []);})(aStream);
+return self;}
+}),
+smalltalk.ChunkExporter);
+
+smalltalk.addMethod(
+"_exportPackageExtensionsOf_on_",
+smalltalk.method({
+selector: "exportPackageExtensionsOf:on:",
+fn: function (package, aStream) {
+var self=this;
+var name=nil;
+var map=nil;
+(name=smalltalk.send(package, "_name", []));
+smalltalk.send(smalltalk.send((smalltalk.Package || Package), "_sortedClasses_", [smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_classes", [])]), "_do_", [(function(each){return smalltalk.send([each,smalltalk.send(each, "_class", [])], "_do_", [(function(aClass){(map=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));smalltalk.send(aClass, "_protocolsDo_", [(function(category, methods){return ((($receiver = smalltalk.send(category, "_match_", [smalltalk.send("^\x5c*", "__comma", [name])])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(map, "_at_put_", [category, methods]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(map, "_at_put_", [category, methods]);})]));})]);return smalltalk.send(smalltalk.send(smalltalk.send(map, "_keys", []), "_sorted_", [(function(a, b){return ((($receiver = a).klass === smalltalk.Number) ? $receiver <=b : smalltalk.send($receiver, "__lt_eq", [b]));})]), "_do_", [(function(category){var methods=nil;
+(methods=smalltalk.send(map, "_at_", [category]));return smalltalk.send(self, "_exportMethods_category_of_on_", [methods, category, aClass, aStream]);})]);})]);})]);
+return self;}
+}),
+smalltalk.ChunkExporter);
+
+
+
+smalltalk.addClass('StrippedExporter', smalltalk.Exporter, [], 'Importer-Exporter');
+smalltalk.addMethod(
+"_exportDefinitionOf_on_",
+smalltalk.method({
+selector: "exportDefinitionOf:on:",
+fn: function (aClass, aStream) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["smalltalk.addClass("]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("'", "__comma", [smalltalk.send(self, "_classNameFor_", [aClass])]), "__comma", ["', "])]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send("smalltalk.", "__comma", [smalltalk.send(self, "_classNameFor_", [smalltalk.send(aClass, "_superclass", [])])])]);return smalltalk.send($rec, "_nextPutAll_", [", ["]);})(aStream);
+smalltalk.send(smalltalk.send(aClass, "_instanceVariableNames", []), "_do_separatedBy_", [(function(each){return smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send(smalltalk.send("'", "__comma", [each]), "__comma", ["'"])]);}), (function(){return smalltalk.send(aStream, "_nextPutAll_", [", "]);})]);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["], '"]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(aClass, "_category", []), "__comma", ["'"])]);return smalltalk.send($rec, "_nextPutAll_", [");"]);})(aStream);
+smalltalk.send(aStream, "_lf", []);
+return self;}
+}),
+smalltalk.StrippedExporter);
+
+smalltalk.addMethod(
+"_exportMethod_of_on_",
+smalltalk.method({
+selector: "exportMethod:of:on:",
+fn: function (aMethod, aClass, aStream) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["smalltalk.addMethod("]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aMethod, "_selector", []), "_asSelector", []), "_asJavascript", []), "__comma", [","])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", ["smalltalk.method({"]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("selector: ", "__comma", [smalltalk.send(smalltalk.send(aMethod, "_selector", []), "_asJavascript", [])]), "__comma", [","])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send("fn: ", "__comma", [smalltalk.send(smalltalk.send(aMethod, "_fn", []), "_compiledSource", [])])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", ["}),"]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send("smalltalk.", "__comma", [smalltalk.send(self, "_classNameFor_", [aClass])])]);smalltalk.send($rec, "_nextPutAll_", [");"]);smalltalk.send($rec, "_lf", []);return smalltalk.send($rec, "_lf", []);})(aStream);
+return self;}
+}),
+smalltalk.StrippedExporter);
+
+
+
+smalltalk.addClass('Importer', smalltalk.Object, [], 'Importer-Exporter');
+smalltalk.addMethod(
+"_import_",
+smalltalk.method({
+selector: "import:",
+fn: function (aStream) {
+var self=this;
+var chunk=nil;
+var result=nil;
+var parser=nil;
+var lastEmpty=nil;
+(parser=smalltalk.send((smalltalk.ChunkParser || ChunkParser), "_on_", [aStream]));
+(lastEmpty=false);
+(function(){while(!(function(){(chunk=smalltalk.send(parser, "_nextChunk", []));return smalltalk.send(chunk, "_isNil", []);})()) {(function(){return ((($receiver = smalltalk.send(chunk, "_isEmpty", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return (lastEmpty=true);})() : (function(){(result=smalltalk.send(smalltalk.send((smalltalk.Compiler || Compiler), "_new", []), "_evaluateExpression_", [chunk]));return ((($receiver = lastEmpty).klass === smalltalk.Boolean) ? ($receiver ? (function(){(lastEmpty=false);return smalltalk.send(result, "_scanFrom_", [parser]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){(lastEmpty=false);return smalltalk.send(result, "_scanFrom_", [parser]);})]));})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return (lastEmpty=true);}), (function(){(result=smalltalk.send(smalltalk.send((smalltalk.Compiler || Compiler), "_new", []), "_evaluateExpression_", [chunk]));return ((($receiver = lastEmpty).klass === smalltalk.Boolean) ? ($receiver ? (function(){(lastEmpty=false);return smalltalk.send(result, "_scanFrom_", [parser]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){(lastEmpty=false);return smalltalk.send(result, "_scanFrom_", [parser]);})]));})]));})()}})();
+return self;}
+}),
+smalltalk.Importer);
+
+
+

+ 456 - 0
js/Importer-Exporter.js

@@ -0,0 +1,456 @@
+smalltalk.addPackage('Importer-Exporter', {});
+smalltalk.addClass('ChunkParser', smalltalk.Object, ['stream'], 'Importer-Exporter');
+smalltalk.addMethod(
+"_nextChunk",
+smalltalk.method({
+selector: "nextChunk",
+category: 'reading',
+fn: function () {
+var self=this;
+var $early={};
+try{var char_=nil;
+var result=nil;
+var chunk=nil;
+(result=smalltalk.send("", "_writeStream", []));
+(function(){while((function(){(char_=smalltalk.send(self['@stream'], "_next", []));return smalltalk.send(char_, "_notNil", []);})()) {(function(){((($receiver = smalltalk.send(char_, "__eq", ["!"])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return ((($receiver = smalltalk.send(smalltalk.send(self['@stream'], "_peek", []), "__eq", ["!"])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self['@stream'], "_next", []);})() : (function(){return (function(){throw $early=[smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])]})();})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(self['@stream'], "_next", []);}), (function(){return (function(){throw $early=[smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])]})();})]));})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return ((($receiver = smalltalk.send(smalltalk.send(self['@stream'], "_peek", []), "__eq", ["!"])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self['@stream'], "_next", []);})() : (function(){return (function(){throw $early=[smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])]})();})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(self['@stream'], "_next", []);}), (function(){return (function(){throw $early=[smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])]})();})]));})]));return smalltalk.send(result, "_nextPut_", [char_]);})()}})();
+return nil;
+return self;
+} catch(e) {if(e===$early)return e[0]; throw e}},
+args: [],
+source: "nextChunk\x0a\x09\x22The chunk format (Smalltalk Interchange Format or Fileout format)\x0a\x09is a trivial format but can be a bit tricky to understand:\x0a\x09\x09- Uses the exclamation mark as delimiter of chunks.\x0a\x09\x09- Inside a chunk a normal exclamation mark must be doubled.\x0a\x09\x09- A non empty chunk must be a valid Smalltalk expression.\x0a\x09\x09- A chunk on top level with a preceding empty chunk is an instruction chunk:\x0a\x09\x09\x09- The object created by the expression then takes over reading chunks.\x0a\x0a\x09This metod returns next chunk as a String (trimmed), empty String (all whitespace) or nil.\x22\x0a\x0a\x09| char result chunk |\x0a\x09result := '' writeStream.\x0a        [char := stream next.\x0a        char notNil] whileTrue: [\x0a                 char = '!' ifTrue: [\x0a                         stream peek = '!'\x0a                                ifTrue: [stream next \x22skipping the escape double\x22]\x0a                                ifFalse: [^result contents trimBoth  \x22chunk end marker found\x22]].\x0a                 result nextPut: char].\x0a\x09^nil \x22a chunk needs to end with !\x22",
+messageSends: ["writeStream", "whileTrue:", "next", "notNil", "ifTrue:", "=", "ifTrue:ifFalse:", "peek", "trimBoth", "contents", "nextPut:"],
+referencedClasses: []
+}),
+smalltalk.ChunkParser);
+
+smalltalk.addMethod(
+"_stream_",
+smalltalk.method({
+selector: "stream:",
+category: 'accessing',
+fn: function (aStream) {
+var self=this;
+(self['@stream']=aStream);
+return self;},
+args: ["aStream"],
+source: "stream: aStream\x0a\x09stream := aStream",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ChunkParser);
+
+
+smalltalk.addMethod(
+"_on_",
+smalltalk.method({
+selector: "on:",
+category: 'not yet classified',
+fn: function (aStream) {
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_new", []), "_stream_", [aStream]);
+return self;},
+args: ["aStream"],
+source: "on: aStream\x0a\x09^self new stream: aStream",
+messageSends: ["stream:", "new"],
+referencedClasses: []
+}),
+smalltalk.ChunkParser.klass);
+
+
+smalltalk.addClass('Exporter', smalltalk.Object, [], 'Importer-Exporter');
+smalltalk.addMethod(
+"_classNameFor_",
+smalltalk.method({
+selector: "classNameFor:",
+category: 'private',
+fn: function (aClass) {
+var self=this;
+return ((($receiver = smalltalk.send(aClass, "_isMetaclass", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_instanceClass", []), "_name", []), "__comma", [".klass"]);})() : (function(){return ((($receiver = smalltalk.send(aClass, "_isNil", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return "nil";})() : (function(){return smalltalk.send(aClass, "_name", []);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return "nil";}), (function(){return smalltalk.send(aClass, "_name", []);})]));})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_instanceClass", []), "_name", []), "__comma", [".klass"]);}), (function(){return ((($receiver = smalltalk.send(aClass, "_isNil", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return "nil";})() : (function(){return smalltalk.send(aClass, "_name", []);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return "nil";}), (function(){return smalltalk.send(aClass, "_name", []);})]));})]));
+return self;},
+args: ["aClass"],
+source: "classNameFor: aClass\x0a\x09^aClass isMetaclass\x0a\x09    ifTrue: [aClass instanceClass name, '.klass']\x0a\x09    ifFalse: [\x0a\x09\x09aClass isNil\x0a\x09\x09    ifTrue: ['nil']\x0a\x09\x09    ifFalse: [aClass name]]",
+messageSends: ["ifTrue:ifFalse:", "isMetaclass", ",", "name", "instanceClass", "isNil"],
+referencedClasses: []
+}),
+smalltalk.Exporter);
+
+smalltalk.addMethod(
+"_exportAll",
+smalltalk.method({
+selector: "exportAll",
+category: 'fileOut',
+fn: function () {
+var self=this;
+return smalltalk.send((smalltalk.String || String), "_streamContents_", [(function(stream){return smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_packages", []), "_do_", [(function(pkg){return smalltalk.send(stream, "_nextPutAll_", [smalltalk.send(self, "_exportPackage_", [smalltalk.send(pkg, "_name", [])])]);})]);})]);
+return self;},
+args: [],
+source: "exportAll\x0a    \x22Export all packages in the system.\x22\x0a\x0a    ^String streamContents: [:stream |\x0a    \x09Smalltalk current packages do: [:pkg |\x0a\x09\x09stream nextPutAll: (self exportPackage: pkg name)]]",
+messageSends: ["streamContents:", "do:", "packages", "current", "nextPutAll:", "exportPackage:", "name"],
+referencedClasses: ["String", "Smalltalk"]
+}),
+smalltalk.Exporter);
+
+smalltalk.addMethod(
+"_exportClass_",
+smalltalk.method({
+selector: "exportClass:",
+category: 'fileOut',
+fn: function (aClass) {
+var self=this;
+return smalltalk.send((smalltalk.String || String), "_streamContents_", [(function(stream){smalltalk.send(self, "_exportDefinitionOf_on_", [aClass, stream]);smalltalk.send(self, "_exportMethodsOf_on_", [aClass, stream]);smalltalk.send(self, "_exportMetaDefinitionOf_on_", [aClass, stream]);return smalltalk.send(self, "_exportMethodsOf_on_", [smalltalk.send(aClass, "_class", []), stream]);})]);
+return self;},
+args: ["aClass"],
+source: "exportClass: aClass\x0a\x09\x22Export a single class. Subclasses override these methods.\x22\x0a\x0a\x09^String streamContents: [:stream |\x0a\x09\x09self exportDefinitionOf: aClass on: stream.\x0a\x09\x09self exportMethodsOf: aClass on: stream.\x0a\x09\x09self exportMetaDefinitionOf: aClass on: stream.\x0a\x09\x09self exportMethodsOf: aClass class on: stream]",
+messageSends: ["streamContents:", "exportDefinitionOf:on:", "exportMethodsOf:on:", "exportMetaDefinitionOf:on:", "class"],
+referencedClasses: ["String"]
+}),
+smalltalk.Exporter);
+
+smalltalk.addMethod(
+"_exportDefinitionOf_on_",
+smalltalk.method({
+selector: "exportDefinitionOf:on:",
+category: 'private',
+fn: function (aClass, aStream) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["smalltalk.addClass("]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("'", "__comma", [smalltalk.send(self, "_classNameFor_", [aClass])]), "__comma", ["', "])]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send("smalltalk.", "__comma", [smalltalk.send(self, "_classNameFor_", [smalltalk.send(aClass, "_superclass", [])])])]);return smalltalk.send($rec, "_nextPutAll_", [", ["]);})(aStream);
+smalltalk.send(smalltalk.send(aClass, "_instanceVariableNames", []), "_do_separatedBy_", [(function(each){return smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send(smalltalk.send("'", "__comma", [each]), "__comma", ["'"])]);}), (function(){return smalltalk.send(aStream, "_nextPutAll_", [", "]);})]);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["], '"]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(aClass, "_category", []), "__comma", ["'"])]);return smalltalk.send($rec, "_nextPutAll_", [");"]);})(aStream);
+((($receiver = smalltalk.send(smalltalk.send(aClass, "_comment", []), "_notEmpty", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return (function($rec){smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", ["smalltalk."]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(self, "_classNameFor_", [aClass])]);smalltalk.send($rec, "_nextPutAll_", [".comment="]);return smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(aClass, "_comment", []), "_asJavascript", [])]);})(aStream);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return (function($rec){smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", ["smalltalk."]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(self, "_classNameFor_", [aClass])]);smalltalk.send($rec, "_nextPutAll_", [".comment="]);return smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(aClass, "_comment", []), "_asJavascript", [])]);})(aStream);})]));
+smalltalk.send(aStream, "_lf", []);
+return self;},
+args: ["aClass", "aStream"],
+source: "exportDefinitionOf: aClass on: aStream\x0a\x09aStream \x0a\x09    nextPutAll: 'smalltalk.addClass(';\x0a\x09    nextPutAll: '''', (self classNameFor: aClass), ''', ';\x0a\x09    nextPutAll: 'smalltalk.', (self classNameFor: aClass superclass);\x0a\x09    nextPutAll: ', ['.\x0a\x09aClass instanceVariableNames \x0a\x09    do: [:each | aStream nextPutAll: '''', each, '''']\x0a\x09    separatedBy: [aStream nextPutAll: ', '].\x0a\x09aStream\x09\x0a\x09    nextPutAll: '], ''';\x0a\x09    nextPutAll: aClass category, '''';\x0a\x09    nextPutAll: ');'.\x0a\x09aClass comment notEmpty ifTrue: [\x0a\x09    aStream \x0a\x09    \x09lf;\x0a\x09\x09nextPutAll: 'smalltalk.';\x0a\x09\x09nextPutAll: (self classNameFor: aClass);\x0a\x09\x09nextPutAll: '.comment=';\x0a\x09\x09nextPutAll: aClass comment asJavascript].\x0a\x09aStream lf",
+messageSends: ["nextPutAll:", ",", "classNameFor:", "superclass", "do:separatedBy:", "instanceVariableNames", "category", "ifTrue:", "notEmpty", "comment", "lf", "asJavascript"],
+referencedClasses: []
+}),
+smalltalk.Exporter);
+
+smalltalk.addMethod(
+"_exportMetaDefinitionOf_on_",
+smalltalk.method({
+selector: "exportMetaDefinitionOf:on:",
+category: 'private',
+fn: function (aClass, aStream) {
+var self=this;
+((($receiver = smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_class", []), "_instanceVariableNames", []), "_isEmpty", [])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send("smalltalk.", "__comma", [smalltalk.send(self, "_classNameFor_", [smalltalk.send(aClass, "_class", [])])])]);return smalltalk.send($rec, "_nextPutAll_", [".iVarNames = ["]);})(aStream);smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_class", []), "_instanceVariableNames", []), "_do_separatedBy_", [(function(each){return smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send(smalltalk.send("'", "__comma", [each]), "__comma", ["'"])]);}), (function(){return smalltalk.send(aStream, "_nextPutAll_", [","]);})]);return smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send("];", "__comma", [smalltalk.send((smalltalk.String || String), "_lf", [])])]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send("smalltalk.", "__comma", [smalltalk.send(self, "_classNameFor_", [smalltalk.send(aClass, "_class", [])])])]);return smalltalk.send($rec, "_nextPutAll_", [".iVarNames = ["]);})(aStream);smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_class", []), "_instanceVariableNames", []), "_do_separatedBy_", [(function(each){return smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send(smalltalk.send("'", "__comma", [each]), "__comma", ["'"])]);}), (function(){return smalltalk.send(aStream, "_nextPutAll_", [","]);})]);return smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send("];", "__comma", [smalltalk.send((smalltalk.String || String), "_lf", [])])]);})]));
+return self;},
+args: ["aClass", "aStream"],
+source: "exportMetaDefinitionOf: aClass on: aStream\x0a\x09aClass class instanceVariableNames isEmpty ifFalse: [\x0a\x09    aStream \x0a\x09\x09nextPutAll: 'smalltalk.', (self classNameFor: aClass class);\x0a\x09\x09nextPutAll: '.iVarNames = ['.\x0a\x09    aClass class instanceVariableNames\x0a\x09\x09do: [:each | aStream nextPutAll: '''', each, '''']\x0a\x09\x09separatedBy: [aStream nextPutAll: ','].\x0a\x09    aStream nextPutAll: '];', String lf]",
+messageSends: ["ifFalse:", "isEmpty", "instanceVariableNames", "class", "nextPutAll:", ",", "classNameFor:", "do:separatedBy:", "lf"],
+referencedClasses: ["String"]
+}),
+smalltalk.Exporter);
+
+smalltalk.addMethod(
+"_exportMethod_of_on_",
+smalltalk.method({
+selector: "exportMethod:of:on:",
+category: 'private',
+fn: function (aMethod, aClass, aStream) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["smalltalk.addMethod("]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aMethod, "_selector", []), "_asSelector", []), "_asJavascript", []), "__comma", [","])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", ["smalltalk.method({"]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("selector: ", "__comma", [smalltalk.send(smalltalk.send(aMethod, "_selector", []), "_asJavascript", [])]), "__comma", [","])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("category: '", "__comma", [smalltalk.send(aMethod, "_category", [])]), "__comma", ["',"])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("fn: ", "__comma", [smalltalk.send(smalltalk.send(aMethod, "_fn", []), "_compiledSource", [])]), "__comma", [","])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("args: ", "__comma", [smalltalk.send(smalltalk.send(aMethod, "_arguments", []), "_asJavascript", [])]), "__comma", [","])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("source: ", "__comma", [smalltalk.send(smalltalk.send(aMethod, "_source", []), "_asJavascript", [])]), "__comma", [","])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("messageSends: ", "__comma", [smalltalk.send(smalltalk.send(aMethod, "_messageSends", []), "_asJavascript", [])]), "__comma", [","])]);smalltalk.send($rec, "_lf", []);return smalltalk.send($rec, "_nextPutAll_", [smalltalk.send("referencedClasses: ", "__comma", [smalltalk.send(smalltalk.send(aMethod, "_referencedClasses", []), "_asJavascript", [])])]);})(aStream);
+(function($rec){smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", ["}),"]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send("smalltalk.", "__comma", [smalltalk.send(self, "_classNameFor_", [aClass])])]);smalltalk.send($rec, "_nextPutAll_", [");"]);smalltalk.send($rec, "_lf", []);return smalltalk.send($rec, "_lf", []);})(aStream);
+return self;},
+args: ["aMethod", "aClass", "aStream"],
+source: "exportMethod: aMethod of: aClass on: aStream\x0a\x09aStream \x0a\x09\x09nextPutAll: 'smalltalk.addMethod(';lf;\x0a\x09\x09nextPutAll: aMethod selector asSelector asJavascript, ',';lf;\x0a\x09\x09nextPutAll: 'smalltalk.method({';lf;\x0a\x09\x09nextPutAll: 'selector: ', aMethod selector asJavascript, ',';lf;\x0a\x09\x09nextPutAll: 'category: ''', aMethod category, ''',';lf;\x0a\x09\x09nextPutAll: 'fn: ', aMethod fn compiledSource, ',';lf;\x0a\x09\x09nextPutAll: 'args: ', aMethod arguments asJavascript, ','; lf;\x0a\x09\x09nextPutAll: 'source: ', aMethod source asJavascript, ',';lf;\x0a\x09\x09nextPutAll: 'messageSends: ', aMethod messageSends asJavascript, ',';lf;\x0a\x09\x09nextPutAll: 'referencedClasses: ', aMethod referencedClasses asJavascript.\x0a\x09aStream\x0a\x09\x09lf;\x0a\x09\x09nextPutAll: '}),';lf;\x0a\x09\x09nextPutAll: 'smalltalk.', (self classNameFor: aClass);\x0a\x09\x09nextPutAll: ');';lf;lf",
+messageSends: ["nextPutAll:", "lf", ",", "asJavascript", "asSelector", "selector", "category", "compiledSource", "fn", "arguments", "source", "messageSends", "referencedClasses", "classNameFor:"],
+referencedClasses: []
+}),
+smalltalk.Exporter);
+
+smalltalk.addMethod(
+"_exportMethodsOf_on_",
+smalltalk.method({
+selector: "exportMethodsOf:on:",
+category: 'private',
+fn: function (aClass, aStream) {
+var self=this;
+smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_methodDictionary", []), "_values", []), "_sorted_", [(function(a, b){return ((($receiver = smalltalk.send(a, "_selector", [])).klass === smalltalk.Number) ? $receiver <=smalltalk.send(b, "_selector", []) : smalltalk.send($receiver, "__lt_eq", [smalltalk.send(b, "_selector", [])]));})]), "_do_", [(function(each){return ((($receiver = smalltalk.send(smalltalk.send(each, "_category", []), "_match_", ["^\x5c*"])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(self, "_exportMethod_of_on_", [each, aClass, aStream]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(self, "_exportMethod_of_on_", [each, aClass, aStream]);})]));})]);
+smalltalk.send(aStream, "_lf", []);
+return self;},
+args: ["aClass", "aStream"],
+source: "exportMethodsOf: aClass on: aStream\x0a\x09\x22Issue #143: sort methods alphabetically\x22\x0a\x0a\x09((aClass methodDictionary values) sorted: [:a :b | a selector <= b selector]) do: [:each |\x0a\x09\x09(each category match: '^\x5c*') ifFalse: [\x0a\x09\x09\x09self exportMethod: each of: aClass on: aStream]].\x0a\x09aStream lf",
+messageSends: ["do:", "sorted:", "values", "methodDictionary", "<=", "selector", "ifFalse:", "match:", "category", "exportMethod:of:on:", "lf"],
+referencedClasses: []
+}),
+smalltalk.Exporter);
+
+smalltalk.addMethod(
+"_exportPackage_",
+smalltalk.method({
+selector: "exportPackage:",
+category: 'fileOut',
+fn: function (packageName) {
+var self=this;
+var package=nil;
+return smalltalk.send((smalltalk.String || String), "_streamContents_", [(function(stream){(package=smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_packageAt_", [packageName]));smalltalk.send(self, "_exportPackageDefinitionOf_on_", [package, stream]);smalltalk.send(smalltalk.send(smalltalk.send(package, "_sortedClasses", []), "_asSet", []), "_do_", [(function(each){return smalltalk.send(stream, "_nextPutAll_", [smalltalk.send(self, "_exportClass_", [each])]);})]);return smalltalk.send(self, "_exportPackageExtensionsOf_on_", [package, stream]);})]);
+return self;},
+args: ["packageName"],
+source: "exportPackage: packageName\x0a\x09\x22Export a given package by name.\x22\x0a\x0a\x09| package |\x0a\x09^String streamContents: [:stream |\x0a                package := Smalltalk current packageAt: packageName.\x0a                self exportPackageDefinitionOf: package on: stream.\x0a\x0a\x09\x09\x22Export classes in dependency order.\x0a\x09\x09Update (issue #171): Remove duplicates for export\x22\x0a\x09    \x09package sortedClasses asSet do: [:each |\x0a                        stream nextPutAll: (self exportClass: each)].\x0a\x09\x09self exportPackageExtensionsOf: package on: stream]",
+messageSends: ["streamContents:", "packageAt:", "current", "exportPackageDefinitionOf:on:", "do:", "asSet", "sortedClasses", "nextPutAll:", "exportClass:", "exportPackageExtensionsOf:on:"],
+referencedClasses: ["String", "Smalltalk"]
+}),
+smalltalk.Exporter);
+
+smalltalk.addMethod(
+"_exportPackageDefinitionOf_on_",
+smalltalk.method({
+selector: "exportPackageDefinitionOf:on:",
+category: 'private',
+fn: function (package, aStream) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["smalltalk.addPackage("]);return smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send("'", "__comma", [smalltalk.send(package, "_name", [])]), "__comma", ["', "]), "__comma", [smalltalk.send(package, "_propertiesAsJSON", [])]), "__comma", [");"])]);})(aStream);
+smalltalk.send(aStream, "_lf", []);
+return self;},
+args: ["package", "aStream"],
+source: "exportPackageDefinitionOf: package on: aStream\x0a\x09aStream \x0a\x09    nextPutAll: 'smalltalk.addPackage(';\x0a\x09    nextPutAll: '''', package name, ''', ', package propertiesAsJSON , ');'.\x0a\x09aStream lf",
+messageSends: ["nextPutAll:", ",", "name", "propertiesAsJSON", "lf"],
+referencedClasses: []
+}),
+smalltalk.Exporter);
+
+smalltalk.addMethod(
+"_exportPackageExtensionsOf_on_",
+smalltalk.method({
+selector: "exportPackageExtensionsOf:on:",
+category: 'private',
+fn: function (package, aStream) {
+var self=this;
+var name=nil;
+(name=smalltalk.send(package, "_name", []));
+smalltalk.send(smalltalk.send((smalltalk.Package || Package), "_sortedClasses_", [smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_classes", [])]), "_do_", [(function(each){return smalltalk.send([each,smalltalk.send(each, "_class", [])], "_do_", [(function(aClass){return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_methodDictionary", []), "_values", []), "_sorted_", [(function(a, b){return ((($receiver = smalltalk.send(a, "_selector", [])).klass === smalltalk.Number) ? $receiver <=smalltalk.send(b, "_selector", []) : smalltalk.send($receiver, "__lt_eq", [smalltalk.send(b, "_selector", [])]));})]), "_do_", [(function(method){return ((($receiver = smalltalk.send(smalltalk.send(method, "_category", []), "_match_", [smalltalk.send("^\x5c*", "__comma", [name])])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_exportMethod_of_on_", [method, aClass, aStream]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(self, "_exportMethod_of_on_", [method, aClass, aStream]);})]));})]);})]);})]);
+return self;},
+args: ["package", "aStream"],
+source: "exportPackageExtensionsOf: package on: aStream\x0a\x09\x22Issue #143: sort classes and methods alphabetically\x22\x0a\x0a\x09| name |\x0a\x09name := package name.\x0a\x09(Package sortedClasses: Smalltalk current classes) do: [:each |\x0a\x09\x09{each. each class} do: [:aClass | \x0a\x09\x09\x09((aClass methodDictionary values) sorted: [:a :b | a selector <= b selector]) do: [:method |\x0a\x09\x09\x09\x09(method category match: '^\x5c*', name) ifTrue: [\x0a\x09\x09\x09\x09\x09self exportMethod: method of: aClass on: aStream ]]]]",
+messageSends: ["name", "do:", "sortedClasses:", "classes", "current", "class", "sorted:", "values", "methodDictionary", "<=", "selector", "ifTrue:", "match:", "category", ",", "exportMethod:of:on:"],
+referencedClasses: ["Package", "Smalltalk"]
+}),
+smalltalk.Exporter);
+
+
+
+smalltalk.addClass('ChunkExporter', smalltalk.Exporter, [], 'Importer-Exporter');
+smalltalk.addMethod(
+"_chunkEscape_",
+smalltalk.method({
+selector: "chunkEscape:",
+category: 'not yet classified',
+fn: function (aString) {
+var self=this;
+return smalltalk.send(smalltalk.send(aString, "_replace_with_", ["!", "!!"]), "_trimBoth", []);
+return self;},
+args: ["aString"],
+source: "chunkEscape: aString\x0a\x09\x22Replace all occurrences of ! with !! and trim at both ends.\x22\x0a\x0a\x09^(aString replace: '!' with: '!!') trimBoth",
+messageSends: ["trimBoth", "replace:with:"],
+referencedClasses: []
+}),
+smalltalk.ChunkExporter);
+
+smalltalk.addMethod(
+"_classNameFor_",
+smalltalk.method({
+selector: "classNameFor:",
+category: 'not yet classified',
+fn: function (aClass) {
+var self=this;
+return ((($receiver = smalltalk.send(aClass, "_isMetaclass", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_instanceClass", []), "_name", []), "__comma", [" class"]);})() : (function(){return ((($receiver = smalltalk.send(aClass, "_isNil", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return "nil";})() : (function(){return smalltalk.send(aClass, "_name", []);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return "nil";}), (function(){return smalltalk.send(aClass, "_name", []);})]));})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_instanceClass", []), "_name", []), "__comma", [" class"]);}), (function(){return ((($receiver = smalltalk.send(aClass, "_isNil", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return "nil";})() : (function(){return smalltalk.send(aClass, "_name", []);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return "nil";}), (function(){return smalltalk.send(aClass, "_name", []);})]));})]));
+return self;},
+args: ["aClass"],
+source: "classNameFor: aClass\x0a\x09^aClass isMetaclass\x0a\x09    ifTrue: [aClass instanceClass name, ' class']\x0a\x09    ifFalse: [\x0a\x09\x09aClass isNil\x0a\x09\x09    ifTrue: ['nil']\x0a\x09\x09    ifFalse: [aClass name]]",
+messageSends: ["ifTrue:ifFalse:", "isMetaclass", ",", "name", "instanceClass", "isNil"],
+referencedClasses: []
+}),
+smalltalk.ChunkExporter);
+
+smalltalk.addMethod(
+"_exportDefinitionOf_on_",
+smalltalk.method({
+selector: "exportDefinitionOf:on:",
+category: 'not yet classified',
+fn: function (aClass, aStream) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(self, "_classNameFor_", [smalltalk.send(aClass, "_superclass", [])])]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(" subclass: #", "__comma", [smalltalk.send(self, "_classNameFor_", [aClass])])]);smalltalk.send($rec, "_lf", []);return smalltalk.send($rec, "_nextPutAll_", ["\x09instanceVariableNames: '"]);})(aStream);
+smalltalk.send(smalltalk.send(aClass, "_instanceVariableNames", []), "_do_separatedBy_", [(function(each){return smalltalk.send(aStream, "_nextPutAll_", [each]);}), (function(){return smalltalk.send(aStream, "_nextPutAll_", [" "]);})]);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["'"]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("\x09package: '", "__comma", [smalltalk.send(aClass, "_category", [])]), "__comma", ["'!"])]);return smalltalk.send($rec, "_lf", []);})(aStream);
+((($receiver = smalltalk.send(smalltalk.send(aClass, "_comment", []), "_notEmpty", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return (function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("!", "__comma", [smalltalk.send(self, "_classNameFor_", [aClass])]), "__comma", [" commentStamp!"])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(self, "_chunkEscape_", [smalltalk.send(aClass, "_comment", [])]), "__comma", ["!"])]);return smalltalk.send($rec, "_lf", []);})(aStream);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return (function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("!", "__comma", [smalltalk.send(self, "_classNameFor_", [aClass])]), "__comma", [" commentStamp!"])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(self, "_chunkEscape_", [smalltalk.send(aClass, "_comment", [])]), "__comma", ["!"])]);return smalltalk.send($rec, "_lf", []);})(aStream);})]));
+smalltalk.send(aStream, "_lf", []);
+return self;},
+args: ["aClass", "aStream"],
+source: "exportDefinitionOf: aClass on: aStream\x0a    \x22Chunk format.\x22\x0a\x0a    aStream \x0a        nextPutAll: (self classNameFor: aClass superclass);\x0a        nextPutAll: ' subclass: #', (self classNameFor: aClass); lf;\x0a        nextPutAll: '\x09instanceVariableNames: '''.\x0a    aClass instanceVariableNames \x0a        do: [:each | aStream nextPutAll: each]\x0a        separatedBy: [aStream nextPutAll: ' '].\x0a    aStream \x0a        nextPutAll: ''''; lf;\x0a        nextPutAll: '\x09package: ''', aClass category, '''!'; lf.\x0a    aClass comment notEmpty ifTrue: [\x0a        aStream \x0a        nextPutAll: '!', (self classNameFor: aClass), ' commentStamp!';lf;\x0a        nextPutAll: (self chunkEscape: aClass comment), '!';lf].\x0a    aStream lf",
+messageSends: ["nextPutAll:", "classNameFor:", "superclass", ",", "lf", "do:separatedBy:", "instanceVariableNames", "category", "ifTrue:", "notEmpty", "comment", "chunkEscape:"],
+referencedClasses: []
+}),
+smalltalk.ChunkExporter);
+
+smalltalk.addMethod(
+"_exportMetaDefinitionOf_on_",
+smalltalk.method({
+selector: "exportMetaDefinitionOf:on:",
+category: 'not yet classified',
+fn: function (aClass, aStream) {
+var self=this;
+((($receiver = smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_class", []), "_instanceVariableNames", []), "_isEmpty", [])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(self, "_classNameFor_", [smalltalk.send(aClass, "_class", [])])]);return smalltalk.send($rec, "_nextPutAll_", [" instanceVariableNames: '"]);})(aStream);smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_class", []), "_instanceVariableNames", []), "_do_separatedBy_", [(function(each){return smalltalk.send(aStream, "_nextPutAll_", [each]);}), (function(){return smalltalk.send(aStream, "_nextPutAll_", [" "]);})]);return (function($rec){smalltalk.send($rec, "_nextPutAll_", ["'!"]);smalltalk.send($rec, "_lf", []);return smalltalk.send($rec, "_lf", []);})(aStream);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(self, "_classNameFor_", [smalltalk.send(aClass, "_class", [])])]);return smalltalk.send($rec, "_nextPutAll_", [" instanceVariableNames: '"]);})(aStream);smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_class", []), "_instanceVariableNames", []), "_do_separatedBy_", [(function(each){return smalltalk.send(aStream, "_nextPutAll_", [each]);}), (function(){return smalltalk.send(aStream, "_nextPutAll_", [" "]);})]);return (function($rec){smalltalk.send($rec, "_nextPutAll_", ["'!"]);smalltalk.send($rec, "_lf", []);return smalltalk.send($rec, "_lf", []);})(aStream);})]));
+return self;},
+args: ["aClass", "aStream"],
+source: "exportMetaDefinitionOf: aClass on: aStream\x0a\x0a\x09aClass class instanceVariableNames isEmpty ifFalse: [\x0a\x09\x09aStream \x0a\x09\x09    nextPutAll: (self classNameFor: aClass class);\x0a\x09\x09    nextPutAll: ' instanceVariableNames: '''.\x0a\x09\x09aClass class instanceVariableNames \x0a\x09\x09    do: [:each | aStream nextPutAll: each]\x0a\x09\x09    separatedBy: [aStream nextPutAll: ' '].\x0a\x09\x09aStream\x09\x0a\x09\x09    nextPutAll: '''!'; lf; lf]",
+messageSends: ["ifFalse:", "isEmpty", "instanceVariableNames", "class", "nextPutAll:", "classNameFor:", "do:separatedBy:", "lf"],
+referencedClasses: []
+}),
+smalltalk.ChunkExporter);
+
+smalltalk.addMethod(
+"_exportMethod_of_on_",
+smalltalk.method({
+selector: "exportMethod:of:on:",
+category: 'not yet classified',
+fn: function (aMethod, aClass, aStream) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(self, "_chunkEscape_", [smalltalk.send(aMethod, "_source", [])])]);smalltalk.send($rec, "_lf", []);return smalltalk.send($rec, "_nextPutAll_", ["!"]);})(aStream);
+return self;},
+args: ["aMethod", "aClass", "aStream"],
+source: "exportMethod: aMethod of: aClass on: aStream\x0a\x09aStream \x0a\x09\x09lf; lf; nextPutAll: (self chunkEscape: aMethod source); lf;\x0a\x09\x09nextPutAll: '!'",
+messageSends: ["lf", "nextPutAll:", "chunkEscape:", "source"],
+referencedClasses: []
+}),
+smalltalk.ChunkExporter);
+
+smalltalk.addMethod(
+"_exportMethods_category_of_on_",
+smalltalk.method({
+selector: "exportMethods:category:of:on:",
+category: 'not yet classified',
+fn: function (methods, category, aClass, aStream) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send("!", "__comma", [smalltalk.send(self, "_classNameFor_", [aClass])])]);return smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(" methodsFor: '", "__comma", [category]), "__comma", ["'!"])]);})(aStream);
+smalltalk.send(smalltalk.send(methods, "_sorted_", [(function(a, b){return ((($receiver = smalltalk.send(a, "_selector", [])).klass === smalltalk.Number) ? $receiver <=smalltalk.send(b, "_selector", []) : smalltalk.send($receiver, "__lt_eq", [smalltalk.send(b, "_selector", [])]));})]), "_do_", [(function(each){return smalltalk.send(self, "_exportMethod_of_on_", [each, aClass, aStream]);})]);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", [" !"]);smalltalk.send($rec, "_lf", []);return smalltalk.send($rec, "_lf", []);})(aStream);
+return self;},
+args: ["methods", "category", "aClass", "aStream"],
+source: "exportMethods: methods category: category of: aClass on: aStream\x0a\x09\x22Issue #143: sort methods alphabetically\x22\x0a\x0a\x09aStream\x0a\x09\x09nextPutAll: '!', (self classNameFor: aClass);\x0a\x09\x09nextPutAll: ' methodsFor: ''', category, '''!'.\x0a\x09\x09(methods sorted: [:a :b | a selector <= b selector]) do: [:each |\x0a\x09\x09\x09\x09self exportMethod: each of: aClass on: aStream].\x0a\x09aStream nextPutAll: ' !'; lf; lf",
+messageSends: ["nextPutAll:", ",", "classNameFor:", "do:", "sorted:", "<=", "selector", "exportMethod:of:on:", "lf"],
+referencedClasses: []
+}),
+smalltalk.ChunkExporter);
+
+smalltalk.addMethod(
+"_exportMethodsOf_on_",
+smalltalk.method({
+selector: "exportMethodsOf:on:",
+category: 'not yet classified',
+fn: function (aClass, aStream) {
+var self=this;
+var map=nil;
+(map=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));
+smalltalk.send(aClass, "_protocolsDo_", [(function(category, methods){return ((($receiver = smalltalk.send(category, "_match_", ["^\x5c*"])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(map, "_at_put_", [category, methods]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(map, "_at_put_", [category, methods]);})]));})]);
+smalltalk.send(smalltalk.send(smalltalk.send(map, "_keys", []), "_sorted_", [(function(a, b){return ((($receiver = a).klass === smalltalk.Number) ? $receiver <=b : smalltalk.send($receiver, "__lt_eq", [b]));})]), "_do_", [(function(category){var methods=nil;
+(methods=smalltalk.send(map, "_at_", [category]));return smalltalk.send(self, "_exportMethods_category_of_on_", [methods, category, aClass, aStream]);})]);
+return self;},
+args: ["aClass", "aStream"],
+source: "exportMethodsOf: aClass on: aStream\x0a\x09\x22Issue #143: sort protocol alphabetically\x22\x0a\x0a\x09| map |\x0a\x09map := Dictionary new.\x0a\x09aClass protocolsDo: [:category :methods | \x0a\x09\x09(category match: '^\x5c*') ifFalse: [ map at: category put: methods ]].\x0a\x09(map keys sorted: [:a :b | a <= b ]) do: [:category | | methods |\x0a\x09\x09methods := map at: category.\x0a\x09\x09self\x0a\x09\x09\x09exportMethods: methods\x0a\x09\x09\x09category: category\x0a\x09\x09\x09of: aClass\x0a\x09\x09\x09on: aStream ]",
+messageSends: ["new", "protocolsDo:", "ifFalse:", "match:", "at:put:", "do:", "sorted:", "keys", "<=", "at:", "exportMethods:category:of:on:"],
+referencedClasses: ["Dictionary"]
+}),
+smalltalk.ChunkExporter);
+
+smalltalk.addMethod(
+"_exportPackageDefinitionOf_on_",
+smalltalk.method({
+selector: "exportPackageDefinitionOf:on:",
+category: 'not yet classified',
+fn: function (package, aStream) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send("Smalltalk current createPackage: '", "__comma", [smalltalk.send(package, "_name", [])]), "__comma", ["' properties: "]), "__comma", [smalltalk.send(smalltalk.send(package, "_properties", []), "_storeString", [])]), "__comma", ["!"])]);return smalltalk.send($rec, "_lf", []);})(aStream);
+return self;},
+args: ["package", "aStream"],
+source: "exportPackageDefinitionOf: package on: aStream\x0a\x09\x22Chunk format.\x22\x0a\x0a\x09aStream \x0a\x09    nextPutAll: 'Smalltalk current createPackage: ''', package name,\x0a\x09\x09''' properties: ', package properties storeString, '!'; lf.",
+messageSends: ["nextPutAll:", ",", "name", "storeString", "properties", "lf"],
+referencedClasses: []
+}),
+smalltalk.ChunkExporter);
+
+smalltalk.addMethod(
+"_exportPackageExtensionsOf_on_",
+smalltalk.method({
+selector: "exportPackageExtensionsOf:on:",
+category: 'not yet classified',
+fn: function (package, aStream) {
+var self=this;
+var name=nil;
+var map=nil;
+(name=smalltalk.send(package, "_name", []));
+smalltalk.send(smalltalk.send((smalltalk.Package || Package), "_sortedClasses_", [smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_classes", [])]), "_do_", [(function(each){return smalltalk.send([each,smalltalk.send(each, "_class", [])], "_do_", [(function(aClass){(map=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));smalltalk.send(aClass, "_protocolsDo_", [(function(category, methods){return ((($receiver = smalltalk.send(category, "_match_", [smalltalk.send("^\x5c*", "__comma", [name])])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(map, "_at_put_", [category, methods]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(map, "_at_put_", [category, methods]);})]));})]);return smalltalk.send(smalltalk.send(smalltalk.send(map, "_keys", []), "_sorted_", [(function(a, b){return ((($receiver = a).klass === smalltalk.Number) ? $receiver <=b : smalltalk.send($receiver, "__lt_eq", [b]));})]), "_do_", [(function(category){var methods=nil;
+(methods=smalltalk.send(map, "_at_", [category]));return smalltalk.send(self, "_exportMethods_category_of_on_", [methods, category, aClass, aStream]);})]);})]);})]);
+return self;},
+args: ["package", "aStream"],
+source: "exportPackageExtensionsOf: package on: aStream\x0a\x09\x22We need to override this one too since we need to group\x0a\x09all methods in a given protocol under a leading methodsFor: chunk\x0a\x09for that class.\x22\x0a\x0a\x09\x22Issue #143: sort protocol alphabetically\x22\x0a\x0a\x09| name map |\x0a\x09name := package name.\x0a\x09(Package sortedClasses: Smalltalk current classes) do: [:each |\x0a\x09\x09{each. each class} do: [:aClass |\x0a\x09\x09\x09map := Dictionary new.\x0a\x09\x09\x09aClass protocolsDo: [:category :methods | \x0a\x09\x09\x09\x09(category match: '^\x5c*', name) ifTrue: [ map at: category put: methods ]].\x0a\x09\x09\x09(map keys sorted: [:a :b | a <= b ]) do: [:category | | methods |\x0a\x09\x09\x09\x09methods := map at: category.\x09\x0a\x09\x09\x09\x09self exportMethods: methods category: category of: aClass on: aStream ]]]",
+messageSends: ["name", "do:", "sortedClasses:", "classes", "current", "class", "new", "protocolsDo:", "ifTrue:", "match:", ",", "at:put:", "sorted:", "keys", "<=", "at:", "exportMethods:category:of:on:"],
+referencedClasses: ["Package", "Smalltalk", "Dictionary"]
+}),
+smalltalk.ChunkExporter);
+
+
+
+smalltalk.addClass('StrippedExporter', smalltalk.Exporter, [], 'Importer-Exporter');
+smalltalk.addMethod(
+"_exportDefinitionOf_on_",
+smalltalk.method({
+selector: "exportDefinitionOf:on:",
+category: 'private',
+fn: function (aClass, aStream) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["smalltalk.addClass("]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("'", "__comma", [smalltalk.send(self, "_classNameFor_", [aClass])]), "__comma", ["', "])]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send("smalltalk.", "__comma", [smalltalk.send(self, "_classNameFor_", [smalltalk.send(aClass, "_superclass", [])])])]);return smalltalk.send($rec, "_nextPutAll_", [", ["]);})(aStream);
+smalltalk.send(smalltalk.send(aClass, "_instanceVariableNames", []), "_do_separatedBy_", [(function(each){return smalltalk.send(aStream, "_nextPutAll_", [smalltalk.send(smalltalk.send("'", "__comma", [each]), "__comma", ["'"])]);}), (function(){return smalltalk.send(aStream, "_nextPutAll_", [", "]);})]);
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["], '"]);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(aClass, "_category", []), "__comma", ["'"])]);return smalltalk.send($rec, "_nextPutAll_", [");"]);})(aStream);
+smalltalk.send(aStream, "_lf", []);
+return self;},
+args: ["aClass", "aStream"],
+source: "exportDefinitionOf: aClass on: aStream\x0a\x09aStream \x0a\x09    nextPutAll: 'smalltalk.addClass(';\x0a\x09    nextPutAll: '''', (self classNameFor: aClass), ''', ';\x0a\x09    nextPutAll: 'smalltalk.', (self classNameFor: aClass superclass);\x0a\x09    nextPutAll: ', ['.\x0a\x09aClass instanceVariableNames \x0a\x09    do: [:each | aStream nextPutAll: '''', each, '''']\x0a\x09    separatedBy: [aStream nextPutAll: ', '].\x0a\x09aStream\x09\x0a\x09    nextPutAll: '], ''';\x0a\x09    nextPutAll: aClass category, '''';\x0a\x09    nextPutAll: ');'.\x0a\x09aStream lf",
+messageSends: ["nextPutAll:", ",", "classNameFor:", "superclass", "do:separatedBy:", "instanceVariableNames", "category", "lf"],
+referencedClasses: []
+}),
+smalltalk.StrippedExporter);
+
+smalltalk.addMethod(
+"_exportMethod_of_on_",
+smalltalk.method({
+selector: "exportMethod:of:on:",
+category: 'private',
+fn: function (aMethod, aClass, aStream) {
+var self=this;
+(function($rec){smalltalk.send($rec, "_nextPutAll_", ["smalltalk.addMethod("]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aMethod, "_selector", []), "_asSelector", []), "_asJavascript", []), "__comma", [","])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", ["smalltalk.method({"]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send("selector: ", "__comma", [smalltalk.send(smalltalk.send(aMethod, "_selector", []), "_asJavascript", [])]), "__comma", [","])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send("fn: ", "__comma", [smalltalk.send(smalltalk.send(aMethod, "_fn", []), "_compiledSource", [])])]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", ["}),"]);smalltalk.send($rec, "_lf", []);smalltalk.send($rec, "_nextPutAll_", [smalltalk.send("smalltalk.", "__comma", [smalltalk.send(self, "_classNameFor_", [aClass])])]);smalltalk.send($rec, "_nextPutAll_", [");"]);smalltalk.send($rec, "_lf", []);return smalltalk.send($rec, "_lf", []);})(aStream);
+return self;},
+args: ["aMethod", "aClass", "aStream"],
+source: "exportMethod: aMethod of: aClass on: aStream\x0a\x09aStream \x0a\x09\x09nextPutAll: 'smalltalk.addMethod(';lf;\x0a\x09\x09nextPutAll: aMethod selector asSelector asJavascript, ',';lf;\x0a\x09\x09nextPutAll: 'smalltalk.method({';lf;\x0a\x09\x09nextPutAll: 'selector: ', aMethod selector asJavascript, ',';lf;\x0a\x09\x09nextPutAll: 'fn: ', aMethod fn compiledSource;lf;\x0a\x09\x09nextPutAll: '}),';lf;\x0a\x09\x09nextPutAll: 'smalltalk.', (self classNameFor: aClass);\x0a\x09\x09nextPutAll: ');';lf;lf",
+messageSends: ["nextPutAll:", "lf", ",", "asJavascript", "asSelector", "selector", "compiledSource", "fn", "classNameFor:"],
+referencedClasses: []
+}),
+smalltalk.StrippedExporter);
+
+
+
+smalltalk.addClass('Importer', smalltalk.Object, [], 'Importer-Exporter');
+smalltalk.addMethod(
+"_import_",
+smalltalk.method({
+selector: "import:",
+category: 'fileIn',
+fn: function (aStream) {
+var self=this;
+var chunk=nil;
+var result=nil;
+var parser=nil;
+var lastEmpty=nil;
+(parser=smalltalk.send((smalltalk.ChunkParser || ChunkParser), "_on_", [aStream]));
+(lastEmpty=false);
+(function(){while(!(function(){(chunk=smalltalk.send(parser, "_nextChunk", []));return smalltalk.send(chunk, "_isNil", []);})()) {(function(){return ((($receiver = smalltalk.send(chunk, "_isEmpty", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return (lastEmpty=true);})() : (function(){(result=smalltalk.send(smalltalk.send((smalltalk.Compiler || Compiler), "_new", []), "_evaluateExpression_", [chunk]));return ((($receiver = lastEmpty).klass === smalltalk.Boolean) ? ($receiver ? (function(){(lastEmpty=false);return smalltalk.send(result, "_scanFrom_", [parser]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){(lastEmpty=false);return smalltalk.send(result, "_scanFrom_", [parser]);})]));})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return (lastEmpty=true);}), (function(){(result=smalltalk.send(smalltalk.send((smalltalk.Compiler || Compiler), "_new", []), "_evaluateExpression_", [chunk]));return ((($receiver = lastEmpty).klass === smalltalk.Boolean) ? ($receiver ? (function(){(lastEmpty=false);return smalltalk.send(result, "_scanFrom_", [parser]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){(lastEmpty=false);return smalltalk.send(result, "_scanFrom_", [parser]);})]));})]));})()}})();
+return self;},
+args: ["aStream"],
+source: "import: aStream\x0a    | chunk result parser lastEmpty |\x0a    parser := ChunkParser on: aStream.\x0a    lastEmpty := false.\x0a    [chunk := parser nextChunk.\x0a     chunk isNil] whileFalse: [\x0a        chunk isEmpty\x0a       \x09\x09ifTrue: [lastEmpty := true]\x0a       \x09\x09ifFalse: [\x0a        \x09\x09result := Compiler new evaluateExpression: chunk.\x0a        \x09\x09lastEmpty \x0a            \x09\x09\x09ifTrue: [\x0a                                  \x09lastEmpty := false.\x0a                                  \x09result scanFrom: parser]]]",
+messageSends: ["on:", "whileFalse:", "nextChunk", "isNil", "ifTrue:ifFalse:", "isEmpty", "evaluateExpression:", "new", "ifTrue:", "scanFrom:"],
+referencedClasses: ["ChunkParser", "Compiler"]
+}),
+smalltalk.Importer);
+
+
+

+ 520 - 0
st/Compiler-AST.st

@@ -0,0 +1,520 @@
+Smalltalk current createPackage: 'Compiler-AST' properties: #{}!
+Object subclass: #Node
+	instanceVariableNames: 'nodes used alias'
+	package: 'Compiler-AST'!
+!Node commentStamp!
+I am the abstract root class of the abstract syntax tree.!
+
+!Node methodsFor: 'accessing'!
+
+addNode: aNode
+	self nodes add: aNode
+!
+
+alias
+	^ alias
+!
+
+alias: aString
+	alias := aString
+!
+
+beUsed
+	used := true
+!
+
+nodes
+	^nodes ifNil: [nodes := Array new]
+!
+
+used
+	^ used ifNil: [ false ]
+!
+
+used: aBoolean
+	used := aBoolean
+! !
+
+!Node methodsFor: 'building'!
+
+nodes: aCollection
+	nodes := aCollection
+! !
+
+!Node methodsFor: 'testing'!
+
+canAliasChildren
+	^ true
+!
+
+isAliased
+	^ self alias notNil
+!
+
+isBlockNode
+	^false
+!
+
+isBlockSequenceNode
+	^false
+!
+
+isSendNode
+	^false
+!
+
+isUsed
+	^ self used
+!
+
+isValueNode
+	^false
+!
+
+shouldBeAliased
+	^ self isUsed and: [ self alias isNil ]
+! !
+
+!Node methodsFor: 'visiting'!
+
+accept: aVisitor
+	aVisitor visitNode: self
+! !
+
+Node subclass: #AssignmentNode
+	instanceVariableNames: 'left right'
+	package: 'Compiler-AST'!
+
+!AssignmentNode methodsFor: 'accessing'!
+
+left
+	^left
+!
+
+left: aNode
+	left := aNode.
+	left assigned: true
+!
+
+nodes
+	^ Array with: self left with: self right
+!
+
+right
+	^right
+!
+
+right: aNode
+	right := aNode
+! !
+
+!AssignmentNode methodsFor: 'visiting'!
+
+accept: aVisitor
+	aVisitor visitAssignmentNode: self
+! !
+
+Node subclass: #BlockNode
+	instanceVariableNames: 'parameters scope inlined'
+	package: 'Compiler-AST'!
+
+!BlockNode methodsFor: 'accessing'!
+
+inlined
+	^inlined ifNil: [false]
+!
+
+inlined: aBoolean
+	inlined := aBoolean
+!
+
+parameters
+	^parameters ifNil: [parameters := Array new]
+!
+
+parameters: aCollection
+	parameters := aCollection
+!
+
+scope
+	^ scope
+!
+
+scope: aLexicalScope
+	scope := aLexicalScope
+! !
+
+!BlockNode methodsFor: 'testing'!
+
+isBlockNode
+	^true
+! !
+
+!BlockNode methodsFor: 'visiting'!
+
+accept: aVisitor
+	aVisitor visitBlockNode: self
+! !
+
+Node subclass: #CascadeNode
+	instanceVariableNames: 'receiver'
+	package: 'Compiler-AST'!
+
+!CascadeNode methodsFor: 'accessing'!
+
+receiver
+	^receiver
+!
+
+receiver: aNode
+	receiver := aNode
+! !
+
+!CascadeNode methodsFor: 'visiting'!
+
+accept: aVisitor
+	aVisitor visitCascadeNode: self
+! !
+
+Node subclass: #DynamicArrayNode
+	instanceVariableNames: ''
+	package: 'Compiler-AST'!
+
+!DynamicArrayNode methodsFor: 'visiting'!
+
+accept: aVisitor
+	aVisitor visitDynamicArrayNode: self
+! !
+
+Node subclass: #DynamicDictionaryNode
+	instanceVariableNames: ''
+	package: 'Compiler-AST'!
+
+!DynamicDictionaryNode methodsFor: 'visiting'!
+
+accept: aVisitor
+	aVisitor visitDynamicDictionaryNode: self
+! !
+
+Node subclass: #JSStatementNode
+	instanceVariableNames: 'source'
+	package: 'Compiler-AST'!
+
+!JSStatementNode methodsFor: 'accessing'!
+
+source
+	^source ifNil: ['']
+!
+
+source: aString
+	source := aString
+! !
+
+!JSStatementNode methodsFor: 'visiting'!
+
+accept: aVisitor
+	aVisitor visitJSStatementNode: self
+! !
+
+Node subclass: #MethodNode
+	instanceVariableNames: 'selector arguments source scope classReferences messageSends'
+	package: 'Compiler-AST'!
+
+!MethodNode methodsFor: 'accessing'!
+
+arguments
+	^arguments ifNil: [#()]
+!
+
+arguments: aCollection
+	arguments := aCollection
+!
+
+classReferences
+	^ classReferences
+!
+
+classReferences: aCollection
+	classReferences := aCollection
+!
+
+hasNonLocalReturn
+	^ self scope
+		ifNil: [ false ]
+		ifNotNil: [ self scope hasNonLocalReturn ]
+!
+
+messageSends
+	^ messageSends
+!
+
+messageSends: aCollection
+	messageSends := aCollection
+!
+
+scope
+	^ scope
+!
+
+scope: aMethodScope
+	scope := aMethodScope
+!
+
+selector
+	^selector
+!
+
+selector: aString
+	selector := aString
+!
+
+source
+	^source
+!
+
+source: aString
+	source := aString
+! !
+
+!MethodNode methodsFor: 'testing'!
+
+canAliasChildren
+	^ false
+! !
+
+!MethodNode methodsFor: 'visiting'!
+
+accept: aVisitor
+	aVisitor visitMethodNode: self
+! !
+
+Node subclass: #ReturnNode
+	instanceVariableNames: 'nonLocalReturn'
+	package: 'Compiler-AST'!
+
+!ReturnNode methodsFor: 'accessing'!
+
+nonLocalReturn
+	^ nonLocalReturn ifNil: [ false ]
+!
+
+nonLocalReturn: aBoolean
+	nonLocalReturn := aBoolean
+! !
+
+!ReturnNode methodsFor: 'testing'!
+
+shouldBeAliased
+	^ false
+! !
+
+!ReturnNode methodsFor: 'visiting'!
+
+accept: aVisitor
+	aVisitor visitReturnNode: self
+! !
+
+Node subclass: #SendNode
+	instanceVariableNames: 'selector arguments receiver'
+	package: 'Compiler-AST'!
+
+!SendNode methodsFor: 'accessing'!
+
+arguments
+	^arguments ifNil: [arguments := #()]
+!
+
+arguments: aCollection
+	arguments := aCollection
+!
+
+cascadeNodeWithMessages: aCollection
+	| first |
+	first := SendNode new
+	    selector: self selector;
+	    arguments: self arguments;
+	    yourself.
+	^CascadeNode new
+	    receiver: self receiver;
+	    nodes: (Array with: first), aCollection;
+	    yourself
+!
+
+nodes
+	^ (Array withAll: self arguments)
+		add: self receiver;
+		yourself
+!
+
+receiver
+	^receiver
+!
+
+receiver: aNode
+	receiver := aNode
+!
+
+selector
+	^selector
+!
+
+selector: aString
+	selector := aString
+!
+
+valueForReceiver: anObject
+	^SendNode new
+	    receiver: (self receiver 
+		ifNil: [anObject]
+		ifNotNil: [self receiver valueForReceiver: anObject]);
+	    selector: self selector;
+	    arguments: self arguments;
+	    yourself
+! !
+
+!SendNode methodsFor: 'testing'!
+
+isSendNode
+	^ true
+! !
+
+!SendNode methodsFor: 'visiting'!
+
+accept: aVisitor
+	aVisitor visitSendNode: self
+! !
+
+Node subclass: #SequenceNode
+	instanceVariableNames: 'temps scope'
+	package: 'Compiler-AST'!
+
+!SequenceNode methodsFor: 'accessing'!
+
+scope
+	^ scope
+!
+
+scope: aLexicalScope
+	scope := aLexicalScope
+!
+
+temps
+	^temps ifNil: [#()]
+!
+
+temps: aCollection
+	temps := aCollection
+! !
+
+!SequenceNode methodsFor: 'testing'!
+
+asBlockSequenceNode
+	^BlockSequenceNode new
+	    nodes: self nodes;
+	    temps: self temps;
+	    yourself
+!
+
+canAliasChildren
+	^ false
+! !
+
+!SequenceNode methodsFor: 'visiting'!
+
+accept: aVisitor
+	aVisitor visitSequenceNode: self
+! !
+
+SequenceNode subclass: #BlockSequenceNode
+	instanceVariableNames: ''
+	package: 'Compiler-AST'!
+
+!BlockSequenceNode methodsFor: 'testing'!
+
+isBlockSequenceNode
+	^true
+! !
+
+!BlockSequenceNode methodsFor: 'visiting'!
+
+accept: aVisitor
+	aVisitor visitBlockSequenceNode: self
+! !
+
+Node subclass: #ValueNode
+	instanceVariableNames: 'value'
+	package: 'Compiler-AST'!
+
+!ValueNode methodsFor: 'accessing'!
+
+value
+	^value
+!
+
+value: anObject
+	value := anObject
+! !
+
+!ValueNode methodsFor: 'testing'!
+
+isValueNode
+	^true
+!
+
+shouldBeAliased
+	^ false
+! !
+
+!ValueNode methodsFor: 'visiting'!
+
+accept: aVisitor
+	aVisitor visitValueNode: self
+! !
+
+ValueNode subclass: #VariableNode
+	instanceVariableNames: 'assigned binding'
+	package: 'Compiler-AST'!
+
+!VariableNode methodsFor: 'accessing'!
+
+alias
+	^ self binding alias
+!
+
+assigned
+	^assigned ifNil: [false]
+!
+
+assigned: aBoolean
+	assigned := aBoolean
+!
+
+beAssigned
+	assigned := true
+!
+
+binding
+	^ binding
+!
+
+binding: aScopeVar
+	(aScopeVar isKindOf: SemanticAnalyzer) ifTrue: [ self halt ].
+	binding := aScopeVar
+! !
+
+!VariableNode methodsFor: 'visiting'!
+
+accept: aVisitor
+	aVisitor visitVariableNode: self
+! !
+
+VariableNode subclass: #ClassReferenceNode
+	instanceVariableNames: ''
+	package: 'Compiler-AST'!
+
+!ClassReferenceNode methodsFor: 'visiting'!
+
+accept: aVisitor
+	aVisitor visitClassReferenceNode: self
+! !
+

+ 333 - 0
st/Compiler-Core.st

@@ -0,0 +1,333 @@
+Smalltalk current createPackage: 'Compiler-Core' properties: #{}!
+Object subclass: #Compiler
+	instanceVariableNames: 'currentClass source unknownVariables codeGeneratorClass'
+	package: 'Compiler-Core'!
+
+!Compiler methodsFor: 'accessing'!
+
+codeGeneratorClass
+	^codeGeneratorClass ifNil: [FunCodeGenerator]
+!
+
+codeGeneratorClass: aClass
+	codeGeneratorClass := aClass
+!
+
+currentClass
+	^currentClass
+!
+
+currentClass: aClass
+	currentClass := aClass
+!
+
+source
+	^source ifNil: ['']
+!
+
+source: aString
+	source := aString
+!
+
+unknownVariables
+	^unknownVariables
+!
+
+unknownVariables: aCollection
+	unknownVariables := aCollection
+! !
+
+!Compiler methodsFor: 'compiling'!
+
+compile: aString
+	^self compileNode: (self parse: aString)
+!
+
+compile: aString forClass: aClass
+	self currentClass: aClass.
+	self source: aString.
+	^self compile: aString
+!
+
+compileExpression: aString
+	self currentClass: DoIt.
+	self source: 'doIt ^[', aString, '] value'.
+	^self compileNode: (self parse: self source)
+!
+
+compileNode: aNode
+	| generator result |
+	generator := self codeGeneratorClass new.
+	generator
+		source: self source;
+		currentClass: self currentClass.
+	result := generator compileNode: aNode.
+	self unknownVariables: #().
+	^result
+!
+
+eval: aString
+	<return eval(aString)>
+!
+
+evaluateExpression: aString
+	"Unlike #eval: evaluate a Smalltalk expression and answer the returned object"
+	| result |
+	DoIt addCompiledMethod: (self eval: (self compileExpression: aString)).
+	result := DoIt new doIt.
+	DoIt removeCompiledMethod: (DoIt methodDictionary at: 'doIt').
+	^result
+!
+
+parse: aString
+    ^Smalltalk current parse: aString
+!
+
+parseExpression: aString
+    ^self parse: 'doIt ^[', aString, '] value'
+!
+
+recompile: aClass
+	aClass methodDictionary do: [:each |
+		self install: each source forClass: aClass category: each category].
+	self setupClass: aClass.
+	aClass isMetaclass ifFalse: [self recompile: aClass class]
+!
+
+recompileAll
+	Smalltalk current classes do: [:each |
+		Transcript show: each; cr.
+		[self recompile: each] valueWithTimeout: 100]
+!
+
+setupClass: aClass
+	<smalltalk.init(aClass)>
+! !
+
+!Compiler class methodsFor: 'compiling'!
+
+recompile: aClass
+	self new recompile: aClass
+!
+
+recompileAll
+	Smalltalk current classes do: [:each |
+		self recompile: each]
+! !
+
+Object subclass: #DoIt
+	instanceVariableNames: ''
+	package: 'Compiler-Core'!
+
+Object subclass: #JSStream
+	instanceVariableNames: 'stream'
+	package: 'Compiler-Core'!
+
+!JSStream methodsFor: 'accessing'!
+
+contents
+	^ stream contents
+! !
+
+!JSStream methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+	stream := '' writeStream.
+! !
+
+!JSStream methodsFor: 'streaming'!
+
+lf
+	stream lf
+!
+
+nextPut: aString
+	stream nextPut: aString
+!
+
+nextPutAll: aString
+	stream nextPutAll: aString
+!
+
+nextPutAssignment: varInstruction to: valueInstruction
+	varInstruction emitOn: self.
+	stream nextPutAll: '='.
+	valueInstruction emitOn: self
+!
+
+nextPutClosureWith: aBlock arguments: anArray
+	stream nextPutAll: '(function('.
+	anArray 
+		do: [ :each | stream nextPutAll: each ]
+		separatedBy: [ stream nextPut: ',' ].
+	stream nextPutAll: '){'; lf.
+	aBlock value.
+	stream nextPutAll: '})'
+!
+
+nextPutFunctionWith: aBlock arguments: anArray
+	stream nextPutAll: 'fn: function('.
+	anArray 
+		do: [ :each | stream nextPutAll: each ]
+		separatedBy: [ stream nextPut: ',' ].
+	stream nextPutAll: '){'; lf.
+	self nextPutVar: '$return'.
+	stream nextPutAll: 'var self=this;'; lf.
+	aBlock value.
+	stream nextPutAll: 'return $return || self;}'
+!
+
+nextPutMethodDeclaration: aMethod with: aBlock
+	stream 
+		nextPutAll: 'smalltalk.method({'; lf;
+		nextPutAll: 'selector: "', aMethod selector, '",'; lf;
+		nextPutAll: 'source: ', aMethod source asJavascript, ',';lf.
+	aBlock value.
+	stream 
+		nextPutAll: ',', String lf, 'messageSends: ';
+		nextPutAll: aMethod messageSends asArray asJavascript, ','; lf;
+          	nextPutAll: 'args: ', (aMethod arguments collect: [ :each | each value ]) asArray asJavascript, ','; lf;
+		nextPutAll: 'referencedClasses: ['.
+	aMethod classReferences 
+		do: [:each | stream nextPutAll: each asJavascript]
+		separatedBy: [stream nextPutAll: ','].
+	stream 
+		nextPutAll: ']';
+		nextPutAll: '})'
+!
+
+nextPutNonLocalReturnHandlingWith: aBlock
+	stream 
+		nextPutAll: 'var $early={};'; lf;
+		nextPutAll: 'try {'; lf.
+	aBlock value.
+	stream 
+		nextPutAll: '}'; lf;
+		nextPutAll: 'catch(e) {if(e===$early)return e[0]; throw e}'; lf
+!
+
+nextPutNonLocalReturnWith: aBlock
+	stream nextPutAll: '(function(){throw $early=['.
+	aBlock value.
+	stream nextPutAll: ']})()'
+!
+
+nextPutReturnWith: aBlock
+	stream nextPutAll: '$return='.
+	aBlock value
+!
+
+nextPutSendTo: receiver selector: selector arguments: arguments
+	stream nextPutAll: 'smalltalk.send('.
+	receiver emitOn: self. 
+	stream nextPutAll: ',"', selector asSelector, '",['.
+	arguments 
+		do: [ :each | each emitOn: self ]
+		separatedBy: [ stream nextPutAll: ',' ].
+	stream nextPutAll: '])'
+!
+
+nextPutSequenceWith: aBlock
+	stream 
+		nextPutAll: 'switch(smalltalk.thisContext.pc){'; lf.
+	aBlock value.
+	stream 
+		nextPutAll: '};'; lf
+!
+
+nextPutStatement: anInteger with: aBlock
+	stream 
+		nextPutAll: 'case ', anInteger asString, ':'; lf.
+	aBlock value.
+	stream 
+		nextPutAll: ';'; lf;
+		nextPutAll: 'smalltalk.thisContext.pc=', (anInteger + 1) asString, ';'; lf
+!
+
+nextPutVar: aString
+	stream nextPutAll: 'var ', aString, ';'; lf
+!
+
+nextPutVars: aCollection
+	stream nextPutAll: 'var '.
+	aCollection 
+		do: [ :each | stream nextPutAll: each ]
+		separatedBy: [ stream nextPutAll: ',' ].
+	stream nextPutAll: ';'; lf
+! !
+
+Object subclass: #NodeVisitor
+	instanceVariableNames: ''
+	package: 'Compiler-Core'!
+
+!NodeVisitor methodsFor: 'visiting'!
+
+visit: aNode
+	aNode accept: self
+!
+
+visitAll: aCollection
+	aCollection do: [ :each | self visit: each ]
+!
+
+visitAssignmentNode: aNode
+	self visitNode: aNode
+!
+
+visitBlockNode: aNode
+	self visitNode: aNode
+!
+
+visitBlockSequenceNode: aNode
+	self visitSequenceNode: aNode
+!
+
+visitCascadeNode: aNode
+	self visitNode: aNode
+!
+
+visitClassReferenceNode: aNode
+	self visitNode: aNode
+!
+
+visitDynamicArrayNode: aNode
+	self visitNode: aNode
+!
+
+visitDynamicDictionaryNode: aNode
+	self visitNode: aNode
+!
+
+visitJSStatementNode: aNode
+	self visitNode: aNode
+!
+
+visitMethodNode: aNode
+	self visitNode: aNode
+!
+
+visitNode: aNode
+	aNode nodes do: [ :each | self visit: each ]
+!
+
+visitReturnNode: aNode
+	self visitNode: aNode
+!
+
+visitSendNode: aNode
+	self visitNode: aNode
+!
+
+visitSequenceNode: aNode
+	self visitNode: aNode
+!
+
+visitValueNode: aNode
+	self visitNode: aNode
+!
+
+visitVariableNode: aNode
+	self visitNode: aNode
+! !
+

+ 641 - 0
st/Compiler-IR.st

@@ -0,0 +1,641 @@
+Smalltalk current createPackage: 'Compiler-IR' properties: #{}!
+NodeVisitor subclass: #IRASTTranslator
+	instanceVariableNames: 'builder source'
+	package: 'Compiler-IR'!
+!IRASTTranslator commentStamp!
+I an the AST (abstract syntax tree) visitor responsible for building the intermediate representation graph.
+I rely on a builder object, instance of IRBuilder.!
+
+!IRASTTranslator methodsFor: 'accessing'!
+
+builder
+	^ builder ifNil: [ builder := IRBuilder new ]
+!
+
+builder: aBuilder
+	builder := aBuilder
+!
+
+source
+	^ source
+!
+
+source: aString
+	source := aString
+! !
+
+!IRASTTranslator methodsFor: 'visiting'!
+
+visitAssignmentNode: aNode
+	self builder assignment 
+		with: [ self visit: aNode left ];
+		with: [ self visit: aNode right ]
+!
+
+visitBlockNode: aNode
+	self builder closure 
+		with: [ super visitBlockNode: aNode ];
+		arguments: aNode parameters
+!
+
+visitJSStatementNode: aNode
+	self builder verbatim: aNode source
+!
+
+visitMethodNode: aNode
+	self builder method 
+		source: self source;
+		arguments: aNode arguments;
+		selector: aNode selector;
+		messageSends: aNode messageSends;
+		classReferences: aNode classReferences.
+
+	aNode scope temps do: [ :each |
+		self builder tempDeclaration name: each name ].
+	aNode hasNonLocalReturn 
+		ifTrue: [ self builder nonLocalReturnHandling with: [
+			super visitMethodNode: aNode ]]
+		ifFalse: [ super visitMethodNode: aNode ]
+!
+
+visitReturnNode: aNode
+	(aNode nonLocalReturn 
+		ifTrue: [ self builder nonLocalReturn ]
+		ifFalse: [ self builder return ]) with: [ super visitReturnNode: aNode ]
+!
+
+visitSendNode: aNode
+	self builder send
+		selector: aNode selector;
+		with: [
+			self visit: aNode receiver.
+			(aNode arguments do: [ :each | self visit: each ]) ]
+!
+
+visitSequenceNode: aNode
+	self builder sequence with: [
+		super visitSequenceNode: aNode ]
+!
+
+visitValueNode: aNode
+	self builder value: aNode value
+!
+
+visitVariableNode: aNode
+	self builder variable: aNode binding
+! !
+
+IRASTTranslator subclass: #IRASTResolver
+	instanceVariableNames: 'nextAlias'
+	package: 'Compiler-IR'!
+!IRASTResolver commentStamp!
+I resolve nodes by creating an alias variable when appropriate, to flatten the AST.
+Nodes referenced in other nodes are aliased, except for some specific nodes such as variable or value nodes.!
+
+!IRASTResolver methodsFor: 'accessing'!
+
+nextAlias
+	"Message sends are assigned, or 'aliased', to internal variables.
+	Internal variable names are unique, and attached to the annotated send node"
+
+	nextAlias ifNil: [nextAlias := 0].
+	nextAlias := nextAlias + 1.
+	^ '$_', nextAlias asString
+! !
+
+!IRASTResolver methodsFor: 'visiting'!
+
+resolve: aNode
+	aNode isBlockSequenceNode ifFalse: [
+		aNode nodes do: [ :each | self resolve: each ]].
+	aNode shouldBeAliased ifTrue: [
+		| alias |
+		alias := self nextAlias.
+		self builder method internalVariables add: alias.
+		self builder assignment
+			with: [ self builder variable: (AliasVar new name: alias) ];
+			with: [ self visit: aNode resolving: false ].
+			aNode alias: alias ]
+!
+
+visit: aNode
+	self visit: aNode resolving: aNode canAliasChildren
+!
+
+visit: aNode resolving: aBoolean
+	aBoolean ifTrue: [ self resolve: aNode ].
+	aNode isAliased 
+		ifTrue: [ self visitAliased: aNode ]
+		ifFalse: [ super visit: aNode ]
+!
+
+visitAliased: aNode
+	^ self builder variable: (AliasVar new name: aNode alias)
+! !
+
+Object subclass: #IRBuilder
+	instanceVariableNames: 'method root nextPc'
+	package: 'Compiler-IR'!
+!IRBuilder commentStamp!
+I am responsible for building the IR (Intermatiate Representation) graph, composed of IRInstruction objects.!
+
+!IRBuilder methodsFor: 'accessing'!
+
+method
+	^ method
+!
+
+nextPc
+	nextPc ifNil: [ nextPc := 0 ].
+	nextPc := nextPc + 1.
+	^ nextPc
+!
+
+root
+	^ root
+!
+
+root: anIRInstruction
+	root := anIRInstruction
+! !
+
+!IRBuilder methodsFor: 'building'!
+
+add: aClass
+	^ self root append: (aClass on: self)
+!
+
+append: anObject
+	^root append: anObject
+!
+
+assignment
+	^ self add: IRAssignment
+!
+
+closure
+	^ self add: IRClosure
+!
+
+nonLocalReturn
+	^ self add: IRNonLocalReturn
+!
+
+nonLocalReturnHandling
+	^ self add: IRNonLocalReturnHandling
+!
+
+return
+	^ self add: IRReturn
+!
+
+send
+	^ self add: IRSend
+!
+
+sequence
+	^ self add: IRSequence
+!
+
+statement
+	^ self add: IRStatement
+!
+
+tempDeclaration
+	^ self add: IRTempDeclaration
+!
+
+value
+	^ self add: IRValue
+!
+
+value: aString
+	^ self value
+		value: aString;
+		yourself
+!
+
+variable
+	^ self add: IRVariable
+!
+
+variable: aScopeVariable
+	^ self variable
+		variable: aScopeVariable;
+		yourself
+!
+
+verbatim: aString
+	^(self add: IRVerbatim)
+		source: aString;
+		yourself
+!
+
+with: anObject
+	self root with: anObject
+! !
+
+!IRBuilder methodsFor: 'emiting'!
+
+emitOn: aStream
+	method emitOn: aStream
+! !
+
+!IRBuilder methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+	root := method := IRMethod on: self
+! !
+
+Object subclass: #IRInstruction
+	instanceVariableNames: 'builder instructions'
+	package: 'Compiler-IR'!
+!IRInstruction commentStamp!
+I am the abstract root class of the IR (intermediate representation) instructions class hierarchy.
+The IR graph is used to emit JavaScript code using a JSStream.!
+
+!IRInstruction methodsFor: 'accessing'!
+
+builder
+	^ builder
+!
+
+builder: aBuilder
+	builder := aBuilder
+!
+
+instructions
+	^ instructions ifNil: [ instructions := OrderedCollection new ]
+! !
+
+!IRInstruction methodsFor: 'building'!
+
+append: anObject
+	anObject appendToInstruction: self.
+	^ anObject
+!
+
+appendBlock: aBlock
+	| root |
+	root := self builder root.
+	self builder root: self.
+	aBlock value.
+	self builder root: root
+!
+
+appendInstruction: anIRInstruction
+	self instructions add: anIRInstruction
+!
+
+appendString: aString
+	self append: (self builder value: aString)
+!
+
+appendToInstruction: anIRInstruction
+	anIRInstruction appendInstruction: self
+!
+
+with: anObject
+	anObject appendToInstruction: self
+! !
+
+!IRInstruction methodsFor: 'emiting'!
+
+emitOn: aStream
+	"Just emit all sub instructions to aStream.
+	Subclasses should not forget to call `super emitOn:`"
+
+	self instructions do: [ :each |
+		each emitOn: aStream ]
+! !
+
+!IRInstruction class methodsFor: 'instance creation'!
+
+on: aBuilder
+	^ self new
+		builder: aBuilder;
+		yourself
+! !
+
+IRInstruction subclass: #IRAssignment
+	instanceVariableNames: 'left right'
+	package: 'Compiler-IR'!
+
+!IRAssignment methodsFor: 'emiting'!
+
+emitOn: aStream
+	aStream 
+		nextPutAssignment: self instructions first
+		to: self instructions second
+! !
+
+IRInstruction subclass: #IRClosure
+	instanceVariableNames: 'arguments'
+	package: 'Compiler-IR'!
+
+!IRClosure methodsFor: 'accessing'!
+
+arguments
+	^ arguments
+!
+
+arguments: aCollection
+	arguments := aCollection
+! !
+
+!IRClosure methodsFor: 'emiting'!
+
+emitOn: aStream
+	aStream 
+		nextPutClosureWith: [ super emitOn: aStream ]
+		arguments: (self arguments collect: [ :each | each asVariableName ])
+! !
+
+IRInstruction subclass: #IRMethod
+	instanceVariableNames: 'source selector classReferences messageSends arguments internalVariables source'
+	package: 'Compiler-IR'!
+!IRMethod commentStamp!
+I am a method instruction!
+
+!IRMethod methodsFor: 'accessing'!
+
+arguments
+	^ arguments
+!
+
+arguments: aCollection
+	arguments := aCollection
+!
+
+classReferences
+	^ classReferences
+!
+
+classReferences: aCollection
+	classReferences := aCollection
+!
+
+internalVariables
+	^ internalVariables ifNil: [ internalVariables := Set new ]
+!
+
+messageSends
+	^ messageSends
+!
+
+messageSends: aCollection
+	messageSends := aCollection
+!
+
+selector
+	^ selector
+!
+
+selector: aString
+	selector := aString
+!
+
+source
+	^ source
+!
+
+source: aString
+	source := aString
+! !
+
+!IRMethod methodsFor: 'emiting'!
+
+emitOn: aStream
+	aStream 
+		nextPutMethodDeclaration: self
+		with: [
+			aStream 
+				nextPutFunctionWith: [ 
+					self internalVariables notEmpty ifTrue: [
+						aStream nextPutVars: self internalVariables ].
+					super emitOn: aStream ]
+				arguments: (self arguments collect: [ :each | each asVariableName ]) ]
+! !
+
+IRInstruction subclass: #IRNonLocalReturn
+	instanceVariableNames: ''
+	package: 'Compiler-IR'!
+!IRNonLocalReturn commentStamp!
+I am a non local return instruction.
+Non local returns are handled using a try/catch JS statement.
+
+See IRNonLocalReturnHandling class!
+
+!IRNonLocalReturn methodsFor: 'emiting'!
+
+emitOn: aStream
+	aStream nextPutNonLocalReturnWith: [
+		super emitOn: aStream ]
+! !
+
+IRInstruction subclass: #IRNonLocalReturnHandling
+	instanceVariableNames: ''
+	package: 'Compiler-IR'!
+!IRNonLocalReturnHandling commentStamp!
+I represent a non local return handling instruction.
+Non local returns are handled with a try/catch statement!
+
+!IRNonLocalReturnHandling methodsFor: 'emiting'!
+
+emitOn: aStream
+	aStream nextPutNonLocalReturnHandlingWith: [
+		super emitOn: aStream ]
+! !
+
+IRInstruction subclass: #IRReturn
+	instanceVariableNames: ''
+	package: 'Compiler-IR'!
+!IRReturn commentStamp!
+I am a local return instruction.!
+
+!IRReturn methodsFor: 'emiting'!
+
+emitOn: aStream
+	aStream nextPutReturnWith: [
+		super emitOn: aStream ]
+! !
+
+IRInstruction subclass: #IRSend
+	instanceVariableNames: 'selector superSend'
+	package: 'Compiler-IR'!
+!IRSend commentStamp!
+I am a message send instruction.!
+
+!IRSend methodsFor: 'accessing'!
+
+emitOn: aStream
+
+	aStream nextPutAll: 'smalltalk.send('.
+	self instructions first emitOn: aStream.
+	aStream nextPutAll:  ',"', self selector asSelector, '", ['.
+	self instructions allButFirst
+		do: [ :each | each emitOn: aStream ]
+		separatedBy: [ aStream nextPutAll: ',' ].
+	aStream nextPutAll: '])'
+!
+
+selector
+	^ selector
+!
+
+selector: aString
+	selector := aString
+!
+
+superSend
+	^ superSend ifNil: [ false ]
+!
+
+superSend: aBoolean
+	superSend := aBoolean
+! !
+
+IRInstruction subclass: #IRSequence
+	instanceVariableNames: ''
+	package: 'Compiler-IR'!
+
+!IRSequence methodsFor: 'emiting'!
+
+appendInstruction: anIRInstruction
+	self instructions add: ((IRStatement on: self builder) with: anIRInstruction)
+!
+
+emitOn: aStream
+	aStream nextPutSequenceWith: [
+		"self instructions do: [ :each |
+			((IRStatement on: self builder)
+				pc: self builder nextPc;
+				with: each;
+				yourself) emitOn: aStream ]"
+		super emitOn: aStream ]
+! !
+
+IRInstruction subclass: #IRStatement
+	instanceVariableNames: 'pc'
+	package: 'Compiler-IR'!
+
+!IRStatement methodsFor: 'accessing'!
+
+pc
+	^ pc ifNil: [pc := self builder nextPc]
+! !
+
+!IRStatement methodsFor: 'emiting'!
+
+emitOn: aStream
+	aStream nextPutStatement: self pc with: [
+		super emitOn: aStream ]
+! !
+
+IRInstruction subclass: #IRTempDeclaration
+	instanceVariableNames: 'name'
+	package: 'Compiler-IR'!
+!IRTempDeclaration commentStamp!
+I am a temporary variable declaration instruction!
+
+!IRTempDeclaration methodsFor: 'accessing'!
+
+name
+	^ name
+!
+
+name: aString
+	name := aString
+! !
+
+!IRTempDeclaration methodsFor: 'emiting'!
+
+emitOn: aStream
+	aStream nextPutVar: self name asVariableName
+! !
+
+IRInstruction subclass: #IRValue
+	instanceVariableNames: 'value'
+	package: 'Compiler-IR'!
+!IRValue commentStamp!
+I am the simplest possible instruction. I represent a value.!
+
+!IRValue methodsFor: 'accessing'!
+
+value
+	^value
+!
+
+value: aString
+	value := aString
+! !
+
+!IRValue methodsFor: 'emiting'!
+
+emitOn: aStream
+	aStream nextPutAll: self value asJavascript
+! !
+
+IRInstruction subclass: #IRVariable
+	instanceVariableNames: 'variable'
+	package: 'Compiler-IR'!
+
+!IRVariable methodsFor: 'accessing'!
+
+variable
+	^ variable
+!
+
+variable: aScopeVariable
+	variable := aScopeVariable
+! !
+
+!IRVariable methodsFor: 'emiting'!
+
+emitOn: aStream
+	aStream nextPutAll: self variable alias
+! !
+
+IRInstruction subclass: #IRVerbatim
+	instanceVariableNames: 'source'
+	package: 'Compiler-IR'!
+
+!IRVerbatim methodsFor: 'accessing'!
+
+source
+	^ source
+!
+
+source: aString
+	source := aString
+! !
+
+!IRVerbatim methodsFor: 'emiting'!
+
+emitOn: aStream
+	aStream nextPutAll: self source, ';'
+! !
+
+!BlockClosure methodsFor: '*Compiler-IR'!
+
+appendToInstruction: anIRInstruction
+    anIRInstruction appendBlock: self
+! !
+
+!String methodsFor: '*Compiler-IR'!
+
+appendToInstruction: anInstruction
+	anInstruction appendString: self
+!
+
+asVariableName
+	^ (Smalltalk current reservedWords includes: self)
+		ifTrue: [ self, '_' ]
+		ifFalse: [ self ]
+!
+
+emitOn: aStream
+	aStream nextPutAll: self
+! !
+

+ 484 - 0
st/Compiler-Semantic.st

@@ -0,0 +1,484 @@
+Smalltalk current createPackage: 'Compiler-Semantic' properties: #{}!
+Object subclass: #LexicalScope
+	instanceVariableNames: 'temps args outerScope'
+	package: 'Compiler-Semantic'!
+!LexicalScope commentStamp!
+I represent a lexical scope where variable names are associated with ScopeVars
+Instances are used for block scopes. Method scopes are instances of MethodLexicalScope.
+
+I am attached to a ScopeVar and method/block nodes.
+Each context (method/closure) get a fresh scope that inherits from its outer scope.!
+
+!LexicalScope methodsFor: 'accessing'!
+
+allVariableNames
+	^ self args keys, self temps keys
+!
+
+args
+	^ args ifNil: [ args := Dictionary new ]
+!
+
+bindingFor: aStringOrNode
+	^ self args at: aStringOrNode value ifAbsent: [
+		self temps at: aStringOrNode value ifAbsent: [ nil ]]
+!
+
+lookupVariable: aNode
+	| lookup |
+	lookup := (self bindingFor: aNode).
+	lookup ifNil: [
+		lookup := self outerScope ifNotNil: [ 
+			(self outerScope lookupVariable: aNode) ]].
+	^ lookup
+!
+
+methodScope
+	^ self outerScope ifNotNil: [
+		self outerScope methodScope ]
+!
+
+outerScope
+	^ outerScope
+!
+
+outerScope: aLexicalScope
+	outerScope := aLexicalScope
+!
+
+temps
+	^ temps ifNil: [ temps := Dictionary new ]
+! !
+
+!LexicalScope methodsFor: 'adding'!
+
+addArg: aString
+	self args at: aString put: (ArgVar on: aString).
+	(self args at: aString) scope: self
+!
+
+addTemp: aString
+	self temps at: aString put: (TempVar on: aString).
+	(self temps at: aString) scope: self
+! !
+
+!LexicalScope methodsFor: 'testing'!
+
+isMethodScope
+	^ false
+! !
+
+LexicalScope subclass: #MethodLexicalScope
+	instanceVariableNames: 'iVars unknownVariables nonLocalReturn'
+	package: 'Compiler-Semantic'!
+!MethodLexicalScope commentStamp!
+I represent a method scope.!
+
+!MethodLexicalScope methodsFor: 'accessing'!
+
+allVariableNames
+	^ super allVariableNames, self iVars keys
+!
+
+bindingFor: aNode
+	^ (super bindingFor: aNode) ifNil: [
+		self iVars at: aNode value ifAbsent: [ nil ]]
+!
+
+iVars
+	^ iVars ifNil: [ iVars := Dictionary new ]
+!
+
+methodScope
+	^ self
+!
+
+nonLocalReturn
+	^ nonLocalReturn ifNil: [ false ]
+!
+
+nonLocalReturn: aBoolean
+	nonLocalReturn := aBoolean
+!
+
+unknownVariables
+	^ unknownVariables ifNil: [ unknownVariables := OrderedCollection new ]
+! !
+
+!MethodLexicalScope methodsFor: 'adding'!
+
+addIvar: aString
+	self iVars at: aString put: (InstanceVar on: aString).
+	(self iVars at: aString) scope: self
+! !
+
+!MethodLexicalScope methodsFor: 'testing'!
+
+hasNonLocalReturn
+	^ self nonLocalReturn
+!
+
+isMethodScope
+	^ true
+! !
+
+Object subclass: #ScopeVar
+	instanceVariableNames: 'scope name'
+	package: 'Compiler-Semantic'!
+!ScopeVar commentStamp!
+I am an entry in a LexicalScope that gets associated with variable nodes of the same name.  
+There are 4 different subclasses of vars: temp vars, local vars, args, and unknown/global vars.!
+
+!ScopeVar methodsFor: 'accessing'!
+
+alias
+	^ self name asVariableName
+!
+
+name
+	^ name
+!
+
+name: aString
+	name := aString
+!
+
+scope
+	^ scope
+!
+
+scope: aScope
+	scope := aScope
+! !
+
+!ScopeVar methodsFor: 'testing'!
+
+isArgVar
+	^ false
+!
+
+isInstanceVar
+	^ false
+!
+
+isTempVar
+	^ false
+!
+
+isUnknownVar
+	^ false
+! !
+
+!ScopeVar class methodsFor: 'instance creation'!
+
+on: aString
+	^ self new 
+		name: aString;
+		yourself
+! !
+
+ScopeVar subclass: #AliasVar
+	instanceVariableNames: ''
+	package: 'Compiler-Semantic'!
+!AliasVar commentStamp!
+I am an internally defined variable by the compiler!
+
+ScopeVar subclass: #ArgVar
+	instanceVariableNames: ''
+	package: 'Compiler-Semantic'!
+!ArgVar commentStamp!
+I am an argument of a method or block.!
+
+!ArgVar methodsFor: 'testing'!
+
+isArgVar
+	^ true
+! !
+
+ScopeVar subclass: #ClassRefVar
+	instanceVariableNames: ''
+	package: 'Compiler-Semantic'!
+
+!ClassRefVar methodsFor: 'accessing'!
+
+alias
+	^ '(Smalltalk.', self name, ' || ', self name, ')'
+! !
+
+ScopeVar subclass: #InstanceVar
+	instanceVariableNames: ''
+	package: 'Compiler-Semantic'!
+!InstanceVar commentStamp!
+I am an instance variable of a method or block.!
+
+!InstanceVar methodsFor: 'testing'!
+
+alias
+	^ 'self["@', self name, ']'
+!
+
+isInstanceVar
+	^ true
+! !
+
+ScopeVar subclass: #TempVar
+	instanceVariableNames: ''
+	package: 'Compiler-Semantic'!
+!TempVar commentStamp!
+I am an temporary variable of a method or block.!
+
+!TempVar methodsFor: 'testing'!
+
+isTempVar
+	^ true
+! !
+
+ScopeVar subclass: #UnknownVar
+	instanceVariableNames: ''
+	package: 'Compiler-Semantic'!
+!UnknownVar commentStamp!
+I am an unknown variable. Amber uses unknown variables as JavaScript globals!
+
+!UnknownVar methodsFor: 'testing'!
+
+isUnknownVar
+	^ true
+! !
+
+NodeVisitor subclass: #SemanticAnalyzer
+	instanceVariableNames: 'currentScope theClass classReferences messageSends'
+	package: 'Compiler-Semantic'!
+!SemanticAnalyzer commentStamp!
+I semantically analyze the abstract syntax tree and annotate it with informations such as non local returns and variable scopes.!
+
+!SemanticAnalyzer methodsFor: 'accessing'!
+
+classReferences
+	^ classReferences ifNil: [ classReferences := Set new ]
+!
+
+messageSends
+	^ messageSends ifNil: [ messageSends := Set new ]
+!
+
+pseudoVariables
+	^#('self' 'super' 'true' 'false' 'nil' 'thisContext')
+!
+
+theClass
+	^ theClass
+!
+
+theClass: aClass
+	theClass := aClass
+! !
+
+!SemanticAnalyzer methodsFor: 'error handling'!
+
+errorInvalidAssignment: aString
+	InvalidAssignmentError new
+		variableName: aString;
+		signal
+!
+
+errorShadowingVariable: aString
+	ShadowingVariableError new
+		variableName: aString;
+		signal
+!
+
+errorUnknownVariable: aNode
+	self allowUnknownVariables 
+		ifTrue: [ currentScope methodScope unknownVariables add: aNode value ]
+		ifFalse: [ 
+			UnknownVariableError new
+				variableName: aNode value;
+				signal ]
+! !
+
+!SemanticAnalyzer methodsFor: 'factory'!
+
+newBlockScope
+	^ self newScopeOfClass: LexicalScope
+!
+
+newMethodScope
+	^ self newScopeOfClass: MethodLexicalScope
+!
+
+newScopeOfClass: aLexicalScopeClass
+	^ aLexicalScopeClass new 
+		outerScope: currentScope;
+		yourself
+! !
+
+!SemanticAnalyzer methodsFor: 'scope'!
+
+popScope
+	currentScope ifNotNil: [
+		currentScope := currentScope outerScope ]
+!
+
+pushScope: aScope
+	aScope outerScope: currentScope.
+	currentScope := aScope
+!
+
+validateVariableScope: aString
+	"Validate the variable scope in by doing a recursive lookup, up to the method scope"
+
+	(currentScope lookupVariable: aString) ifNotNil: [
+		self errorShadowingVariable: aString ]
+! !
+
+!SemanticAnalyzer methodsFor: 'testing'!
+
+allowUnknownVariables
+	^ true
+! !
+
+!SemanticAnalyzer methodsFor: 'visiting'!
+
+visitAssignmentNode: aNode
+	(self pseudoVariables includes: aNode left value) ifTrue: [
+		self errorInvalidAssignment: aNode left ].
+	aNode left beAssigned.
+	aNode right beUsed.
+	super visitAssignmentNode: aNode
+!
+
+visitBlockNode: aNode
+	self pushScope: self newBlockScope.
+	aNode scope: currentScope.
+	
+	aNode parameters do: [ :each | 
+		self validateVariableScope: each.
+		currentScope addArg: each ].
+
+	super visitBlockNode: aNode.
+	self popScope
+!
+
+visitClassReferenceNode: aNode
+	self classReferences add: aNode value.
+	aNode binding: (ClassRefVar new name: aNode value; yourself)
+!
+
+visitMethodNode: aNode
+	self pushScope: self newMethodScope.
+	aNode scope: currentScope.
+
+	self theClass allInstanceVariableNames do: [:each | 
+		currentScope addIVar: each ].
+	aNode arguments do: [ :each | 
+		self validateVariableScope: each.
+		currentScope addArg: each ].
+
+	super visitMethodNode: aNode.
+
+	aNode 
+		classReferences: self classReferences;
+		messageSends: self messageSends.
+	self popScope
+!
+
+visitReturnNode: aNode
+	currentScope isMethodScope ifFalse: [
+		currentScope methodScope nonLocalReturn: true.
+		aNode nonLocalReturn: true ].
+	aNode nodes first beUsed.
+	super visitReturnNode: aNode
+!
+
+visitSendNode: aNode
+	self messageSends add: aNode selector.
+	aNode receiver beUsed.
+	aNode arguments do: [ :each |
+		each beUsed ].
+	super visitSendNode: aNode
+!
+
+visitSequenceNode: aNode
+	aNode temps do: [ :each | 
+		self validateVariableScope: each.
+		currentScope addTemp: each ].
+
+	super visitSequenceNode: aNode
+!
+
+visitVariableNode: aNode
+	"Bind a ScopeVar to aNode by doing a lookup in the current scope.
+	If no ScopeVar is found, bind a UnknowVar and throw an error"
+
+	aNode binding: ((currentScope lookupVariable: aNode) ifNil: [ 
+		self errorUnknownVariable: aNode.
+		UnknownVar new name: aNode value; yourself ])
+! !
+
+!SemanticAnalyzer class methodsFor: 'instance creation'!
+
+on: aClass
+	^ self new
+		theClass: aClass;
+		yourself
+! !
+
+Error subclass: #SemanticError
+	instanceVariableNames: ''
+	package: 'Compiler-Semantic'!
+!SemanticError commentStamp!
+I represent an abstract semantic error thrown by the SemanticAnalyzer.
+Semantic errors can be unknown variable errors, etc.
+See my subclasses for concrete errors.
+
+The IDE should catch instances of Semantic error to deal with them when compiling!
+
+SemanticError subclass: #InvalidAssignmentError
+	instanceVariableNames: 'variableName'
+	package: 'Compiler-Semantic'!
+!InvalidAssignmentError commentStamp!
+I get signaled when a pseudo variable gets assigned.!
+
+!InvalidAssignmentError methodsFor: 'accessing'!
+
+variableName
+	^ variableName
+!
+
+variableName: aString
+	variableName := aString
+! !
+
+SemanticError subclass: #ShadowingVariableError
+	instanceVariableNames: 'variableName'
+	package: 'Compiler-Semantic'!
+!ShadowingVariableError commentStamp!
+I get signaled when a variable in a block or method scope shadows a variable of the same name in an outer scope.!
+
+!ShadowingVariableError methodsFor: 'accessing'!
+
+variableName
+	^ variableName
+!
+
+variableName: aString
+	variableName := aString
+! !
+
+SemanticError subclass: #UnknownVariableError
+	instanceVariableNames: 'variableName'
+	package: 'Compiler-Semantic'!
+!UnknownVariableError commentStamp!
+I get signaled when a variable is not defined.
+The default behavior is to allow it, as this is how Amber currently is able to seamlessly send messages to JavaScript objects.!
+
+!UnknownVariableError methodsFor: 'accessing'!
+
+variableName
+	^ variableName
+!
+
+variableName: aString
+	variableName := aString
+! !
+

+ 1307 - 0
st/Compiler-Visitors.st

@@ -0,0 +1,1307 @@
+Smalltalk current createPackage: 'Compiler-Visitors' properties: #{}!
+NodeVisitor subclass: #AbstractCodeGenerator
+	instanceVariableNames: 'currentClass source'
+	package: 'Compiler-Visitors'!
+
+!AbstractCodeGenerator methodsFor: 'accessing'!
+
+classNameFor: aClass
+	^aClass isMetaclass
+	    ifTrue: [aClass instanceClass name, '.klass']
+	    ifFalse: [
+		aClass isNil
+		    ifTrue: ['nil']
+		    ifFalse: [aClass name]]
+!
+
+currentClass
+	^currentClass
+!
+
+currentClass: aClass
+	currentClass := aClass
+!
+
+pseudoVariables
+	^#('self' 'super' 'true' 'false' 'nil' 'thisContext')
+!
+
+safeVariableNameFor: aString
+	^(Smalltalk current reservedWords includes: aString)
+		ifTrue: [aString, '_']
+		ifFalse: [aString]
+!
+
+source
+	^source ifNil: ['']
+!
+
+source: aString
+	source := aString
+! !
+
+!AbstractCodeGenerator methodsFor: 'compiling'!
+
+compileNode: aNode
+	self subclassResponsibility
+! !
+
+AbstractCodeGenerator subclass: #CodeGenerator
+	instanceVariableNames: ''
+	package: 'Compiler-Visitors'!
+
+!CodeGenerator methodsFor: 'compiling'!
+
+compileNode: aNode
+	| ir stream |
+	self semanticAnalyzer visit: aNode.
+	ir := self translator visit: aNode; builder.
+	stream := JSStream new.
+	ir emitOn: stream.
+	^ stream contents
+!
+
+semanticAnalyzer
+	^ SemanticAnalyzer on: self currentClass
+!
+
+translator
+	^ IRASTResolver new
+		source: self source;
+		yourself
+! !
+
+AbstractCodeGenerator subclass: #FunCodeGenerator
+	instanceVariableNames: 'stream nestedBlocks earlyReturn currentSelector unknownVariables tempVariables messageSends referencedClasses classReferenced argVariables'
+	package: 'Compiler-Visitors'!
+
+!FunCodeGenerator methodsFor: 'accessing'!
+
+argVariables
+	^argVariables copy
+!
+
+knownVariables
+	^self pseudoVariables 
+		addAll: self tempVariables;
+		addAll: self argVariables;
+		yourself
+!
+
+tempVariables
+	^tempVariables copy
+!
+
+unknownVariables
+	^unknownVariables copy
+! !
+
+!FunCodeGenerator methodsFor: 'compiling'!
+
+compileNode: aNode
+	stream := '' writeStream.
+	self visit: aNode.
+	^stream contents
+! !
+
+!FunCodeGenerator methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+	stream := '' writeStream. 
+	unknownVariables := #().
+	tempVariables := #().
+	argVariables := #().
+	messageSends := #().
+	classReferenced := #()
+! !
+
+!FunCodeGenerator methodsFor: 'optimizations'!
+
+checkClass: aClassName for: receiver
+        stream nextPutAll: '((($receiver = ', receiver, ').klass === smalltalk.', aClassName, ') ? '
+!
+
+inline: aSelector receiver: receiver argumentNodes: aCollection
+        | inlined |
+        inlined := false.
+
+	"-- Booleans --"
+
+	(aSelector = 'ifFalse:') ifTrue: [
+		aCollection first isBlockNode ifTrue: [
+                	self checkClass: 'Boolean' for: receiver.
+                	stream nextPutAll: '(!! $receiver ? '.
+                	self visit: aCollection first.
+          		stream nextPutAll: '() : nil)'.
+                	inlined := true]].
+
+	(aSelector = 'ifTrue:') ifTrue: [
+		aCollection first isBlockNode ifTrue: [
+                	self checkClass: 'Boolean' for: receiver.
+                	stream nextPutAll: '($receiver ? '.
+                	self visit: aCollection first.
+          		stream nextPutAll: '() : nil)'.
+                	inlined := true]].
+
+	(aSelector = 'ifTrue:ifFalse:') ifTrue: [
+		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
+                	self checkClass: 'Boolean' for: receiver.
+                	stream nextPutAll: '($receiver ? '.
+                	self visit: aCollection first.
+          		stream nextPutAll: '() : '.
+          		self visit: aCollection second.
+          		stream nextPutAll: '())'.
+                	inlined := true]].
+
+	(aSelector = 'ifFalse:ifTrue:') ifTrue: [
+		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
+                	self checkClass: 'Boolean' for: receiver.
+                	stream nextPutAll: '(!! $receiver ? '.
+                	self visit: aCollection first.
+          		stream nextPutAll: '() : '.
+          		self visit: aCollection second.
+          		stream nextPutAll: '())'.
+                	inlined := true]].
+
+	"-- Numbers --"
+
+	(aSelector = '<') ifTrue: [
+                self checkClass: 'Number' for: receiver.
+                stream nextPutAll: '$receiver <'.
+                self visit: aCollection first.
+                inlined := true].
+
+	(aSelector = '<=') ifTrue: [
+                self checkClass: 'Number' for: receiver.
+                stream nextPutAll: '$receiver <='.
+                self visit: aCollection first.
+                inlined := true].
+
+	(aSelector = '>') ifTrue: [ 
+                self checkClass: 'Number' for: receiver.
+                stream nextPutAll: '$receiver >'.
+                self visit: aCollection first.
+                inlined := true].
+
+	(aSelector = '>=') ifTrue: [
+                self checkClass: 'Number' for: receiver.
+                stream nextPutAll: '$receiver >='.
+                self visit: aCollection first.
+                inlined := true].
+
+        (aSelector = '+') ifTrue: [
+                self checkClass: 'Number' for: receiver.
+                stream nextPutAll: '$receiver +'.
+                self visit: aCollection first.
+                inlined := true].
+
+        (aSelector = '-') ifTrue: [
+                self checkClass: 'Number' for: receiver.
+                stream nextPutAll: '$receiver -'.
+                self visit: aCollection first.
+                inlined := true].
+
+        (aSelector = '*') ifTrue: [
+                self checkClass: 'Number' for: receiver.
+                stream nextPutAll: '$receiver *'.
+                self visit: aCollection first.
+                inlined := true].
+
+        (aSelector = '/') ifTrue: [
+                self checkClass: 'Number' for: receiver.
+                stream nextPutAll: '$receiver /'.
+                self visit: aCollection first.
+                inlined := true].
+
+        ^inlined
+!
+
+inlineLiteral: aSelector receiverNode: anObject argumentNodes: aCollection
+        | inlined |
+        inlined := false.
+ 
+	"-- BlockClosures --"
+
+	(aSelector = 'whileTrue:') ifTrue: [
+          	(anObject isBlockNode and: [aCollection first isBlockNode]) ifTrue: [
+                	stream nextPutAll: '(function(){while('.
+                  	self visit: anObject.
+                  	stream nextPutAll: '()) {'.
+                	self visit: aCollection first.
+          		stream nextPutAll: '()}})()'.
+                	inlined := true]].
+
+	(aSelector = 'whileFalse:') ifTrue: [
+          	(anObject isBlockNode and: [aCollection first isBlockNode]) ifTrue: [
+                	stream nextPutAll: '(function(){while(!!'.
+                  	self visit: anObject.
+                  	stream nextPutAll: '()) {'.
+                	self visit: aCollection first.
+          		stream nextPutAll: '()}})()'.
+                	inlined := true]].
+
+	(aSelector = 'whileTrue') ifTrue: [
+          	anObject isBlockNode ifTrue: [
+                	stream nextPutAll: '(function(){while('.
+                  	self visit: anObject.
+                  	stream nextPutAll: '()) {}})()'.
+                	inlined := true]].
+
+	(aSelector = 'whileFalse') ifTrue: [
+          	anObject isBlockNode ifTrue: [
+                	stream nextPutAll: '(function(){while(!!'.
+                  	self visit: anObject.
+                  	stream nextPutAll: '()) {}})()'.
+                	inlined := true]].
+
+	"-- Numbers --"
+
+	(aSelector = '+') ifTrue: [
+          	(self isNode: anObject ofClass: Number) ifTrue: [
+                  	self visit: anObject.
+                  	stream nextPutAll: ' + '.
+                	self visit: aCollection first.
+                	inlined := true]].
+
+	(aSelector = '-') ifTrue: [
+          	(self isNode: anObject ofClass: Number) ifTrue: [
+                  	self visit: anObject.
+                  	stream nextPutAll: ' - '.
+                	self visit: aCollection first.
+                	inlined := true]].
+
+	(aSelector = '*') ifTrue: [
+          	(self isNode: anObject ofClass: Number) ifTrue: [
+                  	self visit: anObject.
+                  	stream nextPutAll: ' * '.
+                	self visit: aCollection first.
+                	inlined := true]].
+
+	(aSelector = '/') ifTrue: [
+          	(self isNode: anObject ofClass: Number) ifTrue: [
+                  	self visit: anObject.
+                  	stream nextPutAll: ' / '.
+                	self visit: aCollection first.
+                	inlined := true]].
+
+	(aSelector = '<') ifTrue: [
+          	(self isNode: anObject ofClass: Number) ifTrue: [
+                  	self visit: anObject.
+                  	stream nextPutAll: ' < '.
+                	self visit: aCollection first.
+                	inlined := true]].
+
+	(aSelector = '<=') ifTrue: [
+          	(self isNode: anObject ofClass: Number) ifTrue: [
+                  	self visit: anObject.
+                  	stream nextPutAll: ' <= '.
+                	self visit: aCollection first.
+                	inlined := true]].
+
+	(aSelector = '>') ifTrue: [
+          	(self isNode: anObject ofClass: Number) ifTrue: [
+                  	self visit: anObject.
+                  	stream nextPutAll: ' > '.
+                	self visit: aCollection first.
+                	inlined := true]].
+
+	(aSelector = '>=') ifTrue: [
+          	(self isNode: anObject ofClass: Number) ifTrue: [
+                  	self visit: anObject.
+                  	stream nextPutAll: ' >= '.
+                	self visit: aCollection first.
+                	inlined := true]].
+                	   
+	"-- UndefinedObject --"
+
+	(aSelector = 'ifNil:') ifTrue: [
+		aCollection first isBlockNode ifTrue: [
+          		stream nextPutAll: '(($receiver = '.
+          		self visit: anObject.
+          		stream nextPutAll: ') == nil || $receiver == undefined) ? '.
+                  	self visit: aCollection first.
+                  	stream nextPutAll: '() : $receiver'.
+                  	inlined := true]].
+
+	(aSelector = 'ifNotNil:') ifTrue: [
+		aCollection first isBlockNode ifTrue: [
+          		stream nextPutAll: '(($receiver = '.
+          		self visit: anObject.
+          		stream nextPutAll: ') !!= nil && $receiver !!= undefined) ? '.
+                  	self visit: aCollection first.
+                  	stream nextPutAll: '() : nil'.
+                  	inlined := true]].
+
+	(aSelector = 'ifNil:ifNotNil:') ifTrue: [
+		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
+          		stream nextPutAll: '(($receiver = '.
+          		self visit: anObject.
+          		stream nextPutAll: ') == nil || $receiver == undefined) ? '.
+                  	self visit: aCollection first.
+                  	stream nextPutAll: '() : '.
+                  	self visit: aCollection second.
+                  	stream nextPutAll: '()'.
+                  	inlined := true]].
+
+	(aSelector = 'ifNotNil:ifNil:') ifTrue: [
+		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
+          		stream nextPutAll: '(($receiver = '.
+          		self visit: anObject.
+          		stream nextPutAll: ') == nil || $receiver == undefined) ? '.
+                  	self visit: aCollection second.
+                  	stream nextPutAll: '() : '.
+                  	self visit: aCollection first.
+                  	stream nextPutAll: '()'.
+                  	inlined := true]].
+                 
+        ^inlined
+!
+
+isNode: aNode ofClass: aClass
+	^aNode isValueNode and: [
+          	aNode value class = aClass or: [
+          		aNode value = 'self' and: [self currentClass = aClass]]]
+! !
+
+!FunCodeGenerator methodsFor: 'testing'!
+
+performOptimizations
+	^self class performOptimizations
+! !
+
+!FunCodeGenerator methodsFor: 'visiting'!
+
+send: aSelector to: aReceiver arguments: aCollection superSend: aBoolean
+	^String streamContents: [:str || tmp |
+        	tmp := stream.
+		str nextPutAll: 'smalltalk.send('.
+		str nextPutAll: aReceiver.
+		str nextPutAll: ', "', aSelector asSelector, '", ['.
+                stream := str.
+		aCollection
+	    		do: [:each | self visit: each]
+	    		separatedBy: [stream nextPutAll: ', '].
+                stream := tmp.
+                str nextPutAll: ']'.
+		aBoolean ifTrue: [
+			str nextPutAll: ', smalltalk.', (self classNameFor: self currentClass), '.superclass || nil'].
+		str nextPutAll: ')']
+!
+
+visit: aNode
+	aNode accept: self
+!
+
+visitAssignmentNode: aNode
+	stream nextPutAll: '('.
+	self visit: aNode left.
+	stream nextPutAll: '='.
+	self visit: aNode right.
+	stream nextPutAll: ')'
+!
+
+visitBlockNode: aNode
+	stream nextPutAll: '(function('.
+	aNode parameters 
+	    do: [:each |
+		tempVariables add: each.
+		stream nextPutAll: each]
+	    separatedBy: [stream nextPutAll: ', '].
+	stream nextPutAll: '){'.
+	aNode nodes do: [:each | self visit: each].
+	stream nextPutAll: '})'
+!
+
+visitBlockSequenceNode: aNode
+	| index |
+	nestedBlocks := nestedBlocks + 1.
+	aNode nodes isEmpty
+	    ifTrue: [
+		stream nextPutAll: 'return nil;']
+	    ifFalse: [
+		aNode temps do: [:each | | temp |
+                    temp := self safeVariableNameFor: each.
+		    tempVariables add: temp.
+		    stream nextPutAll: 'var ', temp, '=nil;'; lf].
+		index := 0.
+		aNode nodes do: [:each |
+		    index := index + 1.
+		    index = aNode nodes size ifTrue: [
+			stream nextPutAll: 'return '].
+		    self visit: each.
+		    stream nextPutAll: ';']].
+	nestedBlocks := nestedBlocks - 1
+!
+
+visitCascadeNode: aNode
+	| index |
+	index := 0.
+	(tempVariables includes: '$rec') ifFalse: [
+		tempVariables add: '$rec'].
+	stream nextPutAll: '(function($rec){'.
+	aNode nodes do: [:each |
+	    index := index + 1.
+	    index = aNode nodes size ifTrue: [
+		stream nextPutAll: 'return '].
+	    each receiver: (VariableNode new value: '$rec').
+	    self visit: each.
+	    stream nextPutAll: ';'].
+	stream nextPutAll: '})('.
+	self visit: aNode receiver.
+	stream nextPutAll: ')'
+!
+
+visitClassReferenceNode: aNode
+	(referencedClasses includes: aNode value) ifFalse: [
+		referencedClasses add: aNode value].
+	stream nextPutAll: '(smalltalk.', aNode value, ' || ', aNode value, ')'
+!
+
+visitDynamicArrayNode: aNode
+	stream nextPutAll: '['.
+	aNode nodes 
+		do: [:each | self visit: each]
+		separatedBy: [stream nextPutAll: ','].
+	stream nextPutAll: ']'
+!
+
+visitDynamicDictionaryNode: aNode
+	stream nextPutAll: 'smalltalk.HashedCollection._fromPairs_(['.
+		aNode nodes 
+			do: [:each | self visit: each]
+			separatedBy: [stream nextPutAll: ','].
+		stream nextPutAll: '])'
+!
+
+visitFailure: aFailure
+	self error: aFailure asString
+!
+
+visitJSStatementNode: aNode
+	stream nextPutAll: aNode source
+!
+
+visitMethodNode: aNode
+	| str currentSelector | 
+	currentSelector := aNode selector asSelector.
+	nestedBlocks := 0.
+	earlyReturn := false.
+	messageSends := #().
+	referencedClasses := #().
+	unknownVariables := #().
+	tempVariables := #().
+	argVariables := #().
+	stream 
+	    nextPutAll: 'smalltalk.method({'; lf;
+	    nextPutAll: 'selector: "', aNode selector, '",'; lf.
+	stream nextPutAll: 'source: ', self source asJavascript, ',';lf.
+	stream nextPutAll: 'fn: function('.
+	aNode arguments 
+	    do: [:each | 
+		argVariables add: each.
+		stream nextPutAll: each]
+	    separatedBy: [stream nextPutAll: ', '].
+	stream 
+	    nextPutAll: '){'; lf;
+	    nextPutAll: 'var self=this;'; lf.
+	str := stream.
+	stream := '' writeStream.
+	aNode nodes do: [:each |
+	    self visit: each].
+	earlyReturn ifTrue: [
+	    str nextPutAll: 'var $early={};'; lf; nextPutAll: 'try{'].
+	str nextPutAll: stream contents.
+	stream := str.
+	stream 
+	    lf; 
+	    nextPutAll: 'return self;'.
+	earlyReturn ifTrue: [
+	    stream lf; nextPutAll: '} catch(e) {if(e===$early)return e[0]; throw e}'].
+	stream nextPutAll: '}'.
+	stream 
+		nextPutAll: ',', String lf, 'messageSends: ';
+		nextPutAll: messageSends asJavascript, ','; lf;
+          	nextPutAll: 'args: ', argVariables asJavascript, ','; lf;
+		nextPutAll: 'referencedClasses: ['.
+	referencedClasses 
+		do: [:each | stream nextPutAll: each printString]
+		separatedBy: [stream nextPutAll: ','].
+	stream nextPutAll: ']'.
+	stream nextPutAll: '})'
+!
+
+visitReturnNode: aNode
+	nestedBlocks > 0 ifTrue: [
+	    earlyReturn := true].
+	nestedBlocks > 0
+	    ifTrue: [
+		stream
+		    nextPutAll: '(function(){throw $early=[']
+	    ifFalse: [stream nextPutAll: 'return '].
+	aNode nodes do: [:each |
+	    self visit: each].
+	nestedBlocks > 0 ifTrue: [
+	    stream nextPutAll: ']})()']
+!
+
+visitSendNode: aNode
+        | str receiver superSend inlined |
+        str := stream.
+        (messageSends includes: aNode selector) ifFalse: [
+                messageSends add: aNode selector].
+        stream := '' writeStream.
+        self visit: aNode receiver.
+        superSend := stream contents = 'super'.
+        receiver := superSend ifTrue: ['self'] ifFalse: [stream contents].
+        stream := str.
+	
+	self performOptimizations 
+		ifTrue: [
+			(self inlineLiteral: aNode selector receiverNode: aNode receiver argumentNodes: aNode arguments) ifFalse: [
+				(self inline: aNode selector receiver: receiver argumentNodes: aNode arguments)
+                			ifTrue: [stream nextPutAll: ' : ', (self send: aNode selector to: '$receiver' arguments: aNode arguments superSend: superSend), ')']
+                			ifFalse: [stream nextPutAll: (self send: aNode selector to: receiver arguments: aNode arguments superSend: superSend)]]]
+		ifFalse: [stream nextPutAll: (self send: aNode selector to: receiver arguments: aNode arguments superSend: superSend)]
+!
+
+visitSequenceNode: aNode
+	aNode temps do: [:each || temp |
+            temp := self safeVariableNameFor: each.
+	    tempVariables add: temp.
+	    stream nextPutAll: 'var ', temp, '=nil;'; lf].
+	aNode nodes do: [:each |
+	    self visit: each.
+	    stream nextPutAll: ';']
+	    separatedBy: [stream lf]
+!
+
+visitValueNode: aNode
+	stream nextPutAll: aNode value asJavascript
+!
+
+visitVariableNode: aNode
+	| varName |
+	(self currentClass allInstanceVariableNames includes: aNode value) 
+		ifTrue: [stream nextPutAll: 'self[''@', aNode value, ''']']
+		ifFalse: [
+                  	varName := self safeVariableNameFor: aNode value.
+			(self knownVariables includes: varName) 
+                  		ifFalse: [
+                                  	unknownVariables add: aNode value.
+                                  	aNode assigned 
+                                  		ifTrue: [stream nextPutAll: varName]
+                                  		ifFalse: [stream nextPutAll: '(typeof ', varName, ' == ''undefined'' ? nil : ', varName, ')']]
+                  		ifTrue: [
+                                  	aNode value = 'thisContext'
+                                  		ifTrue: [stream nextPutAll: '(smalltalk.getThisContext())']
+                				ifFalse: [stream nextPutAll: varName]]]
+! !
+
+FunCodeGenerator class instanceVariableNames: 'performOptimizations'!
+
+!FunCodeGenerator class methodsFor: 'accessing'!
+
+performOptimizations
+	^performOptimizations ifNil: [true]
+!
+
+performOptimizations: aBoolean
+	performOptimizations := aBoolean
+! !
+
+AbstractCodeGenerator subclass: #ImpCodeGenerator
+	instanceVariableNames: 'stream nestedBlocks earlyReturn currentSelector unknownVariables tempVariables messageSends referencedClasses classReferenced argVariables mutables target lazyVars realVarNames'
+	package: 'Compiler-Visitors'!
+
+!ImpCodeGenerator methodsFor: 'accessing'!
+
+argVariables
+	^argVariables copy
+!
+
+knownVariables
+	^self pseudoVariables 
+		addAll: self tempVariables;
+		addAll: self argVariables;
+		yourself
+!
+
+tempVariables
+	^tempVariables copy
+!
+
+unknownVariables
+	^unknownVariables copy
+! !
+
+!ImpCodeGenerator methodsFor: 'compilation DSL'!
+
+aboutToModifyState
+| list old |
+	list := mutables.
+	mutables := Set new.
+	old := self switchTarget: nil.
+	list do: [ :each | | value |
+		self switchTarget: each.
+		self realAssign: (lazyVars at: each)
+	].
+	self switchTarget: old
+!
+
+ifValueWanted: aBlock
+	target ifNotNil: aBlock
+!
+
+isolated: node
+ 	^ self visit: node targetBeing: self nextLazyvarName
+!
+
+isolatedUse: node
+| old |
+	old := self switchTarget: self nextLazyvarName.
+	self visit: node.
+	^self useValueNamed: (self switchTarget: old)
+!
+
+lazyAssign: aString dependsOnState: aBoolean
+	(lazyVars includesKey: target)
+		ifTrue: [ lazyVars at: target put: aString. aBoolean ifTrue: [ mutables add: target ] ]
+		ifFalse: [ self realAssign: aString ]
+!
+
+lazyAssignExpression: aString
+	self lazyAssign: aString dependsOnState: true
+!
+
+lazyAssignValue: aString
+	self lazyAssign: aString dependsOnState: false
+!
+
+makeTargetRealVariable
+	(lazyVars includesKey: target) ifTrue: [
+		lazyVars removeKey: target.
+		lazyVars at: 'assigned ',target put: nil. "<-- only to retain size, it is used in nextLazyvarName"
+		realVarNames add: target ].
+!
+
+nextLazyvarName
+	| name |
+	name := '$', lazyVars size asString.
+	lazyVars at: name put: name.
+	^name
+!
+
+nilIfValueWanted
+	target ifNotNil: [ self lazyAssignValue: 'nil' ]
+!
+
+realAssign: aString
+	| closer |
+	aString ifNotEmpty: [
+		self aboutToModifyState.
+		closer := ''.
+		self ifValueWanted: [ stream nextPutAll:
+			(target = '^' ifTrue: ['return '] ifFalse: [
+				target = '!!' ifTrue: [ closer := ']'. 'throw $early=['] ifFalse: [
+					target, '=']]) ].
+		self makeTargetRealVariable.
+		stream nextPutAll: aString, closer, ';', self mylf ]
+!
+
+switchTarget: aString
+	| old |
+	old := target.
+	target := aString.
+	^old
+!
+
+useValueNamed: key
+	| val |
+	(realVarNames includes: key) ifTrue: [ ^key ].
+	mutables remove: key.
+	^lazyVars at: key
+!
+
+visit: aNode targetBeing: aString
+| old |
+	old := self switchTarget: aString.
+	self visit: aNode.
+	^ self switchTarget: old.
+! !
+
+!ImpCodeGenerator methodsFor: 'compiling'!
+
+compileNode: aNode
+	stream := '' writeStream.
+	self visit: aNode.
+	^stream contents
+! !
+
+!ImpCodeGenerator methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+	stream := '' writeStream. 
+	unknownVariables := #().
+	tempVariables := #().
+	argVariables := #().
+	messageSends := #().
+	classReferenced := #().
+	mutables := Set new.
+	realVarNames := Set new.
+	lazyVars := HashedCollection new.
+	target := nil
+! !
+
+!ImpCodeGenerator methodsFor: 'optimizations'!
+
+checkClass: aClassName for: receiver
+	self prvCheckClass: aClassName for: receiver.
+	stream nextPutAll: '{'
+!
+
+checkClass: aClassName for: receiver includeIf: aBoolean
+	self prvCheckClass: aClassName for: receiver.
+	stream nextPutAll: (aBoolean ifTrue: ['if(('] ifFalse: ['if(!!(']), (self useValueNamed: receiver), ')) {'
+!
+
+inline: aSelector receiver: receiver argumentNodes: aCollection
+
+	"-- Booleans --"
+
+	(aSelector = 'ifFalse:') ifTrue: [
+		aCollection first isBlockNode ifTrue: [
+			self checkClass: 'Boolean' for: receiver includeIf: false.
+			self prvPutAndElse: [ self visit: aCollection first nodes first ].
+			self prvPutAndElse: [ self nilIfValueWanted ].
+			^true]].
+
+	(aSelector = 'ifTrue:') ifTrue: [
+		aCollection first isBlockNode ifTrue: [
+			self checkClass: 'Boolean' for: receiver includeIf: true.
+			self prvPutAndElse: [ self visit: aCollection first nodes first ].
+			self prvPutAndElse: [ self nilIfValueWanted ].
+			^true]].
+
+	(aSelector = 'ifTrue:ifFalse:') ifTrue: [
+		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
+			self checkClass: 'Boolean' for: receiver includeIf: true.
+			self prvPutAndElse: [ self visit: aCollection first nodes first ].
+			self prvPutAndElse: [ self visit: aCollection second nodes first ].
+			^true]].
+
+	(aSelector = 'ifFalse:ifTrue:') ifTrue: [
+		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
+			self checkClass: 'Boolean' for: receiver includeIf: false.
+			self prvPutAndElse: [ self visit: aCollection first nodes first ].
+			self prvPutAndElse: [ self visit: aCollection second nodes first ].
+			^true]].
+
+	"-- Numbers --"
+
+	(aSelector = '<') ifTrue: [ | operand |
+		operand := self isolatedUse: aCollection first.
+		self checkClass: 'Number' for: receiver.
+		self prvPutAndElse: [
+			self lazyAssignExpression: '(', (self useValueNamed: receiver), '<', operand, ')' ].
+		^{ VerbatimNode new value: operand }].
+
+	(aSelector = '<=') ifTrue: [ | operand |
+		operand := self isolatedUse: aCollection first.
+		self checkClass: 'Number' for: receiver.
+		self prvPutAndElse: [
+			self lazyAssignExpression: '(', (self useValueNamed: receiver), '<=', operand, ')' ].
+		^{ VerbatimNode new value: operand }].
+
+	(aSelector = '>') ifTrue: [ | operand |
+		operand := self isolatedUse: aCollection first.
+		self checkClass: 'Number' for: receiver.
+		self prvPutAndElse: [
+			self lazyAssignExpression: '(', (self useValueNamed: receiver), '>', operand, ')' ].
+		^{ VerbatimNode new value: operand }].
+
+	(aSelector = '>=') ifTrue: [ | operand |
+		operand := self isolatedUse: aCollection first.
+		self checkClass: 'Number' for: receiver.
+		self prvPutAndElse: [
+			self lazyAssignExpression: '(', (self useValueNamed: receiver), '>=', operand, ')' ].
+		^{ VerbatimNode new value: operand }].
+
+        (aSelector = '+') ifTrue: [ | operand |
+		operand := self isolatedUse: aCollection first.
+		self checkClass: 'Number' for: receiver.
+		self prvPutAndElse: [
+			self lazyAssignExpression: '(', (self useValueNamed: receiver), '+', operand, ')' ].
+		^{ VerbatimNode new value: operand }].
+
+        (aSelector = '-') ifTrue: [ | operand |
+		operand := self isolatedUse: aCollection first.
+		self checkClass: 'Number' for: receiver.
+		self prvPutAndElse: [
+			self lazyAssignExpression: '(', (self useValueNamed: receiver), '-', operand, ')' ].
+		^{ VerbatimNode new value: operand }].
+
+        (aSelector = '*') ifTrue: [ | operand |
+		operand := self isolatedUse: aCollection first.
+		self checkClass: 'Number' for: receiver.
+		self prvPutAndElse: [
+			self lazyAssignExpression: '(', (self useValueNamed: receiver), '*', operand, ')' ].
+		^{ VerbatimNode new value: operand }].
+
+        (aSelector = '/') ifTrue: [ | operand |
+		operand := self isolatedUse: aCollection first.
+		self checkClass: 'Number' for: receiver.
+		self prvPutAndElse: [
+			self lazyAssignExpression: '(', (self useValueNamed: receiver), '/', operand, ')' ].
+		^{ VerbatimNode new value: operand }].
+
+        ^nil
+!
+
+inlineLiteral: aSelector receiverNode: anObject argumentNodes: aCollection
+        | inlined |
+        inlined := false.
+ 
+	"-- BlockClosures --"
+
+	(aSelector = 'whileTrue:') ifTrue: [
+          	(anObject isBlockNode and: [aCollection first isBlockNode]) ifTrue: [ | old |
+			self prvWhileConditionStatement: 'for(;;){' pre: 'if (!!(' condition: anObject post: ')) {'.
+			stream nextPutAll: 'break}', self mylf.
+			self prvPutAndClose: [ self visit: aCollection first nodes first targetBeing: nil ].
+			inlined := true]].
+
+	(aSelector = 'whileFalse:') ifTrue: [
+          	(anObject isBlockNode and: [aCollection first isBlockNode]) ifTrue: [ | old |
+			self prvWhileConditionStatement: 'for(;;){' pre: 'if ((' condition: anObject post: ')) {'.
+			stream nextPutAll: 'break}', self mylf.
+			self prvPutAndClose: [ self visit: aCollection first nodes first targetBeing: nil ].
+			inlined := true]].
+
+	(aSelector = 'whileTrue') ifTrue: [
+          	anObject isBlockNode ifTrue: [
+			self prvWhileConditionStatement: 'do{' pre: '}while((' condition: anObject post: '));', self mylf.
+			inlined := true]].
+
+	(aSelector = 'whileFalse') ifTrue: [
+          	anObject isBlockNode ifTrue: [
+			self prvWhileConditionStatement: 'do{' pre: '}while(!!(' condition: anObject post: '));', self mylf.
+			inlined := true]].
+
+	"-- Numbers --"
+
+	(#('+' '-' '*' '/' '<' '<=' '>=' '>') includes: aSelector) ifTrue: [
+		(self prvInlineNumberOperator: aSelector on: anObject and: aCollection first) ifTrue: [
+			inlined := true]].
+                	   
+	"-- UndefinedObject --"
+
+	(aSelector = 'ifNil:') ifTrue: [
+		aCollection first isBlockNode ifTrue: [ | rcv |
+			self aboutToModifyState.
+			rcv := self isolatedUse: anObject.
+			rcv = 'super' ifTrue: [ rcv := 'self' ].
+			self makeTargetRealVariable.
+			stream nextPutAll: 'if((', rcv, ') === nil || (', rcv, ') == null) {'.
+			self prvPutAndElse: [ self visit: aCollection first nodes first ].
+			self prvPutAndClose: [ self lazyAssignValue: rcv ].
+			inlined := true]].
+
+	(aSelector = 'ifNotNil:') ifTrue: [
+		aCollection first isBlockNode ifTrue: [ | rcv |
+			self aboutToModifyState.
+			rcv := self isolatedUse: anObject.
+			rcv = 'super' ifTrue: [ rcv := 'self' ].
+			self makeTargetRealVariable.
+			stream nextPutAll: 'if((', rcv, ') !!== nil && (', rcv, ') !!= null) {'.
+			self prvPutAndElse: [ self visit: aCollection first nodes first ].
+			self prvPutAndClose: [ self lazyAssignValue: rcv ].
+			inlined := true]].
+
+	(aSelector = 'ifNil:ifNotNil:') ifTrue: [
+		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [ | rcv |
+			self aboutToModifyState.
+			rcv := self isolatedUse: anObject.
+			rcv = 'super' ifTrue: [ rcv := 'self' ].
+			self makeTargetRealVariable.
+			stream nextPutAll: 'if((', rcv, ') === nil || (', rcv, ') == null) {'.
+			self prvPutAndElse: [ self visit: aCollection first nodes first ].
+			self prvPutAndClose: [ self visit: aCollection second nodes first ].
+			inlined := true]].
+
+	(aSelector = 'ifNotNil:ifNil:') ifTrue: [
+		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [ | rcv |
+			self aboutToModifyState.
+			rcv := self isolatedUse: anObject.
+			rcv = 'super' ifTrue: [ rcv := 'self' ].
+			self makeTargetRealVariable.
+			stream nextPutAll: 'if((', rcv, ') !!== nil && (', rcv, ') !!= null) {'.
+			self prvPutAndElse: [ self visit: aCollection first nodes first ].
+			self prvPutAndClose: [ self visit: aCollection second nodes first ].
+			inlined := true]].
+
+	(aSelector = 'isNil') ifTrue: [ | rcv |
+		rcv := self isolatedUse: anObject.
+		rcv = 'super' ifTrue: [ rcv := 'self' ].
+		self lazyAssignValue: '((', rcv, ') === nil || (', rcv, ') == null)'.
+		inlined := true].
+
+	(aSelector = 'notNil') ifTrue: [ | rcv |
+		rcv := self isolatedUse: anObject.
+		rcv = 'super' ifTrue: [ rcv := 'self' ].
+		self lazyAssignValue: '((', rcv, ') !!== nil && (', rcv, ') !!= null)'.
+		inlined := true].
+
+        ^inlined
+!
+
+isNode: aNode ofClass: aClass
+	^aNode isValueNode and: [
+          	aNode value class = aClass or: [
+          		aNode value = 'self' and: [self currentClass = aClass]]]
+!
+
+prvCheckClass: aClassName for: receiver
+	self makeTargetRealVariable.
+	self aboutToModifyState.
+        stream nextPutAll: 'if((', (self useValueNamed: receiver), ').klass === smalltalk.', aClassName, ') '
+!
+
+prvInlineNumberOperator: aSelector on: receiverNode and: operandNode
+	(aSelector = aSelector) ifTrue: [
+		(self isNode: receiverNode ofClass: Number) ifTrue: [
+			| rcv operand |
+			rcv := self isolated: receiverNode.
+			operand := self isolated: operandNode.
+			self lazyAssignValue: ((self useValueNamed: rcv), aSelector, (self useValueNamed: operand)).
+			^true]].
+	^false
+!
+
+prvWhileConditionStatement: stmtString pre: preString condition: anObject post: postString
+	| x |
+	stream nextPutAll: stmtString.
+	x := self isolatedUse: anObject nodes first.
+	x ifEmpty: [ x := '"should not reach - receiver includes ^"' ].
+	stream nextPutAll: preString, x, postString.
+	self nilIfValueWanted
+! !
+
+!ImpCodeGenerator methodsFor: 'output'!
+
+mylf
+	^String lf, ((Array new: nestedBlocks+2)  join: String tab)
+!
+
+prvPutAndClose: aBlock
+
+	aBlock value.
+	stream nextPutAll: '}', self mylf
+!
+
+prvPutAndElse: aBlock
+
+	aBlock value.
+	stream nextPutAll: '} else {'
+!
+
+putTemps: temps
+    temps ifNotEmpty: [
+	stream nextPutAll: 'var '.
+	temps do: [:each | | temp |
+            temp := self safeVariableNameFor: each.
+	    tempVariables add: temp.
+	    stream nextPutAll: temp, '=nil'] separatedBy: [ stream nextPutAll: ',' ].
+	stream nextPutAll: ';', self mylf
+    ]
+! !
+
+!ImpCodeGenerator methodsFor: 'testing'!
+
+assert: aBoolean
+	aBoolean ifFalse: [ self error: 'assertion failed' ]
+!
+
+performOptimizations
+	^self class performOptimizations
+! !
+
+!ImpCodeGenerator methodsFor: 'visiting'!
+
+send: aSelector to: aReceiver arguments: aCollection superSend: aBoolean
+	| args |
+	args := self isolated: (DynamicArrayNode new nodes: aCollection; yourself).
+	self lazyAssignExpression: (String streamContents: [ :str |
+		str nextPutAll: 'smalltalk.send('.
+		str nextPutAll: (self useValueNamed: aReceiver).
+		str nextPutAll: ', "', aSelector asSelector, '", '.
+		str nextPutAll: (self useValueNamed: args).
+		aBoolean ifTrue: [
+			str nextPutAll: ', smalltalk.', (self classNameFor: self currentClass superclass)].
+		str nextPutAll: ')'
+	])
+!
+
+sequenceOfNodes: nodes temps: temps
+	nodes isEmpty
+		ifFalse: [ | old index |
+			self putTemps: temps.
+			old :=self switchTarget: nil.
+			index := 0.
+			nodes do: [:each |
+				index := index + 1.
+				index = nodes size ifTrue: [ self switchTarget: old ].
+			self visit: each ]]
+		ifTrue: [ self nilIfValueWanted ]
+!
+
+visit: aNode
+	aNode accept: self
+!
+
+visitAssignmentNode: aNode
+| olds oldt |
+	olds := stream.
+	stream := '' writeStream.
+	oldt := self switchTarget: self nextLazyvarName.
+	self visit: aNode left.
+	self assert: (lazyVars at: target) ~= target.
+	self switchTarget: (self useValueNamed: (self switchTarget: nil)).
+	self assert: (lazyVars includesKey: target) not.
+	stream := olds.
+	self visit: aNode right.
+	olds := self switchTarget: oldt.
+	self ifValueWanted: [ self lazyAssignExpression: olds ]
+!
+
+visitBlockNode: aNode
+| oldt olds oldm |
+	self assert: aNode nodes size = 1.
+	oldt := self switchTarget: '^'.
+	olds := stream.
+	stream := '' writeStream.
+	stream nextPutAll: '(function('.
+	aNode parameters 
+	    do: [:each |
+		tempVariables add: each.
+		stream nextPutAll: each]
+	    separatedBy: [stream nextPutAll: ', '].
+	stream nextPutAll: '){'.
+	nestedBlocks := nestedBlocks + 1.
+	oldm := mutables.
+	mutables := Set new.
+	self visit: aNode nodes first.
+	self assert: mutables isEmpty.
+	mutables := oldm.
+	nestedBlocks := nestedBlocks - 1.
+	stream nextPutAll: '})'.
+	self switchTarget: oldt.
+	oldt := stream contents.
+	stream := olds.
+	self lazyAssignExpression: oldt
+!
+
+visitBlockSequenceNode: aNode
+	self sequenceOfNodes: aNode nodes temps: aNode temps
+!
+
+visitCascadeNode: aNode
+	| rcv |
+	rcv := self isolated: aNode receiver.
+	self aboutToModifyState.
+	rcv := self useValueNamed: rcv.
+	aNode nodes do: [:each |
+		each receiver: (VerbatimNode new value: rcv) ].
+	self sequenceOfNodes: aNode nodes temps: #()
+!
+
+visitClassReferenceNode: aNode
+	(referencedClasses includes: aNode value) ifFalse: [
+		referencedClasses add: aNode value].
+	self lazyAssignExpression: '(smalltalk.', aNode value, ' || ', aNode value, ')'
+!
+
+visitDynamicArrayNode: aNode
+	| args |
+	args :=aNode nodes collect: [ :node | self isolated: node ].
+	self lazyAssignValue: (String streamContents: [ :str |
+		str nextPutAll: '['.
+		args
+	    		do: [:each | str nextPutAll: (self useValueNamed: each) ]
+	    		separatedBy: [str nextPutAll: ', '].
+                str nextPutAll: ']'
+	])
+!
+
+visitDynamicDictionaryNode: aNode
+	| elements |
+	elements := self isolated: (DynamicArrayNode new nodes: aNode nodes; yourself).
+	self lazyAssignValue: 'smalltalk.HashedCollection._fromPairs_(', (self useValueNamed: elements), ')'
+!
+
+visitFailure: aFailure
+	self error: aFailure asString
+!
+
+visitJSStatementNode: aNode
+	self aboutToModifyState.
+	stream nextPutAll: ';', (aNode source replace: '>>' with: '>'), ';', self mylf
+!
+
+visitMethodNode: aNode
+	| str currentSelector | 
+	currentSelector := aNode selector asSelector.
+	nestedBlocks := 0.
+	earlyReturn := false.
+	messageSends := #().
+	referencedClasses := #().
+	unknownVariables := #().
+	tempVariables := #().
+	argVariables := #().
+	lazyVars := HashedCollection new.
+	mutables := Set new.
+	realVarNames := Set new.
+	stream 
+	    nextPutAll: 'smalltalk.method({'; lf;
+	    nextPutAll: 'selector: "', aNode selector, '",'; lf.
+	stream nextPutAll: 'source: ', self source asJavascript, ',';lf.
+	stream nextPutAll: 'fn: function('.
+	aNode arguments 
+	    do: [:each | 
+		argVariables add: each.
+		stream nextPutAll: each]
+	    separatedBy: [stream nextPutAll: ', '].
+	stream 
+	    nextPutAll: '){var self=this;', self mylf.
+	str := stream.
+	stream := '' writeStream.
+	self switchTarget: nil.
+	self assert: aNode nodes size = 1.
+	self visit: aNode nodes first.
+	realVarNames ifNotEmpty: [ str nextPutAll: 'var ', (realVarNames asArray join: ','), ';', self mylf ].
+	earlyReturn ifTrue: [
+	    str nextPutAll: 'var $early={}; try{', self mylf].
+	str nextPutAll: stream contents.
+	stream := str.
+	(aNode nodes first nodes notEmpty and: [ |checker|
+	    checker := ReturnNodeChecker new.
+	    checker visit: aNode nodes first nodes last.
+	    checker wasReturnNode]) ifFalse: [ self switchTarget: '^'. self lazyAssignValue: 'self'. self switchTarget: nil ].
+	earlyReturn ifTrue: [
+	    stream nextPutAll: '} catch(e) {if(e===$early) return e[0]; throw e}'].
+	stream nextPutAll: '}'.
+	stream 
+		nextPutAll: ',', String lf, 'messageSends: ';
+		nextPutAll: messageSends asJavascript, ','; lf;
+          	nextPutAll: 'args: ', argVariables asJavascript, ','; lf;
+		nextPutAll: 'referencedClasses: ['.
+	referencedClasses 
+		do: [:each | stream nextPutAll: each printString]
+		separatedBy: [stream nextPutAll: ','].
+	stream nextPutAll: ']'.
+	stream nextPutAll: '})'.
+	self assert: mutables isEmpty
+!
+
+visitReturnNode: aNode
+	self assert: aNode nodes size = 1.
+	nestedBlocks > 0 ifTrue: [
+	    earlyReturn := true].
+	self
+		visit: aNode nodes first
+		targetBeing: (nestedBlocks > 0 ifTrue: ['!!'] ifFalse: ['^']).
+	self lazyAssignValue: ''
+!
+
+visitSendNode: aNode
+        | receiver superSend rcv |
+        (messageSends includes: aNode selector) ifFalse: [
+                messageSends add: aNode selector].
+	
+	self performOptimizations 
+		ifTrue: [
+			(self inlineLiteral: aNode selector receiverNode: aNode receiver argumentNodes: aNode arguments) ifTrue: [ ^self ].
+		].
+
+	rcv := self isolated: aNode receiver.
+        superSend := (lazyVars at: rcv ifAbsent: []) = 'super'.
+        superSend ifTrue: [ mutables remove: rcv. lazyVars at: rcv put: 'self' ].
+
+	self performOptimizations 
+		ifTrue: [ | inline |
+			inline := self inline: aNode selector receiver: rcv argumentNodes: aNode arguments.
+			inline ifNotNil: [ | args |
+				args := inline = true ifTrue: [ aNode arguments ] ifFalse: [ inline ].
+				self prvPutAndClose: [ self send: aNode selector to: rcv arguments: args superSend: superSend ].
+				^self ]].
+	self send: aNode selector to: rcv arguments: aNode arguments superSend: superSend
+!
+
+visitSequenceNode: aNode
+	aNode nodes isEmpty ifFalse: [
+		self sequenceOfNodes: aNode nodes temps: aNode temps ]
+!
+
+visitValueNode: aNode
+	self lazyAssignValue: aNode value asJavascript
+!
+
+visitVariableNode: aNode
+	| varName |
+	(self currentClass allInstanceVariableNames includes: aNode value) 
+		ifTrue: [self lazyAssignExpression: 'self[''@', aNode value, ''']']
+		ifFalse: [
+                  	varName := self safeVariableNameFor: aNode value.
+			(self knownVariables includes: varName) 
+                  		ifFalse: [
+                                  	unknownVariables add: aNode value.
+                                  	aNode assigned 
+                                  		ifTrue: [self lazyAssignExpression: varName]
+                                  		ifFalse: [self lazyAssignExpression: '(typeof ', varName, ' == ''undefined'' ? nil : ', varName, ')']]
+                  		ifTrue: [
+                                  	aNode value = 'thisContext'
+                                  		ifTrue: [self lazyAssignExpression: '(smalltalk.getThisContext())']
+                				ifFalse: [(self pseudoVariables includes: varName)
+							ifTrue: [ self lazyAssignValue: varName ]
+							ifFalse: [ self lazyAssignExpression: varName]]]]
+!
+
+visitVerbatimNode: aNode
+	self lazyAssignValue: aNode value
+! !
+
+ImpCodeGenerator class instanceVariableNames: 'performOptimizations'!
+
+!ImpCodeGenerator class methodsFor: 'accessing'!
+
+performOptimizations
+	^performOptimizations ifNil: [true]
+!
+
+performOptimizations: aBoolean
+	performOptimizations := aBoolean
+! !
+
+NodeVisitor subclass: #ReturnNodeChecker
+	instanceVariableNames: 'wasReturnNode'
+	package: 'Compiler-Visitors'!
+
+!ReturnNodeChecker methodsFor: 'accessing'!
+
+wasReturnNode
+	^wasReturnNode
+! !
+
+!ReturnNodeChecker methodsFor: 'initializing'!
+
+initialize
+	wasReturnNode := false
+! !
+
+!ReturnNodeChecker methodsFor: 'visiting'!
+
+visitReturnNode: aNode
+	wasReturnNode := true
+! !
+

+ 343 - 0
st/Importer-Exporter.st

@@ -0,0 +1,343 @@
+Smalltalk current createPackage: 'Importer-Exporter' properties: #{}!
+Object subclass: #ChunkParser
+	instanceVariableNames: 'stream'
+	package: 'Importer-Exporter'!
+
+!ChunkParser methodsFor: 'accessing'!
+
+stream: aStream
+	stream := aStream
+! !
+
+!ChunkParser methodsFor: 'reading'!
+
+nextChunk
+	"The chunk format (Smalltalk Interchange Format or Fileout format)
+	is a trivial format but can be a bit tricky to understand:
+		- Uses the exclamation mark as delimiter of chunks.
+		- Inside a chunk a normal exclamation mark must be doubled.
+		- A non empty chunk must be a valid Smalltalk expression.
+		- A chunk on top level with a preceding empty chunk is an instruction chunk:
+			- The object created by the expression then takes over reading chunks.
+
+	This metod returns next chunk as a String (trimmed), empty String (all whitespace) or nil."
+
+	| char result chunk |
+	result := '' writeStream.
+        [char := stream next.
+        char notNil] whileTrue: [
+                 char = '!!' ifTrue: [
+                         stream peek = '!!'
+                                ifTrue: [stream next "skipping the escape double"]
+                                ifFalse: [^result contents trimBoth  "chunk end marker found"]].
+                 result nextPut: char].
+	^nil "a chunk needs to end with !!"
+! !
+
+!ChunkParser class methodsFor: 'not yet classified'!
+
+on: aStream
+	^self new stream: aStream
+! !
+
+Object subclass: #Exporter
+	instanceVariableNames: ''
+	package: 'Importer-Exporter'!
+
+!Exporter methodsFor: 'fileOut'!
+
+exportAll
+    "Export all packages in the system."
+
+    ^String streamContents: [:stream |
+    	Smalltalk current packages do: [:pkg |
+		stream nextPutAll: (self exportPackage: pkg name)]]
+!
+
+exportClass: aClass
+	"Export a single class. Subclasses override these methods."
+
+	^String streamContents: [:stream |
+		self exportDefinitionOf: aClass on: stream.
+		self exportMethodsOf: aClass on: stream.
+		self exportMetaDefinitionOf: aClass on: stream.
+		self exportMethodsOf: aClass class on: stream]
+!
+
+exportPackage: packageName
+	"Export a given package by name."
+
+	| package |
+	^String streamContents: [:stream |
+                package := Smalltalk current packageAt: packageName.
+                self exportPackageDefinitionOf: package on: stream.
+
+		"Export classes in dependency order.
+		Update (issue #171): Remove duplicates for export"
+	    	package sortedClasses asSet do: [:each |
+                        stream nextPutAll: (self exportClass: each)].
+		self exportPackageExtensionsOf: package on: stream]
+! !
+
+!Exporter methodsFor: 'private'!
+
+classNameFor: aClass
+	^aClass isMetaclass
+	    ifTrue: [aClass instanceClass name, '.klass']
+	    ifFalse: [
+		aClass isNil
+		    ifTrue: ['nil']
+		    ifFalse: [aClass name]]
+!
+
+exportDefinitionOf: aClass on: aStream
+	aStream 
+	    nextPutAll: 'smalltalk.addClass(';
+	    nextPutAll: '''', (self classNameFor: aClass), ''', ';
+	    nextPutAll: 'smalltalk.', (self classNameFor: aClass superclass);
+	    nextPutAll: ', ['.
+	aClass instanceVariableNames 
+	    do: [:each | aStream nextPutAll: '''', each, '''']
+	    separatedBy: [aStream nextPutAll: ', '].
+	aStream	
+	    nextPutAll: '], ''';
+	    nextPutAll: aClass category, '''';
+	    nextPutAll: ');'.
+	aClass comment notEmpty ifTrue: [
+	    aStream 
+	    	lf;
+		nextPutAll: 'smalltalk.';
+		nextPutAll: (self classNameFor: aClass);
+		nextPutAll: '.comment=';
+		nextPutAll: aClass comment asJavascript].
+	aStream lf
+!
+
+exportMetaDefinitionOf: aClass on: aStream
+	aClass class instanceVariableNames isEmpty ifFalse: [
+	    aStream 
+		nextPutAll: 'smalltalk.', (self classNameFor: aClass class);
+		nextPutAll: '.iVarNames = ['.
+	    aClass class instanceVariableNames
+		do: [:each | aStream nextPutAll: '''', each, '''']
+		separatedBy: [aStream nextPutAll: ','].
+	    aStream nextPutAll: '];', String lf]
+!
+
+exportMethod: aMethod of: aClass on: aStream
+	aStream 
+		nextPutAll: 'smalltalk.addMethod(';lf;
+		nextPutAll: aMethod selector asSelector asJavascript, ',';lf;
+		nextPutAll: 'smalltalk.method({';lf;
+		nextPutAll: 'selector: ', aMethod selector asJavascript, ',';lf;
+		nextPutAll: 'category: ''', aMethod category, ''',';lf;
+		nextPutAll: 'fn: ', aMethod fn compiledSource, ',';lf;
+		nextPutAll: 'args: ', aMethod arguments asJavascript, ','; lf;
+		nextPutAll: 'source: ', aMethod source asJavascript, ',';lf;
+		nextPutAll: 'messageSends: ', aMethod messageSends asJavascript, ',';lf;
+		nextPutAll: 'referencedClasses: ', aMethod referencedClasses asJavascript.
+	aStream
+		lf;
+		nextPutAll: '}),';lf;
+		nextPutAll: 'smalltalk.', (self classNameFor: aClass);
+		nextPutAll: ');';lf;lf
+!
+
+exportMethodsOf: aClass on: aStream
+	"Issue #143: sort methods alphabetically"
+
+	((aClass methodDictionary values) sorted: [:a :b | a selector <= b selector]) do: [:each |
+		(each category match: '^\*') ifFalse: [
+			self exportMethod: each of: aClass on: aStream]].
+	aStream lf
+!
+
+exportPackageDefinitionOf: package on: aStream
+	aStream 
+	    nextPutAll: 'smalltalk.addPackage(';
+	    nextPutAll: '''', package name, ''', ', package propertiesAsJSON , ');'.
+	aStream lf
+!
+
+exportPackageExtensionsOf: package on: aStream
+	"Issue #143: sort classes and methods alphabetically"
+
+	| name |
+	name := package name.
+	(Package sortedClasses: Smalltalk current classes) do: [:each |
+		{each. each class} do: [:aClass | 
+			((aClass methodDictionary values) sorted: [:a :b | a selector <= b selector]) do: [:method |
+				(method category match: '^\*', name) ifTrue: [
+					self exportMethod: method of: aClass on: aStream ]]]]
+! !
+
+Exporter subclass: #ChunkExporter
+	instanceVariableNames: ''
+	package: 'Importer-Exporter'!
+
+!ChunkExporter methodsFor: 'not yet classified'!
+
+chunkEscape: aString
+	"Replace all occurrences of !! with !!!! and trim at both ends."
+
+	^(aString replace: '!!' with: '!!!!') trimBoth
+!
+
+classNameFor: aClass
+	^aClass isMetaclass
+	    ifTrue: [aClass instanceClass name, ' class']
+	    ifFalse: [
+		aClass isNil
+		    ifTrue: ['nil']
+		    ifFalse: [aClass name]]
+!
+
+exportDefinitionOf: aClass on: aStream
+    "Chunk format."
+
+    aStream 
+        nextPutAll: (self classNameFor: aClass superclass);
+        nextPutAll: ' subclass: #', (self classNameFor: aClass); lf;
+        nextPutAll: '	instanceVariableNames: '''.
+    aClass instanceVariableNames 
+        do: [:each | aStream nextPutAll: each]
+        separatedBy: [aStream nextPutAll: ' '].
+    aStream 
+        nextPutAll: ''''; lf;
+        nextPutAll: '	package: ''', aClass category, '''!!'; lf.
+    aClass comment notEmpty ifTrue: [
+        aStream 
+        nextPutAll: '!!', (self classNameFor: aClass), ' commentStamp!!';lf;
+        nextPutAll: (self chunkEscape: aClass comment), '!!';lf].
+    aStream lf
+!
+
+exportMetaDefinitionOf: aClass on: aStream
+
+	aClass class instanceVariableNames isEmpty ifFalse: [
+		aStream 
+		    nextPutAll: (self classNameFor: aClass class);
+		    nextPutAll: ' instanceVariableNames: '''.
+		aClass class instanceVariableNames 
+		    do: [:each | aStream nextPutAll: each]
+		    separatedBy: [aStream nextPutAll: ' '].
+		aStream	
+		    nextPutAll: '''!!'; lf; lf]
+!
+
+exportMethod: aMethod of: aClass on: aStream
+	aStream 
+		lf; lf; nextPutAll: (self chunkEscape: aMethod source); lf;
+		nextPutAll: '!!'
+!
+
+exportMethods: methods category: category of: aClass on: aStream
+	"Issue #143: sort methods alphabetically"
+
+	aStream
+		nextPutAll: '!!', (self classNameFor: aClass);
+		nextPutAll: ' methodsFor: ''', category, '''!!'.
+		(methods sorted: [:a :b | a selector <= b selector]) do: [:each |
+				self exportMethod: each of: aClass on: aStream].
+	aStream nextPutAll: ' !!'; lf; lf
+!
+
+exportMethodsOf: aClass on: aStream
+	"Issue #143: sort protocol alphabetically"
+
+	| map |
+	map := Dictionary new.
+	aClass protocolsDo: [:category :methods | 
+		(category match: '^\*') ifFalse: [ map at: category put: methods ]].
+	(map keys sorted: [:a :b | a <= b ]) do: [:category | | methods |
+		methods := map at: category.
+		self
+			exportMethods: methods
+			category: category
+			of: aClass
+			on: aStream ]
+!
+
+exportPackageDefinitionOf: package on: aStream
+	"Chunk format."
+
+	aStream 
+	    nextPutAll: 'Smalltalk current createPackage: ''', package name,
+		''' properties: ', package properties storeString, '!!'; lf.
+!
+
+exportPackageExtensionsOf: package on: aStream
+	"We need to override this one too since we need to group
+	all methods in a given protocol under a leading methodsFor: chunk
+	for that class."
+
+	"Issue #143: sort protocol alphabetically"
+
+	| name map |
+	name := package name.
+	(Package sortedClasses: Smalltalk current classes) do: [:each |
+		{each. each class} do: [:aClass |
+			map := Dictionary new.
+			aClass protocolsDo: [:category :methods | 
+				(category match: '^\*', name) ifTrue: [ map at: category put: methods ]].
+			(map keys sorted: [:a :b | a <= b ]) do: [:category | | methods |
+				methods := map at: category.	
+				self exportMethods: methods category: category of: aClass on: aStream ]]]
+! !
+
+Exporter subclass: #StrippedExporter
+	instanceVariableNames: ''
+	package: 'Importer-Exporter'!
+
+!StrippedExporter methodsFor: 'private'!
+
+exportDefinitionOf: aClass on: aStream
+	aStream 
+	    nextPutAll: 'smalltalk.addClass(';
+	    nextPutAll: '''', (self classNameFor: aClass), ''', ';
+	    nextPutAll: 'smalltalk.', (self classNameFor: aClass superclass);
+	    nextPutAll: ', ['.
+	aClass instanceVariableNames 
+	    do: [:each | aStream nextPutAll: '''', each, '''']
+	    separatedBy: [aStream nextPutAll: ', '].
+	aStream	
+	    nextPutAll: '], ''';
+	    nextPutAll: aClass category, '''';
+	    nextPutAll: ');'.
+	aStream lf
+!
+
+exportMethod: aMethod of: aClass on: aStream
+	aStream 
+		nextPutAll: 'smalltalk.addMethod(';lf;
+		nextPutAll: aMethod selector asSelector asJavascript, ',';lf;
+		nextPutAll: 'smalltalk.method({';lf;
+		nextPutAll: 'selector: ', aMethod selector asJavascript, ',';lf;
+		nextPutAll: 'fn: ', aMethod fn compiledSource;lf;
+		nextPutAll: '}),';lf;
+		nextPutAll: 'smalltalk.', (self classNameFor: aClass);
+		nextPutAll: ');';lf;lf
+! !
+
+Object subclass: #Importer
+	instanceVariableNames: ''
+	package: 'Importer-Exporter'!
+
+!Importer methodsFor: 'fileIn'!
+
+import: aStream
+    | chunk result parser lastEmpty |
+    parser := ChunkParser on: aStream.
+    lastEmpty := false.
+    [chunk := parser nextChunk.
+     chunk isNil] whileFalse: [
+        chunk isEmpty
+       		ifTrue: [lastEmpty := true]
+       		ifFalse: [
+        		result := Compiler new evaluateExpression: chunk.
+        		lastEmpty 
+            			ifTrue: [
+                                  	lastEmpty := false.
+                                  	result scanFrom: parser]]]
+! !
+

Some files were not shown because too many files changed in this diff