Commits

Ryan Macnak  committed 3b1f609

Misc compiler cleanups: types, categories, indentation, dead code.

  • Participants
  • Parent commits d9f3c51

Comments (0)

Files changed (1)

File Newspeak2SqueakCompilation.ns3

 			s nextPutAll: '.'.].
 		assert: [false] message: message].
 )
+compileClassSource: src <ReadStream> within: enclosing <MixinMirror> ^  <MixinRep>   = (
+(* the input is source code for a class declaration and a mirror on the enclosing class of the class to be
+compiled. The result is a pair of type MixinRep, defined recursively as:
+
+MixinRep ={CompiledMixinMirror. Collection[MixinRep]}
+
+It is a tuple whose first element is an uninstalled low level mirror representing an enclosing
+class, and whose second element is a collection of MixinReps, each of which represents one of the nested classes of the enclosing class.
+
+The actual MixinRep returned depends on whether we are compiling a top level class. If so, enclosing is nil, and we return a MixinRep representing said top level class and all its nested classes (recursively).
+
+Otherwise, we return a MixinRep which represents the enclosing class and the nested class that was given in the source (and all its nested classes recursively).
+*)
+
+| tree <AST>  mixinRep  <MixinRep> |
+  tree:: parser classDefinition parse: src.
+  saveInput: src.
+  setScopeFor: tree in: enclosing. (* scope construction phase *)
+
+  mixinRep:: enclosing isNil
+	ifTrue: [ classNode: tree ]
+	ifFalse: [ compileNestedClassAST: tree into: enclosing ].
+
+  scopeMap:: Dictionary new. 
+  ^ mixinRep
+)
+compileNestedClassAST: tree <ClassDeclarationAST> into: enclosingClass <ClassDeclarationMirror> ^ <MixinRep> = (
+	| 
+		nestedClassMixinReps <List[MixinRep]>
+		enclosingMirror <CompiledMixinMirror>
+		lowMirror <LowLevelMixinMirror>
+	|
+		enclosingMirror:: enclosingClass compiledMixinMirror.
+		lowMirror:: enclosingMirror lowLevelMirror.
+		
+		nestedClassMixinReps:: compileNestedClass: tree within: lowMirror.
+		generateSlotAccessorsFor: lowMirror.
+		
+		 
+		
+		^ { enclosingMirror . nestedClassMixinReps }.
+		(* what about other nested classes of enclosing? Not the compiler's responsibility; they are unchanged, and the surrounding reflection system should add them to the mixin rep *)
+)
+currentScope ^ <Scope> = (
+  ^scopeStack last
+)
+doitContextArgumentName = (
+	(* Use #'@context', but this can't be mentioned in the debugger,
+	and doesn't need to be since the debugger provides Inspect Context.
+	But if you're desperate, use ThisContext, as does the Squeak debugger. *)
+	^true ifTrue: [#'@context'] ifFalse: [#'ThisContext']
+)
+futureFor: expression <ExpressionAST> ^<ExpressionAST> = (
+	(* @here Future computing: [expression] *)
+	| 
+	sscope <Scope>
+	block <BlockAST>
+	codebody <CodeBodyAST>
+	futureExp <ExpressionAST>
+	|
+	
+	sscope:: Scope new.
+	sscope superScope: currentScope.
+	
+	futureExp:: NormalSendAST new
+		recv: (NormalSendAST new recv: hereNode; msg: (MessageAST new sel: #Future; args: {}));
+		msg: (MessageAST new sel: #computing:; args: {
+			block:: BlockAST new body: (
+				 codebody:: CodeBodyAST new
+					parameters: OrderedCollection new;
+					 temporaries: OrderedCollection new;
+					statements: {expression}
+			)
+		}).
+		
+	scopeMap at: codebody put: sscope.
+	scopeMap at: block put: sscope.
+	^futureExp
+)
+generateSlotAccessorsFor: m <MixinMirror> = (
+(* we could let the accessors be generated in the mixin. However, we want to optimize mixin application, so it is best if an initial set of accessors is compiled into the mixin. *)
+| 
+sn <String> 
+ivIndices <SequenceableCollection[Integer]> 
+ivs <Collection[InstanceVariableMirror]> 
+|
+	ivs:: m instVars collect:[:iv | iv]. (* Gross - extract a collection from the mirror group *)
+      ivIndices:: 1 to: ivs size.
+	ivs with: ivIndices do: [:iv <InstanceVariableMirror> :n <Integer>  | 
+		| getter  <LowLevelMethodMirror> setter <LowLevelMethodMirror> |
+		sn:: iv name.
+		getter:: (LowLevelMethodMirror new selector: sn asSymbol)
+									method: (Mixin getterPool at:n).
+		getter metadata at: #isSynthetic put: true.
+		
+		m methods addMirror:  getter.
+		setter:: (LowLevelMethodMirror new 
+									selector: (setterSelectorFor: iv)
+									) method: (Mixin setterPool at:n).
+		setter metadata at: #isSynthetic put: true.					
+		m methods addMirror: setter.
+		
+		(sn endsWith: '`slot') ifTrue: [
+			getter metadata at: #isNestedClassAccessor put: true.
+			setter metadata at: #isNestedClassAccessor put: true.
+		].
+	]
+)
+methodNode: aNode <MethodAST> ^ <LowLevelMethodMirror> = (
+
+	| tree <AST> |
+	tree:: aNode apply: rewriter. (* rewrite ast *)
+	tree apply: methodCompiler. (* final pass: visit rewritten ast *)
+	(* pop scope? *)
+	^(methodCompiler result) src: (sourceForNode: aNode)
+)
+nestScope: s <Scope> = (
+(* Hook up a new lexically nested scope, and push onto the scope stack *)
+  s setSuperScope: currentScope.
+  pushScope: s
+)
+popScope ^ <Scope> = (
+   ^scopeStack removeLast
+)
+processClassSideOf: aNode <ClassAST> ofMixin: mixinMirror <LowLevelMixinMirror> = (
+| primaryFactory <MethodMirror> factoryAST <MethodAST> |
+	processFactoryFor: aNode in: mixinMirror.
+	processSide: aNode classSide ofMixin: mixinMirror. (* compile class methods *)
+)
+processInstanceSideOf: aNode <ClassAST> ofMixin: mixinMirror <LowLevelMixinMirror> ^ <Collection[MixinRep]> = (
+| side <SideAST> |
+	processInitializerFor: aNode in: mixinMirror.
+	side:: aNode instanceSide.
+	processSide: side ofMixin: mixinMirror. (* compile instance methods *)
+	^compileNestedClassesOf: side within: mixinMirror. (* gather nested classes *)
+)
+processMethod: aNode <MethodAST> inScope: s <Scope>  in: mixinMirror <LowLevelMixinMirror> = (
+|  scopeBuilder <ScopeBuilder> method <LowLevelMethodMirror> |
+
+	scopeBuilder:: ScopeBuilder nestedIn: s atLevel: currentDepth.
+	aNode apply: scopeBuilder.
+(* need to build scope for method before visiting it *)
+	method:: methodNode: aNode.
+	method metadata at: #isSynthetic put: true.
+	mixinMirror methods addMirror: method.
+	^method
+(* install method *)	
+)
+processSide: side <SideAST> ofMixin: mixinMirror <LowLevelMixinMirror> = (
+  side categories do:[:cat |  | mirr <MethodMirror> |
+                     cat methods do:[:m | 
+	(* who checks that the methods do not conflict with each other or with another slot or class in the same enclosing class? The mirror or the compiler? *)
+	                         	mirr:: methodNode: m.
+					  	mirr metadata at: #category put: cat name.
+                               	mixinMirror methods addMirror: mirr.
+                                 ].
+                     ].
+)
+pushScope: s <Scope> = (
+  scopeStack addLast: s
+)
+saveInput: src <ReadStream> = (
+  src position: 1.
+  input: src. (* save the input *)
+)
+setScopeFor: aNode <AST> in: enclosing <MixinMirror| Nil> = (
+
+| scopeBuilder <ScopeBuilder> |
+
+  pushScope: Scope new.
+  enclosing isNil ifFalse:[nestScope:: ScopeBuilder new buildScopeFor: enclosing].
+						 (* establish enclosing scope *)
+
+  currentDepth:: currentScope depth - 1. 
+(* There should be one scope for each enclosing class, plus the dummy initial scope. *)
+
+  scopeBuilder:: ScopeBuilder nestedIn: currentScope atLevel: currentDepth.
+  aNode apply: scopeBuilder.
+  (* scopeMap:: scopeBuilder scopeMap. *)
+)
+setterSelectorFor: slot <SlotDefAST | InstanceVariableMirror> ^<Symbol> = (
+	^((slot isMutableSlot ifTrue: [ '' ] ifFalse: [ 'setOnce`' ]), slot name, ':') asSymbol.
+)
+sourceForNode: node <AST> ^ <String> = (
+	| savedPos <Integer> pos <Integer> len <Integer> s <String> |
+	savedPos:: input position.
+	len: (node end - node start) + 1.
+	s:: String new: len.
+	input position: node start -1.
+	input next: len into: s startingAt:1.
+	input position: savedPos.
+	^s
+)
+superConstructorMethodFor:  aNode <ClassHeaderAST> ^ <MethodAST> = (
+| 
+start <Integer> 
+end <Integer>
+stmts <List[StmtAST]> 
+var  <VariableAST> 
+initHdr <MessagePatternAST>
+superMsg <MessageAST> 
+send <NormalSendAST>
+body  <CodeBodyAST>
+copier <ASTCopier>
+|
+
+	start:: aNode superConstructorCall start.
+	end::  aNode  superConstructorCall end.
+	copier:: ASTCopier new.
+	initHdr:: aNode constructor apply: copier. (* set up scope with constructor parameters *)
+	initHdr selector:(superConstructorNameFor: aNode).
+	(* create call to superclass initializer *)
+	stmts:: OrderedCollection new. 
+	var:: VariableAST new name: #super; start: start; end: end.
+	superMsg::  aNode  superConstructorCall apply: copier.
+	superMsg sel: (initializerSelectorNameFor: superMsg sel).
+	send:: NormalSendAST new to: var send: superMsg; start: start; end: end. 
+	stmts addFirst: send.
+	body:: CodeBodyAST new temporaries: OrderedCollection new
+                                       	statements: stmts;
+                                      	start: start; end: end.
+	^MethodAST new pattern: initHdr
+                            body: body
+                            visibility: #private;
+                            start: start; end: end	
+)
+superConstructorNameFor: aNode <ClassHeaderAST> ^ <Symbol> = (
+	^(aNode name, '`superInit`', aNode constructor selector) asSymbol 
+)
+syntheticNameSeparator ^ <String> = (
+  ^Language syntheticNameSeparator	
+)
+syntheticNameSeparatorCharacter ^ <Character> = (
+  ^Language syntheticNameSeparatorCharacter	
+)'factories'
+makePrimaryFactoryFor: hdr <ClassHeaderAST> ^<MethodAST> = (
+
+	(* Manufacture a method with the given class header's primary constructor's signature, and body that creates a new instance of the class and calls its initializer *)
+	|
+	cons <MessagePatternAST>
+	start <Integer> end <Integer>
+	
+	newInstance <ExpressionAST>
+	args <List[ExpressionAST]>
+	initializerSelectorName <Symbol>
+	msgFromConstructor <MessageAST>
+	stmts <List[AST]>
+	body <CodeBodyAST>
+	|
+	
+	cons:: hdr constructor apply: ASTCopier new.
+	start:: cons start.
+	end:: cons end.
+
+	newInstance:: NormalSendAST new 
+		to: selfNode
+		send: (MessageAST new 
+			send: #basicNew with: {};
+                  start: start; end: end); 
+		start: start; end: end. (* self basicNew *)
+
+	args:: hdr constructor parameters collect:
+		[:vd <VarDeclAST> | 
+		NormalSendAST new
+			to: hereNode
+			send: (MessageAST new
+				send: vd name with: {};
+				start: vd start; end: vd end);
+		start: vd start; end: vd end].
+
+	initializerSelectorName:: initializerSelectorNameFor: cons selector.
+	msgFromConstructor:: MessageAST new send: initializerSelectorName with: args.
+	msgFromConstructor start: start; end: end.
+
+	stmts:: OrderedCollection new 
+		add: (ReturnStatAST new expr: 
+			(NormalSendAST new 
+				to: newInstance 
+				send: msgFromConstructor;
+				start: start; end: end);
+                   start: start; end: end);
+		yourself.
+		
+	body:: CodeBodyAST new
+		temporaries: OrderedCollection new
+		statements: stmts;
+		start: start; end: end.
+
+	^MethodAST new
+		pattern: cons body: body visibility: #public; 
+		start: start; end: end.
+)
+processFactoryFor: aNode <ClassAST> in: mixinMirror <LowLevelMixinMirror> = (
+	processFactoryFor: aNode hdr inScope: (scopeMap at: aNode classSide) in: mixinMirror.
+)
+processFactoryFor: aNode <ClassHeaderAST> inScope: s in: mixinMirror <LowLevelMixinMirror> = (
+	
+	| factoryAST <MethodAST> |
+ 	factoryAST:: makePrimaryFactoryFor: aNode.
+	(processMethod: factoryAST inScope: s in: mixinMirror)
+		metadata at: #isConstructor put: true.
+)'instance initializers'
+allInitializersFor: aNode <ClassHeaderAST> ^<Collection[MethodAST]> = (
+
+	(* Because the init sequence may not fit in a single method, because too many literals are needed for all the setters and getters, we produce an init method that calls a number of private sub-initializers. This main initializer routine first calls the superclass's main initializer, then calls the subinitializers to set all the slots, and then any initialization code in the header. Answers a collection of MethodASTs including the main and sub intializers. *)
+	| 
+	start <integer>
+	end <Integer>
+	stmts <List[StmtAST]> 
+	initHdr <MessagePatternAST>
+	body <CodeBodyAST>  
+	slots <Collection[StmtAST]>
+	subs <Collection[MethodAST]>
+	copier <ASTCopier>
+	|
+
+	start:: aNode superConstructorCall start.
+	end::  aNode  superConstructorCall end.
+	copier:: ASTCopier new.
+	initHdr:: aNode constructor apply: copier. (* set up scope with constructor parameters *)
+	initHdr selector: (initializerSelectorNameFor: initHdr selector).	
+	subs:: subInitializersFor: aNode. (* compute (empty) subinitializers *)
+	
+	slots:: (aNode slots reject: [:slot | slot initializer isNil]) collect: 
+		[:slot <SlotDefAST> |
+		| aMsg <MessageAST> slotInitializer <ExpressionAST> |
+		slotInitializer:: slot initializer apply: copier.
+		aNode isSeq ifFalse: [slotInitializer:: futureFor: slotInitializer].
+		aMsg:: MessageAST new 
+			send: (setterSelectorFor: slot) with:  {slotInitializer};
+			start: slot start;
+			end: slot end.
+		NormalSendAST new msg: aMsg; 
+			recv: (selfNode start: aMsg start; end: aMsg end);
+			start: aMsg start; end: aMsg end].
+
+	(* populate subinit methods with slot initialization code *)
+	(1 to: slots size) with: slots do: [:n :stmt |
+		(subs at: n  // methodCompiler slotsPerMethod + 1) body statements add: stmt]. 
+
+	stmts:: OrderedCollection new.
+	(* first call the superclass initializer *)
+	stmts add: (superConstructorCallFor: aNode). 
+	(* then call the subinitializers for the slots *)
+	1 to: subs size -1 do: 
+		[:i | stmts add: (sendForSub: (subs at: i))].
+	(* then the initializer code *)
+	aNode initExprs do:
+		[:ie <ExpressionAST> | stmts add: (ie apply: copier)]. 
+
+	body:: CodeBodyAST new
+		temporaries: OrderedCollection new
+		statements: stmts;
+		start: start; end: end.
+	subs at: subs size put: (MethodAST new 
+		pattern: initHdr body: body visibility: #public;
+		start: start; end: end).
+
+	^subs
+)
+initializerSelectorNameFor: selector <Symbol> ^<Symbol> = (
+	^('initializer`', selector) asSymbol
+)
+processInitializerFor: aNode <ClassAST> in: mixinMirror <LowLevelMixinMirror> = (
+	processInitializerFor: aNode hdr inScope: (scopeMap at: aNode instanceSide) in: mixinMirror.
+)
+processInitializerFor: aNode <ClassHeaderAST> inScope: s <Scope> in: mixinMirror <LowLevelMixinMirror> = (
+
+	| initializerASTs <List[MethodAST]> |
+	#BOGUS yourself. (* The superclass clause is not a property of the mixin; this method is specific to the application. That said, all applications derived from the class declaration will share it *)
+	processMethod: (superConstructorMethodFor: aNode) inScope:  s in: mixinMirror. 
+ 	initializerASTs:: allInitializersFor: aNode.
+	initializerASTs do:
+		[:init <MethodAST> | processMethod: init inScope: s in: mixinMirror]
+)
+sendForSub: sub <MethodAST> ^<NormalSendAST> = (
+
+	(* Create a single call to a sub-initializer from the main initiializer *)
+	| args <Collection[SendAST]> |
+	args:: sub pattern parameters collect: [:arg | hereSendFrom: arg].
+	
+	^(NormalSendAST new
+		to: selfNode
+		send: (MessageAST new
+			send: sub selector with: args;
+			start: sub  start; end:   sub end))
+	start: sub start; end: sub end				
+)
+subInitializer: n <Integer> for: aNode <ClassHeaderAST>  ^ <MethodAST> = (
+
+	|  initHdr <MessagePatternAST> body <CodeBodyAST>  |
+	initHdr:: aNode constructor apply: ASTCopier new. (* set up scope with constructor parameters *)
+	initHdr selector: (subinitializer: n nameFor: aNode).
+	body:: CodeBodyAST new
+		temporaries: OrderedCollection new
+		statements: OrderedCollection new;
+		start: aNode start; end: aNode end.
+	^MethodAST new
+		pattern: initHdr body: body visibility: #private;
+		start: aNode start; end: aNode end.
+)
+subInitializersFor: aNode <ClassHeaderAST> ^<Array[MethodAST]> = (
+	
+	| subs <Collection[MethodAST]>  numSubs <Integer>  |
+	numSubs:: aNode slots size // methodCompiler slotsPerMethod + 1.
+	subs:: Array new: numSubs + 1.
+	1 to: numSubs do: [:n <Integer> | 
+		subs at: n put: (subInitializer: n for: aNode)].
+	^subs
+)
+subinitializer: n <Integer> nameFor: aNode <ClassHeaderAST> ^<Symbol> = (
+
+	| prefix <String> suffix <String> fqn <String> |
+	prefix:: aNode name, syntheticNameSeparator, n printString, syntheticNameSeparator, 'init'.
+	suffix:: aNode constructor parameters size = 0 
+                    ifTrue:['']
+                    ifFalse:[
+				aNode constructor parameters size = 1
+					ifTrue:[':']
+					ifFalse:[syntheticNameSeparator, aNode constructor selector]].
+	^(prefix, suffix) asSymbol
+)
+superConstructorCallFor: aNode <ClassHeaderAST> ^<NormalSendAST> = (
+	
+	(* create call to super constructor method *)
+	|
+	var  <VariableAST> 
+	send <NormalSendAST>
+	start <Integer> 
+	end <Integer>  
+	superMsg <MessageAST>
+	args <List[VariableAST]> 
+	|
+
+	start:: aNode superConstructorCall start.
+	end:: aNode superConstructorCall end.
+	var:: VariableAST new name: #self; start: start; end: end.
+	args:: aNode constructor parameters collect:
+		[:p <VarDeclAST> | hereSendFrom: p].
+	superMsg:: MessageAST new 
+		send: (superConstructorNameFor: aNode) with: args; 
+		start: start; end: end.
+	send:: NormalSendAST new to: var send: superMsg; start: start; end: end.	
+	^send
+)'make lexically visible'
+scopeMap = (
+	^super scopeMap
+)'nested classes - private'
+compileNestedClasses: nestedClasses <Collection[ClassDeclarationAST]> within: mixinMirror <LowLevelMixinMirror> ^ <List[MixinRep]> = (
+
+| results <List[MixinRep]> |
+      results:: OrderedCollection new.
+	nestedClasses do:
+		[ :nc <ClassDeclarationAST> |  | nSlotName <String> |
+		nc hdr category: mixinMirror category, '-nested'.
+		nSlotName:: slotNameForNestedClassNamed: nc name 
+		                   within: mixinMirror name.
+		mixinMirror instVars addMirror: (InstanceVariableMirror named: nSlotName mutable: true).
+		results add: (classNode: (nestedMixinWrapperFor: nc in: mixinMirror)). (* make 'mixin' (a Smalltalk subclass of ProtoObject) for nested class *)
+		createNestedClassAccessorFrom: nc within: mixinMirror 
+		].
+	^results
+)
+compileNestedClassesOf: aNode <SideAST> within: mixinMirror <LowLevelMixinMirror> ^ <Collection[MixinRep]> = (
+(* where do we check that nested classes do not conflict with each other, or with methods or slots? *)
+	^compileNestedClasses: aNode nestedClasses within: mixinMirror
+)
+createNestedClassAccessorFrom: classDecl <ClassDeclarationAST> within: mixinMirror <LowLevelMixinMirror> = (
+ 
+(* Create an accessor method for the nested class represented by the incoming class tree.
+This accessor will lazily generate the nested class when its enclosing instance is first asked for it.
+*)
+| n <String>  accessorString <String> ast <MethodAST> nestedName <String> hdr <ClassHeaderAST> |
+
+hdr:: classDecl hdr.
+n:: hdr name. 
+nestedName:: fullyQualifySimpleName: hdr name with: mixinMirror name.
+ast:: accessorASTForNestedClassNamed: n fullName: nestedName superCall: hdr superclassCall.
+(processMethod: ast inScope: (scopeMap at: classDecl instanceSide) superScope in: mixinMirror)
+	metadata at: #isNestedClassAccessor put: true.
+)
+fullyQualifySimpleName: sn <Symbol> with: fqp <Symbol> ^ <Symbol> = (
+	^SystemMetadata fullyQualifySimpleName: sn with: fqp
+)
+nestedMixinWrapperFor: nested <ClassDeclarationAST> in: outerClass <MixinMirror>  ^ <ClassDeclarationAST> = (
+
+(* Wrap a class declaration to make it look like a nested mixin within outerClass should. This includes making the name be the fully qualified name, and hiding the superclass *)
+| wrapper <ClassDeclarationAST> |
+
+wrapper:: nested clone.
+wrapper hdr: nested hdr clone.
+wrapper hdr name: (fullyQualifySimpleName: nested name with: outerClass name).
+^wrapper
+)
+slotNameForNestedClassNamed: ncn <String> within: outerName <String> ^ <String> = (
+	^SystemMetadata mixinSlotNameFor:(
+								fullyQualifySimpleName: ncn 
+		                  			 with: outerName
+					). (* (fullyQualifySimpleName: ncn  with: outerName), '_slot' *)
+)'private'
+computeMixinFrom: aNode <ClassHeaderAST> ^ <LowLevelMixinMirror> = (
+
+	| mixinMirror <LowLevelMixinMirror> hdrString <String>  |
+	
+	mixinMirror::  LowLevelMixinMirror named: aNode name isMeta: false.
+	
+	aNode slots do: [:slot | mixinMirror instVars addMirror: 
+		(InstanceVariableMirror named: slot name mutable: slot isMutableSlot)].
+	
+	hdrString:: input contents copyFrom: aNode start to: aNode end.
+	
+	^(CompiledMixinMirror language: language header: hdrString mirror: mixinMirror)
+					category: aNode category;
+					comment: (aNode classComment isNil 
+									ifTrue:[''] 
+									ifFalse:[aNode classComment]
+									).
+)
+getInstanceVariables: aClassHeaderNode <ClassHeaderAST> ^ <String> = (
+
+ (* returns the language specific slots - e.g. instance variables as a string *)
+^aClassHeaderNode  slots inject:'' into:[:s <String> :v <SlotDefAST>  | s, v name, ' '].
+)
+hereNode ^<VariableAST> = (
+	(* Generates an AST representing the implicit receiver. We use a string so that we can represent a name that is not a legal identier *)
+	
+	^VariableAST new name: #'@here'; start: 0; end: 0.
+)
+hereSendFrom: arg <VarDeclAST> ^<MessageNode> = (
+	^NormalSendAST new
+		to: hereNode
+		send: (MessageAST new 
+			send: arg name
+			with: {};
+			start: arg start; end: arg end); 
+		start: arg start; end: arg end
+)
+selfNode ^ <VariableAST> = (
+
+(* generate a an AST representing self; used for implicit self sends *)
+^VariableAST new name: #self; start: 0; end: 0
+)'public access'
+classNode: node <ClassDeclarationAST> ^ <MixinRep> = (
+	(* type MixinRep = {CompiledMixinMirror. {MixinRep}} *)
+	|
+	mixinMirror <LowLevelMixinMirror>
+	nestedClasses <Collection[MixinRep]>
+	|
+	assert: [node hdr category notNil] message: 'No category for class header'.
+	checkForDuplicateNames: node.
+	mixinMirror:: computeMixinFrom: node hdr.
+
+	currentDepth::currentDepth + 1.
+	nestedClasses:: processInstanceSideOf: node ofMixin: mixinMirror lowLevelMirror.
+	generateSlotAccessorsFor: mixinMirror lowLevelMirror. (* must be called after nested classes are processed, so all synthetic slots have been added *)
+	processClassSideOf: node ofMixin: mixinMirror lowLevelMirror classMixin.
+	currentDepth:: currentDepth - 1.
+	
+	^{mixinMirror. nestedClasses}
+)
 compileClassHeader: src <ReadStream> of: classDecl <MixinMirror> ^ <MixinRep> = (
 	| rep <MixinRep> newMirror <LowLevelMixinMirror> oldMirror <LowLevelMixinMirror> enclosing <NS2ClassStencilMirror> |
 		(* Works by appending () to src and compiling as complete class source
 	(* reindex as changes in slots may have moved synthetic slots for nested classes *)
 	^rep
 )
-compileClassSource: src <ReadStream> within: enclosing <MixinMirror> ^  <MixinRep>   = (
-(* the input is source code for a class declaration and a mirror on the enclosing class of the class to be
-compiled. The result is a pair of type MixinRep, defined recursively as:
-
-MixinRep ={CompiledMixinMirror. Collection[MixinRep]}
-
-It is a tuple whose first element is an uninstalled low level mirror representing an enclosing
-class, and whose second element is a collection of MixinReps, each of which represents one of the nested classes of the enclosing class.
-
-The actual MixinRep returned depends on whether we are compiling a top level class. If so, enclosing is nil, and we return a MixinRep representing said top level class and all its nested classes (recursively).
-
-Otherwise, we return a MixinRep which represents the enclosing class and the nested class that was given in the source (and all its nested classes recursively).
-*)
-
-| tree <AST>  mixinRep  <MixinRep> |
-  tree:: parser classDefinition parse: src.
-  saveInput: src.
-  setScopeFor: tree in: enclosing. (* scope construction phase *)
-
-  mixinRep:: enclosing isNil
-	ifTrue: [ classNode: tree ]
-	ifFalse: [ compileNestedClassAST: tree into: enclosing ].
-
-  scopeMap:: Dictionary new. 
-  ^ mixinRep
-)
 compileExpressionSource: src <ReadStream | String> inContext: aContext <MethodContext> inMixin: enclosing <MixinMirror> ^<LowLevelMethodMirror>
 = (
 	(* Compile a DoIt method.  If aContext is not nil, compile a DoItIn:ctxt method where accesses to names in scope of the context are rewritten to access through the context.  Cog closures complicate this rewriting compared to BlockContexts, as access might be rather indirect.  Also, in cases where a temp is only a copied value and not in an remote indirection vector, it would be impractical to handle writes such that they actually track down all places where the temp lives and update them.  In these cases, we should merely find the most local copy, which I believe is what closure compiled Squeak does. *)
 	method <MethodAST>
 	result <LowLevelMethodMirror>
 	|
-	assert: [aContext isNil or: [aContext method methodClass language isNewspeakLanguage3]] message: 'Context is not NS3!'.
+	assert: [aContext isNil or: [aContext method methodClass language isNewspeakLanguage3]]
+		message: 'Context is not NS3!'.
 	
 	(* Parse as a code body *)
-	src isString ifTrue: [stm:: src readStream] ifFalse: [stm:: src].
+	src isString ifTrue: [stm: src readStream] ifFalse: [stm: src].
 	body:: parser codeBody parse: stm.
 	saveInput: stm.
 	
 	(* Ensure last statement is a return statement *)
-	body statements isEmpty ifFalse: [body statements last isReturnStatNode ifFalse:[
-		| last |
-		last:: body statements removeLast.
-		body statements add: (ReturnStatAST new expr: last; start: last start; end: last end) 
-	]].
+	body statements isEmpty ifFalse:
+		[body statements last isReturnStatNode ifFalse:
+			[| last |
+			last:: body statements removeLast.
+			body statements add: (ReturnStatAST new 
+				expr: last; start: last start; end: last end)]].
 
 	(* Put into a method *)
 	method:: MethodAST new
 		visibility: #public.
 	
 	(* Build scope *)
-	
 	aContext isNil ifTrue: [
 		setScopeFor: method in: (enclosing).
 	] ifFalse: [
 	scopeMap:: Dictionary new.
 	^result
 )
-compileNestedClassAST: tree <ClassDeclarationAST> into: enclosingClass <ClassDeclarationMirror> ^ <MixinRep> = (
-	| 
-		nestedClassMixinReps <List[MixinRep]>
-		enclosingMirror <CompiledMixinMirror>
-		lowMirror <LowLevelMixinMirror>
-	|
-		enclosingMirror:: enclosingClass compiledMixinMirror.
-		lowMirror:: enclosingMirror lowLevelMirror.
-		
-		nestedClassMixinReps:: compileNestedClass: tree within: lowMirror.
-		generateSlotAccessorsFor: lowMirror.
-		
-		 
-		
-		^ { enclosingMirror . nestedClassMixinReps }.
-		(* what about other nested classes of enclosing? Not the compiler's responsibility; they are unchanged, and the surrounding reflection system should add them to the mixin rep *)
-)
-currentScope ^ <Scope> = (
-  ^scopeStack last
-)
-doitContextArgumentName = (
-	(* Use #'@context', but this can't be mentioned in the debugger,
-	and doesn't need to be since the debugger provides Inspect Context.
-	But if you're desperate, use ThisContext, as does the Squeak debugger. *)
-	^true ifTrue: [#'@context'] ifFalse: [#'ThisContext']
-)
-futureFor: expression <ExpressionAST> ^<ExpressionAST> = (
-	(* @here Future computing: [expression] *)
-	| 
-	sscope <Scope>
-	block <BlockAST>
-	codebody <CodeBodyAST>
-	futureExp <ExpressionAST>
-	|
-	
-	sscope:: Scope new.
-	sscope superScope: currentScope.
-	
-	futureExp:: NormalSendAST new
-		recv: (NormalSendAST new recv: hereNode; msg: (MessageAST new sel: #Future; args: {}));
-		msg: (MessageAST new sel: #computing:; args: {
-			block:: BlockAST new body: (
-				 codebody:: CodeBodyAST new
-					parameters: OrderedCollection new;
-					 temporaries: OrderedCollection new;
-					statements: {expression}
-			)
-		}).
-		
-	scopeMap at: codebody put: sscope.
-	scopeMap at: block put: sscope.
-	^futureExp
-)
-generateSlotAccessorsFor: m <MixinMirror> = (
-(* we could let the accessors be generated in the mixin. However, we want to optimize mixin application, so it is best if an initial set of accessors is compiled into the mixin. *)
-| 
-sn <String> 
-ivIndices <SequenceableCollection[Integer]> 
-ivs <Collection[InstanceVariableMirror]> 
-|
-	ivs:: m instVars collect:[:iv | iv]. (* Gross - extract a collection from the mirror group *)
-      ivIndices:: 1 to: ivs size.
-	ivs with: ivIndices do: [:iv <InstanceVariableMirror> :n <Integer>  | 
-		| getter  <LowLevelMethodMirror> setter <LowLevelMethodMirror> |
-		sn:: iv name.
-		getter:: (LowLevelMethodMirror new selector: sn asSymbol)
-									method: (Mixin getterPool at:n).
-		getter metadata at: #isSynthetic put: true.
-		
-		m methods addMirror:  getter.
-		setter:: (LowLevelMethodMirror new 
-									selector: (setterSelectorFor: iv)
-									) method: (Mixin setterPool at:n).
-		setter metadata at: #isSynthetic put: true.					
-		m methods addMirror: setter.
-		
-		(sn endsWith: '`slot') ifTrue: [
-			getter metadata at: #isNestedClassAccessor put: true.
-			setter metadata at: #isNestedClassAccessor put: true.
-		].
-	]
-)
-initializerSelectorNameFor: selector = (
-
-	^ ('initializer`', selector) asSymbol
-)
-makePrimaryFactoryFor: hdr <ClassHeaderAST> = (
-
-(* Manufacture a method with the given class header's primary constructor's signature, and body that creates a new instance of the class and calls its initializer *)
-
-|  newInstance calls body msgFromConstructor args start end cons  initializerSelectorName |
-
-cons:: hdr constructor apply: ASTCopier new.
-
-start:: cons start.
-end:: cons end.
-
-newInstance:: NormalSendAST new 
-                         to:  selfNode send: (MessageAST new 
-                                                                              send: #basicNew 
-                                                                              with: {};
-                                                                              start: start; end: end
-                                                                          ); (* self basicNew *)
-                         start: start; end: end.
-
-args:: hdr constructor parameters collect:[:vd <VarDeclAST> | 
-	NormalSendAST new to: hereNode
-	                                send: (MessageAST new send: vd name with: {}; 
-	                                                                     start: vd start; end: vd end
-	                                         );
-	                              start: vd start; end: vd end
-	].
-
-initializerSelectorName:: initializerSelectorNameFor: cons selector.
-msgFromConstructor:: MessageAST new send:  initializerSelectorName with: args.
-msgFromConstructor start: start; end: end.
-
-calls:: OrderedCollection new add: (ReturnStatAST new 
-                                                           expr:(
-                                                                      NormalSendAST new 
-                                                                           to: newInstance 
-                                                                           send: msgFromConstructor;
-                                                                           start: start; end: end
-                                                                      ) ;
-                                                             start: start; end: end
-                                                        );
-                                               yourself.
-body:: CodeBodyAST new temporaries: OrderedCollection new statements: calls;
-						 start: start; end: end.
-^MethodAST new pattern: cons body: body visibility: #public; 
-				start: start; end: end.
-)
-methodNode: aNode <MethodAST> ^ <LowLevelMethodMirror> = (
-
-	| tree <AST> |
-	tree:: aNode apply: rewriter. (* rewrite ast *)
-	tree apply: methodCompiler. (* final pass: visit rewritten ast *)
-	(* pop scope? *)
-	^(methodCompiler result) src: (sourceForNode: aNode)
-)
-nestScope: s <Scope> = (
-(* Hook up a new lexically nested scope, and push onto the scope stack *)
-  s setSuperScope: currentScope.
-  pushScope: s
-)
-popScope ^ <Scope> = (
-   ^scopeStack removeLast
-)
-processClassSideOf: aNode <ClassAST> ofMixin: mixinMirror <LowLevelMixinMirror> = (
-| primaryFactory <MethodMirror> factoryAST <MethodAST> |
-	processFactoryFor: aNode in: mixinMirror.
-	processSide: aNode classSide ofMixin: mixinMirror. (* compile class methods *)
-)
-processFactoryFor: aNode <ClassAST> in: mixinMirror <LowLevelMixinMirror> = (
-|  factory <MethodMirror> side <SideAST> factoryAST <MethodAST> scopeBuilder <ScopeBuilder> savedScopeMap <Dictionary[AST, Scope]> |
-	processFactoryFor: aNode hdr inScope: (scopeMap at: aNode classSide) in: mixinMirror.
-)
-processFactoryFor: aNode <ClassHeaderAST> inScope: s in: mixinMirror <LowLevelMixinMirror> = (
-|  factory <MethodMirror> side <SideAST> factoryAST <MethodAST> scopeBuilder <ScopeBuilder> savedScopeMap <Dictionary[AST, Scope]> |
- 	factoryAST:: makePrimaryFactoryFor: aNode.
-	(processMethod: factoryAST inScope: s in: mixinMirror)
-		metadata at: #isConstructor put: true.
-
-	(* need to build scope for factory before visiting it *)
-)
-processInitializerFor: aNode <ClassAST> in: mixinMirror <LowLevelMixinMirror> = (
-	processInitializerFor: aNode hdr inScope: (scopeMap at: aNode instanceSide) in: mixinMirror.
-)
-processInitializerFor: aNode <ClassHeaderAST>  inScope: s <Scope> in: mixinMirror <LowLevelMixinMirror> = (
-|   initializerASTs <List[MethodAST]> |
-
-	#BOGUS yourself. 
-	(* The superclass clause is not a property of the mixin; this method is specific to the application. That said, all applications derived from the class declaration will share it *)
-	processMethod: (superConstructorMethodFor: aNode) inScope:  s in: mixinMirror. 
- 	initializerASTs:: allInitializersFor: aNode in: mixinMirror.
-	initializerASTs do:[: init <MethodAST> |
-		processMethod: init inScope: s in: mixinMirror.
-		]
-)
-processInstanceSideOf: aNode <ClassAST> ofMixin: mixinMirror <LowLevelMixinMirror> ^ <Collection[MixinRep]> = (
-| side <SideAST> |
-	processInitializerFor: aNode in: mixinMirror.
-	side:: aNode instanceSide.
-	processSide: side ofMixin: mixinMirror. (* compile instance methods *)
-	^compileNestedClassesOf: side within: mixinMirror. (* gather nested classes *)
-)
-processMethod: aNode <MethodAST> inScope: s <Scope>  in: mixinMirror <LowLevelMixinMirror> = (
-|  scopeBuilder <ScopeBuilder> method <LowLevelMethodMirror> |
-
-	scopeBuilder:: ScopeBuilder nestedIn: s atLevel: currentDepth.
-	aNode apply: scopeBuilder.
-(* need to build scope for method before visiting it *)
-	method:: methodNode: aNode.
-	method metadata at: #isSynthetic put: true.
-	mixinMirror methods addMirror: method.
-	^method
-(* install method *)	
-)
-processSide: side <SideAST> ofMixin: mixinMirror <LowLevelMixinMirror> = (
-  side categories do:[:cat |  | mirr <MethodMirror> |
-                     cat methods do:[:m | 
-	(* who checks that the methods do not conflict with each other or with another slot or class in the same enclosing class? The mirror or the compiler? *)
-	                         	mirr:: methodNode: m.
-					  	mirr metadata at: #category put: cat name.
-                               	mixinMirror methods addMirror: mirr.
-                                 ].
-                     ].
-)
-pushScope: s <Scope> = (
-  scopeStack addLast: s
-)
-resetScope = (
-	scopeMap: Dictionary new.
-)
-resolveStatementForSlot: slot <SlotDefAST> = (
-
-	(* self slotName: self slotName resolve. *)
-	#BOGUS. (* immutable slots *)
-
-	^NormalSendAST new 
-		recv: selfNode;
-		msg: (MessageAST new
-			send: (setterSelectorFor: slot)
-			with: { NormalSendAST new 
-				recv: (NormalSendAST new 
-					recv: selfNode;
-					msg: (MessageAST new 
-						send: slot name asSymbol 
-						with: {}));
-				msg: (MessageAST new 
-					send: #resolve 
-					with: {})})
-)
-saveInput: src <ReadStream> = (
-  src position: 1.
-  input: src. (* save the input *)
-)
-setScopeFor: aNode <AST> in: enclosing <MixinMirror| Nil> = (
-
-| scopeBuilder <ScopeBuilder> |
-
-  pushScope: Scope new.
-  enclosing isNil ifFalse:[nestScope:: ScopeBuilder new buildScopeFor: enclosing].
-						 (* establish enclosing scope *)
-
-  currentDepth:: currentScope depth - 1. 
-(* There should be one scope for each enclosing class, plus the dummy initial scope. *)
-
-  scopeBuilder:: ScopeBuilder nestedIn: currentScope atLevel: currentDepth.
-  aNode apply: scopeBuilder.
-  (* scopeMap:: scopeBuilder scopeMap. *)
-)
-setterSelectorFor: slot <SlotDefAST | InstanceVariableMirror> ^<Symbol> = (
-	^((slot isMutableSlot ifTrue: [ '' ] ifFalse: [ 'setOnce`' ]), slot name, ':') asSymbol.
-)
-sourceForNode: node <AST> ^ <String> = (
-	| savedPos <Integer> pos <Integer> len <Integer> s <String> |
-	savedPos:: input position.
-	len: (node end - node start) + 1.
-	s:: String new: len.
-	input position: node start -1.
-	input next: len into: s startingAt:1.
-	input position: savedPos.
-	^s
-)
-superConstructorCallFor:  aNode <ClassHeaderAST> ^ <NormalSendAST> = (
-(* create call to super constructor method *)
-| 
-var  <VariableAST> 
-send <NormalSendAST>
-start <Integer> 
-end <Integer>  
-copier <ASTCopier>
-superMsg <MessageAST>
-args <List[VariableAST]> 
-|
-
-	start:: aNode superConstructorCall start.
-	end::  aNode  superConstructorCall end.
-	copier:: ASTCopier new.
-	var:: VariableAST new name: #self; start: start; end: end.
-	args:: aNode constructor parameters collect:[:p <VarDeclAST> |
-			hereSendFrom: p
-		].
-	superMsg::  MessageAST new 
-		send: (superConstructorNameFor: aNode) with: args; 
-		start: start; end: end.
-	send:: NormalSendAST new to: var send: superMsg; start: 	start; end: end.	
-	^send
-)
-superConstructorMethodFor:  aNode <ClassHeaderAST> ^ <MethodAST> = (
-| 
-start <Integer> 
-end <Integer>
-stmts <List[StmtAST]> 
-var  <VariableAST> 
-initHdr <MessagePatternAST>
-superMsg <MessageAST> 
-send <NormalSendAST>
-body  <CodeBodyAST>
-copier <ASTCopier>
-|
-
-	start:: aNode superConstructorCall start.
-	end::  aNode  superConstructorCall end.
-	copier:: ASTCopier new.
-	initHdr:: aNode constructor apply: copier. (* set up scope with constructor parameters *)
-	initHdr selector:(superConstructorNameFor: aNode).
-	(* create call to superclass initializer *)
-	stmts:: OrderedCollection new. 
-	var:: VariableAST new name: #super; start: start; end: end.
-	superMsg::  aNode  superConstructorCall apply: copier.
-	superMsg sel: (initializerSelectorNameFor: superMsg sel).
-	send:: NormalSendAST new to: var send: superMsg; start: start; end: end. 
-	stmts addFirst: send.
-	body:: CodeBodyAST new temporaries: OrderedCollection new
-                                       	statements: stmts;
-                                      	start: start; end: end.
-	^MethodAST new pattern: initHdr
-                            body: body
-                            visibility: #private;
-                            start: start; end: end	
-)
-superConstructorNameFor: aNode <ClassHeaderAST> ^ <Symbol> = (
-	^(aNode name, '`superInit`', aNode constructor selector) asSymbol 
-)
-syntheticNameSeparator ^ <String> = (
-  ^Language syntheticNameSeparator	
-)
-syntheticNameSeparatorCharacter ^ <Character> = (
-  ^Language syntheticNameSeparatorCharacter	
-)'make lexically visible'
-scopeMap = (
-	^super scopeMap
-)'nested classes - private'
-compileNestedClasses: nestedClasses <Collection[ClassDeclarationAST]> within: mixinMirror <LowLevelMixinMirror> ^ <List[MixinRep]> = (
-
-| results <List[MixinRep]> |
-      results:: OrderedCollection new.
-	nestedClasses do:
-		[ :nc <ClassDeclarationAST> |  | nSlotName <String> |
-		nc hdr category: mixinMirror category, '-nested'.
-		nSlotName:: slotNameForNestedClassNamed: nc name 
-		                   within: mixinMirror name.
-		mixinMirror instVars addMirror: (InstanceVariableMirror named: nSlotName mutable: true).
-		results add: (classNode: (nestedMixinWrapperFor: nc in: mixinMirror)). (* make 'mixin' (a Smalltalk subclass of ProtoObject) for nested class *)
-		createNestedClassAccessorFrom: nc within: mixinMirror 
-		].
-	^results
-)
-compileNestedClassesOf: aNode <SideAST> within: mixinMirror <LowLevelMixinMirror> ^ <Collection[MixinRep]> = (
-(* where do we check that nested classes do not conflict with each other, or with methods or slots? *)
-	^compileNestedClasses: aNode nestedClasses within: mixinMirror
-)
-createNestedClassAccessorFrom: classDecl <ClassDeclarationAST> within: mixinMirror <LowLevelMixinMirror> = (
- 
-(* Create an accessor method for the nested class represented by the incoming class tree.
-This accessor will lazily generate the nested class when its enclosing instance is first asked for it.
-*)
-| n <String>  accessorString <String> ast <MethodAST> nestedName <String> hdr <ClassHeaderAST> |
-
-hdr:: classDecl hdr.
-n:: hdr name. 
-nestedName:: fullyQualifySimpleName: hdr name with: mixinMirror name.
-ast:: accessorASTForNestedClassNamed: n fullName: nestedName superCall: hdr superclassCall.
-(processMethod: ast inScope: (scopeMap at: classDecl instanceSide) superScope in: mixinMirror)
-	metadata at: #isNestedClassAccessor put: true.
-)
-fullyQualifySimpleName: sn <Symbol> with: fqp <Symbol> ^ <Symbol> = (
-	^SystemMetadata fullyQualifySimpleName: sn with: fqp
-)
-nestedMixinWrapperFor: nested <ClassDeclarationAST> in: outerClass <MixinMirror>  ^ <ClassDeclarationAST> = (
-
-(* Wrap a class declaration to make it look like a nested mixin within outerClass should. This includes making the name be the fully qualified name, and hiding the superclass *)
-| wrapper <ClassDeclarationAST> |
-
-wrapper:: nested clone.
-wrapper hdr: nested hdr clone.
-wrapper hdr name: (fullyQualifySimpleName: nested name with: outerClass name).
-^wrapper
-)
-slotNameForNestedClassNamed: ncn <String> within: outerName <String> ^ <String> = (
-	^SystemMetadata mixinSlotNameFor:(
-								fullyQualifySimpleName: ncn 
-		                  			 with: outerName
-					). (* (fullyQualifySimpleName: ncn  with: outerName), '_slot' *)
-)'private'
-allInitializersFor: aNode <ClassHeaderAST> in: mixinMirror <MixinMirror> ^ <Collection[MethodAST]> = (
-(* 2nd argument unused! *)
-(* Because the init sequence may not fit in a single method (because too many literals are needed for all the setters and getters, we produce an init method that calls a number of private  sub-initializers. This main initializer routine first calls the superclass  main initializer, then calls the subinitializers to set all the slots, and then any initialization code in the header. *)
-| 
-start <integer>
-end <Integer>
-stmts <List[StmtAST]> 
-initHdr <MessagePatternAST>
-body <CodeBodyAST>  
-slots <Collection[StmtAST]>
-subs <Collection[MethodAST]>
-copier <ASTCopier>
-|
-
-	start:: aNode superConstructorCall start.
-	end::  aNode  superConstructorCall end.
-	copier:: ASTCopier new.
-	initHdr:: aNode constructor apply: copier. (* set up scope with constructor parameters *)
-	initHdr selector: (initializerSelectorNameFor: initHdr selector).	
-	subs:: subInitializersFor: aNode. (* compute (empty) subinitializers *)
-	
-	slots:: (aNode slots reject: [:slot | slot initializer isNil]) collect:[:slot <SlotDefAST> |
-		| aMsg <MessageAST> slotInitializer <ExpressionAST> |
-		slotInitializer:: slot initializer apply: copier.
-		aNode isSeq ifFalse: [slotInitializer:: futureFor: slotInitializer].
-		aMsg:: MessageAST new 
-			send: (setterSelectorFor: slot) with:  {slotInitializer};
-			start: slot start;
-			end: slot end.
-		NormalSendAST new msg: aMsg; 
-			recv: (selfNode start: aMsg start; end: aMsg end);
-			start: aMsg start; end: aMsg end.
-	].
-
-	(1 to: slots size) with: slots do:[:n :stmt |
-		(subs at: n  // methodCompiler slotsPerMethod + 1) body statements add: stmt.
-	]. (* populate subinit methods with slot initialization code *)
-
-	(* aNode isSeq ifFalse: [
-		(1 to: slots size) with: aNode slots do:[:n :slot |
-			(subs at: n  // methodCompiler slotsPerMethod + 1) body statements 
-				add: (resolveStatementForSlot: slot).
-		].
-	]. *) (* add resolves if these are simultaneous slots *)
-	#BOGUS. (* this might intermix the resolves and future creations if more than one subinitializer? *)
-	
-
-	stmts:: OrderedCollection new. 
-	
-(* create call to superclass initializer *)
-	stmts addFirst: (superConstructorCallFor: aNode). (* add superclass init call as first statement *)
-
-	1 to: subs size -1 do:[:i | stmts add: (sendForSub: (subs at: i))]. (* create calls to subinitializers *)
-	stmts addAll: (aNode  initExprs collect:[:ie  <ExpressionAST> | ie   apply: copier]). (* process initializer code *)
-
-	body:: CodeBodyAST new temporaries: OrderedCollection new
-                                       	statements: stmts;
-                                      	start: start; end: end.
-
-	subs at: subs size put: (MethodAST new pattern: initHdr
-                            body: body
-                            visibility: #public;
-                            start: start; end: end). (* package method *)
-	^subs
-)
-computeMixinFrom: aNode <ClassHeaderAST> ^ <LowLevelMixinMirror> = (
-
-	| mixinMirror <LowLevelMixinMirror> hdrString <String>  |
-	
-	mixinMirror::  LowLevelMixinMirror named: aNode name isMeta: false.
-	
-	aNode slots do: [:slot | mixinMirror instVars addMirror: 
-		(InstanceVariableMirror named: slot name mutable: slot isMutableSlot)].
-	
-	hdrString:: input contents copyFrom: aNode start to: aNode end.
-	
-	^(CompiledMixinMirror language: language header: hdrString mirror: mixinMirror)
-					category: aNode category;
-					comment: (aNode classComment isNil 
-									ifTrue:[''] 
-									ifFalse:[aNode classComment]
-									).
-)
-enclosingObjectMsgFor: mirror <MixinMirror> ^ <String> = (
-  ^enclosingObjectMsgFromName: mirror name
-)
-enclosingObjectMsgFromName: nm <String> ^ <String> = (
-  ^'enclosingObject', syntheticNameSeparator, nm 
-)
-getInstanceVariables: aClassHeaderNode <ClassHeaderAST> ^ <String> = (
-
- (* returns the language specific slots - e.g. instance variables as a string *)
-^aClassHeaderNode  slots inject:'' into:[:s <String> :v <SlotDefAST>  | s, v name, ' '].
-)
-hereNode ^<VariableAST> = (
-	(* Generates an AST representing the implicit receiver. We use a string so that we can represent a name that is not a legal identier *)
-	
-	^VariableAST new name: #'@here'; start: 0; end: 0.
-)
-hereSendFrom: arg <VarDeclAST> ^<MessageNode> = (
-	^NormalSendAST new
-		to: hereNode
-		send: (MessageAST new 
-			send: arg name
-			with: {};
-			start: arg start; end: arg end); 
-		start: arg start; end: arg end
-)
-selfNode ^ <VariableAST> = (
-
-(* generate a an AST representing self; used for implicit self sends *)
-^VariableAST new name: #self; start: 0; end: 0
-)
-sendForSub: sub <MethodAST> ^ <NormalSendAST> = (
-
-(* Create a single call to a sub-initializer from the main initiializer *)
-| args <Collection[SendAST]> |
-
-  args::  sub pattern parameters collect:[:arg | hereSendFrom: arg].
-  ^ (NormalSendAST new to: selfNode send: (
-	MessageAST new send: sub selector
-					   with: args ;
-					   start: sub  start; end:   sub end
-					)) start: sub start; end: sub end
-					
-)
-subInitializer: n <Integer> for: aNode <ClassHeaderAST>  ^ <MethodAST> = (
-
-|  initHdr <MessagePatternAST> body <CodeBodyAST>  |
-
-initHdr:: aNode constructor apply: ASTCopier new. (* set up scope with constructor parameters *)
-initHdr selector: (subinitializer: n nameFor: aNode).
-body:: CodeBodyAST new temporaries: OrderedCollection new
-                                       statements: OrderedCollection new;
-							start: aNode start; end: aNode end.
-
-^MethodAST new pattern: initHdr
-                           body: body
-                           visibility: #private;
-                            start: aNode start; end: aNode end.
-)
-subInitializersFor: aNode  <ClassHeaderAST>  ^ <Array[MethodAST]> = (
-
-| subs <Collection[MethodAST]>  noSubs <Integer>  |
-  noSubs:: aNode slots size // methodCompiler slotsPerMethod + 1.
-  subs:: Array new: noSubs + 1.
-  1 to: noSubs do:[:n <Integer> | 
-		subs at: n put: (subInitializer: n for: aNode)
-	].
-  ^subs
-)
-subinitializer: n <Integer> nameFor: aNode  <ClassHeaderAST>  ^ <Symbol> = (
-| prefix <String> suffix <String> fqn <String> |
-
-  prefix::  ( aNode name,  syntheticNameSeparator, n printString,  syntheticNameSeparator, 'init').
-  suffix:: aNode constructor parameters size = 0 
-                    ifTrue:['']
-                    ifFalse:[
-				aNode constructor parameters size = 1
-					ifTrue:[':']
-					ifFalse:[syntheticNameSeparator, aNode constructor selector]
-	].
-  ^(prefix, suffix) asSymbol
-)'public access'
-classNode: node <ClassDeclarationAST> ^ <MixinRep> = (
-	(* type MixinRep = {CompiledMixinMirror. {MixinRep}} *)
-	|
-	mixinMirror <LowLevelMixinMirror>
-	nestedClasses <Collection[MixinRep]>
-	|
-	assert: [node hdr category notNil] message: 'No category for class header'.
-	checkForDuplicateNames: node.
-	mixinMirror:: computeMixinFrom: node hdr.
-
-	currentDepth::currentDepth + 1.
-	nestedClasses:: processInstanceSideOf: node ofMixin: mixinMirror lowLevelMirror.
-	generateSlotAccessorsFor: mixinMirror lowLevelMirror. (* must be called after nested classes are processed, so all synthetic slots have been added *)
-	processClassSideOf: node ofMixin: mixinMirror lowLevelMirror classMixin.
-	currentDepth:: currentDepth - 1.
-	
-	^{mixinMirror. nestedClasses}
-)
-compileMethodSource: src <ReadStream | String> within: enclosing <MixinMirror>  
-       			    ^ <LowLevelMethodMirror>
-= (
-| tree <AST> result <LowLevelMethodMirror> stm <ReadStream> | 
-#BOGUS yourself. (* Make sure we take the line below out when new src control is in use *)
-  src isString ifTrue: [stm:: src readStream] ifFalse: [stm:: src].
-  tree:: parser methodDecl parse: stm.
-  saveInput: stm.
-  setScopeFor: tree in:  (enclosing). (* scope construction phase *)
-  result::methodNode: tree. (* rewrite and compile *)
-  scopeMap:: Dictionary new.
-  ^result
+compileMethodSource: src <ReadStream | String> within: enclosing <MixinMirror>  ^<LowLevelMethodMirror> = (
+	| tree <AST> result <LowLevelMethodMirror> stm <ReadStream> | 
+	#BOGUS yourself. (* Make sure we take the line below out when new src control is in use *)
+	src isString ifTrue: [stm:: src readStream] ifFalse: [stm:: src].
+	tree:: parser methodDecl parse: stm.
+	saveInput: stm.
+	setScopeFor: tree in:  (enclosing). (* scope construction phase *)
+	result::methodNode: tree. (* rewrite and compile *)
+	scopeMap:: Dictionary new.
+	^result
 )
 compileNestedClass: nc <ClassDeclarationAST> within: mixinMirror <LowLevelMixinMirror> ^ <List[MixinRep]> = (
 	^compileNestedClasses: (OrderedCollection with: nc) within: mixinMirror.
 )) : ()'as yet unclassified'
 PERFORMANCE_NOTE = (
 	(* The compiler could generate better code in the following areas:
-	
-	1) In some cases, it emits storeIntoTemp followed by pop instead of popIntoTemp.
-	2) Often it generates code to nil out a slot/temp that has yet to be used.  However, in addressing this one must remember explicit initialization to nil is important for temps read before written in an inlined block.
-	3) It is not necessary to remember the argument to a setter send when the send is a top level statement that is not a return statement.
-	4) It could inline ifNil:/ifNotNil: as the Squeak compiler does.
-	5) It could inline and:/or:
-	6) Eliot suggested a way to implement setter sends without adding another temp. The value to be saved could be dup'd and later accessed by tempAt, relying on the fact that tempAt is not bounds checked. This might also be easier to decompile.
-	7) When possible, it should not generate subinitializers, which involve at least two extra sends per mixin to instainate simple objects.
+	* Setter sends evaluated for effect.
+	* Literals evaluated for effect (e.g., the BOGUS marker).
+	* Inlining ifNil: etc
+	* Inlining and:/or:
+	* Eliot suggested a way to implement setter sends without adding another temp. The value to be saved could be dup'd and later accessed by tempAt, relying on the fact that tempAt is not bounds checked. This might also be easier to decompile. (Although note absent receiver here sends will allow a dup-pop pattern similar to cascades.)
+	* When possible, it should not generate subinitializers, which involve at least two extra sends per mixin to instainate simple objects.
 	*)
 )
 assert: c = (