dentaku 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -60,11 +60,12 @@ for you:
60
60
  => 3.0
61
61
 
62
62
 
63
- SUPPORTED OPERATORS
64
- -------------------
63
+ SUPPORTED OPERATORS AND FUNCTIONS
64
+ ---------------------------------
65
65
 
66
- Math: `+ - * /`
67
- Logic: `< > <= >= <> != = AND OR`
66
+ Math: `+ - * /`
67
+ Logic: `< > <= >= <> != = AND OR`
68
+ Functions: `IF`
68
69
 
69
70
  THANKS
70
71
  ------
@@ -58,11 +58,18 @@ module Dentaku
58
58
  def replace_identifiers_with_values
59
59
  @tokens.map do |token|
60
60
  if token.is?(:identifier)
61
- Token.new(:numeric, memory(token.value))
61
+ value = memory(token.value)
62
+ type = type_for_value(value)
63
+
64
+ Token.new(type, value)
62
65
  else
63
66
  token
64
67
  end
65
68
  end
66
69
  end
70
+
71
+ def type_for_value(value)
72
+ value.is_a?(String) ? :string : :numeric
73
+ end
67
74
  end
68
75
  end
@@ -4,6 +4,7 @@ require 'dentaku/token_matcher'
4
4
  module Dentaku
5
5
  class Evaluator
6
6
  T_NUMERIC = TokenMatcher.new(:numeric)
7
+ T_STRING = TokenMatcher.new(:string)
7
8
  T_ADDSUB = TokenMatcher.new(:operator, [:add, :subtract])
8
9
  T_MULDIV = TokenMatcher.new(:operator, [:multiply, :divide])
9
10
  T_COMPARATOR = TokenMatcher.new(:comparator)
@@ -18,7 +19,8 @@ module Dentaku
18
19
  P_GROUP = [T_OPEN, T_NON_GROUP, T_CLOSE]
19
20
  P_MATH_ADD = [T_NUMERIC, T_ADDSUB, T_NUMERIC]
20
21
  P_MATH_MUL = [T_NUMERIC, T_MULDIV, T_NUMERIC]
21
- P_COMPARISON = [T_NUMERIC, T_COMPARATOR, T_NUMERIC]
22
+ P_NUM_COMP = [T_NUMERIC, T_COMPARATOR, T_NUMERIC]
23
+ P_STR_COMP = [T_STRING, T_COMPARATOR, T_STRING]
22
24
  P_COMBINE = [T_LOGICAL, T_COMBINATOR, T_LOGICAL]
23
25
 
24
26
  P_IF = [T_IF, T_OPEN, T_NON_GROUP, T_COMMA, T_NON_GROUP, T_COMMA, T_NON_GROUP, T_CLOSE]
@@ -27,7 +29,8 @@ module Dentaku
27
29
  [P_GROUP, :evaluate_group],
28
30
  [P_MATH_MUL, :apply],
29
31
  [P_MATH_ADD, :apply],
30
- [P_COMPARISON, :apply],
32
+ [P_NUM_COMP, :apply],
33
+ [P_STR_COMP, :apply],
31
34
  [P_COMBINE, :apply],
32
35
  [P_IF, :if],
33
36
  ]
