sorcerer 0.0.1 → 0.0.2

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.
@@ -0,0 +1,50 @@
1
+ module Sorcerer
2
+ class Subexpression
3
+ def initialize(sexp)
4
+ @sexp = sexp
5
+ end
6
+
7
+ def subexpressions
8
+ sub_exp.map { |s| Sorcerer.source(s) }
9
+ end
10
+
11
+ def sub_exp
12
+ @result = []
13
+ recur(@sexp)
14
+ @result
15
+ end
16
+
17
+ def recur(sexp)
18
+ if sexp.is_a?(Array)
19
+ if sexp.first.is_a?(Symbol)
20
+ tagged_sexp(sexp)
21
+ else
22
+ list_sexp(sexp)
23
+ end
24
+ end
25
+ end
26
+
27
+ def list_sexp(sexp)
28
+ sexp.each do |s|
29
+ recur(s)
30
+ end
31
+ end
32
+
33
+ def tagged_sexp(sexp)
34
+ case sexp.first
35
+ when :var_ref, :binary, :call, :array, :hash, :unary
36
+ list_sexp(sexp)
37
+ @result << sexp
38
+ when :aref
39
+ recur(sexp[2])
40
+ @result << sexp
41
+ when :method_add_arg
42
+ list_sexp(sexp[2])
43
+ recur(sexp[1][1])
44
+ @result << sexp
45
+ else
46
+ list_sexp(sexp)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'redcloth'
4
+
5
+ directory "html"
6
+
7
+ desc "Display the README file"
8
+ task :readme => "html/README.html" do
9
+ sh "open html/README.html"
10
+ end
11
+
12
+ desc "format the README file"
13
+ task "html/README.html" => ['html', 'README.textile'] do
14
+ open("README.textile") do |source|
15
+ open('html/README.html', 'w') do |out|
16
+ out.write(RedCloth.new(source.read).to_html)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,75 @@
1
+ require 'test/unit'
2
+ require 'sorcerer'
3
+ require 'ripper'
4
+ require 'pp'
5
+
6
+ class SubexpressionTest < Test::Unit::TestCase
7
+ def assert_subexpressions code, subexpressions, debug=false
8
+ sexp = Ripper::SexpBuilder.new(code).parse
9
+ if debug
10
+ pp sexp
11
+ end
12
+ sub = Sorcerer::Subexpression.new(sexp)
13
+ assert_equal subexpressions, sub.subexpressions
14
+ end
15
+
16
+ def test_simple
17
+ assert_subexpressions "a", ["a"]
18
+ assert_subexpressions "b", ["b"]
19
+ end
20
+
21
+ def test_unary_expressions
22
+ assert_subexpressions "-(a+b)", [
23
+ "a", "b", "a + b", "-(a + b)"
24
+ ]
25
+ end
26
+
27
+ def test_binary_expressions
28
+ assert_subexpressions "a + b", ["a", "b", "a + b"]
29
+ assert_subexpressions("a + b + c",
30
+ ["a", "b", "a + b", "c", "a + b + c"])
31
+ end
32
+
33
+ def test_method_calls_without_args
34
+ assert_subexpressions "o.f", ["o", "o.f"]
35
+ assert_subexpressions "f()", ["f()"]
36
+ end
37
+
38
+ def test_method_calls_with_args
39
+ assert_subexpressions "o.f", ["o", "o.f"]
40
+ assert_subexpressions "o.f(a, b)", [
41
+ "a", "b", "o", "o.f(a, b)"
42
+ ]
43
+ assert_subexpressions "f(a, b)", [
44
+ "a", "b", "f(a, b)"
45
+ ]
46
+ end
47
+
48
+ def test_array_reference
49
+ assert_subexpressions "a[i]", ["i", "a[i]"]
50
+ end
51
+
52
+ def test_array_literal
53
+ assert_subexpressions "[a, b, c]", [
54
+ "a", "b", "c", "[a, b, c]"
55
+ ]
56
+ end
57
+
58
+ def test_hash_literal
59
+ assert_subexpressions "{:a => aa, :b => bb}", [
60
+ "aa", "bb", "{:a => aa, :b => bb}"
61
+ ]
62
+ end
63
+
64
+ def test_pattern_matching
65
+ assert_subexpressions "a =~ /r/", ["a", "a =~ /r/"]
66
+ end
67
+
68
+ def test_complex_expression
69
+ assert_subexpressions "o.f(a+b, c*d, x.y, z(k, 2, 3))", [
70
+ "a", "b", "a + b", "c", "d", "c * d", "x", "x.y", "k", "z(k, 2, 3)",
71
+ "o", "o.f(a + b, c * d, x.y, z(k, 2, 3))"
72
+ ]
73
+ end
74
+
75
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sorcerer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Weirich
@@ -24,9 +24,12 @@ extra_rdoc_files: []
24
24
  files:
