flog 2.2.0 → 2.3.0
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.tar.gz.sig +1 -0
- data/.autotest +15 -0
- data/History.txt +22 -0
- data/Manifest.txt +1 -17
- data/bin/flog +1 -1
- data/lib/flog.rb +107 -103
- data/test/test_flog.rb +463 -1414
- metadata +26 -24
- metadata.gz.sig +0 -0
- data/gem_updater.rb +0 -161
- data/spec_fixtures/collection/bigger_example/acts/date_range.rb +0 -199
- data/spec_fixtures/collection/bigger_example/acts/range.rb +0 -391
- data/spec_fixtures/collection/bigger_example/association_extensions/date_ranged.rb +0 -11
- data/spec_fixtures/collection/bigger_example/association_extensions/ranged.rb +0 -13
- data/spec_fixtures/collection/bigger_example/reflection_extensions/ranged.rb +0 -50
- data/spec_fixtures/directory/bot_filter.rb +0 -70
- data/spec_fixtures/directory/bot_parser.rb +0 -79
- data/spec_fixtures/directory/bot_parser_format.rb +0 -23
- data/spec_fixtures/directory/bot_sender.rb +0 -46
- data/spec_fixtures/empty/empty.rb +0 -0
- data/spec_fixtures/simple/simple.rb +0 -191
- data/test/test_flog_command.rb +0 -343
- data/test/test_flog_integration.rb +0 -946
- data/test/test_helper.rb +0 -65
- data/unpack.rb +0 -22
- data/update_scores.rb +0 -245
data.tar.gz.sig
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
����!�������K�4+5՞��d�l=yT�n�6\�aU���dq���>�'x�\�웍{ᷰеf[ɠlW���'�T�vV�h�|��s���o4�<"�8���15��Lʴ��n�����QO/�*ώ��To�tʲ�I'ߨ�tW<z$i���Kìă���V�� ��G�I�ۗei
|
data/.autotest
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'autotest/restart'
|
4
|
+
require 'autotest/rcov'
|
5
|
+
|
6
|
+
Autotest.add_hook :initialize do |at|
|
7
|
+
at.order = :random
|
8
|
+
|
9
|
+
at.add_mapping(/^spec\/.*_spec\.rb$/) do |filename, _|
|
10
|
+
filename
|
11
|
+
end
|
12
|
+
|
13
|
+
at.libs << ':../../minitest/dev/lib'
|
14
|
+
at.testlib = "minitest/autorun"
|
15
|
+
end
|
data/History.txt
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
=== 2.3.0 / 2009-12-09
|
2
|
+
|
3
|
+
* 1 major enhancement:
|
4
|
+
|
5
|
+
* Added file:line info to the flog report (Marty Andrews)
|
6
|
+
|
7
|
+
* 13 minor enhancements:
|
8
|
+
|
9
|
+
* Added .autotest.
|
10
|
+
* Deleted pre-gauntlet scripts.
|
11
|
+
* Flog#method_name now at least tries show when it is a class method.
|
12
|
+
* Flog.parse_options now takes args directly.
|
13
|
+
* Removed Flog#increment_total_score_by.
|
14
|
+
* Removed Flog#output_summary.
|
15
|
+
* Removed Flog#process_attrset.
|
16
|
+
* Removed Flog#record_method_score.
|
17
|
+
* Removed Flog#summarize_method.
|
18
|
+
* Removed Flog::default_options.
|
19
|
+
* Renamed Flog#analyze_list to process_until_empty.
|
20
|
+
* Renamed Flog#options to #option
|
21
|
+
* Rewrote entire test suite (3100 lines down!). Cleaner and less brittle.
|
22
|
+
|
1
23
|
=== 2.2.0 / 2009-08-14
|
2
24
|
|
3
25
|
* 1 minor enhancement:
|
data/Manifest.txt
CHANGED
@@ -1,26 +1,10 @@
|
|
1
|
+
.autotest
|
1
2
|
History.txt
|
2
3
|
Manifest.txt
|
3
4
|
README.txt
|
4
5
|
Rakefile
|
5
6
|
bin/flog
|
6
|
-
gem_updater.rb
|
7
7
|
lib/flog.rb
|
8
8
|
lib/flog_task.rb
|
9
9
|
lib/gauntlet_flog.rb
|
10
|
-
unpack.rb
|
11
|
-
update_scores.rb
|
12
|
-
spec_fixtures/collection/bigger_example/acts/date_range.rb
|
13
|
-
spec_fixtures/collection/bigger_example/acts/range.rb
|
14
|
-
spec_fixtures/collection/bigger_example/association_extensions/date_ranged.rb
|
15
|
-
spec_fixtures/collection/bigger_example/association_extensions/ranged.rb
|
16
|
-
spec_fixtures/collection/bigger_example/reflection_extensions/ranged.rb
|
17
|
-
spec_fixtures/directory/bot_filter.rb
|
18
|
-
spec_fixtures/directory/bot_parser.rb
|
19
|
-
spec_fixtures/directory/bot_parser_format.rb
|
20
|
-
spec_fixtures/directory/bot_sender.rb
|
21
|
-
spec_fixtures/empty/empty.rb
|
22
|
-
spec_fixtures/simple/simple.rb
|
23
10
|
test/test_flog.rb
|
24
|
-
test/test_flog_command.rb
|
25
|
-
test/test_flog_integration.rb
|
26
|
-
test/test_helper.rb
|
data/bin/flog
CHANGED
data/lib/flog.rb
CHANGED
@@ -4,7 +4,7 @@ require 'ruby_parser'
|
|
4
4
|
require 'optparse'
|
5
5
|
|
6
6
|
class Flog < SexpProcessor
|
7
|
-
VERSION = '2.
|
7
|
+
VERSION = '2.3.0'
|
8
8
|
|
9
9
|
THRESHOLD = 0.60
|
10
10
|
SCORES = Hash.new 1
|
@@ -69,14 +69,8 @@ class Flog < SexpProcessor
|
|
69
69
|
@@no_method = :none
|
70
70
|
|
71
71
|
attr_accessor :multiplier
|
72
|
-
attr_reader :calls, :
|
73
|
-
|
74
|
-
def self.default_options
|
75
|
-
{
|
76
|
-
:quiet => true,
|
77
|
-
:continue => false,
|
78
|
-
}
|
79
|
-
end
|
72
|
+
attr_reader :calls, :option, :class_stack, :method_stack, :mass
|
73
|
+
attr_reader :method_locations
|
80
74
|
|
81
75
|
# REFACTOR: from flay
|
82
76
|
def self.expand_dirs_to_files *dirs
|
@@ -91,27 +85,31 @@ class Flog < SexpProcessor
|
|
91
85
|
}.flatten.sort
|
92
86
|
end
|
93
87
|
|
94
|
-
def self.parse_options
|
95
|
-
|
96
|
-
|
88
|
+
def self.parse_options args = ARGV
|
89
|
+
option = {
|
90
|
+
:quiet => true,
|
91
|
+
:continue => false,
|
92
|
+
}
|
93
|
+
|
94
|
+
OptionParser.new do |opts|
|
97
95
|
opts.on("-a", "--all", "Display all flog results, not top 60%.") do
|
98
|
-
|
96
|
+
option[:all] = true
|
99
97
|
end
|
100
98
|
|
101
99
|
opts.on("-b", "--blame", "Include blame information for methods.") do
|
102
|
-
|
100
|
+
option[:blame] = true
|
103
101
|
end
|
104
102
|
|
105
103
|
opts.on("-c", "--continue", "Continue despite syntax errors.") do
|
106
|
-
|
104
|
+
option[:continue] = true
|
107
105
|
end
|
108
106
|
|
109
107
|
opts.on("-d", "--details", "Show method details.") do
|
110
|
-
|
108
|
+
option[:details] = true
|
111
109
|
end
|
112
110
|
|
113
111
|
opts.on("-g", "--group", "Group and sort by class.") do
|
114
|
-
|
112
|
+
option[:group] = true
|
115
113
|
end
|
116
114
|
|
117
115
|
opts.on("-h", "--help", "Show this message.") do
|
@@ -125,37 +123,34 @@ class Flog < SexpProcessor
|
|
125
123
|
end
|
126
124
|
end
|
127
125
|
|
128
|
-
opts.on("-m", "--methods-only", "Skip code outside of methods.") do
|
129
|
-
|
126
|
+
opts.on("-m", "--methods-only", "Skip code outside of methods.") do
|
127
|
+
option[:methods] = true
|
130
128
|
end
|
131
129
|
|
132
|
-
opts.on("-q", "--quiet", "Don't show method details. [default]")
|
133
|
-
|
130
|
+
opts.on("-q", "--quiet", "Don't show method details. [default]") do
|
131
|
+
option[:quiet] = true
|
134
132
|
end
|
135
133
|
|
136
|
-
opts.on("-s", "--score", "Display total score only.")
|
137
|
-
|
134
|
+
opts.on("-s", "--score", "Display total score only.") do
|
135
|
+
option[:score] = true
|
138
136
|
end
|
139
137
|
|
140
|
-
opts.on("-v", "--verbose", "Display progress during processing.")
|
141
|
-
|
138
|
+
opts.on("-v", "--verbose", "Display progress during processing.") do
|
139
|
+
option[:verbose] = true
|
142
140
|
end
|
143
|
-
end.parse!
|
141
|
+
end.parse! Array(args)
|
144
142
|
|
145
|
-
|
143
|
+
option
|
146
144
|
end
|
147
145
|
|
148
|
-
# TODO: rename options to option, you only deal with them one at a time...
|
149
|
-
|
150
146
|
def add_to_score name, score = OTHER_SCORES[name]
|
151
|
-
@calls[
|
147
|
+
@calls[signature][name] += score * @multiplier
|
152
148
|
end
|
153
149
|
|
154
150
|
##
|
155
151
|
# Process each element of #exp in turn.
|
156
|
-
# TODO: rename, bleed wasn't good, but this is actually worse
|
157
152
|
|
158
|
-
def
|
153
|
+
def process_until_empty exp
|
159
154
|
process exp.shift until exp.empty?
|
160
155
|
end
|
161
156
|
|
@@ -171,7 +166,7 @@ class Flog < SexpProcessor
|
|
171
166
|
begin
|
172
167
|
# TODO: replace File.open to deal with "-"
|
173
168
|
ruby = file == '-' ? $stdin.read : File.read(file)
|
174
|
-
warn "** flogging #{file}" if
|
169
|
+
warn "** flogging #{file}" if option[:verbose]
|
175
170
|
|
176
171
|
ast = @parser.process(ruby, file)
|
177
172
|
next unless ast
|
@@ -182,7 +177,7 @@ class Flog < SexpProcessor
|
|
182
177
|
warn "#{e.inspect} at #{e.backtrace.first(5).join(', ')}"
|
183
178
|
warn "\n...stupid lemmings and their bad erb templates... skipping"
|
184
179
|
else
|
185
|
-
raise e unless
|
180
|
+
raise e unless option[:continue]
|
186
181
|
warn file
|
187
182
|
warn "#{e.inspect} at #{e.backtrace.first(5).join(', ')}"
|
188
183
|
end
|
@@ -190,6 +185,9 @@ class Flog < SexpProcessor
|
|
190
185
|
end
|
191
186
|
end
|
192
187
|
|
188
|
+
##
|
189
|
+
# Adds name to the class stack, for the duration of the block
|
190
|
+
|
193
191
|
def in_klass name
|
194
192
|
@class_stack.unshift name
|
195
193
|
yield
|
@@ -197,33 +195,30 @@ class Flog < SexpProcessor
|
|
197
195
|
end
|
198
196
|
|
199
197
|
##
|
200
|
-
# Adds name to the
|
198
|
+
# Adds name to the method stack, for the duration of the block
|
201
199
|
|
202
|
-
def in_method
|
200
|
+
def in_method(name, file, line)
|
203
201
|
@method_stack.unshift name
|
202
|
+
# "#{klass_name}##{name}"
|
203
|
+
@method_locations[signature] = "#{file}:#{line}"
|
204
204
|
yield
|
205
205
|
@method_stack.shift
|
206
206
|
end
|
207
207
|
|
208
|
-
def
|
209
|
-
raise "@total_score isn't even set yet... dumbass" unless @total_score
|
210
|
-
@total_score += amount
|
211
|
-
end
|
212
|
-
|
213
|
-
def initialize options = {}
|
208
|
+
def initialize option = {}
|
214
209
|
super()
|
215
|
-
@
|
210
|
+
@option = option
|
216
211
|
@class_stack = []
|
217
212
|
@method_stack = []
|
213
|
+
@method_locations = {}
|
218
214
|
@mass = {}
|
219
215
|
@parser = RubyParser.new
|
220
216
|
self.auto_shift_type = true
|
221
|
-
self.require_empty = false # HACK
|
222
217
|
self.reset
|
223
218
|
end
|
224
219
|
|
225
220
|
##
|
226
|
-
#
|
221
|
+
# Returns the first class in the list, or @@no_class if there are
|
227
222
|
# none.
|
228
223
|
|
229
224
|
def klass_name
|
@@ -236,7 +231,7 @@ class Flog < SexpProcessor
|
|
236
231
|
name.delete :colon2
|
237
232
|
name.join("::")
|
238
233
|
when :colon3 then
|
239
|
-
name.last
|
234
|
+
name.last.to_s
|
240
235
|
else
|
241
236
|
name
|
242
237
|
end
|
@@ -245,18 +240,20 @@ class Flog < SexpProcessor
|
|
245
240
|
end
|
246
241
|
|
247
242
|
##
|
248
|
-
#
|
243
|
+
# Returns the first method in the list, or @@no_method if there are
|
249
244
|
# none.
|
250
245
|
|
251
246
|
def method_name
|
252
|
-
@method_stack.first || @@no_method
|
247
|
+
m = @method_stack.first || @@no_method
|
248
|
+
m = "##{m}" unless m =~ /::/ unless m == @@no_method # FIX
|
249
|
+
m
|
253
250
|
end
|
254
251
|
|
255
252
|
def output_details(io, max = nil)
|
256
253
|
my_totals = totals
|
257
254
|
current = 0
|
258
255
|
|
259
|
-
if
|
256
|
+
if option[:group] then
|
260
257
|
scores = Hash.new 0
|
261
258
|
methods = Hash.new { |h,k| h[k] = [] }
|
262
259
|
|
@@ -273,7 +270,12 @@ class Flog < SexpProcessor
|
|
273
270
|
io.puts
|
274
271
|
io.puts "%8.1f: %s" % [total, "#{klass} total"]
|
275
272
|
methods[klass].each do |name, score|
|
276
|
-
|
273
|
+
location = @method_locations[name]
|
274
|
+
if location then
|
275
|
+
io.puts "%8.1f: %-32s %s" % [score, name, location]
|
276
|
+
else
|
277
|
+
io.puts "%8.1f: %s" % [score, name]
|
278
|
+
end
|
277
279
|
end
|
278
280
|
end
|
279
281
|
else
|
@@ -286,21 +288,25 @@ class Flog < SexpProcessor
|
|
286
288
|
end
|
287
289
|
|
288
290
|
def output_method_details(io, class_method, call_list)
|
289
|
-
return 0 if
|
291
|
+
return 0 if option[:methods] and class_method =~ /##{@@no_method}/
|
290
292
|
|
291
293
|
total = totals[class_method]
|
292
|
-
io.puts "%8.1f: %s" % [total, class_method]
|
293
294
|
|
294
|
-
|
295
|
-
|
296
|
-
|
295
|
+
location = @method_locations[class_method]
|
296
|
+
if location then
|
297
|
+
io.puts "%8.1f: %-32s %s" % [total, class_method, location]
|
298
|
+
else
|
299
|
+
io.puts "%8.1f: %s" % [total, class_method]
|
300
|
+
end
|
297
301
|
|
298
|
-
|
299
|
-
|
302
|
+
if option[:details] then
|
303
|
+
call_list.sort_by { |k,v| -v }.each do |call, count|
|
304
|
+
io.puts " %6.1f: %s" % [count, call]
|
305
|
+
end
|
306
|
+
io.puts
|
307
|
+
end
|
300
308
|
|
301
|
-
|
302
|
-
io.puts "%8.1f: %s" % [total, "flog total"]
|
303
|
-
io.puts "%8.1f: %s" % [average, "flog/method average"]
|
309
|
+
total
|
304
310
|
end
|
305
311
|
|
306
312
|
##
|
@@ -315,19 +321,16 @@ class Flog < SexpProcessor
|
|
315
321
|
@multiplier -= bonus
|
316
322
|
end
|
317
323
|
|
318
|
-
def record_method_score(method, score)
|
319
|
-
@totals ||= Hash.new(0)
|
320
|
-
@totals[method] = score
|
321
|
-
end
|
322
|
-
|
323
324
|
##
|
324
325
|
# Report results to #io, STDOUT by default.
|
325
326
|
|
326
327
|
def report(io = $stdout)
|
327
|
-
|
328
|
-
|
328
|
+
io.puts "%8.1f: %s" % [total, "flog total"]
|
329
|
+
io.puts "%8.1f: %s" % [average, "flog/method average"]
|
330
|
+
|
331
|
+
return if option[:score]
|
329
332
|
|
330
|
-
if
|
333
|
+
if option[:all] then
|
331
334
|
output_details(io)
|
332
335
|
else
|
333
336
|
output_details(io, total * THRESHOLD)
|
@@ -354,14 +357,13 @@ class Flog < SexpProcessor
|
|
354
357
|
Math.sqrt(a*a + b*b + c*c)
|
355
358
|
end
|
356
359
|
|
357
|
-
def
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
increment_total_score_by score
|
360
|
+
def signature
|
361
|
+
m = method_name
|
362
|
+
m = "#none" if m == @@no_method
|
363
|
+
"#{klass_name}#{m}" # FIX: ugly
|
362
364
|
end
|
363
365
|
|
364
|
-
def total
|
366
|
+
def total # FIX: I hate this indirectness
|
365
367
|
totals unless @total_score # calculates total_score as well
|
366
368
|
|
367
369
|
@total_score
|
@@ -374,10 +376,16 @@ class Flog < SexpProcessor
|
|
374
376
|
unless @totals then
|
375
377
|
@total_score = 0
|
376
378
|
@totals = Hash.new(0)
|
379
|
+
|
377
380
|
calls.each do |meth, tally|
|
378
|
-
|
381
|
+
next if option[:methods] and meth =~ /##{@@no_method}$/
|
382
|
+
score = score_method(tally)
|
383
|
+
|
384
|
+
@totals[meth] = score
|
385
|
+
@total_score += score
|
379
386
|
end
|
380
387
|
end
|
388
|
+
|
381
389
|
@totals
|
382
390
|
end
|
383
391
|
|
@@ -409,15 +417,9 @@ class Flog < SexpProcessor
|
|
409
417
|
s()
|
410
418
|
end
|
411
419
|
|
412
|
-
def process_attrset(exp)
|
413
|
-
add_to_score :assignment
|
414
|
-
raise exp.inspect
|
415
|
-
s()
|
416
|
-
end
|
417
|
-
|
418
420
|
def process_block(exp)
|
419
421
|
penalize_by 0.1 do
|
420
|
-
|
422
|
+
process_until_empty exp
|
421
423
|
end
|
422
424
|
s()
|
423
425
|
end
|
@@ -461,7 +463,7 @@ class Flog < SexpProcessor
|
|
461
463
|
add_to_score :branch
|
462
464
|
process exp.shift # recv
|
463
465
|
penalize_by 0.1 do
|
464
|
-
|
466
|
+
process_until_empty exp
|
465
467
|
end
|
466
468
|
s()
|
467
469
|
end
|
@@ -469,14 +471,14 @@ class Flog < SexpProcessor
|
|
469
471
|
def process_class(exp)
|
470
472
|
in_klass exp.shift do
|
471
473
|
penalize_by 1.0 do
|
472
|
-
|
474
|
+
process exp.shift # superclass expression
|
473
475
|
end
|
474
|
-
|
476
|
+
process_until_empty exp
|
475
477
|
end
|
476
478
|
s()
|
477
479
|
end
|
478
480
|
|
479
|
-
def process_dasgn_curr(exp)
|
481
|
+
def process_dasgn_curr(exp) # FIX: remove
|
480
482
|
add_to_score :assignment
|
481
483
|
exp.shift # name
|
482
484
|
process exp.shift # assigment, if any
|
@@ -486,16 +488,16 @@ class Flog < SexpProcessor
|
|
486
488
|
alias :process_lasgn :process_dasgn_curr
|
487
489
|
|
488
490
|
def process_defn(exp)
|
489
|
-
in_method exp.shift do
|
490
|
-
|
491
|
+
in_method exp.shift, exp.file, exp.line do
|
492
|
+
process_until_empty exp
|
491
493
|
end
|
492
494
|
s()
|
493
495
|
end
|
494
496
|
|
495
497
|
def process_defs(exp)
|
496
|
-
process exp.shift
|
497
|
-
in_method exp.shift do
|
498
|
-
|
498
|
+
recv = process exp.shift
|
499
|
+
in_method "::#{exp.shift}", exp.file, exp.line do
|
500
|
+
process_until_empty exp
|
499
501
|
end
|
500
502
|
s()
|
501
503
|
end
|
@@ -504,7 +506,7 @@ class Flog < SexpProcessor
|
|
504
506
|
def process_else(exp)
|
505
507
|
add_to_score :branch
|
506
508
|
penalize_by 0.1 do
|
507
|
-
|
509
|
+
process_until_empty exp
|
508
510
|
end
|
509
511
|
s()
|
510
512
|
end
|
@@ -523,15 +525,17 @@ class Flog < SexpProcessor
|
|
523
525
|
|
524
526
|
def process_iter(exp)
|
525
527
|
context = (self.context - [:class, :module, :scope])
|
526
|
-
if context.uniq.sort_by {|s|s.to_s} == [:block, :iter] then
|
528
|
+
if context.uniq.sort_by { |s| s.to_s } == [:block, :iter] then
|
527
529
|
recv = exp.first
|
530
|
+
|
531
|
+
# DSL w/ names. eg task :name do ... end
|
528
532
|
if (recv[0] == :call and recv[1] == nil and recv.arglist[1] and
|
529
533
|
[:lit, :str].include? recv.arglist[1][0]) then
|
530
534
|
msg = recv[2]
|
531
535
|
submsg = recv.arglist[1][1]
|
532
|
-
|
533
|
-
|
534
|
-
|
536
|
+
in_klass msg do # :task
|
537
|
+
in_method submsg, exp.file, exp.line do # :name
|
538
|
+
process_until_empty exp
|
535
539
|
end
|
536
540
|
end
|
537
541
|
return s()
|
@@ -540,12 +544,12 @@ class Flog < SexpProcessor
|
|
540
544
|
|
541
545
|
add_to_score :branch
|
542
546
|
|
543
|
-
exp.delete 0
|
547
|
+
exp.delete 0 # TODO: what is this?
|
544
548
|
|
545
549
|
process exp.shift # no penalty for LHS
|
546
550
|
|
547
551
|
penalize_by 0.1 do
|
548
|
-
|
552
|
+
process_until_empty exp
|
549
553
|
end
|
550
554
|
|
551
555
|
s()
|
@@ -568,13 +572,13 @@ class Flog < SexpProcessor
|
|
568
572
|
|
569
573
|
def process_masgn(exp)
|
570
574
|
add_to_score :assignment
|
571
|
-
|
575
|
+
process_until_empty exp
|
572
576
|
s()
|
573
577
|
end
|
574
578
|
|
575
579
|
def process_module(exp)
|
576
580
|
in_klass exp.shift do
|
577
|
-
|
581
|
+
process_until_empty exp
|
578
582
|
end
|
579
583
|
s()
|
580
584
|
end
|
@@ -582,7 +586,7 @@ class Flog < SexpProcessor
|
|
582
586
|
def process_sclass(exp)
|
583
587
|
penalize_by 0.5 do
|
584
588
|
recv = process exp.shift
|
585
|
-
|
589
|
+
process_until_empty exp
|
586
590
|
end
|
587
591
|
|
588
592
|
add_to_score :sclass
|
@@ -591,7 +595,7 @@ class Flog < SexpProcessor
|
|
591
595
|
|
592
596
|
def process_super(exp)
|
593
597
|
add_to_score :super
|
594
|
-
|
598
|
+
process_until_empty exp
|
595
599
|
s()
|
596
600
|
end
|
597
601
|
|
@@ -608,7 +612,7 @@ class Flog < SexpProcessor
|
|
608
612
|
|
609
613
|
def process_yield(exp)
|
610
614
|
add_to_score :yield
|
611
|
-
|
615
|
+
process_until_empty exp
|
612
616
|
s()
|
613
617
|
end
|
614
618
|
end
|