[squeak-dev] The Inbox: Kernel-cmfcmf.1216.mcz

commits at source.squeak.org commits at source.squeak.org
Wed May 29 20:12:00 UTC 2019

A new version of Kernel was added to project The Inbox:

==================== Summary ====================

Name: Kernel-cmfcmf.1216
Author: cmfcmf
Time: 29 May 2019, 10:09:51.240802 pm
UUID: 3c20ffc1-89f8-474e-95a7-05fab06c9f9b
Ancestors: Kernel-eem.1215

Make Random>>roll: work again and add support for constant operands

This version fixes three issues:

1. Random>>roll: was not working anymore. The following code only produced an error:

Random new roll: '1d20'

This happened due to an issue with Random>>diceToken: which used Number>>readFrom: to extract numbers from the string. Calling Number readFrom: '1d20' results in 100000000000000000000 instead of the expected 1, because $d is seen as an exponent letter by the ExtendedNumberParser used by Number>>readFrom: (see ExtendedNumberParser>>exponentLetters).
I therefore replaced Number>>readFrom: by Integer>>readFrom:, which doesn't use the exponent letters.

2. I also fixed a minor issue with the mini-grammar's 'dice' rule. Before this version, it read as if it only supported one or two operands, when it really supported an unlimited number of operands.

3. The mini-grammer's 'expr' rule read as if it supported constant operands (e.g., '1d20+5' or '42'), because 'expr' was allowed to be just 'num'. As far as I can gather, this has never worked (but I might be wrong). This is now also fixed by always setting res to the token read if the token is a number. If the token is neither a number nor $d, an error is now signalled.

=============== Diff against Kernel-eem.1215 ===============

Item was changed:
  ----- Method: Random>>diceToken: (in category 'die rolling') -----
  diceToken: stream
  	"Private. Mini scanner, see #roll:"
  	stream atEnd ifTrue: [^ nil].
+ 	stream peek isDigit ifTrue: [^ Integer readFrom: stream].
- 	stream peek isDigit ifTrue: [^ Number readFrom: stream].
  	^ stream next asLowercase!

Item was changed:
  ----- Method: Random>>roll: (in category 'die rolling') -----
  roll: diceString
  	"Roll some dice, DnD-style, according to this mini-grammar:
+ 		dice := epxr {pm dice}
- 		dice := epxr {pm expr}
  		pm := '+' | '-'
  		expr := num | num dD | dD numP | num dD numP
  		dD := 'd' | 'D'
  		num := digit+
  		numP := num | '%'"
  	| stream op result |
  	stream := diceString readStream.
  	result := 0.
  	op := #+.
  	[ | res range dice token |
  	token := self diceToken: stream.
  	token isNumber
  		ifTrue: [dice := token.
+ 				res := token.
  				token := self diceToken: stream]
  		ifFalse: [token == $d
  			ifTrue: [dice := 1]
+ 			ifFalse: [self error: 'unknown token' , token]].
- 			ifFalse: [res := 0]].
  	token == $d
  		ifTrue: [token := self diceToken: stream.
  				token isNumber
  					ifTrue: [range := token.
  							token := self diceToken: stream]
  					ifFalse: [token == $%
  						ifTrue: [range := 100.
  								token := self diceToken: stream]
  						ifFalse: [range := 6]].
  				res := 0.
  				dice timesRepeat: [res := res + (self nextInt: range)]].
  	result := result perform: op with: res.
  	token ifNil: [^ result].
  	(token == $+ or: [token == $-])
  		ifFalse: [self error: 'unknown token ' , token].
  	op := token asSymbol] repeat!

More information about the Squeak-dev mailing list