'From Squeak3.7 of ''4 September 2004'' [latest update: #5989] on 17 October 2007 at 11:45:55 pm'!Notification subclass: #ParserNotification	instanceVariableNames: 'name'	classVariableNames: ''	poolDictionaries: ''	category: 'System-Compiler'!ParserNotification subclass: #UndeclaredVariable	instanceVariableNames: 'parser interval'	classVariableNames: ''	poolDictionaries: ''	category: 'System-Compiler'!ParserNotification subclass: #UndefinedVariable	instanceVariableNames: ''	classVariableNames: ''	poolDictionaries: ''	category: 'System-Compiler'!ParserNotification subclass: #UnknownSelector	instanceVariableNames: ''	classVariableNames: ''	poolDictionaries: ''	category: 'System-Compiler'!ParserNotification subclass: #UnusedVariable	instanceVariableNames: ''	classVariableNames: ''	poolDictionaries: ''	category: 'System-Compiler'!!Parser methodsFor: 'error correction' stamp: 'cwp 10/15/2007 23:00'!canDeclareClassVariable	^encoder classEncoding ~~ UndefinedObject! !!Parser methodsFor: 'error correction' stamp: 'cwp 10/17/2007 23:39'!correctSelector: proposedKeyword wordIntervals: spots exprInterval: expInt ifAbort: abortAction	"Correct the proposedKeyword to some selector symbol, correcting the original text if such action is indicated.  abortAction is invoked if the proposedKeyword couldn't be converted into a valid selector.  Spots is an ordered collection of intervals within the test stream of the for each of the keyword parts."	| correctSelector userSelection |	"If we can't ask the user, assume that the keyword will be defined later"	self interactive ifFalse: [ ^ proposedKeyword asSymbol ].	userSelection _ requestor selectionInterval.	requestor selectFrom: spots first first to: spots last last.	requestor select.	correctSelector _ UnknownSelector name: proposedKeyword.	correctSelector ifNil: [ ^ abortAction value ].	requestor deselect.	requestor selectInvisiblyFrom: userSelection first to: userSelection last.	self substituteSelector: correctSelector keywords wordIntervals: spots.	((proposedKeyword last ~~ $:) and: [correctSelector last == $:]) ifTrue: [		^ abortAction value].	^ correctSelector.! !!Parser methodsFor: 'error correction' stamp: 'cwp 10/15/2007 23:09'!correctVariable: proposedVariable interval: spot 	"Correct the proposedVariable to a known variable, or declare it as a new	variable if such action is requested.  We support declaring lowercase	variables as temps or inst-vars, and uppercase variables as Globals or 	ClassVars, depending on whether the context is nil (class=UndefinedObject).	Spot is the interval within the test stream of the variable.	rr 3/4/2004 10:26 : adds the option to define a new class. "	"Check if this is an i-var, that has been corrected already (ugly)"	"Display the pop-up menu"	| tempIvar binding userSelection action |	(encoder classEncoding instVarNames includes: proposedVariable) 		ifTrue: 			[^(LiteralVariableNode new)				name: proposedVariable					index: (encoder classEncoding instVarNames indexOf: proposedVariable) - 1					type: 1;				yourself].	"If we can't ask the user for correction, make it undeclared"	self interactive ifFalse: [^encoder undeclared: proposedVariable].	"First check to see if the requestor knows anything about the variable"	tempIvar := proposedVariable first isLowercase.	(tempIvar and: [(binding := requestor bindingOf: proposedVariable) notNil]) 		ifTrue: [^encoder global: binding name: proposedVariable].	userSelection := requestor selectionInterval.	requestor selectFrom: spot first to: spot last.	requestor select.	"Build the menu with alternatives"	action := UndeclaredVariable 				signalFor: self				name: proposedVariable				inRange: spot.	action ifNil: [^self fail].	"Execute the selected action"	requestor deselect.	requestor selectInvisiblyFrom: userSelection first to: userSelection last.	^action value! !!Parser methodsFor: 'error correction' stamp: 'cwp 10/15/2007 22:58'!possibleVariablesFor: proposedVariable 	^encoder possibleVariablesFor: proposedVariable! !!Parser methodsFor: 'error correction' stamp: 'cwp 10/17/2007 22:38'!queryUndefined	| varStart varName | 	varName _ parseNode key.	varStart _ self endOfLastToken + requestorOffset - varName size + 1.	requestor selectFrom: varStart to: varStart + varName size - 1; select.	(UndefinedVariable name: varName) ifFalse: [^ self fail]! !!Parser methodsFor: 'error correction' stamp: 'cwp 10/17/2007 22:58'!removeUnusedTemps	"Scan for unused temp names, and prompt the user about the prospect of removing each one found"	| str end start madeChanges | 	madeChanges _ false.	str _ requestor text string.	((tempsMark between: 1 and: str size)		and: [(str at: tempsMark) = $|]) ifFalse: [^ self].	encoder unusedTempNames do:		[:temp |		(UnusedVariable name: temp) ifTrue:		[(encoder encodeVariable: temp) isUndefTemp			ifTrue:			[end _ tempsMark.			["Beginning at right temp marker..."			start _ end - temp size + 1.			end < temp size or: [temp = (str copyFrom: start to: end)					and: [(str at: start-1) isSeparator & (str at: end+1) isSeparator]]]			whileFalse:				["Search left for the unused temp"				end _ requestor nextTokenFrom: end direction: -1].			end < temp size ifFalse:				[(str at: start-1) = $  ifTrue: [start _ start-1].				requestor correctFrom: start to: end with: ''.				str _ str copyReplaceFrom: start to: end with: ''. 				madeChanges _ true.				tempsMark _ tempsMark - (end-start+1)]]			ifFalse:			[self inform:'You''ll first have to remove thestatement where it''s stored into']]].	madeChanges ifTrue: [ParserRemovedUnusedTemps signal]! !!Parser methodsFor: 'error correction' stamp: 'cwp 10/15/2007 22:53'!subsituteVariable: each atInterval: anInterval 	self 		substituteWord: each		wordInterval: anInterval		offset: 0.	^encoder encodeVariable: each! !!ParserNotification methodsFor: 'as yet unclassified' stamp: 'cwp 10/17/2007 21:45'!defaultAction		self openMenuIn: 		[:labels :lines :caption | 		(PopUpMenu labelArray: labels asArray lines: lines asArray) 			startUpWithCaption: caption]! !!ParserNotification methodsFor: 'as yet unclassified' stamp: 'cwp 10/17/2007 21:36'!openMenuIn: aBlock	self subclassResponsibility! !!ParserNotification methodsFor: 'as yet unclassified' stamp: 'cwp 10/17/2007 23:29'!setName: aString	name _ aString! !!ParserNotification class methodsFor: 'as yet unclassified' stamp: 'cwp 10/17/2007 23:31'!name: aString	^ (self new setName: aString) signal! !!UndeclaredVariable methodsFor: 'as yet unclassified' stamp: 'cwp 10/16/2007 00:18'!openMenuIn: aBlock 	| alternatives labels actions lines caption choice |	alternatives := parser possibleVariablesFor: name.	labels := OrderedCollection new.	actions := OrderedCollection new.	lines := OrderedCollection new.	name first isLowercase 		ifTrue: 			[labels add: 'declare temp'.			actions add: [parser declareTempAndPaste: name].			labels add: 'declare instance'.			actions add: [parser declareInstVar: name]]		ifFalse: 			[labels add: 'define new class'.			actions add: [parser defineClass: name].			labels add: 'declare global'.			actions add: [parser declareGlobal: name].			parser canDeclareClassVariable 				ifTrue: 					[labels add: 'declare class variable'.					actions add: [parser declareClassVar: name]]].	lines add: labels size.	alternatives do: 		[:each | 		labels add: each.		actions add: [parser subsituteVariable: each atInterval: interval] fixTemps].	lines add: labels size.	labels add: 'cancel'.	caption := 'Unknown variable: ' , name , ' please correct, or cancel:'.	choice := aBlock value: labels value: lines value: caption.	self resume: (actions at: choice ifAbsent: [nil])! !!UndeclaredVariable methodsFor: 'as yet unclassified' stamp: 'cwp 10/15/2007 23:04'!setParser: aParser name: aString range: anInterval 	parser := aParser.	name := aString.	interval := anInterval! !!UndeclaredVariable class methodsFor: 'as yet unclassified' stamp: 'cwp 10/15/2007 22:37'!signalFor: aParser name: aString inRange: anInterval 	^ (self new setParser: aParser name: aString range: anInterval) signal! !!UndefinedVariable methodsFor: 'as yet unclassified' stamp: 'cwp 10/17/2007 22:39'!openMenuIn: aBlock	| labels caption index |	labels _ #('yes' 'no').	caption _ name, ' appears to be undefined at this point.Proceed anyway?'.	index _ aBlock value: labels value: #() value: caption.	^ self resume: index = 1! !!UnknownSelector methodsFor: 'as yet unclassified' stamp: 'cwp 10/17/2007 23:34'!openMenuIn: aBlock	| alternatives labels lines caption choice |	alternatives _ Symbol possibleSelectorsFor: name.	labels _ Array streamContents:				[:s | s nextPut: name; nextPutAll: alternatives; nextPut: 'cancel'].	lines _ {1. alternatives size + 1}.	caption _ 'Unknown selector, please\confirm, correct, or cancel' withCRs.		choice _ aBlock value: labels value: lines value: caption.	choice = 0 ifTrue: [self resume: nil].	choice = 1 ifTrue: [self resume: name asSymbol].	choice = labels size ifTrue: [self resume: nil].	self resume: (alternatives at: choice - 1).! !!UnusedVariable methodsFor: 'as yet unclassified' stamp: 'cwp 10/17/2007 22:51'!openMenuIn: aBlock	| labels caption index |	labels _ #('yes' 'no').	caption _ name , ' appears to beunused in this method.OK to remove it?'.	index _ aBlock value: labels value: #() value: caption.	self resume: index = 1! !Parser removeSelector: #signalUndefinedVariable:isTemp:inRange:!!Parser reorganize!('error correction' canDeclareClassVariable correctSelector:wordIntervals:exprInterval:ifAbort: correctVariable:interval: declareClassVar: declareGlobal: declareInstVar: declareTempAndPaste: defineClass: possibleVariablesFor: queryUndefined removeUnusedTemps subsituteVariable:atInterval: substituteSelector:wordIntervals: substituteWord:wordInterval:offset:)('error handling' expected: fail interactive notify: notify:at: offEnd:)('expression types' argumentName assignment: blockExpression braceExpression cascade expression keylessMessagePartTest:repeat: messagePart:repeat: method:context:encoder: newMethodNode pattern:inContext: primaryExpression statements:innerBlock: temporaries temporaryBlockVariables variable)('primitives' allocateLiteral: externalFunctionDeclaration externalType: primitive primitiveDeclarations)('public access' encoder parse:class: parse:class:noPattern:context:notifying:ifFail: parseArgsAndTemps:notifying: parseMethodComment:setPattern: parseSelector:)('scanning' advance endOfLastToken match: matchReturn matchToken: startOfNextToken)('temps' bindArg: bindTemp:)('private' addComment init:notifying:failBlock: initPattern:notifying:return:)!