dentaku 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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