|  | @@ -1,696 +0,0 @@
 | 
	
		
			
				|  |  | -Smalltalk current createPackage: 'Compiler-Visitors' properties: #{}!
 | 
	
		
			
				|  |  | -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
 | 
	
		
			
				|  |  | -! !
 | 
	
		
			
				|  |  | -
 |