Done, that was simple.
But now we need using a Parser able to parse a decimal representation of a Float without accumulating rounding errors. That is SqNumberParser.
Untill then, we won't interpret correctly the decompiled code we printed correctly...
Nicolas
2009/10/31 Nicolas Cellier nicolas.cellier.aka.nice@gmail.com:
Hehe, I've got a plan.
Use storeOn: rather than printOn: to produce the decompileString. It will be the same for all literals, but Float in which I will override storeOn:
My plan is to print exactly if isFinite, or invoke a message pattern otherwise (Float nan, Float infinity, Float infinity negated). Note that these exceptional values are not literals (I already fixed that).
Nicolas
2009/10/31 Nicolas Cellier nicolas.cellier.aka.nice@gmail.com:
2009/10/31 Nicolas Cellier nicolas.cellier.aka.nice@gmail.com:
2009/10/31 Stéphane Rollandin lecteur@zogotounga.net:
If the meaning of #isLiteral is to indicate that what is printed can be read back (i.e. will be correctly parsed) then I think it is a very useful message that we should keep.
#isLiteral mainly indicates which objects can be created at compile time. They are literally inserted in the compiled method. This must match the syntax definition of Squeak. There is no question about not keeping it.
now I'm confused. are all objects anwering true to #isLiteral also have a printed form that can be read back ? should they ?
Stef
I think this is used as a feature at least in Decompiler.
But can they all be read back ? Float can't always with the current implementation (they don't print exactly).
(Compiler evaluate: Float halfPi printString) = Float halfPi
Nicolas
By the way, there is a workaround in CompiledMethod>>#=
self isFloat ifTrue: [...]
The #halt: in there sounds like calling for a better fix. For example, the workaround does not work with a literal Array of Float...
Nor does it deal with infinity: (Float class compile: (Float class >> #initialize) decompileString classified: nil notifying: requestor trailer: Float class defaultMethodTrailer ifFail: [^nil]) method = (Float class >> #initialize)
We have an excellent absPrintExactlyOn:base: that avoids extra digits when unnecessary... ...but it is 3x to 10x slower and nobody dared generalizing its usage.
{0.0. Float pi. Float pi * 1.0e200. Float pi * 1.0e-200 . 10.0 . 0.1 . 237.128} collect: [:e | [String streamContents: [:s | e absPrintExactlyOn: s base: 10]] bench ->[String streamContents: [:s | e printOn: s base: 10]] bench]
{'12131.77364527095 per second.'->'63358.65653738505 per second.'. '1535.292941411718 per second.'->'6756.64867026595 per second.'. '653.669266146771 per second.'->'6667.066586682664 per second.'. '1004.199160167966 per second.'->'5857.82843431314 per second.'. '8732.85342931414 per second.'->'26025.3949210158 per second.'. '8635.87282543491 per second.'->'19715.45690861827 per second.'. '2666.26674665067 per second.'->'13040.99180163967 per second.'}
Nicolas