'From Cuis 2.3 of 22 March 2010 [latest update: #472] on 24 March 2010 at 12:31:36 pm'!

!Behavior methodsFor: 'compiling' stamp: 'ar 3/12/2010 15:50'!
allowUnderscoreAssignments
	"Return true if the receiver and its subclasses should be allowed to use underscore as assignment operator. Returning nil here means that the compiler should use the system-wide default preference. Also see #allowUnderscoreSelectors.

	Combinations: If both preferences are false, underscore is illegal. If both preferences are true, underscore assignment needs the be surrounded by spaces and a single underscore cannot be used as selector."
	^nil! !

!Behavior methodsFor: 'compiling' stamp: 'ar 3/12/2010 13:05'!
allowUnderscoreSelectors
	"Return true if the receiver and its subclasses should be allowed to use underscore in selectors. Returning nil here means that the compiler should use the system-wide default preference. Also see #allowUnderscoreAssignments.

	Combinations: If both preferences are false, underscore is illegal. If both preferences are true, underscore assignment needs the be surrounded by spaces and a single underscore cannot be used as selector."
	^nil! !


!Preferences class methodsFor: 'standard queries'!
systemWindowEmbedOK
	^ self
		valueOfFlag: #systemWindowEmbedOK
		ifAbsent: [false]! !

!Preferences class methodsFor: 'shout' stamp: 'jmv 3/24/2010 11:42'!
syntaxHighlightingAsYouTypeLeftArrowAssignment
	^ self
		valueOfFlag: #syntaxHighlightingAsYouTypeLeftArrowAssignment
		ifAbsent: [ true ]! !


!Scanner methodsFor: 'multi-character scans' stamp: 'jmv 3/24/2010 11:35'!
xIllegal
	"An illegal character was encountered"
	self notify: 'Illegal character (char code ' , hereChar asciiValue printString, ' 16r' , hereChar asciiValue hex , ')' at: mark! !

