dentaku 1.2.2 → 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/dentaku/evaluator.rb +4 -0
- data/lib/dentaku/rules.rb +39 -37
- data/lib/dentaku/version.rb +1 -1
- data/spec/calculator_spec.rb +2 -0
- data/spec/evaluator_spec.rb +6 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/tokenizer_spec.rb +12 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b3af0752b4a5aa4575036f593ead2f9df154721
|
4
|
+
data.tar.gz: ab61cb8ebd50a48d179197724019a6f5ec167556
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 58d3524e23835e1c842e35a91390c8601cb59fd5da31efdd234edb2e7551399e5b0c176f4f30cbb2f5b849f6cceab16661ae473a95b8ca32fc56913ec8f0f580
|
7
|
+
data.tar.gz: 697075e3d8a11586404c83b2ea0ff685079ab0dc3b80123e87fecfc411d4913a0012573ac7ec87eca55a6205d5957723a7a0e5edcaf8bc295b2937d096ac8667
|
data/lib/dentaku/evaluator.rb
CHANGED
@@ -98,6 +98,10 @@ module Dentaku
|
|
98
98
|
Token.new(token.category, token.value * -1)
|
99
99
|
end
|
100
100
|
|
101
|
+
def pow_negate(base, _, _, exp)
|
102
|
+
Token.new(base.category, base.value ** (exp.value * -1))
|
103
|
+
end
|
104
|
+
|
101
105
|
def percentage(token, _)
|
102
106
|
Token.new(token.category, token.value / 100.0)
|
103
107
|
end
|
data/lib/dentaku/rules.rb
CHANGED
@@ -6,25 +6,26 @@ module Dentaku
|
|
6
6
|
class Rules
|
7
7
|
def self.core_rules
|
8
8
|
[
|
9
|
-
[ p(:if),
|
10
|
-
[ p(:round),
|
11
|
-
[ p(:roundup),
|
12
|
-
[ p(:rounddown),
|
13
|
-
[ p(:not),
|
9
|
+
[ p(:if), :if ],
|
10
|
+
[ p(:round), :round ],
|
11
|
+
[ p(:roundup), :round_int ],
|
12
|
+
[ p(:rounddown), :round_int ],
|
13
|
+
[ p(:not), :not ],
|
14
14
|
|
15
|
-
[ p(:group),
|
16
|
-
[ p(:start_neg),
|
17
|
-
[ p(:math_pow),
|
18
|
-
[ p(:
|
19
|
-
[ p(:
|
20
|
-
[ p(:
|
21
|
-
[ p(:
|
22
|
-
[ p(:
|
23
|
-
[ p(:
|
24
|
-
[ p(:
|
25
|
-
[ p(:
|
26
|
-
[ p(:
|
27
|
-
[ p(:
|
15
|
+
[ p(:group), :evaluate_group ],
|
16
|
+
[ p(:start_neg), :negate ],
|
17
|
+
[ p(:math_pow), :apply ],
|
18
|
+
[ p(:math_neg_pow), :pow_negate ],
|
19
|
+
[ p(:math_mod), :apply ],
|
20
|
+
[ p(:math_mul), :apply ],
|
21
|
+
[ p(:math_add), :apply ],
|
22
|
+
[ p(:percentage), :percentage ],
|
23
|
+
[ p(:negation), :negate ],
|
24
|
+
[ p(:range_asc), :expand_range ],
|
25
|
+
[ p(:range_desc), :expand_range ],
|
26
|
+
[ p(:num_comp), :apply ],
|
27
|
+
[ p(:str_comp), :apply ],
|
28
|
+
[ p(:combine), :apply ]
|
28
29
|
]
|
29
30
|
end
|
30
31
|
|
@@ -68,7 +69,7 @@ module Dentaku
|
|
68
69
|
:comparator, :comp_gt, :comp_lt, :fopen, :open, :close, :comma,
|
69
70
|
:non_close_plus, :non_group, :non_group_star, :arguments,
|
70
71
|
:logical, :combinator, :if, :round, :roundup, :rounddown, :not,
|
71
|
-
:anchored_minus
|
72
|
+
:anchored_minus, :math_neg_pow
|
72
73
|
].each_with_object({}) do |name, matchers|
|
73
74
|
matchers[name] = TokenMatcher.send(name)
|
74
75
|
end
|
@@ -76,25 +77,26 @@ module Dentaku
|
|
76
77
|
|
77
78
|
def self.p(name)
|
78
79
|
@patterns ||= {
|
79
|
-
group:
|
80
|
-
math_add:
|
81
|
-
math_mul:
|
82
|
-
math_pow:
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
80
|
+
group: pattern(:open, :non_group_star, :close),
|
81
|
+
math_add: pattern(:numeric, :addsub, :numeric),
|
82
|
+
math_mul: pattern(:numeric, :muldiv, :numeric),
|
83
|
+
math_pow: pattern(:numeric, :pow, :numeric),
|
84
|
+
math_neg_pow: pattern(:numeric, :pow, :subtract, :numeric),
|
85
|
+
math_mod: pattern(:numeric, :mod, :numeric),
|
86
|
+
negation: pattern(:subtract, :numeric),
|
87
|
+
start_neg: pattern(:anchored_minus, :numeric),
|
88
|
+
percentage: pattern(:numeric, :mod),
|
89
|
+
range_asc: pattern(:numeric, :comp_lt, :numeric, :comp_lt, :numeric),
|
90
|
+
range_desc: pattern(:numeric, :comp_gt, :numeric, :comp_gt, :numeric),
|
91
|
+
num_comp: pattern(:numeric, :comparator, :numeric),
|
92
|
+
str_comp: pattern(:string, :comparator, :string),
|
93
|
+
combine: pattern(:logical, :combinator, :logical),
|
92
94
|
|
93
|
-
if:
|
94
|
-
round:
|
95
|
-
roundup:
|
96
|
-
rounddown:
|
97
|
-
not:
|
95
|
+
if: func_pattern(:if, :non_group, :comma, :non_group, :comma, :non_group),
|
96
|
+
round: func_pattern(:round, :arguments),
|
97
|
+
roundup: func_pattern(:roundup, :arguments),
|
98
|
+
rounddown: func_pattern(:rounddown, :arguments),
|
99
|
+
not: func_pattern(:not, :arguments)
|
98
100
|
}
|
99
101
|
|
100
102
|
@patterns[name]
|
data/lib/dentaku/version.rb
CHANGED
data/spec/calculator_spec.rb
CHANGED
@@ -22,6 +22,8 @@ describe Dentaku::Calculator do
|
|
22
22
|
expect(calculator.evaluate('1 + -2 ^ 2')).to eq(-3)
|
23
23
|
expect(calculator.evaluate('3 + -num', :num => 2)).to eq(1)
|
24
24
|
expect(calculator.evaluate('-num + 3', :num => 2)).to eq(1)
|
25
|
+
expect(calculator.evaluate('10 ^ 2')).to eq(100)
|
26
|
+
expect(calculator.evaluate('0 * 10 ^ -5')).to eq(0)
|
25
27
|
end
|
26
28
|
|
27
29
|
describe 'memory' do
|
data/spec/evaluator_spec.rb
CHANGED
@@ -48,6 +48,12 @@ describe Dentaku::Evaluator do
|
|
48
48
|
expect(evaluator.evaluate(token_stream(:subtract, 1, :add, 1))).to eq(0)
|
49
49
|
end
|
50
50
|
|
51
|
+
it 'evaluates a number multiplied by an exponent' do
|
52
|
+
expect(evaluator.evaluate(token_stream(10, :pow, 2))).to eq(100)
|
53
|
+
expect(evaluator.evaluate(token_stream(0, :multiply, 10, :pow, 5))).to eq(0)
|
54
|
+
expect(evaluator.evaluate(token_stream(0, :multiply, 10, :pow, :subtract, 5))).to eq(0)
|
55
|
+
end
|
56
|
+
|
51
57
|
it 'supports unary percentage' do
|
52
58
|
expect(evaluator.evaluate(token_stream(50, :mod))).to eq(0.5)
|
53
59
|
expect(evaluator.evaluate(token_stream(50, :mod, :multiply, 100))).to eq(50)
|
data/spec/spec_helper.rb
CHANGED
data/spec/tokenizer_spec.rb
CHANGED
@@ -37,6 +37,18 @@ describe Dentaku::Tokenizer do
|
|
37
37
|
expect(tokens.map(&:value)).to eq([1, :divide, 1])
|
38
38
|
end
|
39
39
|
|
40
|
+
it 'tokenizes power operations' do
|
41
|
+
tokens = tokenizer.tokenize('10 ^ 2')
|
42
|
+
expect(tokens.map(&:category)).to eq([:numeric, :operator, :numeric])
|
43
|
+
expect(tokens.map(&:value)).to eq([10, :pow, 2])
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'tokenizes power operations' do
|
47
|
+
tokens = tokenizer.tokenize('0 * 10 ^ -5')
|
48
|
+
expect(tokens.map(&:category)).to eq([:numeric, :operator, :numeric, :operator, :operator, :numeric])
|
49
|
+
expect(tokens.map(&:value)).to eq([0, :multiply, 10, :pow, :subtract, 5])
|
50
|
+
end
|
51
|
+
|
40
52
|
it 'handles floating point' do
|
41
53
|
tokens = tokenizer.tokenize('1.5 * 3.7')
|
42
54
|
expect(tokens.map(&:category)).to eq([:numeric, :operator, :numeric])
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dentaku
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Solomon White
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|