soroban 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -6,12 +6,11 @@ group :development do
6
6
  gem "rubyXL", "~> 1.2.7"
7
7
  gem "nokogiri", ">= 1.4.4"
8
8
  gem "rubyzip", ">= 0.9.4"
9
- gem "ditz"
10
9
  end
11
10
 
12
11
  group :test do
13
12
  gem "rake"
14
- gem "rspec", "~> 2.9.0"
13
+ gem "rspec", "~> 2.12.0"
15
14
  gem "yard", "~> 0.7"
16
15
  end
17
16
 
data/Gemfile.lock CHANGED
@@ -2,48 +2,44 @@ GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
4
  diff-lcs (1.1.3)
5
- ditz (0.5)
6
- trollop (>= 1.9)
7
5
  git (1.2.5)
8
- jeweler (1.8.3)
6
+ jeweler (1.8.4)
9
7
  bundler (~> 1.0)
10
8
  git (>= 1.2.5)
11
9
  rake
12
10
  rdoc
13
- json (1.7.3)
14
- nokogiri (1.5.2)
11
+ json (1.7.6)
12
+ nokogiri (1.5.6)
15
13
  polyglot (0.3.3)
16
- rake (0.9.2.2)
14
+ rake (10.0.3)
17
15
  rdoc (3.12)
18
16
  json (~> 1.4)
19
- redcarpet (2.1.1)
20
- rspec (2.9.0)
21
- rspec-core (~> 2.9.0)
22
- rspec-expectations (~> 2.9.0)
23
- rspec-mocks (~> 2.9.0)
24
- rspec-core (2.9.0)
25
- rspec-expectations (2.9.1)
17
+ redcarpet (2.2.2)
18
+ rspec (2.12.0)
19
+ rspec-core (~> 2.12.0)
20
+ rspec-expectations (~> 2.12.0)
21
+ rspec-mocks (~> 2.12.0)
22
+ rspec-core (2.12.2)
23
+ rspec-expectations (2.12.1)
26
24
  diff-lcs (~> 1.1.3)
27
- rspec-mocks (2.9.0)
28
- rubyXL (1.2.7)
29
- rubyzip (0.9.8)
30
- treetop (1.4.10)
25
+ rspec-mocks (2.12.1)
26
+ rubyXL (1.2.10)
27
+ rubyzip (0.9.9)
28
+ treetop (1.4.12)
31
29
  polyglot
32
30
  polyglot (>= 0.3.1)
33
- trollop (1.16.2)
34
- yard (0.8.1)
31
+ yard (0.8.3)
35
32
 
36
33
  PLATFORMS
37
34
  ruby
38
35
 
39
36
  DEPENDENCIES
40
- ditz
41
37
  jeweler (~> 1.8.3)
42
38
  nokogiri (>= 1.4.4)
43
39
  rake
44
40
  rdoc (~> 3.12)
45
41
  redcarpet
46
- rspec (~> 2.9.0)
42
+ rspec (~> 2.12.0)
47
43
  rubyXL (~> 1.2.7)
48
44
  rubyzip (>= 0.9.4)
49
45
  treetop (~> 1.4.10)
data/Rakefile CHANGED
@@ -36,6 +36,10 @@ RSpec::Core::RakeTask.new(:rcov) do |spec|
36
36
  spec.rcov = false
37
37
  end
38
38
 
39
+ task 'treetop' do
40
+ system('tt lib/soroban/parser/grammar.treetop -o lib/soroban/parser/grammar.rb')
41
+ end
42
+
39
43
  task :default => :spec
40
44
 
41
45
  require 'yard'
data/Soroban.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "soroban"
8
- s.version = "0.3.1"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jason Hutchens"]
12
- s.date = "2012-05-22"
12
+ s.date = "2013-01-09"
13
13
  s.description = "Soroban makes it easy to extract and execute formulas from Excel spreadsheets. It rewrites Excel formulas as Ruby expressions, and allows you to bind named variables to spreadsheet cells to easily manipulate inputs and capture outputs."
14
14
  s.email = "jason.hutchens@agworld.com.au"