@@ -7,6 +7,8 @@ module Dentaku
7
7
  SCANNERS = [
8
8
  TokenScanner.new(:whitespace, '\s+'),
9
9
  TokenScanner.new(:numeric, '(\d+(\.\d+)?|\.\d+)', lambda{|raw| raw =~ /\./ ? raw.to_f : raw.to_i }),
10
+ TokenScanner.new(:string, '"[^"]*"', lambda{|raw| raw.gsub(/^"|"$/, '') }),
11
+ TokenScanner.new(:string, "'[^']*'", lambda{|raw| raw.gsub(/^'|'$/, '') }),
10
12
  TokenScanner.new(:operator, '\+|-|\*|\/', lambda do |raw|
11
13
  case raw
12
14
  when '+' then :add
@@ -1,3 +1,3 @@
1
1
  module Dentaku
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
@@ -50,6 +50,11 @@ describe Dentaku::Calculator do
50
50
  calculator.evaluate('foo * 2', 'foo' => 4).should eq(8)
51
51
  end
52
52
 
53
+ it 'should compare string literals with string variables' do
54
+ calculator.evaluate('fruit = "apple"', :fruit => 'apple').should be_true
55
+ calculator.evaluate('fruit = "apple"', :fruit => 'pear').should be_false
56
+ end
57
+
53
58
  describe 'functions' do
54
59
  it 'should include IF' do
55
60
  calculator.evaluate('if (foo < 8, 10, 20)', :foo => 2).should eq(10)
@@ -22,6 +22,7 @@ describe Dentaku::Evaluator do
22
22
 
23
23
  it 'single numeric should return value' do
24
24
  evaluator.evaluate([Dentaku::Token.new(:numeric, 10)]).should eq(10)
25
+ evaluator.evaluate([Dentaku::Token.new(:string, 'a')]).should eq('a')
25
26
  end
26
27
 
27
28
  it 'should evaluate one apply step' do
@@ -37,6 +37,18 @@ describe Dentaku::Tokenizer do
37
37
  tokens.map(&:value).should eq([:monkeys, :gt, 1500])
38
38
  end
39
39
 
40
+ it 'should recognize double-quoted strings' do
41
+ tokens = tokenizer.tokenize('animal = "giraffe"')
42
+ tokens.map(&:category).should eq([:identifier, :comparator, :string])
43
+ tokens.map(&:value).should eq([:animal, :eq, 'giraffe'])
44
+ end
45
+
46
+ it 'should recognize single-quoted strings' do
47
+ tokens = tokenizer.tokenize("animal = 'giraffe'")
48
+ tokens.map(&:category).should eq([:identifier, :comparator, :string])
49
+ tokens.map(&:value).should eq([:animal, :eq, 'giraffe'])
50
+ end
51
+
40
52
  it 'should match "<=" before "<"' do
41
53
  tokens = tokenizer.tokenize('perimeter <= 7500')
42
54
  tokens.map(&:category).should eq([:identifier, :comparator, :numeric])
metadata CHANGED
@@ -1,36 +1,47 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: dentaku
3
- version: !ruby/object:Gem::Version
4
- version: 0.1.2
5
- prerelease:
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 3
10
+ version: 0.1.3
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Solomon White
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-01-25 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2012-01-31 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
15
22
  name: rspec
16
- requirement: &70323614305400 !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
17
25
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '0'
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
22
33
  type: :development
23
- prerelease: false
24
- version_requirements: *70323614305400
25
- description: ! ' Dentaku is a parser and evaluator for mathematical formulas
26
-
27
- '
28
- email:
34
+ version_requirements: *id001
35
+ description: " Dentaku is a parser and evaluator for mathematical formulas\n"
36
+ email:
29
37
  - rubysolo@gmail.com
30
38
  executables: []
39
+
31
40
  extensions: []
41
+
32
42
  extra_rdoc_files: []
33
- files:
43
+
44
+ files:
34
45
  - .gitignore
35
46
  - Gemfile
36
47
  - README.md
@@ -51,31 +62,41 @@ files:
51
62
  - spec/token_scanner_spec.rb
52
63
  - spec/token_spec.rb
53
64
  - spec/tokenizer_spec.rb
65
+ has_rdoc: true
54
66
  homepage: http://github.com/rubysolo/dentaku
55
67
  licenses: []
68
+
56
69
  post_install_message:
57
70
  rdoc_options: []
58
- require_paths:
71
+
72
+ require_paths:
59
73
  - lib
60
- required_ruby_version: !ruby/object:Gem::Requirement
74
+ required_ruby_version: !ruby/object:Gem::Requirement
61
75
  none: false
62
- requirements:
63
- - - ! '>='
64
- - !ruby/object:Gem::Version
65
- version: '0'
66
- required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ hash: 3
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
84
  none: false
68
- requirements:
69
- - - ! '>='
70
- - !ruby/object:Gem::Version
71
- version: '0'
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ hash: 3
89
+ segments:
90
+ - 0
91
+ version: "0"
72
92
  requirements: []
93
+
73
94
  rubyforge_project: dentaku
74
- rubygems_version: 1.8.10
95
+ rubygems_version: 1.3.7
75
96
  signing_key:
76
97
  specification_version: 3
77
98
  summary: A formula language parser and evaluator
78
- test_files:
99
+ test_files:
79
100
  - spec/calculator_spec.rb
80
101
  - spec/dentaku_spec.rb
81
102
  - spec/evaluator_spec.rb