Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.849.mcz ==================== Summary ==================== Name: Kernel-nice.849 Author: nice Time: 13 May 2014, 12:12:10.829 am UUID: c7a61a26-0156-479f-af39-9c351f618fc3 Ancestors: Kernel-nice.848 Authorize implicit specification of ScaledDecimal scale 123s -> 123.s0 , 0.27s -> 0.27s2 like VW and Pharo. (Issue http://bugs.squeak.org/view.php?id=7755) Note that if other letters follow the s, then s is not interpreted as a scale, because it could be a message. For example, (25sin) is interpreted as (25 sin) like in Pharo rather than (25s0 in) like in VW. This way, the chances of ambiguous interpretation of existing code base is limited to the sole message #s. =============== Diff against Kernel-nice.848 =============== Item was changed: ----- Method: ExtendedNumberParser>>nextNumber (in category 'parsing-public') ----- nextNumber "main method for reading a number. This one can read Float Integer and ScaledDecimal" | numberOfTrailingZeroInIntegerPart | base := 10. neg := self peekSignIsMinus. integerPart := self nextUnsignedIntegerOrNilBase: base. integerPart ifNil: [(sourceStream peekFor: $.) ifTrue: [ "Try .1 syntax" ^self readNumberWithoutIntegerPart] ifFalse: [ "This is not a regular number beginning with a digit It is time to check for exceptional condition NaN and Infinity" ^self readNamedFloatOrFail]]. numberOfTrailingZeroInIntegerPart := nDigits - lastNonZero. (sourceStream peekFor: $r) ifTrue: ["<base>r<integer>" | oldNeg pos | + pos := sourceStream position - 1. - pos := sourceStream position. (base := integerPart) < 2 ifTrue: ["A radix currently need to be greater than 1, ungobble the r and return the integer part" sourceStream skip: -1. ^neg ifTrue: [base negated] ifFalse: [base]]. oldNeg := neg. self peekSignIsMinus ifTrue: [neg := neg not]. integerPart := self nextUnsignedIntegerOrNilBase: base. integerPart ifNil: [ (sourceStream peekFor: $.) ifTrue: [self readNumberWithoutIntegerPartOrNil ifNotNil: [:aNumber | ^aNumber]]. sourceStream position: pos. ^oldNeg ifTrue: [base negated] ifFalse: [base]]. numberOfTrailingZeroInIntegerPart := nDigits - lastNonZero]. ^ (sourceStream peekFor: $.) ifTrue: [self readNumberWithFractionPartNumberOfTrailingZeroInIntegerPart: numberOfTrailingZeroInIntegerPart] ifFalse: [self makeIntegerOrScaledInteger]! Item was changed: ----- Method: ExtendedNumberParser>>readNumberWithFractionPartNumberOfTrailingZeroInIntegerPart: (in category 'parsing-private') ----- readNumberWithFractionPartNumberOfTrailingZeroInIntegerPart: numberOfTrailingZeroInIntegerPart "at this stage, sign integerPart and a decimal point have been read. try and form a number with a fractionPart" | numberOfNonZeroFractionDigits numberOfTrailingZeroInFractionPart mantissa value | fractionPart := self nextUnsignedIntegerOrNilBase: base. fractionPart + ifNil: + ["No fractionPart found, but can be a 1.e2 syntax" - ifNil: [ - "No fractionPart found, but can be a 1.e2 syntax" fractionPart := 0. + nDigits := 0. numberOfNonZeroFractionDigits := 0. numberOfTrailingZeroInFractionPart := 0] + ifNotNil: + [numberOfNonZeroFractionDigits := lastNonZero. - ifNotNil: [. - numberOfNonZeroFractionDigits := lastNonZero. numberOfTrailingZeroInFractionPart := nDigits - lastNonZero]. self readExponent + ifFalse: [(self readScaleWithDefaultNumberOfDigits: nDigits) + ifTrue: [^self + makeScaledDecimalWithNumberOfNonZeroFractionDigits: numberOfNonZeroFractionDigits - ifFalse: [self readScale - ifTrue: [^self makeScaledDecimalWithNumberOfNonZeroFractionDigits: numberOfNonZeroFractionDigits andNumberOfTrailingZeroInFractionPart: numberOfTrailingZeroInFractionPart]]. fractionPart isZero + ifTrue: + [mantissa := integerPart - ifTrue: [mantissa := integerPart // (base raisedToInteger: numberOfTrailingZeroInIntegerPart). exponent := exponent + numberOfTrailingZeroInIntegerPart] + ifFalse: + [mantissa := integerPart + * (base raisedToInteger: numberOfNonZeroFractionDigits) + + (fractionPart // (base raisedToInteger: numberOfTrailingZeroInFractionPart)). - ifFalse: [mantissa := integerPart - * (base raisedToInteger: numberOfNonZeroFractionDigits) + (fractionPart // (base raisedToInteger: numberOfTrailingZeroInFractionPart)). exponent := exponent - numberOfNonZeroFractionDigits]. value := self makeFloatFromMantissa: mantissa exponent: exponent base: base. ^ neg ifTrue: [value isZero ifTrue: [Float negativeZero] ifFalse: [value negated]] ifFalse: [value]! Item was changed: ----- Method: ExtendedNumberParser>>readNumberWithoutIntegerPartOrNil (in category 'parsing-private') ----- readNumberWithoutIntegerPartOrNil "at this stage, sign followed by a decimal point have been read, but no intergerPart try and form a number with a fractionPart" | numberOfNonZeroFractionDigits numberOfTrailingZeroInFractionPart mantissa value | integerPart := 0. fractionPart := self nextUnsignedIntegerOrNilBase: base. fractionPart ifNil: [ "No integer part, no fractionPart, this does not look like a number..." ^nil]. numberOfNonZeroFractionDigits := lastNonZero. numberOfTrailingZeroInFractionPart := nDigits - lastNonZero. self readExponent + ifFalse: [(self readScaleWithDefaultNumberOfDigits: nDigits) - ifFalse: [self readScale ifTrue: [^self makeScaledDecimalWithNumberOfNonZeroFractionDigits: numberOfNonZeroFractionDigits andNumberOfTrailingZeroInFractionPart: numberOfTrailingZeroInFractionPart]]. fractionPart isZero ifTrue: [mantissa := 0] ifFalse: [mantissa := (fractionPart // (base raisedToInteger: numberOfTrailingZeroInFractionPart)). exponent := exponent - numberOfNonZeroFractionDigits]. value := self makeFloatFromMantissa: mantissa exponent: exponent base: base. ^ neg ifTrue: [value isZero ifTrue: [Float negativeZero] ifFalse: [value negated]] ifFalse: [value]! Item was changed: ----- Method: SqNumberParser>>makeIntegerOrScaledInteger (in category 'parsing-private') ----- makeIntegerOrScaledInteger "at this point, there is no digit, nor fractionPart. maybe it can be a scaled decimal with fraction omitted..." neg ifTrue: [integerPart := integerPart negated]. self readExponent ifTrue: [^integerPart * (base raisedToInteger: exponent)]. + (self readScaleWithDefaultNumberOfDigits: 0) + ifTrue: [^integerPart asScaledDecimal: scale]. - self readScale - ifTrue: [^ScaledDecimal newFromNumber: integerPart scale: scale]. ^ integerPart! Item was changed: ----- Method: SqNumberParser>>makeScaledDecimalWithNumberOfNonZeroFractionDigits:andNumberOfTrailingZeroInFractionPart: (in category 'parsing-private') ----- makeScaledDecimalWithNumberOfNonZeroFractionDigits: numberOfNonZeroFractionDigits andNumberOfTrailingZeroInFractionPart: numberOfTrailingZeroInFractionPart "at this point integerPart fractionPart and scale have been read out (in inst var). Form a ScaledDecimal. Care of eliminating trailing zeroes from the fractionPart" | decimalMultiplier decimalFraction | decimalMultiplier := base raisedToInteger: numberOfNonZeroFractionDigits. decimalFraction := integerPart * decimalMultiplier + (fractionPart // (base raisedTo: numberOfTrailingZeroInFractionPart)) / decimalMultiplier. + neg + ifTrue: [decimalFraction := decimalFraction negated]. + ^decimalFraction asScaledDecimal: scale! - ^ ScaledDecimal - newFromNumber: (neg - ifTrue: [decimalFraction negated] - ifFalse: [decimalFraction]) - scale: scale! Item was changed: ----- Method: SqNumberParser>>nextScaledDecimal (in category 'parsing-public') ----- nextScaledDecimal "Main method for reading a (scaled) decimal number. Good Gracious, do not accept a decimal in another base than 10!! In other words, do not accept radix notation like 2r1.1, even not 10r5.3 Do not accept exponent notation neither, like 1.0e-3" | numberOfNonZeroFractionDigits numberOfTrailingZeroInFractionPart | base := 10. neg := sourceStream peekFor: $-. integerPart := self nextUnsignedIntegerBase: base. (sourceStream peekFor: $.) ifTrue: [fractionPart := self nextUnsignedIntegerOrNilBase: base. fractionPart ifNil: ["Oops, the decimal point seems not part of this number" sourceStream skip: -1. ^ neg ifTrue: [integerPart negated asScaledDecimal: 0] ifFalse: [integerPart asScaledDecimal: 0]]. numberOfNonZeroFractionDigits := lastNonZero. numberOfTrailingZeroInFractionPart := nDigits - lastNonZero. + (self readScaleWithDefaultNumberOfDigits: nDigits) - self readScale ifFalse: ["No scale were provided. use number of digits after decimal point as scale" scale := nDigits]. ^self makeScaledDecimalWithNumberOfNonZeroFractionDigits: numberOfNonZeroFractionDigits andNumberOfTrailingZeroInFractionPart: numberOfTrailingZeroInFractionPart]. + self readScaleWithDefaultNumberOfDigits: 0. - self readScale. neg ifTrue: [integerPart := integerPart negated]. ^integerPart asScaledDecimal: scale! Item was changed: ----- Method: SqNumberParser>>readNumberWithFractionPartNumberOfTrailingZeroInIntegerPart: (in category 'parsing-private') ----- readNumberWithFractionPartNumberOfTrailingZeroInIntegerPart: numberOfTrailingZeroInIntegerPart "at this stage, sign integerPart and a decimal point have been read. try and form a number with a fractionPart" | numberOfNonZeroFractionDigits numberOfTrailingZeroInFractionPart mantissa value | fractionPart := self nextUnsignedIntegerOrNilBase: base. fractionPart ifNil: ["No fractionPart found,ungobble the decimal point and return the integerPart" sourceStream skip: -1. ^ neg ifTrue: [integerPart negated] ifFalse: [integerPart]]. numberOfNonZeroFractionDigits := lastNonZero. numberOfTrailingZeroInFractionPart := nDigits - lastNonZero. self readExponent + ifFalse: [(self readScaleWithDefaultNumberOfDigits: nDigits) - ifFalse: [self readScale ifTrue: [^self makeScaledDecimalWithNumberOfNonZeroFractionDigits: numberOfNonZeroFractionDigits andNumberOfTrailingZeroInFractionPart: numberOfTrailingZeroInFractionPart]]. fractionPart isZero ifTrue: [mantissa := integerPart // (base raisedToInteger: numberOfTrailingZeroInIntegerPart). exponent := exponent + numberOfTrailingZeroInIntegerPart] ifFalse: [mantissa := integerPart * (base raisedToInteger: numberOfNonZeroFractionDigits) + (fractionPart // (base raisedToInteger: numberOfTrailingZeroInFractionPart)). exponent := exponent - numberOfNonZeroFractionDigits]. value := self makeFloatFromMantissa: mantissa exponent: exponent base: base. ^ neg ifTrue: [value isZero ifTrue: [Float negativeZero] ifFalse: [value negated]] ifFalse: [value]! Item was removed: - ----- Method: SqNumberParser>>readScale (in category 'parsing-private') ----- - readScale - "read the scale if any (stored in instVar). - Answer true if found, answer false if none. - If scale letter is not followed by a digit, this is not considered as an error. - Scales are always read in base 10, though i do not see why..." - - scale := 0. - sourceStream atEnd ifTrue: [^ false]. - (sourceStream peekFor: $s) - ifFalse: [^ false]. - scale := self nextUnsignedIntegerOrNilBase: 10. - scale ifNil: [ - scale := 0. - sourceStream skip: -1. "ungobble the s" - ^ false]. - ^ true! Item was added: + ----- Method: SqNumberParser>>readScaleWithDefaultNumberOfDigits: (in category 'parsing-private') ----- + readScaleWithDefaultNumberOfDigits: anInteger + "Read the scale if any and store it into scale instance Variable. + Answer true if found, answer false if none. + The scale is specified by letter s, optionnally followed by a positive integer in base 10. + If no integer is specified, that means using as many digits as provided after the fraction separator, as provided by parameter anInteger. + A letter s followed by another letter is not considered as a scale specification, because it could be part of a message." + + scale := 0. + sourceStream atEnd + ifTrue: [ ^ false ]. + (sourceStream peekFor: $s) + ifFalse: [ ^ false ]. + scale := self nextUnsignedIntegerOrNilBase: 10. + scale + ifNil: [ + scale := anInteger. + (sourceStream peek ifNil: [ false ] ifNotNil: [ :nextChar | nextChar isLetter ]) + ifTrue: [ + sourceStream skip: -1. "ungobble the s" + ^ false ] + ifFalse: [ ^ true ] ]. + ^ true! |
Free forum by Nabble | Edit this page |