15
15
  s.extra_rdoc_files = [
@@ -28,10 +28,6 @@ Gem::Specification.new do |s|
28
28
  "Rakefile",
29
29
  "Soroban.gemspec",
30
30
  "VERSION",
31
- "bugs/issue-096ca8b758759b2b32d9c58a88a2ab05672336b8.yaml",
32
- "bugs/issue-2257df466e56d29a07b2ecc2453296d9d1401d77.yaml",
33
- "bugs/issue-d84ed3471e4dd2930795446dca750c20700746e0.yaml",
34
- "bugs/project.yaml",
35
31
  "files/Physics.xlsx",
36
32
  "lib/soroban.rb",
37
33
  "lib/soroban/cell.rb",
@@ -66,7 +62,7 @@ Gem::Specification.new do |s|
66
62
  s.homepage = "https://github.com/agworld/soroban"
67
63
  s.licenses = ["MIT"]
68
64
  s.require_paths = ["lib"]
69
- s.rubygems_version = "1.8.10"
65
+ s.rubygems_version = "1.8.24"
70
66
  s.summary = "Soroban is a calculating engine that understands Excel formulas."
71
67
 
72
68
  if s.respond_to? :specification_version then
@@ -77,20 +73,17 @@ Gem::Specification.new do |s|
77
73
  s.add_development_dependency(%q<rubyXL>, ["~> 1.2.7"])
78
74
  s.add_development_dependency(%q<nokogiri>, [">= 1.4.4"])
79
75
  s.add_development_dependency(%q<rubyzip>, [">= 0.9.4"])
80
- s.add_development_dependency(%q<ditz>, [">= 0"])
81
76
  else
82
77
  s.add_dependency(%q<treetop>, ["~> 1.4.10"])
83
78
  s.add_dependency(%q<rubyXL>, ["~> 1.2.7"])
84
79
  s.add_dependency(%q<nokogiri>, [">= 1.4.4"])
85
80
  s.add_dependency(%q<rubyzip>, [">= 0.9.4"])
86
- s.add_dependency(%q<ditz>, [">= 0"])
87
81
  end
88
82
  else
89
83
  s.add_dependency(%q<treetop>, ["~> 1.4.10"])
90
84
  s.add_dependency(%q<rubyXL>, ["~> 1.2.7"])
91
85
  s.add_dependency(%q<nokogiri>, [">= 1.4.4"])
92
86
  s.add_dependency(%q<rubyzip>, [">= 0.9.4"])
93
- s.add_dependency(%q<ditz>, [">= 0"])
94
87
  end
95
88
  end
96
89
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.1
1
+ 0.4.0
@@ -1185,6 +1185,18 @@ module Soroban
1185
1185
  r0
1186
1186
  end
1187
1187
 
1188
+ module Number0
1189
+ def float
1190
+ elements[1]
1191
+ end
1192
+ end
1193
+
1194
+ module Number1
1195
+ def integer
1196
+ elements[1]
1197
+ end
1198
+ end
1199
+
1188
1200
  def _nt_number
1189
1201
  start_index = index
1190
1202
  if node_cache[:number].has_key?(index)
@@ -1205,8 +1217,56 @@ module Soroban
1205
1217
  if r2
1206
1218
  r0 = r2
1207
1219
  else
1208
- @index = i0
1209
- r0 = nil
1220
+ i3, s3 = index, []
1221
+ if has_terminal?('-', false, index)
1222
+ r4 = instantiate_node(SyntaxNode,input, index...(index + 1))
1223
+ @index += 1
1224
+ else
1225
+ terminal_parse_failure('-')
1226
+ r4 = nil
1227
+ end
1228
+ s3 << r4
1229
+ if r4
1230
+ r5 = _nt_float
1231
+ s3 << r5
1232
+ end
1233
+ if s3.last
1234
+ r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
1235
+ r3.extend(Number0)
1236
+ else
1237
+ @index = i3
1238
+ r3 = nil
1239
+ end
1240
+ if r3
1241
+ r0 = r3
1242
+ else
1243
+ i6, s6 = index, []
1244
+ if has_terminal?('-', false, index)
1245
+ r7 = instantiate_node(SyntaxNode,input, index...(index + 1))
1246
+ @index += 1
1247
+ else
1248
+ terminal_parse_failure('-')
1249
+ r7 = nil
1250
+ end
1251
+ s6 << r7
1252
+ if r7
1253
+ r8 = _nt_integer
1254
+ s6 << r8
1255
+ end
1256
+ if s6.last
1257
+ r6 = instantiate_node(SyntaxNode,input, i6...index, s6)
1258
+ r6.extend(Number1)
1259
+ else
1260
+ @index = i6
1261
+ r6 = nil
1262
+ end
1263
+ if r6
1264
+ r0 = r6
1265
+ else
1266
+ @index = i0
1267
+ r0 = nil
1268
+ end
1269
+ end
1210
1270
  end
1211
1271
  end
1212
1272
 
@@ -42,7 +42,7 @@ grammar Soroban
42
42
  logical ( space? ',' space? logical )*
43
43
  end
44
44
  rule number
45
- float / integer
45
+ ( float / integer / '-' float / '-' integer )
46
46
  end
47
47
  rule float
48
48
  [0-9]* '.' [0-9]+
data/lib/soroban/sheet.rb CHANGED
@@ -11,7 +11,8 @@ module Soroban
11
11
  attr_reader :bindings
12
12
 
13
13
  # Creates a new sheet.
14
- def initialize
14
+ def initialize(logger=nil)
15
+ @logger = logger
15
16
  @cells = {}
16
17
  @bindings = {}
17
18
  end
@@ -30,8 +31,10 @@ module Soroban
30
31
  # Set the contents of one or more cells or ranges.
31
32
  def set(options_hash)
32
33
  options_hash.each do |label_or_range, contents|
34
+ _debug("setting '#{label_or_range}' to '#{contents}'")
33
35
  unless range = Soroban::getRange(label_or_range)
34
- return _add(label_or_range, contents)
36
+ _add(label_or_range, contents)
37
+ next
35
38
  end
36
39
  fc, fr, tc, tr = range
37
40
  if fc == tc || fr == tr
@@ -52,6 +55,7 @@ module Soroban
52
55
  # Retrieve the contents of a cell.
53
56
  def get(label_or_name)
54
57
  label = @bindings[label_or_name.to_sym] || label_or_name
58
+ _debug("retrieving '#{label_or_name}' from '#{label}'}")
55
59
  if Soroban::range?(label)
56
60
  walk(label)
57
61
  else
@@ -62,6 +66,7 @@ module Soroban
62
66
  # Bind one or more named variables to a cell.
63
67
  def bind(options_hash)
64
68
  options_hash.each do |name, label_or_range|
69
+ _debug("binding '#{name}' to '#{label_or_range}'}")
65
70
  if Soroban::range?(label_or_range)
66
71
  LabelWalker.new(label_or_range).each do |label|
67
72
  next if @cells.keys.include?(label.to_sym)
@@ -96,6 +101,11 @@ module Soroban
96
101
 
97
102
  private
98
103
 
104
+ def _debug(message)
105
+ return if @logger.nil?
106
+ @logger.debug "SOROBAN: #{message}"
107
+ end
108
+
99
109
  def _add(label, contents)
100
110
  internal = "@#{label}"
101
111
  _expose(internal, label)
@@ -30,6 +30,8 @@ describe "Documentation" do
30
30
 
31
31
  # Bindings
32
32
 
33
+ s = Soroban::Sheet.new()
34
+
33
35
  s.set(:A1 => 'hello', 'B1:B5' => [1,2,3,4,5])
34
36
 
35
37
  s.bind(:foo => :A1, :bar => 'B1:B5')
@@ -47,6 +49,8 @@ describe "Documentation" do
47
49
 
48
50
  # Persistence
49
51
 
52
+ s = Soroban::Sheet.new()
53
+
50
54
  s.F1 = "= E1 + SUM(D1:D5)"
51
55
 
52
56
  s.missing # => [:E1, :D1, :D2, :D3, :D4, :D5]
data/spec/import_spec.rb CHANGED
@@ -1,6 +1,12 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
- describe "Documentation", :if => Gem.available?("rubyXL") do
3
+ has_rubyxl = begin
4
+ Gem::Specification::find_by_name("rubyXL")
5
+ rescue Gem::LoadError
6
+ false
7
+ end
8
+
9
+ describe "Documentation", :if => has_rubyxl do
4
10
 
5
11
  it "can import xlsx files using RubyXL" do
6
12
 
data/spec/soroban_spec.rb CHANGED
@@ -104,4 +104,11 @@ describe "Soroban" do
104
104
  }.should raise_error(Soroban::ParseError)
