Hi José, Thanks for your feedback, suggestions and code. I incorporated a slightly changed version (fixing the precision issue; you also did not provided the necessary changes to support writing Fractions and ScaledDecimals). I also added some unit tests. In #bleedingEdge: === Name: STON-Core-SvenVanCaekenberghe.50 Author: SvenVanCaekenberghe Time: 2 June 2014, 12:52:39.808591 pm UUID: ce24c992-4f32-4f3a-8853-a4a9cf55c453 Ancestors: STON-Core-SvenVanCaekenberghe.49 Add support for Fractions and ScaledDecimals as primitive numbers (thx José Comesaña): - add Fraction>>#stonOn: delegating to STONWriter>>#writeFraction: - add ScaledDecimal>>#stonOn: delegating to STONWriter>>#writeScaledDecimal: - extended STONReader>>#parseNumber to allow / and s notations - changed STONReader>>#parseNumberFraction to return pure Fractions as required by ScaledDecimal === Name: STON-Tests-SvenVanCaekenberghe.45 Author: SvenVanCaekenberghe Time: 2 June 2014, 12:53:39.436939 pm UUID: bf7a8e27-4b7b-4a0e-b517-6321c1da1694 Ancestors: STON-Tests-SvenVanCaekenberghe.44 Add support for Fractions and ScaledDecimals as primitive numbers (thx José Comesaña). Added specific tests for Fractions and ScaledDecimals === Please let me know if this works for you. Regards, Sven On 02 Jun 2014, at 01:56, José Comesaña <jose.comesana@gmail.com> wrote:
And this is an improved version. More changes to avoid parsing weird things as 123.456s3e2 (it could be improved, for sure, but I don't have any more time...)
parseNumber | negated number | negated := readStream peekFor: $-. number := self parseNumberInteger. (readStream peekFor: $.) ifTrue: [ number := number + self parseNumberFraction ]. (readStream peekFor: $s) ifTrue: [ | scale | scale := self parseNumberInteger. number := ScaledDecimal newFromNumber: number scale: scale ] ifFalse: [ (readStream peekFor: $/) ifTrue: [ | denominator | denominator := self parseNumberInteger. number := Fraction numerator: number denominator: denominator ] ifFalse: [ ((readStream peekFor: $e) or: [ readStream peekFor: $E ]) ifTrue: [ number := number * self parseNumberExponent ]. ] ]. negated ifTrue: [ number := number negated ]. self consumeWhitespace. ^ number
2014-06-02 1:51 GMT+02:00 José Comesaña <jose.comesana@gmail.com>: Hi Sven.
First of all, I know that in VisualWorks there exists a class called FixedPoint, that is (more or less) similar to ScaledDecimal (is what the class comment says). But, instead of 123.45s2, VWs writes 123.45s. NEVERTHELESS, it can read 123.45s2 with no pain.
There exists a Fraction type also in VW, which, I believe, uses the same notation as in Pharo.
I know that portability is an important issue, but, at least for me, portability from Pharo to Pharo is the most important. I depend on ScaledDecimal for an application (for storing money values -changing the storage mode is not an option now-) and need the possibility of converting it to string and reading it back. The string version is my database, that gets loaded into memory upon program start.
You can see here the changes I have made to STONReader >>#parseNumber:
parseNumber | negated number | negated := readStream peekFor: $-. number := self parseNumberInteger. (readStream peekFor: $.) ifTrue: [ number := number + self parseNumberFraction ]. " -------------- New from here -------------- " (readStream peekFor: $s) ifTrue: [ | scale | scale := self parseNumberInteger. number := ScaledDecimal newFromNumber: number scale: scale ]. (readStream peekFor: $/) ifTrue: [ | denominator | denominator := self parseNumberInteger. number := Fraction numerator: number denominator: denominator ]. " -------------- to here -------------- " ((readStream peekFor: $e) or: [ readStream peekFor: $E ]) ifTrue: [ number := number * self parseNumberExponent ]. negated ifTrue: [ number := number negated ]. self consumeWhitespace. ^ number â I am a newbie about STON. I don't know if it is correct, but it works for me, at least for some tests I have made. I know it needs improvements, thinking about strange strings we could receive. But I trust the writer not to create such weird things.
I could suggest another way of making the function of parseNumber (OK, OK, I know I am thinking from a Pharo-only perspective...). Seeing that number parsing always ends with this condition:
readStream atEnd not and: [ readStream peek isDigit ]
why not create a temporary string (including possibility of $e, $s, $/, even $@ ...) to that point (tmpString) and do:
number := Number readFromString: tmpString
That way, we would have a "native" parsing in each language
Hope this helps. If someone needs more information, pleas ask.
Best regards
2014-05-31 21:29 GMT+02:00 Sven Van Caekenberghe <sven@stfx.eu>:
Hi José,
On 31 May 2014, at 01:32, José Comesaña <jose.comesana@gmail.com> wrote:
Wouldn't it be good if STON could save ScaledDecimals as 12345.678s?. That way, we could read them back again as ScaledDecimal, instead of Float. I have tried and it seems quite useful.
Regards
That is an interesting idea and it is probably nice to have for those relying on ScaledDecimals.
One of the ideas of STON is to be portable across dialects, so I am wondering if ScaledDecimals exists everywhere ?
I am curious as to how you did it though, since STONReader basically contains its own number parser. Could you share your code ?
Sven