Refactoring ScaledDecimal literals?

VA Smalltalk is a "100% VisualAge compatible" IDE that includes the original VisualAge technology and the popular VA Assist and WidgetKit add-ons.

Moderators: Eric Clayberg, wembley, tc, Diane Engles, solveig

Refactoring ScaledDecimal literals?

Postby bpieber » Sat Dec 15, 2007 5:20 am

The Refactoring Browser introduces compile errors in methods with ScaledDecimal literals. It replaces 0s with 0 s and 100s with 100 s.

Does anyone know how to fix or work around this?

Cheers,
Bernhard
bpieber
 
Posts: 27
Joined: Sat Nov 04, 2006 4:00 am

Postby tc » Sun Dec 16, 2007 5:46 am

Hello,

I added the following method to a class using the Refactoring browser in VA Smalltalk 7.5:
Code: Select all
num
   | num |
   num := 0s.
   ^num


. . . and called it. It returned a ScaledDecimal, as expected. If you do not have the latest browser, it can be downloaded from http://www.refactory.com.

--tc
tc
Moderator
 
Posts: 304
Joined: Tue Oct 17, 2006 7:40 am
Location: Raleigh, NC

Postby bpieber » Sun Dec 16, 2007 7:12 am

Hi tc,

Thanks for answering. I realize I should have described my problem better. When I do the following:

- Select 0s in your new method.
- Do Selection > Extract to Temporary...
- Enter a as the name of the temporary variable

I get the following:
Code: Select all
num
   | num a |
   a := 0 s.
   num := a.
   ^num

Note the space between 0 and s.

I tried this in a vanilla 7.5.2 image.

Cheers,
Bernhard
bpieber
 
Posts: 27
Joined: Sat Nov 04, 2006 4:00 am

Postby bpieber » Sun Dec 16, 2007 7:30 am

A small addition: I just tried it in the newest version I downloaded from customrefactor.sourceforge.net, Camp Smalltalk 12 Release Candidate 2. The bug seems to be in there as well.

Bernhard
bpieber
 
Posts: 27
Joined: Sat Nov 04, 2006 4:00 am

Postby bpieber » Sun Dec 16, 2007 9:02 am

I looked into the problem. It does not happen under VisualWorks. It seems to be in the RBParser. Whereas
Code: Select all
RBParser parseExpression: '0s'
returns an RBLiteralValueNode in VW it returns an RBMessageNode in VA Smalltalk.

RBScanner>>#scanNumberIBM seems not to account for ScaledDecimal literals.

Cheers,
Bernhard
bpieber
 
Posts: 27
Joined: Sat Nov 04, 2006 4:00 am

VA RB parsing of ..s..

Postby NiallRoss » Tue Dec 18, 2007 10:15 am

The VA RB's #scanNumberIBM calls

Code: Select all
scanNumberWithoutExponent
    ...
    (currentCharacter == $r ...)
        ifTrue: ...
        ifFalse: [number := base]


which lacks an equivalent to the ifFalse: clause behaviour in the VW RB's
Code: Select all
readSmalltalkSyntaxFrom:
    (aStream peekFor: $r)
        ifTrue: ...
        ifFalse: [self readSmalltalkFloat: ... from: ...]

where readSmalltalkFloat:from: leads to a call of

Code: Select all
           self chooseFloatRepresentationFor: eChar


which detects the 's' and returns a FixedPoint.

It appears the VA RB code never handled SCaledDecimals although I am surprised this could have lived apparently unnoticed in the RB till now, given that the VW code was correct as far back as VW3 at least.

The ifFalse: clause in scanNumberWithoutExponent looks like the right place to fix this. Ideally we would call a VA base image method (or methods) resembling VW base methods readSmalltalkFloat:from: and chooseFloatRepresentationFor:. (Anyone knowing suitable methods please indicate.) Alternatively, we could clone chooseFloatRepresentationFor: and some related code to the relevant VA classes.

----
Code: Select all
chooseFloatRepresentationFor: exponentChar
(('deqs' includes: exponentChar)
   or: [SystemUtils isVW20LanguageCompatible
   and: [exponentChar = $f]])
  ifFalse: [^nil].
exponentChar == Float exponentCharacter
  ifTrue: [^Float].
(exponentChar == Double exponentCharacter
   or: [exponentChar == Double altExponentCharacter])
  ifTrue: [^Double].
(exponentChar == FixedPoint exponentCharacter
   or: [exponentChar == $f])
  ifTrue: [^FixedPoint].
^self error: (#errExponentNotSupported << #dialogs >> 'This exponent character has not been adequately supported')

readSmalltalkFloat: integerPart from: aStream
...
...
eChar == nil
  ifTrue: [possibleCoercionClass := nil]
  ifFalse:
   [SystemUtils isVW20LanguageCompatible ifTrue: [eChar := eChar asLowercase].
   possibleCoercionClass := self chooseFloatRepresentationFor: eChar.
   possibleCoercionClass == nil ifFalse: [aStream next]].
exp := nil.
possibleCoercionClass == nil
  ifFalse:
   [coercionClass := possibleCoercionClass.
   endOfNumber := aStream position.
   neg := aStream peekFor: $-.
   ((digit := aStream peek) notNil and: [digit isDigit])
    ifTrue:
     [exp := self readIntegerFrom: aStream radix: 10.
     neg ifTrue: [exp := exp negated]]
    ifFalse: [aStream position: endOfNumber]].
value := integerPart + (num / den). "The exponent will be added in the next step."
^self
  coerce: value
  to: coercionClass
  precision: precision
  exponent: exp
  exponentChar: eChar
NiallRoss
 
Posts: 2
Joined: Tue Dec 18, 2007 9:24 am
Location: UK

Postby bpieber » Wed Dec 19, 2007 3:00 pm

Anyone knowing suitable methods please indicate.


I have looked around a little bit for a VA Smalltalk method to reuse and I found EsScanner>>#readNumber.

However, to reuse it from RBScanner it would have to be refactored. It references the EsScanner instance variables sourceString and currentPosition and calls the EsScanner instance methods #number:, #syntaxError: and #readExponent.

The algorithm could be moved to a NumberScanner which would be used from EsScanner and RBScanner. What do others think?

SUnit tests for EsScanner would be great to have before such a refactoring, though. I wonder if Instantiations has such tests?

Cheers,
Bernhard
bpieber
 
Posts: 27
Joined: Sat Nov 04, 2006 4:00 am


Return to VA Smalltalk 7.0, 7.5 & 8.0

Who is online

Users browsing this forum: Yahoo [Bot] and 1 guest