105
105
  end
106
106
 
107
+ it "can handle negative numbers" do
108
+ sheet.set(:A1 => -10)
109
+ sheet.set(:A2 => "-20")
110
+ sheet.set(:A3 => '=-10+A2-A1')
111
+ sheet.A3.should eq(-20)
112
+ end
113
+
107
114
  end
metadata CHANGED
@@ -1,110 +1,90 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: soroban
3
- version: !ruby/object:Gem::Version
4
- hash: 17
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 3
9
- - 1
10
- version: 0.3.1
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Jason Hutchens
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-05-22 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2013-01-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: treetop
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.4.10
21
22
  type: :runtime
22
23
  prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
+ version_requirements: !ruby/object:Gem::Requirement
24
25
  none: false
25
- requirements:
26
+ requirements:
26
27
  - - ~>
27
- - !ruby/object:Gem::Version
28
- hash: 19
29
- segments:
30
- - 1
31
- - 4
32
- - 10
28
+ - !ruby/object:Gem::Version
33
29
  version: 1.4.10
34
- version_requirements: *id001
35
- name: treetop
36
- - !ruby/object:Gem::Dependency
37
- type: :development
38
- prerelease: false
39
- requirement: &id002 !ruby/object:Gem::Requirement
30
+ - !ruby/object:Gem::Dependency
31
+ name: rubyXL
32
+ requirement: !ruby/object:Gem::Requirement
40
33
  none: false