25
25
  - README.textile
26
26
  - Rakefile
27
- - lib/sorcerer/sorcerer.rb
27
+ - rakelib/readme.rake
28
+ - lib/sorcerer/resource.rb
29
+ - lib/sorcerer/subexpression.rb
28
30
  - lib/sorcerer.rb
29
31
  - test/sorcerer/sorcerer_test.rb
32
+ - test/sorcerer/subexpression_test.rb
30
33
  has_rdoc: true
31
34
  homepage: http://github.com/jimweirich/sorcerer
32
35
  licenses: []
@@ -55,7 +58,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
55
58
  version:
56
59
  requirements: []
57
60
 
58
- rubyforge_project:
61
+ rubyforge_project: sorcerer
59
62
  rubygems_version: 1.3.5
60
63
  signing_key:
61
64
  specification_version: 3
@@ -1,715 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'ripper'
4
-
5
- class Sorcerer
6
- class NoHandlerError < StandardError
7
- end
8
-
9
- # Generate the source code for teh given Ripper S-Expression.
10
- def Sorcerer.source(sexp, debug=false)
11
- new(sexp, debug).source
12
- end
13
-
14
- def initialize(sexp, debug=false)
15
- @sexp = sexp
16
- @source = ''
17
- @debug = debug
18
- @word_level = 0
19
- end
20
-
21
- def source
22
- resource(@sexp)
23
- @source
24
- end
25
-
26
- def resource(sexp)
27
- return unless sexp
28
- handler = Handlers[sexp.first]
29
- raise NoHandlerError.new(sexp.first) unless handler
30
- if @debug
31
- puts "----------------------------------------------------------"
32
- pp sexp
33
- end
34
- handler.call(self, sexp)
35
- end
36
-
37
- def handle_block(sexp)
38
- resource(sexp[1]) # Arguments
39
- if ! void?(sexp[2])
40
- emit(" ")
41
- resource(sexp[2]) # Statements
42
- end
43
- emit(" ")
44
- end
45
-
46
- def opt_parens(sexp)
47
- emit(" ") unless sexp.first == :arg_paren || sexp.first == :paren
48
- resource(sexp)
49
- end
50
-
51
- def emit(string)
52
- puts "EMITTING '#{string}'" if @debug
53
- @source << string
54
- end
55
-
56
- def nyi(sexp)
57
- raise "Handler for #{sexp.first} not implemented (#{sexp.inspect})"
58
- end
59
-
60
- def emit_separator(sep, first)
61
- emit(sep) unless first
62
- false
63
- end
64
-
65
- def params(normal_args, default_args, rest_args, unknown, block_arg)
66
- first = true
67
- if normal_args
68
- normal_args.each do |sx|
69
- first = emit_separator(", ", first)
70
- resource(sx)
71
- end
72
- end
73
- if default_args
74
- default_args.each do |sx|
75
- first = emit_separator(", ", first)
76
- resource(sx[0])
77
- emit("=")
78
- resource(sx[1])
79
- end
80
- end
81
- if rest_args
82
- first = emit_separator(", ", first)
83
- resource(rest_args)
84
- end
85
- if block_arg
86
- first = emit_separator(", ", first)
87
- resource(block_arg)
88
- end
89
- end
90
-
91
- def words(marker, sexp)
92
- emit("%#{marker}{") if @word_level == 0
93
- @word_level += 1
94
- if sexp[1] != [:qwords_new] && sexp[1] != [:words_new]
95
- resource(sexp[1])
96
- emit(" ")
97
- end
98
- resource(sexp[2])
99
- @word_level -= 1
100
- emit("}") if @word_level == 0
101
- end
102
-
103
- VOID_STATEMENT = [:stmts_add, [:stmts_new], [:void_stmt]]
104
- VOID_BODY = [:body_stmt, VOID_STATEMENT, nil, nil, nil]
105
-
106
- def void?(sexp)
107
- sexp.nil? ||
108
- sexp == VOID_STATEMENT ||
109
- sexp == VOID_BODY
110
- end
111
-
112
- NYI = lambda { |src, sexp| src.nyi(sexp) }
113
- DBG = lambda { |src, sexp| pp(sexp) }
114
- NOOP = lambda { |src, sexp| }
115
- SPACE = lambda { |src, sexp| src.emit(" ") }
116
- PASS1 = lambda { |src, sexp| src.resource(sexp[1]) }
117
- PASS2 = lambda { |src, sexp| src.resource(sexp[2]) }
118
- EMIT1 = lambda { |src, sexp| src.emit(sexp[1]) }
119
-
120
- Handlers = {
121
- # parser keywords
122
-
123
- :BEGIN => lambda { |src, sexp|
124
- src.emit("BEGIN {")
125
- unless src.void?(sexp[1])
126
- src.emit(" ")
127
- src.resource(sexp[1])
128
- end
129
- src.emit(" }")
130
- },
131
- :END => lambda { |src, sexp|
132
- src.emit("END {")
133
- unless src.void?(sexp[1])
134
- src.emit(" ")
135
- src.resource(sexp[1])
136
- end
137
- src.emit(" }")
138
- },
139
- :alias => lambda { |src, sexp|
140
- src.emit("alias ")
141
- src.resource(sexp[1])
142
- src.emit(" ")
143
- src.resource(sexp[2])
144
- },
145
- :alias_error => NYI,
146
- :aref => lambda { |src, sexp|
147
- src.resource(sexp[1])
148
- src.emit("[")
149
- src.resource(sexp[2])
150
- src.emit("]")
151
- },
152
- :aref_field => lambda { |src, sexp|
153
- src.resource(sexp[1])
154
- src.emit("[")
155
- src.resource(sexp[2])
156
- src.emit("]")
157
- },
158
- :arg_ambiguous => NYI,
159
- :arg_paren => lambda { |src, sexp|
160
- src.emit("(")
161
- src.resource(sexp[1]) if sexp[1]
162
- src.emit(")")
163
- },
164
- :args_add => lambda { |src, sexp|
165
- src.resource(sexp[1])
166
- if sexp[1].first != :args_new
167
- src.emit(", ")
168
- end
169
- src.resource(sexp[2])
170
- },
171
- :args_add_block => lambda { |src, sexp|
172
- src.resource(sexp[1])
173
- if sexp[2]
174
- if sexp[1].first != :args_new
175
- src.emit(", ")
176
- end
177
- if sexp[2]
178
- src.emit("&")
179
- src.resource(sexp[2])
180
- end
181
- end
182
- },
183
- :args_add_star => lambda { |src, sexp|
184
- src.resource(sexp[1])
185
- if sexp[1].first != :args_new
186
- src.emit(", ")
187
- end
188
- src.emit("*")
189
- src.resource(sexp[2])
190
- },
191
- :args_new => NOOP,
192
- :args_prepend => NYI,
193
- :array => lambda { |src, sexp|
194
- src.emit("[")
195
- src.resource(sexp[1])
196
- src.emit("]")
197
- },
198
- :assign => lambda { |src, sexp|
199
- src.resource(sexp[1])
200
- src.emit(" = ")
201
- src.resource(sexp[2])
202
- },
203
- :assign_error => NYI,
204
- :assoc_new => lambda { |src, sexp|
205
- src.resource(sexp[1])
206
- src.emit(" => ")
207
- src.resource(sexp[2])
208
- },
209
- :assoclist_from_args => lambda { |src, sexp|
210
- first = true
211
- sexp[1].each do |sx|
212
- src.emit(", ") unless first
213
- first = false
214
- src.resource(sx)
215
- end
216
- },
217
- :bare_assoc_hash => lambda { |src, sexp|
218
- first = true
219
- sexp[1].each do |sx|
220
- src.emit(", ") unless first
221
- first = false
222
- src.resource(sx)
223
- end
224
- },
225
- :begin => lambda { |src, sexp|
226
- src.emit("begin")
227
- src.resource(sexp[1])
228
- src.emit("end")
229
- },
230
- :binary => lambda { |src, sexp|
231
- src.resource(sexp[1])
232
- src.emit(" #{sexp[2]} ")
233
- src.resource(sexp[3])
234
- },
235
- :block_var => lambda { |src, sexp|
236
- src.emit(" |")
237
- src.resource(sexp[1])
238
- src.emit("|")
239
- },
240
- :block_var_add_block => NYI,
241
- :block_var_add_star => NYI,
242
- :blockarg => lambda { |src, sexp|
243
- src.emit("&")
244
- src.resource(sexp[1])
245
- },
246
- :body_stmt => lambda { |src, sexp|
247
- src.resource(sexp[1]) # Main Body
248
- src.emit("; ")
249
- src.resource(sexp[2]) # Rescue
250
- src.resource(sexp[4]) # Ensure
251
- },
252
- :brace_block => lambda { |src, sexp|
253
- src.emit(" {")
254
- src.handle_block(sexp)
255
- src.emit("}")
256
- },
257
- :break => lambda { |src, sexp|
258
- src.emit("break")
259
- src.emit(" ") unless sexp[1] == [:args_new]
260
- src.resource(sexp[1])
261
- },
262
- :call => lambda { |src, sexp|
263
- src.resource(sexp[1])
264
- src.emit(sexp[2])
265
- src.resource(sexp[3])
266
- },
267
- :case => lambda { |src, sexp|
268
- src.emit("case ")
269
- src.resource(sexp[1])
270
- src.emit(" ")
271
- src.resource(sexp[2])
272
- src.emit(" end")
273
- },
274
- :class => lambda { |src, sexp|
275
- src.emit("class ")
276
- src.resource(sexp[1])
277
- if ! src.void?(sexp[2])
278
- src.emit " < "
279
- src.resource(sexp[2])
280
- end
281
- src.emit("; ")
282
- src.resource(sexp[3]) unless src.void?(sexp[3])
283
- src.emit("end")
284
- },
285
- :class_name_error => NYI,
286
- :command => lambda { |src, sexp|
287
- src.resource(sexp[1])
288
- src.emit(" ")
289
- src.resource(sexp[2])
290
- },
291
- :command_call => NYI,
292
- :const_path_field => lambda { |src, sexp|
293
- src.resource(sexp[1])
294
- src.emit("::")
295
- src.resource(sexp[2])
296
- },
297
- :const_path_ref => lambda { |src, sexp|
298
- src.resource(sexp[1])
299
- src.emit("::")
300
- src.resource(sexp[2])
301
- },
302
- :const_ref => PASS1,
303
- :def => lambda { |src, sexp|
304
- src.emit("def ")
305
- src.resource(sexp[1])
306
- src.opt_parens(sexp[2])
307
- src.resource(sexp[3])
308
- src.emit("end")
309
- },
310
- :defined => lambda { |src, sexp|
311
- src.emit("defined?(")
312
- src.resource(sexp[1])
313
- src.emit(")")
314
- },
315
- :defs => NYI,
316
- :do_block => lambda { |src, sexp|
317
- src.emit(" do")
318
- src.handle_block(sexp)
319
- src.emit("end")
320
- },
321
- :dot2 => lambda { |src, sexp|
322
- src.resource(sexp[1])
323
- src.emit("..")
324
- src.resource(sexp[2])
325
- },
326
- :dot3 => lambda { |src, sexp|
327
- src.resource(sexp[1])
328
- src.emit("...")
329
- src.resource(sexp[2])
330
- },
331
- :dyna_symbol => lambda { |src, sexp|
332
- src.emit(':"')
333
- src.resource(sexp[1])
334
- src.emit('"')
335
- },
336
- :else => lambda { |src, sexp|
337
- src.emit(" else ")
338
- src.resource(sexp[1])
339
- },
340
- :elsif => lambda { |src, sexp|
341
- src.emit(" elsif ")
342
- src.resource(sexp[1])
343
- src.emit(" then ")
344
- src.resource(sexp[2])
345
- src.resource(sexp[3])
346
- },
347
- :ensure => lambda { |src, sexp|
348
- src.emit("ensure ")
349
- if sexp[1]
350
- src.resource(sexp[1])
351
- src.emit("; ") unless src.void?(sexp[1])
352
- end
353
- },
354
- :excessed_comma => NYI,
355
- :fcall => PASS1,
356
- :field => lambda { |src, sexp|
357
- src.resource(sexp[1])
358
- src.emit(sexp[2])
359
- src.resource(sexp[3])
360
- },
361
- :for => lambda { |src, sexp|
362
- src.emit("for ")
363
- src.resource(sexp[1])
364
- src.emit(" in ")
365
- src.resource(sexp[2])
366
- src.emit(" do ")
367
- unless src.void?(sexp[3])
368
- src.resource(sexp[3])
369
- src.emit(" ")
370
- end
371
- src.emit("end")
372
- },
373
- :hash => lambda { |src, sexp|
374
- src.emit("{")
375
- src.resource(sexp[1])
376
- src.emit("}")
377
- },
378
- :if => lambda { |src, sexp|
379
- src.emit("if ")
380
- src.resource(sexp[1])
381
- src.emit(" then ")
382
- src.resource(sexp[2])
383
- src.resource(sexp[3])
384
- src.emit(" end")
385
- },
386
- :if_mod => lambda { |src, sexp|
387
- src.resource(sexp[2])
388
- src.emit(" if ")
389
- src.resource(sexp[1])
390
- },
391
- :ifop => lambda { |src, sexp|
392
- src.resource(sexp[1])
393
- src.emit(" ? ")
394
- src.resource(sexp[2])
395
- src.emit(" : ")
396
- src.resource(sexp[3])
397
- },
398
- :lambda => lambda { |src, sexp|
399
- src.emit("->")
400
- src.resource(sexp[1])
401
- src.emit(" {")
402
- if ! src.void?(sexp[2])
403
- src.emit(" ")
404
- src.resource(sexp[2])
405
- end
406
- src.emit(" ")
407
- src.emit("}")
408
- },
409
- :magic_comment => NYI,
410
- :massign => lambda { |src, sexp|
411
- src.resource(sexp[1])
412
- src.emit(" = ")
413
- src.resource(sexp[2])
414
- },
415
- :method_add_arg => lambda { |src, sexp|
416
- src.resource(sexp[1])
417
- src.resource(sexp[2])
418
- },
419
- :method_add_block => lambda { |src, sexp|
420
- src.resource(sexp[1])
421
- src.resource(sexp[2])
422
- },
423
- :mlhs_add => lambda { |src, sexp|
424
- src.resource(sexp[1])
425
- src.emit(", ") unless sexp[1] == [:mlhs_new]
426
- src.resource(sexp[2])
427
- },
428
- :mlhs_add_star => lambda { |src, sexp|
429
- src.resource(sexp[1])
430
- src.emit(", ") unless sexp[1] == [:mlhs_new]
431
- src.emit("*")
432
- src.resource(sexp[2])
433
- },
434
- :mlhs_new => NOOP,
435
- :mlhs_paren => lambda { |src, sexp|
436
- src.emit("(")
437
- src.resource(sexp[1])
438
- src.emit(")")
439
- },
440
- :module => lambda { |src, sexp|
441
- src.emit("module ")
442
- src.resource(sexp[1])
443
- if src.void?(sexp[2])
444
- src.emit("; ")
445
- else
446
- src.resource(sexp[2])
447
- end
448
- src.emit("end")
449
- },
450
- :mrhs_add => lambda { |src, sexp|
451
- src.resource(sexp[1])
452
- src.emit(", ")
453
- src.resource(sexp[2])
454
- },
455
- :mrhs_add_star => lambda { |src, sexp|
456
- src.resource(sexp[1])
457
- src.emit(", ")
458
- src.emit("*")
459
- src.resource(sexp[2])
460
- },
461
- :mrhs_new => NYI,
462
- :mrhs_new_from_args => PASS1,
463
- :next => lambda { |src, sexp|
464
- src.emit("next")
465
- },
466
- :opassign => lambda { |src, sexp|
467
- src.resource(sexp[1])
468
- src.emit(" ")
469
- src.resource(sexp[2])
470
- src.emit(" ")
471
- src.resource(sexp[3])
472
- },
473
- :param_error => NYI,
474
- :params => lambda { |src, sexp|
475
- src.params(sexp[1], sexp[2], sexp[3], sexp[4], sexp[5])
476
- },
477
- :paren => lambda { |src, sexp|
478
- src.emit("(")
479
- src.resource(sexp[1])
480
- src.emit(")")
481
- },
482
- :parse_error => NYI,
483
- :program => PASS1,
484
- :qwords_add => lambda { |src, sexp|
485
- src.words("w", sexp)
486
- },
487
- :qwords_new => NOOP,
488
- :redo => lambda { |src, sexp|
489
- src.emit("redo")
490
- },
491
- :regexp_literal => lambda { |src, sexp|
492
- src.emit("/")
493
- src.resource(sexp[1])
494
- src.emit("/")
495
- },
496
- :rescue => lambda { |src, sexp|
497
- src.emit("rescue")
498
- if sexp[1] # Exception list
499
- src.emit(" ")
500
- if sexp[1].first.kind_of?(Symbol)
501
- src.resource(sexp[1])
502
- else
503
- src.resource(sexp[1].first)
504
- end
505
- src.emit(" => ")
506
- src.resource(sexp[2])
507
- end
508
- src.emit(";")
509
- if sexp[3] # Rescue Code
510
- if src.void?(sexp[3])
511
- src.emit(" ")
512
- else
513
- src.emit(" ")
514
- src.resource(sexp[3])
515
- src.emit("; ")
516
- end
517
- end
518
- },
519
- :rescue_mod => lambda { |src, sexp|
520
- src.resource(sexp[2])
521
- src.emit(" rescue ")
522
- src.resource(sexp[1])
523
- },
524
- :rest_param => lambda { |src, sexp|
525
- src.emit("*")
526
- src.resource(sexp[1])
527
- },
528
- :retry => lambda { |src, sexp|
529
- src.emit("retry")
530
- },
531
- :return => lambda { |src, sexp|
532
- src.emit("return")
533
- src.opt_parens(sexp[1])
534
- },
535
- :return0 => lambda { |src, sexp|
536
- src.emit("return")
537
- },
538
- :sclass => NYI,
539
- :stmts_add => lambda { |src, sexp|
540
- if sexp[1] != [:stmts_new]
541
- src.resource(sexp[1])
542
- src.emit("; ")
543
- end
544
- src.resource(sexp[2])
545
- },
546
- :stmts_new => NOOP,
547
- :string_add => lambda { |src, sexp|
548
- src.resource(sexp[1])
549
- src.resource(sexp[2])
550
- },
551
- :string_concat => lambda { |src, sexp|
552
- src.resource(sexp[1])
553
- src.emit(" ")
554
- src.resource(sexp[2])
555
- },
556
- :string_content => NOOP,
557
- :string_dvar => NYI,
558
- :string_embexpr => lambda { |src, sexp|
559
- src.emit('#{')
560
- src.resource(sexp[1])
561
- src.emit('}')
562
- },
563
- :string_literal => lambda { |src, sexp|
564
- src.emit('"')
565
- src.resource(sexp[1])
566
- src.emit('"')
567
- },
568
- :super => lambda { |src, sexp|
569
- src.emit("super")
570
- src.opt_parens(sexp[1])
571
- },
572
- :symbol => lambda { |src, sexp|
573
- src.emit(":")
574
- src.resource(sexp[1])
575
- },
576
- :symbol_literal => PASS1,
577
- :top_const_field => NYI,
578
- :top_const_ref => NYI,
579
- :unary => lambda { |src, sexp|
580
- src.emit(sexp[1].to_s[0,1])
581
- src.resource(sexp[2])
582
- },
583
- :undef => lambda { |src, sexp|
584
- src.emit("undef ")
585
- src.resource(sexp[1].first)
586
- },
587
- :unless => lambda { |src, sexp|
588
- src.emit("unless ")
589
- src.resource(sexp[1])
590
- src.emit(" then ")
591
- src.resource(sexp[2])
592
- src.resource(sexp[3])
593
- src.emit(" end")
594
- },
595
- :unless_mod => lambda { |src, sexp|
596
- src.resource(sexp[2])
597
- src.emit(" unless ")
598
- src.resource(sexp[1])
599
- },
600
- :until => lambda { |src, sexp|
601
- src.emit("until ")
602
- src.resource(sexp[1])
603
- src.emit(" do ")
604
- src.resource(sexp[2])
605
- src.emit(" end")
606
- },
607
- :until_mod => lambda { |src, sexp|
608
- src.resource(sexp[2])
609
- src.emit(" until ")
610
- src.resource(sexp[1])
611
- },
612
- :var_alias => NYI,
613
- :var_field => PASS1,
614
- :var_ref => PASS1,
615
- :void_stmt => NOOP,
616
- :when => lambda { |src, sexp|
617
- src.emit("when ")
618
- src.resource(sexp[1])
619
- src.emit("; ")
620
- src.resource(sexp[2])
621
- if sexp[3] && sexp[3].first == :when
622
- src.emit(" ")
623
- end
624
- src.resource(sexp[3])
625
- },
626
- :while => lambda { |src, sexp|
627
- src.emit("while ")
628
- src.resource(sexp[1])
629
- src.emit(" do ")
630
- src.resource(sexp[2])
631
- src.emit(" end")
632
- },
633
- :while_mod => lambda { |src, sexp|
634
- src.resource(sexp[2])
635
- src.emit(" while ")
636
- src.resource(sexp[1])
637
- },
638
- :word_add => PASS2,
639
- :word_new => NOOP,
640
- :words_add => lambda { |src, sexp|
641
- src.words("W", sexp)
642
- },
643
- :words_new => NOOP,
644
- :xstring_add => lambda { |src, sexp|
645
- src.resource(sexp[1])
646
- src.resource(sexp[2])
647
- },
648
- :xstring_literal => lambda { |src, sexp|
649
- src.emit('"')
650
- src.resource(sexp[1])
651
- src.emit('"')
652
- },
653
- :xstring_new => NOOP,
654
- :yield => lambda { |src, sexp|
655
- src.emit("yield")
656
- src.opt_parens(sexp[1])
657
- },
658
- :yield0 => lambda { |src, sexp|
659
- src.emit("yield")
660
- },
661
- :zsuper => lambda { |src, sexp|
662
- src.emit("super")
663
- },
664
-
665
- # Scanner keywords
666
-
667
- :@CHAR => NYI,
668
- :@__end__ => NYI,
669
- :@backref => NYI,
670
- :@backtick => NYI,
671
- :@comma => NYI,
672
- :@comment => NYI,
673
- :@const => EMIT1,
674
- :@cvar => EMIT1,
675
- :@embdoc => NYI,
676
- :@embdoc_beg => NYI,
677
- :@embdoc_end => NYI,
678
- :@embexpr_beg => NYI,
679
- :@embexpr_end => NYI,
680
- :@embvar => NYI,
681
- :@float => EMIT1,
682
- :@gvar => EMIT1,
683
- :@heredoc_beg => NYI,
684
- :@heredoc_end => NYI,
685
- :@ident => EMIT1,
686
- :@ignored_nl => NYI,
687
- :@int => EMIT1,
688
- :@ivar => EMIT1,
689
- :@kw => EMIT1,
690
- :@label => NYI,
691
- :@lbrace => NYI,
692
- :@lbracket => NYI,
693
- :@lparen => NYI,
694
- :@nl => NYI,
695
- :@op => EMIT1,
696
- :@period => NYI,
697
- :@qwords_beg => NYI,
698
- :@rbrace => NYI,
699
- :@rbracket => NYI,
700
- :@regexp_beg => NYI,
701
- :@regexp_end => NYI,
702
- :@rparen => NYI,
703
- :@semicolon => NYI,
704
- :@sp => NYI,
705
- :@symbeg => NYI,
706
- :@tlambda => NYI,
707
- :@tlambeg => NYI,
708
- :@tstring_beg => NYI,
709
- :@tstring_content => EMIT1,
710
- :@tstring_end => NYI,
711
- :@words_beg => NYI,
712
- :@words_sep => NYI,
713
- }
714
- end
715
-