lxl 0.4.0 → 0.4.1
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/CHANGES +4 -0
- data/VERSION +1 -1
- data/lib/lxl.rb +47 -20
- metadata +1 -1
data/CHANGES
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.1
|
data/lib/lxl.rb
CHANGED
@@ -162,6 +162,29 @@ module LXL
|
|
162
162
|
|
163
163
|
end
|
164
164
|
|
165
|
+
# Holds the lexical type and value of a parsed token.
|
166
|
+
#
|
167
|
+
class LXL::Token
|
168
|
+
|
169
|
+
# Lexical type (Fixnum).
|
170
|
+
attr_accessor :type
|
171
|
+
|
172
|
+
# Parsed value.
|
173
|
+
attr_accessor :value
|
174
|
+
|
175
|
+
def initialize(type, value)
|
176
|
+
@type = type
|
177
|
+
@value = value
|
178
|
+
end
|
179
|
+
|
180
|
+
def to_s()
|
181
|
+
"T:#{@type.chr}:#{@value}"
|
182
|
+
end
|
183
|
+
|
184
|
+
alias inspect to_s
|
185
|
+
|
186
|
+
end
|
187
|
+
|
165
188
|
# =Lexical Types
|
166
189
|
#
|
167
190
|
# ; Statement separator
|
@@ -183,14 +206,6 @@ end
|
|
183
206
|
#
|
184
207
|
class LXL::Parser
|
185
208
|
|
186
|
-
class Token
|
187
|
-
attr_accessor :type, :value
|
188
|
-
def initialize(type, value) @type = type; @value = value end
|
189
|
-
def whitespace?() value.to_s.strip.empty? end
|
190
|
-
def to_s() "T:#{@type.chr}:#{@value}" end
|
191
|
-
alias inspect to_s
|
192
|
-
end
|
193
|
-
|
194
209
|
RUBY_OPERATORS = ['+', '-', '*', '/', '<=', '>=', '==', '!=', '<', '>', '+', '**']
|
195
210
|
EXCEL_OPERATORS = ['+', '-', '*', '/', '<=', '>=', '=', '<>', '<', '>', '&', '^' ]
|
196
211
|
|
@@ -200,6 +215,12 @@ class LXL::Parser
|
|
200
215
|
self.new.eval(formula)
|
201
216
|
end
|
202
217
|
|
218
|
+
# Default token class.
|
219
|
+
#
|
220
|
+
def self.token_class
|
221
|
+
LXL::Token
|
222
|
+
end
|
223
|
+
|
203
224
|
# Default lexer class.
|
204
225
|
#
|
205
226
|
def self.lexer_class
|
@@ -218,7 +239,7 @@ class LXL::Parser
|
|
218
239
|
LXL::Range
|
219
240
|
end
|
220
241
|
|
221
|
-
# Initialize namespace and
|
242
|
+
# Initialize namespace and lexer.
|
222
243
|
#
|
223
244
|
def initialize(namespace=self.class.namespace_class.new)
|
224
245
|
@namespace = namespace
|
@@ -240,7 +261,7 @@ class LXL::Parser
|
|
240
261
|
[/\A\w+/, ?u], # Unknown
|
241
262
|
])
|
242
263
|
end
|
243
|
-
|
264
|
+
|
244
265
|
# Evaluate a formula.
|
245
266
|
#
|
246
267
|
def eval(string)
|
@@ -252,6 +273,12 @@ class LXL::Parser
|
|
252
273
|
|
253
274
|
protected
|
254
275
|
|
276
|
+
# Store parsed token type and value.
|
277
|
+
#
|
278
|
+
def store(type, value)
|
279
|
+
self.class.token_class.new(type, value)
|
280
|
+
end
|
281
|
+
|
255
282
|
# Quote a string.
|
256
283
|
#
|
257
284
|
# quote('a "quoted" value.')
|
@@ -310,22 +337,22 @@ class LXL::Parser
|
|
310
337
|
text << tokens.shift
|
311
338
|
end
|
312
339
|
text = text.join.chomp
|
313
|
-
formulas.last <<
|
340
|
+
formulas.last << store(type, translate_quotes(quote(text))) unless text.empty?
|
314
341
|
# Formula
|
315
342
|
else
|
316
|
-
t =
|
343
|
+
t = store(type, token)
|
317
344
|
case type
|
318
345
|
when ?; then formulas << []
|
319
346
|
when ?= then formulas << []
|
320
|
-
when ?o then formulas.last <<
|
321
|
-
when ?s then formulas.last <<
|
322
|
-
when ?p then formulas.last <<
|
323
|
-
when ?f then formulas.last <<
|
324
|
-
when ?i then formulas.last <<
|
347
|
+
when ?o then formulas.last << store(type, ops[token])
|
348
|
+
when ?s then formulas.last << store(type, translate_quotes(token))
|
349
|
+
when ?p then formulas.last << store(type, token.to_f/100)
|
350
|
+
when ?f then formulas.last << store(type, token.to_f)
|
351
|
+
when ?i then formulas.last << store(type, token.to_i)
|
325
352
|
when ?r then
|
326
353
|
range = token.split(/:/)
|
327
354
|
range[1] = range[0] if range.size == 1
|
328
|
-
formulas.last <<
|
355
|
+
formulas.last << store(type, "self.class.range_class.new(*#{range.inspect})")
|
329
356
|
when ?u then
|
330
357
|
upper = token.to_s.upcase
|
331
358
|
lower = token.to_s.downcase
|
@@ -334,12 +361,12 @@ class LXL::Parser
|
|
334
361
|
# Constants
|
335
362
|
if tokens.first != '('
|
336
363
|
if @namespace.const_defined?(upper) or custom_const_missing
|
337
|
-
formulas.last <<
|
364
|
+
formulas.last << store(?C, "@namespace.const_get(:#{upper})")
|
338
365
|
else formulas.last << t end
|
339
366
|
# Functions
|
340
367
|
else
|
341
368
|
if @namespace.respond_to?(lower) or @namespace.respond_to?(:method_missing)
|
342
|
-
formulas.last <<
|
369
|
+
formulas.last << store(?F, "@namespace.#{lower}")
|
343
370
|
else formulas.last << t end
|
344
371
|
end
|
345
372
|
else formulas.last << t end
|
metadata
CHANGED
@@ -3,7 +3,7 @@ rubygems_version: 0.8.3
|
|
3
3
|
specification_version: 1
|
4
4
|
name: lxl
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.4.
|
6
|
+
version: 0.4.1
|
7
7
|
date: 2005-02-16
|
8
8
|
summary: LXL (Like Excel) is a mini-language that mimics Microsoft Excel formulas. Easily extended with new constants and functions.
|
9
9
|
require_paths:
|