41
- requirements:
34
+ requirements:
42
35
  - - ~>
43
- - !ruby/object:Gem::Version
44
- hash: 17
45
- segments:
46
- - 1
47
- - 2
48
- - 7
36
+ - !ruby/object:Gem::Version
49
37
  version: 1.2.7
50
- version_requirements: *id002
51
- name: rubyXL
52
- - !ruby/object:Gem::Dependency
53
38
  type: :development
54
39
  prerelease: false
55
- requirement: &id003 !ruby/object:Gem::Requirement
40
+ version_requirements: !ruby/object:Gem::Requirement
56
41
  none: false
57
- requirements:
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- hash: 15
61
- segments:
62
- - 1
63
- - 4
64
- - 4
65
- version: 1.4.4
66
- version_requirements: *id003
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.2.7
46
+ - !ruby/object:Gem::Dependency
67
47
  name: nokogiri
68
- - !ruby/object:Gem::Dependency
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 1.4.4
69
54
  type: :development
70
55
  prerelease: false
71
- requirement: &id004 !ruby/object:Gem::Requirement
56
+ version_requirements: !ruby/object:Gem::Requirement
72
57
  none: false
73
- requirements:
74
- - - ">="
75
- - !ruby/object:Gem::Version
76
- hash: 51
77
- segments:
78
- - 0
79
- - 9
80
- - 4
81
- version: 0.9.4
82
- version_requirements: *id004
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 1.4.4
62
+ - !ruby/object:Gem::Dependency
83
63
  name: rubyzip
84
- - !ruby/object:Gem::Dependency
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: 0.9.4
85
70
  type: :development
86
71
  prerelease: false
87
- requirement: &id005 !ruby/object:Gem::Requirement
72
+ version_requirements: !ruby/object:Gem::Requirement
88
73
  none: false
89
- requirements:
90
- - - ">="
91
- - !ruby/object:Gem::Version
92
- hash: 3
93
- segments:
94
- - 0
95
- version: "0"
96
- version_requirements: *id005
97
- name: ditz
98
- description: Soroban makes it easy to extract and execute formulas from Excel spreadsheets. It rewrites Excel formulas as Ruby expressions, and allows you to bind named variables to spreadsheet cells to easily manipulate inputs and capture outputs.
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: 0.9.4
78
+ description: Soroban makes it easy to extract and execute formulas from Excel spreadsheets.
79
+ It rewrites Excel formulas as Ruby expressions, and allows you to bind named variables
80
+ to spreadsheet cells to easily manipulate inputs and capture outputs.
99
81
  email: jason.hutchens@agworld.com.au
100
82
  executables: []
101
-
102
83
  extensions: []
103
-
104
- extra_rdoc_files:
84
+ extra_rdoc_files:
105
85
  - LICENSE.txt
106
86
  - README.md
107
- files:
87
+ files:
108
88
  - .document
109
89
  - .rspec
110
90
  - .travis.yml
@@ -116,10 +96,6 @@ files:
116
96
  - Rakefile
117
97
  - Soroban.gemspec
118
98
  - VERSION
119
- - bugs/issue-096ca8b758759b2b32d9c58a88a2ab05672336b8.yaml
120
- - bugs/issue-2257df466e56d29a07b2ecc2453296d9d1401d77.yaml
121
- - bugs/issue-d84ed3471e4dd2930795446dca750c20700746e0.yaml
122
- - bugs/project.yaml
123
99
  - files/Physics.xlsx