!Scanner methodsFor: 'multi-character scans' stamp: 'ar 3/12/2010 15:52'!
xLetter
	"Form a word or keyword."

	| type |
	buffer reset.
	[(type := self typeTableAt: hereChar) == #xLetter
		or: [type == #xDigit
		or: [type == #xUnderscore and:[self allowUnderscoreSelectors]]]] whileTrue:
			["open code step for speed"
			buffer nextPut: hereChar.
			hereChar := aheadChar.
			aheadChar := source atEnd
							ifTrue: [30 asCharacter "doit"]
							ifFalse: [source next]].
	tokenType := (type == #colon or: [type == #xColon and: [aheadChar ~~ $=]])
					ifTrue: 
						[buffer nextPut: self step.
						"Allow any number of embedded colons in literal symbols"
						[(self typeTableAt: hereChar) == #xColon] whileTrue:
							[buffer nextPut: self step].
						#keyword]
					ifFalse: 
						[type == #leftParenthesis 
							ifTrue:
								[buffer nextPut: self step; nextPut: $).
								 #positionalMessage]
							ifFalse:[#word]].
	token := buffer contents! !

!Scanner methodsFor: 'multi-character scans' stamp: 'ar 3/12/2010 16:10'!
xUnderscore
	self allowUnderscoreAssignments ifTrue:[ | type |
		"Figure out if x _foo (no space between _ and foo) 
		should be a selector or assignment"
		(((type := self typeTableAt: aheadChar) == #xLetter
			or:[type == #xDigit or:[type == #xUnderscore]]) 
			and:[self allowUnderscoreSelectors]) ifFalse:[
				self step.
				tokenType := #leftArrow.
				^token := #':='
		].
	].
	self allowUnderscoreSelectors ifTrue:[^self xLetter].
	^self xIllegal
! !

!Scanner methodsFor: 'private' stamp: 'jmv 3/24/2010 12:30'!
allowUnderscoreAssignments
	"Also see #allowUnderscoreSelectors.
	When true, $_ (left arrow / underscore) can be used as assignment operator"
	
"Important:
	If you set this preference to true, and the following character: _ looks like an underscore, evaluate
		StrikeFont useLeftArrow

	If you set this preference to false, be sure that #syntaxHighlightingAsYouTypeLeftArrowAssignment is also set to false.
	In addition, you'll most likely feel useful to set #syntaxHighlightingAsYouTypeAnsiAssignment to true
	Besides, if the following character: _ looks like a left arrow, you might prefer evaluating
		StrikeFont useUnderscore"

	^Preferences allowUnderscoreAssignments

"
On 3/12/2010 8:14 PM, Andreas Raab wrote:
> Folks -
>
> Attached my take on selectors with underscores. It basically separates
> the issue of using underscores in assignment from the issue of using
> underscores in selectors, puts this into two individual preferences, and
> allows per-class scoping while providing a system-wide default.
>
> The possible combinations of preferences are:
>
> * allowUnderscoreAssignments off, allowUnderscoreSelectors: off
> The use of underscores is forbidden, i.e., the Croquet model.
>
> * allowUnderscoreAssignments on, allowUnderscoreSelectors: off
> The classic Squeak usage; all of the following are assignments:
>
> a _ b => a := b
> b_ c => b := c
> d _e => d := e
> f_g => f := g.
>
> * allowUnderscoreAssignments off, allowUnderscoreSelectors: on
> The standard usage in other dialects
>
> a _ b => ((a) _) b
> b_ c => (b_) c
> d _e => (d) _e
> f_g => (f_g)
>
> * allowUnderscoreAssignments on, allowUnderscoreSelectors: on
> The hybrid usage requiring spaces around underscore for assignment:
>
> a _ b => a := b
> b_ c => (b_) c
> d _e => (d) _e
> f_g => (f_g)
>
> This gives us a range of options to decide how to deal with it. I would
> personally say that for the core image we should go with the first
> option (disable underscores altogether) and only enable whichever option
> we like for the release.
>
> What do people think about this approach? I think it provides the most
> options and gives us ample flexibility to decide what we'd like to use
> down the road.
>
> If there is no fundamental opposition I'll push it into the trunk in a
> couple of days.
>
> Cheers,
> - Andreas
"! !

!Scanner methodsFor: 'private' stamp: 'jmv 3/24/2010 12:31'!
allowUnderscoreSelectors
	"Also see #allowUnderscoreAssignments
	When true, $_ (left arrow / underscore) can be used in selectors and variable names
	
	If you set this preference to true, most likely you'll want character this: _ (character 95) to look like an underscore and not like a left arrow.
	For this, evaluate
		StrikeFont useUnderscore
	"
	^Preferences allowUnderscoreSelectors

	"At #allowUnderscoreAssignments see the bottom comment from a mail to squeak-dev by Andreas (ar)"! !


!Parser methodsFor: 'private' stamp: 'ar 3/12/2010 16:10'!
allowUnderscoreAssignments
	"Query class + preference"
	^encoder classEncoding allowUnderscoreAssignments
		ifNil:[super allowUnderscoreAssignments]! !

!Parser methodsFor: 'private' stamp: 'ar 3/12/2010 15:55'!
allowUnderscoreSelectors
	"Query class + preference"
	^encoder classEncoding allowUnderscoreSelectors
		ifNil:[super allowUnderscoreSelectors]! !


!Scanner class methodsFor: 'initialization' stamp: 'ar 3/12/2010 15:55'!
initialize
	| newTable |
	newTable := Array new: 256 withAll: #xBinary. "default"
	newTable atAll: #(9 10 12 13 32 ) put: #xDelimiter. "tab lf ff cr space"
	newTable atAll: ($0 asciiValue to: $9 asciiValue) put: #xDigit.

	1 to: 255
		do: [:index |
			(Character value: index) isLetter
				ifTrue: [newTable at: index put: #xLetter]].

	newTable at: 30 put: #doIt.
	newTable at: $" asciiValue put: #xDoubleQuote.
	newTable at: $# asciiValue put: #xLitQuote.
	newTable at: $$ asciiValue put: #xDollar.
	newTable at: $' asciiValue put: #xSingleQuote.
	newTable at: $: asciiValue put: #xColon.
	newTable at: $( asciiValue put: #leftParenthesis.
	newTable at: $) asciiValue put: #rightParenthesis.
	newTable at: $. asciiValue put: #period.
	newTable at: $; asciiValue put: #semicolon.
	newTable at: $[ asciiValue put: #leftBracket.
	newTable at: $] asciiValue put: #rightBracket.
	newTable at: ${ asciiValue put: #leftBrace.
	newTable at: $} asciiValue put: #rightBrace.
	newTable at: $^ asciiValue put: #upArrow.
	newTable at: $_ asciiValue put: #xUnderscore.
	newTable at: $| asciiValue put: #verticalBar.
	TypeTable := newTable "bon voyage!!"

	"Scanner initialize"! !


!Parser class methodsFor: 'class initialization' stamp: 'jmv 3/24/2010 11:29'!
initialize
		
	Preferences
		addPreference: #allowBlockArgumentAssignment 
		category: #compiler 
		default: false
		balloonHelp: 'If enabled, the compiler will allow assignment into block arguments.\This provides backward compatibility with the pre-closure compiler.' withCRs.
	Preferences
		addPreference: #allowUnderscoreAssignments 
		category: #compiler 
		default: true
		balloonHelp: 'When true, $_ (left arrow / underscore) can be used as assignment operator'.
	Preferences
		addPreference: #allowUnderscoreSelectors 
		category: #compiler 
		default: false
		balloonHelp: 'When true, $_ (left arrow / underscore) can be used in selectors and variable names'! !

Parser initialize!
Scanner initialize!
Preferences class removeSelector: #allowUnderscoreAssignment!
"Postscript:
Leave the line above, and replace the rest of this comment by a useful one.
Executable statements should follow this comment, and should
be separated by periods, with no exclamation points (!!).
Be sure to put any further comments in double-quotes, like this one."
Preferences removePreference: #allowUnderscoreAssignment.!

