crapshoot 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/README.rdoc +6 -2
- data/lib/crapshoot/parser/scan.rb +51 -34
- data/lib/crapshoot/parser/scan.rl +1 -1
- data/lib/crapshoot/postfixer.rb +28 -4
- data/lib/crapshoot/tokens/arithmetic.rb +9 -0
- data/lib/crapshoot/tokens/base.rb +3 -0
- data/lib/crapshoot/version.rb +1 -1
- data/test/crapshoot_test.rb +7 -0
- data/test/postfixer_test.rb +5 -1
- metadata +3 -3
data/.gitignore
CHANGED
data/README.rdoc
CHANGED
@@ -12,9 +12,13 @@ You might otherwise want to roll three twenty-sided dice and drop the highest, a
|
|
12
12
|
|
13
13
|
Crapshoot.roll '3d20^+6'
|
14
14
|
|
15
|
-
Or you might just want nine:
|
15
|
+
Or you might just want nine divided by three:
|
16
16
|
|
17
|
-
Crapshoot.roll '9'
|
17
|
+
Crapshoot.roll '9 / 3'
|
18
|
+
|
19
|
+
Crapshoot supports addition, subtraction, multiplication, and division with correct order of operations:
|
20
|
+
|
21
|
+
Crapshoot.roll '1 + 2 * 3' # returns seven
|
18
22
|
|
19
23
|
== Rolling Dice
|
20
24
|
|
@@ -27,10 +27,10 @@ class << self
|
|
27
27
|
private :_scanner_trans_keys, :_scanner_trans_keys=
|
28
28
|
end
|
29
29
|
self._scanner_trans_keys = [
|
30
|
-
0, 0, 48, 57, 9,
|
30
|
+
0, 0, 48, 57, 9, 47,
|
31
31
|
9, 57, 9, 57, 48,
|
32
32
|
57, 9, 100, 9, 118,
|
33
|
-
9,
|
33
|
+
9, 47, 0
|
34
34
|
]
|
35
35
|
|
36
36
|
class << self
|
@@ -38,8 +38,8 @@ class << self
|
|
38
38
|
private :_scanner_key_spans, :_scanner_key_spans=
|
39
39
|
end
|
40
40
|
self._scanner_key_spans = [
|
41
|
-
0, 10,
|
42
|
-
|
41
|
+
0, 10, 39, 49, 49, 10, 92, 110,
|
42
|
+
39
|
43
43
|
]
|
44
44
|
|
45
45
|
class << self
|
@@ -47,8 +47,8 @@ class << self
|
|
47
47
|
private :_scanner_index_offsets, :_scanner_index_offsets=
|
48
48
|
end
|
49
49
|
self._scanner_index_offsets = [
|
50
|
-
0, 0, 11,
|
51
|
-
|
50
|
+
0, 0, 11, 51, 101, 151, 162, 255,
|
51
|
+
366
|
52
52
|
]
|
53
53
|
|
54
54
|
class << self
|
@@ -61,52 +61,52 @@ self._scanner_indicies = [
|
|
61
61
|
1, 1, 1, 1, 1, 1, 1, 1,
|
62
62
|
1, 1, 1, 1, 1, 1, 1, 1,
|
63
63
|
1, 1, 2, 1, 1, 1, 1, 1,
|
64
|
-
1, 1, 1, 1,
|
65
|
-
1,
|
64
|
+
1, 1, 1, 1, 3, 3, 1, 3,
|
65
|
+
1, 3, 1, 4, 4, 4, 4, 4,
|
66
66
|
1, 1, 1, 1, 1, 1, 1, 1,
|
67
67
|
1, 1, 1, 1, 1, 1, 1, 1,
|
68
|
-
|
68
|
+
1, 1, 4, 1, 1, 1, 1, 1,
|
69
69
|
1, 1, 1, 1, 1, 1, 1, 1,
|
70
|
-
|
71
|
-
5, 5,
|
70
|
+
1, 1, 5, 5, 5, 5, 5, 5,
|
71
|
+
5, 5, 5, 5, 1, 6, 6, 6,
|
72
|
+
6, 6, 1, 1, 1, 1, 1, 1,
|
72
73
|
1, 1, 1, 1, 1, 1, 1, 1,
|
74
|
+
1, 1, 1, 1, 6, 1, 1, 1,
|
73
75
|
1, 1, 1, 1, 1, 1, 1, 1,
|
74
|
-
1, 1,
|
76
|
+
1, 1, 1, 1, 0, 0, 0, 0,
|
77
|
+
0, 0, 0, 0, 0, 0, 1, 7,
|
78
|
+
7, 7, 7, 7, 7, 7, 7, 7,
|
79
|
+
7, 1, 8, 8, 8, 8, 8, 1,
|
75
80
|
1, 1, 1, 1, 1, 1, 1, 1,
|
76
|
-
1, 1, 0, 0, 0, 0, 0, 0,
|
77
|
-
0, 0, 0, 0, 1, 7, 7, 7,
|
78
|
-
7, 7, 7, 7, 7, 7, 7, 1,
|
79
|
-
8, 8, 8, 8, 8, 1, 1, 1,
|
80
81
|
1, 1, 1, 1, 1, 1, 1, 1,
|
81
|
-
1,
|
82
|
+
1, 8, 1, 1, 1, 1, 1, 1,
|
83
|
+
1, 1, 1, 9, 9, 1, 9, 1,
|
84
|
+
9, 10, 10, 10, 10, 10, 10, 10,
|
85
|
+
10, 10, 10, 1, 1, 1, 1, 1,
|
82
86
|
1, 1, 1, 1, 1, 1, 1, 1,
|
83
|
-
1, 1, 9, 1, 9, 1, 1, 10,
|
84
|
-
10, 10, 10, 10, 10, 10, 10, 10,
|
85
|
-
10, 1, 1, 1, 1, 1, 1, 1,
|
86
87
|
1, 1, 1, 1, 1, 1, 1, 1,
|
87
88
|
1, 1, 1, 1, 1, 1, 1, 1,
|
88
89
|
1, 1, 1, 1, 1, 1, 1, 1,
|
90
|
+
1, 1, 1, 1, 1, 11, 1, 12,
|
91
|
+
12, 12, 12, 12, 1, 1, 1, 1,
|
89
92
|
1, 1, 1, 1, 1, 1, 1, 1,
|
90
|
-
1, 1, 1,
|
91
|
-
12, 12, 1, 1, 1, 1, 1, 1,
|
93
|
+
1, 1, 1, 1, 1, 1, 12, 1,
|
92
94
|
1, 1, 1, 1, 1, 1, 1, 1,
|
93
|
-
|
94
|
-
|
95
|
-
1, 13, 1, 1, 14, 14, 14, 14,
|
96
|
-
14, 14, 14, 14, 14, 14, 1, 1,
|
95
|
+
13, 13, 1, 13, 1, 13, 14, 14,
|
96
|
+
14, 14, 14, 14, 14, 14, 14, 14,
|
97
97
|
1, 1, 1, 1, 1, 1, 1, 1,
|
98
98
|
1, 1, 1, 1, 1, 1, 1, 1,
|
99
99
|
1, 1, 1, 1, 1, 1, 1, 1,
|
100
100
|
1, 1, 1, 1, 1, 1, 1, 1,
|
101
|
-
1, 1,
|
101
|
+
1, 1, 1, 1, 15, 1, 1, 1,
|
102
102
|
1, 1, 1, 1, 1, 1, 1, 1,
|
103
103
|
1, 1, 1, 1, 1, 1, 1, 1,
|
104
|
-
1, 1,
|
105
|
-
16,
|
104
|
+
1, 1, 1, 1, 15, 1, 16, 16,
|
105
|
+
16, 16, 16, 1, 1, 1, 1, 1,
|
106
106
|
1, 1, 1, 1, 1, 1, 1, 1,
|
107
|
-
1, 1, 1,
|
108
|
-
1, 1, 1, 1, 1, 1,
|
109
|
-
17, 1, 0
|
107
|
+
1, 1, 1, 1, 1, 16, 1, 1,
|
108
|
+
1, 1, 1, 1, 1, 1, 1, 17,
|
109
|
+
17, 1, 17, 1, 17, 1, 0
|
110
110
|
]
|
111
111
|
|
112
112
|
class << self
|
@@ -208,25 +208,31 @@ begin
|
|
208
208
|
# line 4 "lib/crapshoot/parser/scan.rl"
|
209
209
|
begin
|
210
210
|
@mark_num = p end
|
211
|
+
# line 4 "lib/crapshoot/parser/scan.rl"
|
211
212
|
when 5 then
|
212
213
|
# line 5 "lib/crapshoot/parser/scan.rl"
|
213
214
|
begin
|
214
215
|
@num_stack.push atos(data[@mark_num..p-1]) end
|
216
|
+
# line 5 "lib/crapshoot/parser/scan.rl"
|
215
217
|
when 2 then
|
216
218
|
# line 15 "lib/crapshoot/parser/scan.rl"
|
217
219
|
begin
|
218
220
|
@tokens << Tokens::Arithmetic.new(data[p-1].chr) end
|
221
|
+
# line 15 "lib/crapshoot/parser/scan.rl"
|
219
222
|
when 4 then
|
220
223
|
# line 5 "lib/crapshoot/parser/scan.rl"
|
221
224
|
begin
|
222
225
|
@num_stack.push atos(data[@mark_num..p-1]) end
|
226
|
+
# line 5 "lib/crapshoot/parser/scan.rl"
|
223
227
|
# line 7 "lib/crapshoot/parser/scan.rl"
|
224
228
|
begin
|
225
229
|
@tokens << Tokens::Constant.new(@num_stack.pop) end
|
230
|
+
# line 7 "lib/crapshoot/parser/scan.rl"
|
226
231
|
when 6 then
|
227
232
|
# line 5 "lib/crapshoot/parser/scan.rl"
|
228
233
|
begin
|
229
234
|
@num_stack.push atos(data[@mark_num..p-1]) end
|
235
|
+
# line 5 "lib/crapshoot/parser/scan.rl"
|
230
236
|
# line 8 "lib/crapshoot/parser/scan.rl"
|
231
237
|
begin
|
232
238
|
|
@@ -236,17 +242,21 @@ begin
|
|
236
242
|
count = @num_stack.pop
|
237
243
|
@tokens << Tokens::Series.new(count, sides, drop)
|
238
244
|
end
|
245
|
+
# line 8 "lib/crapshoot/parser/scan.rl"
|
239
246
|
when 3 then
|
240
247
|
# line 15 "lib/crapshoot/parser/scan.rl"
|
241
248
|
begin
|
242
249
|
@tokens << Tokens::Arithmetic.new(data[p-1].chr) end
|
250
|
+
# line 15 "lib/crapshoot/parser/scan.rl"
|
243
251
|
# line 4 "lib/crapshoot/parser/scan.rl"
|
244
252
|
begin
|
245
253
|
@mark_num = p end
|
254
|
+
# line 4 "lib/crapshoot/parser/scan.rl"
|
246
255
|
when 7 then
|
247
256
|
# line 17 "lib/crapshoot/parser/scan.rl"
|
248
257
|
begin
|
249
258
|
@drop_current = data[p-1].chr end
|
259
|
+
# line 17 "lib/crapshoot/parser/scan.rl"
|
250
260
|
# line 8 "lib/crapshoot/parser/scan.rl"
|
251
261
|
begin
|
252
262
|
|
@@ -256,7 +266,8 @@ begin
|
|
256
266
|
count = @num_stack.pop
|
257
267
|
@tokens << Tokens::Series.new(count, sides, drop)
|
258
268
|
end
|
259
|
-
# line
|
269
|
+
# line 8 "lib/crapshoot/parser/scan.rl"
|
270
|
+
# line 271 "lib/crapshoot/parser/scan.rb"
|
260
271
|
end
|
261
272
|
end
|
262
273
|
end
|
@@ -278,13 +289,16 @@ begin
|
|
278
289
|
# line 5 "lib/crapshoot/parser/scan.rl"
|
279
290
|
begin
|
280
291
|
@num_stack.push atos(data[@mark_num..p-1]) end
|
292
|
+
# line 5 "lib/crapshoot/parser/scan.rl"
|
281
293
|
# line 7 "lib/crapshoot/parser/scan.rl"
|
282
294
|
begin
|
283
295
|
@tokens << Tokens::Constant.new(@num_stack.pop) end
|
296
|
+
# line 7 "lib/crapshoot/parser/scan.rl"
|
284
297
|
when 6 then
|
285
298
|
# line 5 "lib/crapshoot/parser/scan.rl"
|
286
299
|
begin
|
287
300
|
@num_stack.push atos(data[@mark_num..p-1]) end
|
301
|
+
# line 5 "lib/crapshoot/parser/scan.rl"
|
288
302
|
# line 8 "lib/crapshoot/parser/scan.rl"
|
289
303
|
begin
|
290
304
|
|
@@ -294,10 +308,12 @@ begin
|
|
294
308
|
count = @num_stack.pop
|
295
309
|
@tokens << Tokens::Series.new(count, sides, drop)
|
296
310
|
end
|
311
|
+
# line 8 "lib/crapshoot/parser/scan.rl"
|
297
312
|
when 7 then
|
298
313
|
# line 17 "lib/crapshoot/parser/scan.rl"
|
299
314
|
begin
|
300
315
|
@drop_current = data[p-1].chr end
|
316
|
+
# line 17 "lib/crapshoot/parser/scan.rl"
|
301
317
|
# line 8 "lib/crapshoot/parser/scan.rl"
|
302
318
|
begin
|
303
319
|
|
@@ -307,7 +323,8 @@ begin
|
|
307
323
|
count = @num_stack.pop
|
308
324
|
@tokens << Tokens::Series.new(count, sides, drop)
|
309
325
|
end
|
310
|
-
# line
|
326
|
+
# line 8 "lib/crapshoot/parser/scan.rl"
|
327
|
+
# line 328 "lib/crapshoot/parser/scan.rb"
|
311
328
|
end
|
312
329
|
end
|
313
330
|
|
@@ -23,7 +23,7 @@
|
|
23
23
|
Drop = ('^' | 'v') %drop;
|
24
24
|
Series = Number 'd' Number Drop? %series;
|
25
25
|
|
26
|
-
Arithmetic = ('+' | '-') %arithmetic;
|
26
|
+
Arithmetic = ('+' | '-' | '*' | '/') %arithmetic;
|
27
27
|
|
28
28
|
UnaryExpression = Series | Constant;
|
29
29
|
BinaryExpression = UnaryExpression (space* Arithmetic space* UnaryExpression)+;
|
data/lib/crapshoot/postfixer.rb
CHANGED
@@ -1,24 +1,48 @@
|
|
1
1
|
module Crapshoot
|
2
2
|
# Translate the infix-notation tokens into postfix notation to make evaluating them easier.
|
3
3
|
class Postfixer
|
4
|
+
|
5
|
+
# Postfixify turns the infix list of tokens from Scanner into a postfix list
|
6
|
+
# by repeatedly calling "step"
|
4
7
|
def postfixify(infix_tokens)
|
5
8
|
@infix_orig = infix_tokens
|
6
9
|
@infix = @infix_orig.dup
|
7
10
|
@postfix = []
|
11
|
+
@operator_stack = []
|
8
12
|
until @infix.empty?
|
9
13
|
step
|
10
14
|
end
|
11
15
|
|
16
|
+
until @operator_stack.empty?
|
17
|
+
@postfix.push @operator_stack.pop
|
18
|
+
end
|
19
|
+
|
12
20
|
return @postfix
|
13
21
|
end
|
14
22
|
|
23
|
+
# step shifts an independent (Constant or Series) token to the
|
24
|
+
# postfix list, or loads a dependent (Arithmetic) token into the
|
25
|
+
# operator_stack for future postfixing.
|
15
26
|
def step
|
16
27
|
candidate = @infix.shift
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
28
|
+
process_independent candidate
|
29
|
+
process_operator candidate
|
30
|
+
end
|
31
|
+
|
32
|
+
def process_independent(candidate)
|
33
|
+
return unless candidate.independent
|
21
34
|
@postfix.push candidate
|
22
35
|
end
|
36
|
+
|
37
|
+
def process_operator(candidate)
|
38
|
+
return if candidate.independent
|
39
|
+
|
40
|
+
if @operator_stack.empty? || candidate.precedent(@operator_stack.last)
|
41
|
+
@operator_stack.push candidate
|
42
|
+
else
|
43
|
+
@postfix.push @operator_stack.pop
|
44
|
+
@operator_stack.push candidate
|
45
|
+
end
|
46
|
+
end
|
23
47
|
end
|
24
48
|
end
|
@@ -9,6 +9,15 @@ module Crapshoot
|
|
9
9
|
false
|
10
10
|
end
|
11
11
|
|
12
|
+
def precedent(stack_top)
|
13
|
+
return true if high_priority? && !stack_top.high_priority?
|
14
|
+
return false
|
15
|
+
end
|
16
|
+
|
17
|
+
def high_priority?
|
18
|
+
@operation == '*' || @operation == '/'
|
19
|
+
end
|
20
|
+
|
12
21
|
def eval(stack)
|
13
22
|
r = stack.pop
|
14
23
|
l = stack.pop
|
data/lib/crapshoot/version.rb
CHANGED
data/test/crapshoot_test.rb
CHANGED
@@ -27,6 +27,13 @@ class TestCrapshoot < Test::Unit::TestCase
|
|
27
27
|
should_roll '10-5', '=='=>5
|
28
28
|
should_roll '5-10', '=='=>-5
|
29
29
|
|
30
|
+
should_roll '2*5', '=='=>10
|
31
|
+
should_roll '10/2', '=='=>5
|
32
|
+
should_roll '1 + 2 * 3', '=='=>7
|
33
|
+
should_roll '4 * 5 + 6', '=='=>26
|
34
|
+
should_roll '4 * 5 / 10', '=='=>2
|
35
|
+
should_roll '2 * 3 + 4 * 5 + 10 + 10 * 8 / 2', '=='=>76
|
36
|
+
|
30
37
|
should_describe '1 + 2', '1+2'
|
31
38
|
should_describe '10 - 5', '10-5'
|
32
39
|
should_describe '2d6', /\(\d\+\d\)/
|
data/test/postfixer_test.rb
CHANGED
@@ -14,9 +14,11 @@ class TestPostfixer < Test::Unit::TestCase
|
|
14
14
|
end
|
15
15
|
|
16
16
|
five = Constant.new '5'
|
17
|
+
six = Constant.new '6'
|
18
|
+
seven = Constant.new '7'
|
17
19
|
plus = Arithmetic.new '+'
|
18
20
|
minus = Arithmetic.new '-'
|
19
|
-
|
21
|
+
times = Arithmetic.new '*'
|
20
22
|
series1 = Series.new '5', '6', nil
|
21
23
|
series2 = Series.new '4', '20', 'v'
|
22
24
|
|
@@ -24,5 +26,7 @@ class TestPostfixer < Test::Unit::TestCase
|
|
24
26
|
[five, six, plus])
|
25
27
|
should_postfixify([series1, plus, six, minus, series2],
|
26
28
|
[series1, six, plus, series2, minus])
|
29
|
+
should_postfixify([five, plus, six, times, seven],
|
30
|
+
[five, six, seven, times, plus])
|
27
31
|
end
|
28
32
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
7
|
+
- 4
|
8
8
|
- 0
|
9
|
-
version: 0.
|
9
|
+
version: 0.4.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Bryce Kerley
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-01-12 00:00:00
|
17
|
+
date: 2011-01-12 00:00:00 +00:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|