Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.424.mcz ==================== Summary ==================== Name: Kernel-nice.424 Author: nice Time: 14 March 2010, 11:19:27.192 pm UUID: 0ed744aa-5d6e-470a-9adc-a064c3d874df Ancestors: Kernel-laza.423 Cache well known digit values in NumberParser for speed. Testing the base as of previous implementation was not a good idea, because some Unicode characters could have a digitValue < 10. =============== Diff against Kernel-laza.423 =============== Item was added: + ----- Method: NumberParser classSide>>initializeDigitValues (in category 'class initialization') ----- + initializeDigitValues + "Initialize the well known digit value of ascii characters." + + DigitValues := Array new: 256 withAll: -1. + 0 to: 255 do: [:i | DigitValues at: i + 1 put: (Character value: i) digitValue]! Item was added: + ----- Method: NumberParser classSide>>initialize (in category 'class initialization') ----- + initialize + self initializeDigitValues.! Item was changed: ----- Method: NumberParser>>nextElementaryLargeIntegerBase: (in category 'parsing-large int') ----- nextElementaryLargeIntegerBase: aRadix "Form an unsigned integer with incoming digits from sourceStream. Return this integer, or zero if no digits found. Stop reading if end of digits or if a LargeInteger is formed. Count the number of digits and the position of lastNonZero digit and store them in instVar" + | value digit code char | - | value digit | value := 0. nDigits := 0. lastNonZero := 0. + DigitValues ifNil: [self class initializeDigitValues]. + "Avoid using digitValue which is awfully slow" + [value isLarge or: [(char := sourceStream next) == nil + or: [code := char charCode. + digit := code < 256 + ifTrue: [DigitValues at: 1 + code] + ifFalse: [char digitValue]. + (0 > digit or: [digit >= aRadix]) + and: [sourceStream skip: -1. + true]]]] + whileFalse: [ + nDigits := nDigits + 1. + 0 = digit + ifFalse: [lastNonZero := nDigits]. + value := value * aRadix + digit]. - aRadix <= 10 - ifTrue: ["Avoid using digitValue which is awfully slow" - [value isLarge or: [sourceStream atEnd - or: [digit := sourceStream next charCode - 48. - (0 > digit - or: [digit >= aRadix]) - and: [sourceStream skip: -1. - true]]]] - whileFalse: [nDigits := nDigits + 1. - 0 = digit - ifFalse: [lastNonZero := nDigits]. - value := value * aRadix + digit]] - ifFalse: [ - [value isLarge or: [sourceStream atEnd - or: [digit := sourceStream next digitValue. - (0 > digit - or: [digit >= aRadix]) - and: [sourceStream skip: -1. - true]]]] - whileFalse: [nDigits := nDigits + 1. - 0 = digit - ifFalse: [lastNonZero := nDigits]. - value := value * aRadix + digit]]. ^value! Item was changed: Object subclass: #NumberParser instanceVariableNames: 'sourceStream base neg integerPart fractionPart exponent scale nDigits lastNonZero requestor failBlock' + classVariableNames: 'DigitValues' - classVariableNames: '' poolDictionaries: '' category: 'Kernel-Numbers'! + !NumberParser commentStamp: 'nice 3/14/2010 22:42' prior: 0! - !NumberParser commentStamp: 'nice 2/25/2010 02:34' prior: 0! NumberParser is an abstract class for parsing and building numbers from string/stream. It offers a framework with utility methods and exception handling. Number syntax is not defined and should be subclassResponsibility. + Note that class variable DigitValues is a duplication of Character class variable. This is only an optimization, decoding digitValues being a major contributor of algorithm cost. + Instance variables: sourceStream <Stream> the stream of characters from which the number is read base <Integer> the radix in which to interpret digits neg <Boolean> true in case of minus sign integerPart <Integer> the integer part of the number fractionPart <Integer> the fraction part of the number if any exponent <Integer> the exponent used in scientific notation if any scale <Integer> the scale used in case of ScaledDecimal number if any nDigits <Integer> number of digits read to form an Integer lasNonZero <Integer> position of last non zero digit, starting at 1 from left, 0 if all digits are zero requestor <TextEditor | nil> can be used to insert an error message in the requestor failBlock <BlockClosure> Block to execute whenever an error occurs. + The fail block can have 0, 1 or 2 arguments (errorString and source position) + + Class variables: + DigitValues <Array of: Integer> this is a mapping character asciiCode + 1 -> digit value (or -1 if character is not a digit)! - The fail block can have 0, 1 or 2 arguments (errorString and source position)! |
Free forum by Nabble | Edit this page |