> On 18 Sep 2018, at 16:45, Sven Van Caekenberghe <[email protected]> wrote:
> 
> Of course, we could also extend the basic number parser and allow the native 
> (stored) notation
> 
> 1/3
> 3/2s2
> 
> Note how that last one should use the more exact #storeOn: notation, not the 
> #printOn: 
> 
> I'll have to think about this a bit more, as I can really not choose right 
> now.

I am still not sure if we should do this or not, but here is a POC 
implementation of the above.

It implements the following syntax extension (see the class comment of STON for 
the rest).

number
  int
  int denominator
  int denominator scale
  int frac
  int exp
  int frac exp

denominator
  / digits

scale
  s digits


STONWriter>>#writeFraction: fraction
        jsonMode
                ifTrue: [ self writeFloat: fraction asFloat ] 
                ifFalse: [
                        writeStream
                                print: fraction numerator;
                                nextPut: $/;
                                print: fraction denominator ]

STONWriter>>#writeScaledDecimal: scaledDecimal
        jsonMode
                ifTrue: [ self writeFloat: scaledDecimal asFloat ]
                ifFalse: [ 
                        writeStream
                                print: scaledDecimal numerator;
                                nextPut: $/;
                                print: scaledDecimal denominator;
                                nextPut: $s;
                                print: scaledDecimal scale ]

Fraction>>#stonOn: stonWriter
        stonWriter writeFraction: self

ScaledDecimal>>#stonOn: stonWriter
        stonWriter writeScaledDecimal: self

STONReader>>parseNumber
        | negated number |
        negated := readStream peekFor: $-.
        number := self parseNumberInteger.
        (readStream peekFor: $/)
                ifTrue: [ 
                        number := Fraction numerator: number denominator: self 
parseNumberInteger.
                        (readStream peekFor: $s)
                                ifTrue: [ number := ScaledDecimal 
newFromNumber: number scale: self parseNumberInteger ] ]
                ifFalse: [ 
                        (readStream peekFor: $.)
                                ifTrue: [ number := number + self 
parseNumberFraction ].
                        ((readStream peekFor: $e) or: [ readStream peekFor: $E 
])
                                ifTrue: [ number := number * self 
parseNumberExponent ] ].
        negated
                ifTrue: [ number := number negated ].
        self consumeWhitespace.
        ^ number

Sven


Reply via email to