124
100
  - lib/soroban.rb
125
101
  - lib/soroban/cell.rb
@@ -151,37 +127,31 @@ files:
151
127
  - spec/soroban_spec.rb
152
128
  - spec/spec_helper.rb
153
129
  homepage: https://github.com/agworld/soroban
154
- licenses:
130
+ licenses:
155
131
  - MIT
156
132
  post_install_message:
157
133
  rdoc_options: []
158
-
159
- require_paths:
134
+ require_paths:
160
135
  - lib
161
- required_ruby_version: !ruby/object:Gem::Requirement
136
+ required_ruby_version: !ruby/object:Gem::Requirement
162
137
  none: false
163
- requirements:
164
- - - ">="
165
- - !ruby/object:Gem::Version
166
- hash: 3
167
- segments:
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ segments:
168
143
  - 0
169
- version: "0"
170
- required_rubygems_version: !ruby/object:Gem::Requirement
144
+ hash: 1741913376236821456
145
+ required_rubygems_version: !ruby/object:Gem::Requirement
171
146
  none: false
172
- requirements:
173
- - - ">="
174
- - !ruby/object:Gem::Version
175
- hash: 3
176
- segments:
177
- - 0
178
- version: "0"
147
+ requirements:
148
+ - - ! '>='
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
179
151
  requirements: []
180
-
181
152
  rubyforge_project:
182
- rubygems_version: 1.8.10
153
+ rubygems_version: 1.8.24
183
154
  signing_key:
184
155
  specification_version: 3
185
156
  summary: Soroban is a calculating engine that understands Excel formulas.
186
157
  test_files: []
187
-
@@ -1,18 +0,0 @@
1
- --- !ditz.rubyforge.org,2008-03-06/issue
2
- title: Implement dump and restore as a JSON blob
3
- desc: Dump the entire state out as a JSON blob, and load it back in. Write tests. Makes for easy serialisation.
4
- type: :task
5
- component: soroban
6
- release:
7
- reporter: Jason Hutchens <jason@agworld.com.au>
8
- status: :unstarted
9
- disposition:
10
- creation_time: 2012-05-03 07:50:15.815354 Z
11
- references: []
12
-
13
- id: 096ca8b758759b2b32d9c58a88a2ab05672336b8
14
- log_events:
15
- - - 2012-05-03 07:50:20.319126 Z
16
- - Jason Hutchens <jason@agworld.com.au>
17
- - created
18
- - ""
@@ -1,18 +0,0 @@
1
- --- !ditz.rubyforge.org,2008-03-06/issue
2
- title: Fix issue with importing rows of equations
3
- desc: I have a sheet where the same equation has been copied/pasted between cells, and it only gets imported once.
4
- type: :bugfix
5
- component: soroban
6
- release:
7
- reporter: Jason Hutchens <jason@agworld.com.au>
8
- status: :unstarted
9
- disposition:
10
- creation_time: 2012-05-03 07:51:21.582499 Z
11
- references: []
12
-
13
- id: 2257df466e56d29a07b2ecc2453296d9d1401d77
14
- log_events:
15
- - - 2012-05-03 07:51:24.022969 Z
16
- - Jason Hutchens <jason@agworld.com.au>
17
- - created
18
- - ""
@@ -1,18 +0,0 @@
1
- --- !ditz.rubyforge.org,2008-03-06/issue
2
- title: Rewrite formulas as valud Javascript
3
- desc: Soroban currently rewrites formulas as valid Ruby for execution on the server. It is possible to rewrite as valid JS code for execution on the client. Do this thing.
4
- type: :feature
5
- component: soroban
6
- release:
7
- reporter: Jason Hutchens <jason@agworld.com.au>
8
- status: :unstarted
9
- disposition:
10
- creation_time: 2012-05-03 07:52:17.446014 Z
11
- references: []
12
-
13
- id: d84ed3471e4dd2930795446dca750c20700746e0
14
- log_events:
15
- - - 2012-05-03 07:52:19.141383 Z
16
- - Jason Hutchens <jason@agworld.com.au>
17
- - created
18
- - ""
data/bugs/project.yaml DELETED
@@ -1,8 +0,0 @@
1
- --- !ditz.rubyforge.org,2008-03-06/project
2
- name: soroban
3
- version: "0.5"
4
- components:
5
- - !ditz.rubyforge.org,2008-03-06/component
6
- name: soroban
7
- releases: []
8
-