'From Cuis 1.0 of 28 November 2009 [latest update: #337] on 3 January 2010 at 2:46:02 pm'!

!Compiler methodsFor: 'public access' stamp: 'jmv 1/3/2010 14:33'!
compiledMethodFor: textOrStream in: aContext to: receiver notifying: aRequestor ifFail: failBlock logged: logFlag
	"Compiles the sourceStream into a parse tree, then generates code
	 into a method, and answers it.  If receiver is not nil, then the text can
	 refer to instance variables of that receiver (the Inspector uses this).
	 If aContext is not nil, the text can refer to temporaries in that context
	 (the Debugger uses this). If aRequestor is not nil, then it will receive a 
	 notify:at: message before the attempt to evaluate is aborted."

	| methodNode method |
	class := (aContext == nil ifTrue: [receiver] ifFalse: [aContext receiver]) class.
	self from: textOrStream class: class context: aContext notifying: aRequestor.
	methodNode := self translate: sourceStream noPattern: true ifFail: [^failBlock value].
	method := methodNode generate: #(0 0 0 0).
	self interactive ifTrue:
		[method := method copyWithTempsFromMethodNode: methodNode].
	logFlag ifTrue:
		[SystemChangeNotifier uniqueInstance evaluated: sourceStream contents context: aContext].
	^method! !


!Integer methodsFor: 'printing' stamp: 'jmv 1/3/2010 14:42'!
numberOfDigitsInBase: b 
	"Return how many digits are necessary to print this number in base b.
	This does not count any place for minus sign, radix prefix or whatever.
	Note that this algorithm may cost a few operations on LargeInteger."

	| nDigits q |
	self negative ifTrue: [^self negated numberOfDigitsInBase: b].
	self < b ifTrue: [^1].
	b isPowerOfTwo	ifTrue: [^self highBit + b highBit - 2 quo: b highBit - 1].
	
	"A conversion from base 2 to base b has to be performed.
	This algorithm avoids Float computations like (self log: b) floor + 1,
	1) because they are inexact
	2) because LargeInteger might overflow
	3) because this algorithm might be cheaper than conversion"

	"Make an initial nDigits guess that is lower than or equal to required number of digits"
	b = 10
		ifTrue: [nDigits := ((self highBit - 1) * 3 quo: 10) + 1. "This is because 1024 is a little more than a kilo"]
		ifFalse: [nDigits := self highBit quo: b highBit].

	"See how many digits remains above these first nDigits guess"
	q := self quo: (b raisedTo: nDigits).
	^q = 0
		ifTrue: [nDigits]
		ifFalse: [nDigits + (q numberOfDigitsInBase: b)]! !

!Integer methodsFor: 'printing' stamp: 'jmv 1/3/2010 14:40'!
radix: base 
	^ self printStringBase: base! !


!LargePositiveInteger methodsFor: 'printing' stamp: 'jmv 1/3/2010 14:43'!
printStringBase: base
	"For LargeIntegers, it's faster to use the stream version.
	This reproduces Number implementation to avoid speed down if one defines Integer>>#printStringBase:
	This method should be removed if  Integer>>#printStringBase: is removed.
	Note: tests preallocating stream space with exact numberOfDigitsInBase: did not gain speed"
	
	^String streamContents: [:str | self printOn: str base: base]! !


!SmallInteger methodsFor: 'printing' stamp: 'jmv 1/3/2010 14:42'!
decimalDigitLength
	"Answer the number of digits printed out in base 10.
	Note that this only works for positive SmallIntegers."
	
	^ self < 10000
		ifTrue: [self < 100
				ifTrue: [self < 10
						ifTrue: [1]
						ifFalse: [2]]
				ifFalse: [self < 1000
						ifTrue: [3]
						ifFalse: [4]]]
		ifFalse: [self < 1000000
				ifTrue: [self < 100000
						ifTrue: [5]
						ifFalse: [6]]
				ifFalse: [self < 100000000
						ifTrue: [self < 10000000
								ifTrue: [7]
								ifFalse: [8]]
						ifFalse: [self < 1000000000
								ifTrue: [9]
								ifFalse: [10]]]]! !

!SmallInteger methodsFor: 'printing' stamp: 'jmv 1/3/2010 14:42'!
numberOfDigitsInBase: b 
	"Return how many digits are necessary to print this number in base b.
	Mostly same as super but an optimized version for base 10 case"
	
	b = 10 ifFalse: [^super numberOfDigitsInBase: b].
	self < 0 ifTrue: [^self negated numberOfDigitsInBase: b].
	^self decimalDigitLength! !

!SmallInteger methodsFor: 'printing' stamp: 'jmv 1/3/2010 14:42'!
printStringBase: b 
	"Return a String representation of this number in base b.
	For SmallIntegers, it is more efficient to print directly in a String,
	rather than using a Stream like super."

	self < 0
		ifTrue: [^ '-'
				, (self negated printStringBase: b)].
	self < b
		ifTrue: [^ String
				with: (Character digitValue: self)].
	^ self printStringBase: b nDigits: (self numberOfDigitsInBase: b)! !

!SmallInteger methodsFor: 'printing' stamp: 'jmv 1/3/2010 14:41'!
printStringBase: b nDigits: n
	"Return a string representation of this number in base b with n digits (left padded with 0).
	Should be invoked with: 0 <= self < (b raisedToInteger: n)."
	
	| integer next result |
	result := String new: n.
	integer := self.
	n to: 1 by: -1 do: [:i |
		next := integer // b.
		result byteAt: i put: (Character digitValue: (integer - (next * b))).
		integer := next].
	^result! !


!LargePositiveInteger reorganize!
('arithmetic' * + - / // \\ \\\ abs negated quo:)
('bit manipulation' bitAnd: bitOr: bitShift: bitXor: hashMultiply highBit highBitOfMagnitude)
('testing' negative positive sign strictlyPositive)
('comparing' < <= = > >= hash ~=)
('converting' as31BitSmallInt normalize withAtLeastNDigits:)
('system primitives' digitAt: digitAt:put: digitLength replaceFrom:to:with:startingAt:)
('printing' printStringBase:)
!

