ruby_parser 2.0.5 → 3.0.0.a1

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.
@@ -3,10 +3,15 @@ require 'racc/parser'
3
3
  require 'sexp'
4
4
  require 'strscan'
5
5
 
6
+ def d o
7
+ $stderr.puts o.inspect
8
+ end
9
+
6
10
  # WHY do I have to do this?!?
7
11
  class Regexp
8
- unless defined? ONCE then
9
- ONCE = 0 # 16 # ?
12
+ ONCE = 0 unless defined? ONCE # FIX: remove this - it makes no sense
13
+
14
+ unless defined? ENC_NONE then
10
15
  ENC_NONE = /x/n.options
11
16
  ENC_EUC = /x/e.options
12
17
  ENC_SJIS = /x/s.options
@@ -29,36 +34,31 @@ class RPStringScanner < StringScanner
29
34
  # old_getch
30
35
  # end
31
36
  # end
32
-
33
37
  def current_line # HAHA fuck you (HACK)
34
38
  string[0..pos][/\A.*__LINE__/m].split(/\n/).size
35
39
  end
36
40
 
41
+ def extra_lines_added
42
+ @extra_lines_added ||= 0
43
+ end
44
+
45
+ def extra_lines_added= val
46
+ @extra_lines_added = val
47
+ end
48
+
37
49
  def lineno
38
- string[0...pos].count("\n") + 1
50
+ string[0...pos].count("\n") + 1 - extra_lines_added
39
51
  end
40
52
 
41
53
  # TODO: once we get rid of these, we can make things like
42
54
  # TODO: current_line and lineno much more accurate and easy to do
43
- def unread c # TODO: remove this entirely - we should not need it
44
- return if c.nil? # UGH
45
- warn({:unread => caller[0]}.inspect) if ENV['TALLY']
46
- string[pos, 0] = c
47
- end
48
55
 
49
56
  def unread_many str # TODO: remove this entirely - we should not need it
50
57
  warn({:unread_many => caller[0]}.inspect) if ENV['TALLY']
58
+ self.extra_lines_added += str.count("\n")
51
59
  string[pos, 0] = str
52
60
  end
53
61
 
54
- def begin_of_line?
55
- pos == 0 or string[pos-1] == ?\n
56
- end
57
-
58
- def was_begin_of_line # TODO: kill me
59
- pos <= 2 or string[pos-2] == ?\n
60
- end
61
-
62
62
  if ENV['DEBUG'] then
63
63
  alias :old_getch :getch
64
64
  def getch
@@ -70,7 +70,7 @@ class RPStringScanner < StringScanner
70
70
  alias :old_scan :scan
71
71
  def scan re
72
72
  s = old_scan re
73
- p :scan => [s, caller.first] if s
73
+ d :scan => [s, caller.first] if s
74
74
  s
75
75
  end
76
76
  end
@@ -114,21 +114,12 @@ class RPStringScanner < StringScanner
114
114
  # end
115
115
  end
116
116
 
117
- class RubyParser < Racc::Parser
118
- VERSION = '2.0.5' unless constants.include? "VERSION" # SIGH
117
+ module RubyParserStuff
118
+ VERSION = '3.0.0.a1' unless constants.include? "VERSION" # SIGH
119
119
 
120
120
  attr_accessor :lexer, :in_def, :in_single, :file
121
121
  attr_reader :env, :comments
122
122
 
123
- def append_to_block head, tail # FIX: wtf is this?!? switch to block_append
124
- return head if tail.nil?
125
- return tail if head.nil?
126
-
127
- head = s(:block, head) unless head.node_type == :block
128
- head << tail
129
- head
130
- end
131
-
132
123
  def arg_add(node1, node2) # TODO: nuke
133
124
  return s(:arglist, node2) unless node1
134
125
 
@@ -150,7 +141,32 @@ class RubyParser < Racc::Parser
150
141
  node1
151
142
  end
152
143
 
153
- def args arg, optarg, rest_arg, block_arg
144
+ def block_var ary, splat, block
145
+ ary ||= s(:array)
146
+
147
+ if splat then
148
+ if splat == s(:splat) then
149
+ ary << splat
150
+ else
151
+ ary << s(:splat, splat)
152
+ end
153
+ end
154
+
155
+ if block then
156
+ block[-1] = :"&#{block[-1]}"
157
+ ary << block
158
+ end
159
+
160
+ result = if ary.length > 2 or ary.splat then
161
+ s(:masgn, ary)
162
+ else
163
+ ary.last
164
+ end
165
+
166
+ result
167
+ end
168
+
169
+ def args arg, optarg, rest_arg, block_arg, post_arg = nil
154
170
  arg ||= s(:args)
155
171
 
156
172
  result = arg
@@ -162,15 +178,53 @@ class RubyParser < Racc::Parser
162
178
  end
163
179
 
164
180
  result << rest_arg if rest_arg
181
+
165
182
  result << :"&#{block_arg.last}" if block_arg
166
183
  result << optarg if optarg # TODO? huh - processed above as well
184
+ post_arg[1..-1].each {|pa| result << pa } if post_arg
185
+
186
+ result
187
+ end
188
+
189
+ def args19 vals # TODO: migrate to args once 1.8 tests pass as well
190
+ result = s(:args)
191
+ block = nil
192
+
193
+ vals.each do |val|
194
+ case val
195
+ when Sexp then
196
+ case val.first
197
+ when :args then
198
+ val[1..-1].each do |name|
199
+ result << name
200
+ end
201
+ when :block_arg then
202
+ result << :"&#{val.last}"
203
+ when :block then
204
+ block = val
205
+ val[1..-1].each do |lasgn| # FIX clean sexp iter
206
+ raise "wtf? #{val.inspect}" unless lasgn[0] == :lasgn
207
+ result << lasgn[1]
208
+ end
209
+ else
210
+ raise "unhandled sexp: #{val.inspect}"
211
+ end
212
+ when Symbol then
213
+ result << val
214
+ when ",", nil then
215
+ # ignore
216
+ else
217
+ raise "unhandled val: #{val.inspect} in #{vals.inspect}"
218
+ end
219
+ end
220
+
221
+ result << block if block
167
222
 
168
223
  result
169
224
  end
170
225
 
171
226
  def aryset receiver, index
172
- index[0] = :arglist if index[0] == :array
173
- s(:attrasgn, receiver, :"[]=", index)
227
+ s(:attrasgn, receiver, :"[]=", *index[1..-1])
174
228
  end
175
229
 
176
230
  def assignable(lhs, value = nil)
@@ -217,9 +271,9 @@ class RubyParser < Racc::Parser
217
271
  return result
218
272
  end
219
273
 
220
- def block_append(head, tail, strip_tail_block=false)
221
- return head unless tail
222
- return tail unless head
274
+ def block_append(head, tail)
275
+ return head if tail.nil?
276
+ return tail if head.nil?
223
277
 
224
278
  case head[0]
225
279
  when :lit, :str then
@@ -229,16 +283,10 @@ class RubyParser < Racc::Parser
229
283
  line = [head.line, tail.line].compact.min
230
284
 
231
285
  head = remove_begin(head)
232
- head = s(:block, head) unless head[0] == :block
233
-
234
- if strip_tail_block and Sexp === tail and tail[0] == :block then
235
- head.push(*tail.values)
236
- else
237
- head << tail
238
- end
286
+ head = s(:block, head) unless head.node_type == :block
239
287
 
240
288
  head.line = line
241
- head
289
+ head << tail
242
290
  end
243
291
 
244
292
  def cond node
@@ -295,20 +343,11 @@ class RubyParser < Racc::Parser
295
343
  end
296
344
  end
297
345
 
298
- return s(:call, lhs, :"=~", s(:arglist, rhs)).line(lhs.line)
346
+ return new_call(lhs, :"=~", argl(rhs)).line(lhs.line)
299
347
  end
300
348
 
301
349
  def gettable(id)
302
- raise "no: #{id.inspect}" if Sexp === id
303
- id = id.to_sym if Sexp === id # HACK
304
- id = id.to_sym if String === id # HACK
305
-
306
- return s(:self) if id == :self
307
- return s(:nil) if id == :nil
308
- return s(:true) if id == :true
309
- return s(:false) if id == :false
310
- return s(:str, self.file) if id == :"__FILE__"
311
- return s(:lit, lexer.src.current_line) if id == :"__LINE__"
350
+ id = id.to_sym if String === id
312
351
 
313
352
  result = case id.to_s
314
353
  when /^@@/ then
@@ -323,25 +362,38 @@ class RubyParser < Racc::Parser
323
362
  type = env[id]
324
363
  if type then
325
364
  s(type, id)
326
- elsif env.dynamic? and :dvar == env[id] then
327
- s(:lvar, id)
328
365
  else
329
- s(:call, nil, id, s(:arglist))
366
+ new_call(nil, id)
330
367
  end
331
368
  end
332
369
 
333
- return result if result
370
+ raise "identifier #{id.inspect} is not valid" unless result
334
371
 
335
- raise "identifier #{id.inspect} is not valid"
372
+ result
336
373
  end
337
374
 
338
- def initialize
339
- super
340
- self.lexer = RubyLexer.new
375
+ ##
376
+ # Canonicalize conditionals. Eg:
377
+ #
378
+ # not x ? a : b
379
+ #
380
+ # becomes:
381
+ #
382
+ # x ? b : a
383
+
384
+ attr_accessor :canonicalize_conditions
385
+
386
+ def initialize(options = {})
387
+ super()
388
+
389
+ v = self.class.name[/1[89]/]
390
+ self.lexer = RubyLexer.new v && v.to_i
341
391
  self.lexer.parser = self
342
392
  @env = Environment.new
343
393
  @comments = []
344
394
 
395
+ @canonicalize_conditions = true
396
+
345
397
  self.reset
346
398
  end
347
399
 
@@ -456,14 +508,37 @@ class RubyParser < Racc::Parser
456
508
  return result
457
509
  end
458
510
 
511
+ def argl x
512
+ x = s(:arglist, x) if x and x[0] != :arglist
513
+ x
514
+ end
515
+
516
+ def backref_assign_error ref
517
+ # TODO: need a test for this... obviously
518
+ case ref.first
519
+ when :nth_ref then
520
+ raise SyntaxError, "Can't set variable %p" % ref.last
521
+ when :back_ref then
522
+ raise SyntaxError, "Can't set back reference %p" % ref.last
523
+ else
524
+ raise "Unknown backref type: #{ref.inspect}"
525
+ end
526
+ end
527
+
459
528
  def new_call recv, meth, args = nil
460
529
  result = s(:call, recv, meth)
461
530
  result.line = recv.line if recv
462
531
 
532
+ # TODO: need a test with f(&b) to produce block_pass
533
+ # TODO: need a test with f(&b) { } to produce warning
534
+
463
535
  args ||= s(:arglist)
464
536
  args[0] = :arglist if args.first == :array
465
537
  args = s(:arglist, args) unless args.first == :arglist
466
- result << args
538
+
539
+ # HACK quick hack to make this work quickly... easy to clean up above
540
+ result.concat args[1..-1]
541
+
467
542
  result
468
543
  end
469
544
 
@@ -476,6 +551,11 @@ class RubyParser < Racc::Parser
476
551
  body = body.delete_at 3
477
552
  end
478
553
 
554
+ result[2..-1].each do |node|
555
+ block = node.block(:delete)
556
+ node.concat block[1..-1] if block
557
+ end
558
+
479
559
  # else
480
560
  body = nil if body == s(:block)
481
561
  result << body
@@ -486,8 +566,17 @@ class RubyParser < Racc::Parser
486
566
 
487
567
  def new_class val
488
568
  line, path, superclass, body = val[1], val[2], val[3], val[5]
489
- scope = s(:scope, body).compact
490
- result = s(:class, path, superclass, scope)
569
+
570
+ result = s(:class, path, superclass)
571
+
572
+ if body then
573
+ if body.first == :block then
574
+ result.push(*body[1..-1])
575
+ else
576
+ result.push body
577
+ end
578
+ end
579
+
491
580
  result.line = line
492
581
  result.comments = self.comments.pop
493
582
  result
@@ -500,15 +589,20 @@ class RubyParser < Racc::Parser
500
589
  end
501
590
 
502
591
  def new_defn val
503
- (line, bol), name, args, body = val[2], val[1], val[3], val[4]
592
+ (_, line), name, args, body = val[0], val[1], val[3], val[4]
504
593
  body ||= s(:nil)
505
594
 
506
- body ||= s(:block)
507
- body = s(:block, body) unless body.first == :block
595
+ result = s(:defn, name.to_sym, args)
596
+
597
+ if body then
598
+ if body.first == :block then
599
+ result.push(*body[1..-1])
600
+ else
601
+ result.push body
602
+ end
603
+ end
508
604
 
509
- result = s(:defn, name.to_sym, args, s(:scope, body))
510
605
  result.line = line
511
- result.line -= 1 if bol
512
606
  result.comments = self.comments.pop
513
607
  result
514
608
  end
@@ -516,10 +610,16 @@ class RubyParser < Racc::Parser
516
610
  def new_defs val
517
611
  recv, name, args, body = val[1], val[4], val[6], val[7]
518
612
 
519
- body ||= s(:block)
520
- body = s(:block, body) unless body.first == :block
613
+ result = s(:defs, recv, name.to_sym, args)
614
+
615
+ if body then
616
+ if body.first == :block then
617
+ result.push(*body[1..-1])
618
+ else
619
+ result.push body
620
+ end
621
+ end
521
622
 
522
- result = s(:defs, recv, name.to_sym, args, s(:scope, body))
523
623
  result.line = recv.line
524
624
  result.comments = self.comments.pop
525
625
  result
@@ -534,7 +634,7 @@ class RubyParser < Racc::Parser
534
634
  def new_if c, t, f
535
635
  l = [c.line, t && t.line, f && f.line].compact.min
536
636
  c = cond c
537
- c, t, f = c.last, f, t if c[0] == :not
637
+ c, t, f = c.last, f, t if c[0] == :not and canonicalize_conditions
538
638
  s(:if, c, t, f).line(l)
539
639
  end
540
640
 
@@ -559,7 +659,7 @@ class RubyParser < Racc::Parser
559
659
  def new_module val
560
660
  line, path, body = val[1], val[2], val[4]
561
661
  body = s(:scope, body).compact
562
- result = s(:module, path, body)
662
+ result = s(:module, path, *body[1..-1])
563
663
  result.line = line
564
664
  result.comments = self.comments.pop
565
665
  result
@@ -578,8 +678,7 @@ class RubyParser < Racc::Parser
578
678
  s(:op_asgn_and, self.gettable(name), lhs)
579
679
  else
580
680
  # TODO: why [2] ?
581
- lhs[2] = new_call(self.gettable(name), asgn_op,
582
- s(:arglist, arg))
681
+ lhs[2] = new_call(self.gettable(name), asgn_op, argl(arg))
583
682
  lhs
584
683
  end
585
684
  result.line = lhs.line
@@ -631,10 +730,28 @@ class RubyParser < Racc::Parser
631
730
  node
632
731
  end
633
732
 
733
+ def new_resbody cond, body
734
+ if body && body.first == :block then
735
+ body.shift # remove block and splat it in directly
736
+ else
737
+ body = [body]
738
+ end
739
+ s(:resbody, cond, *body)
740
+ end
741
+
634
742
  def new_sclass val
635
743
  recv, in_def, in_single, body = val[3], val[4], val[6], val[7]
636
- scope = s(:scope, body).compact
637
- result = s(:sclass, recv, scope)
744
+
745
+ result = s(:sclass, recv)
746
+
747
+ if body then
748
+ if body.first == :block then
749
+ result.push(*body[1..-1])
750
+ else
751
+ result.push body
752
+ end
753
+ end
754
+
638
755
  result.line = val[2]
639
756
  self.in_def = in_def
640
757
  self.in_single = in_single
@@ -659,25 +776,34 @@ class RubyParser < Racc::Parser
659
776
  end
660
777
 
661
778
  def new_until block, expr, pre
662
- expr = (expr.first == :not ? expr.last : s(:not, expr)).line(expr.line)
663
- new_while block, expr, pre
779
+ new_until_or_while :until, block, expr, pre
664
780
  end
665
781
 
666
- def new_while block, expr, pre
782
+ def new_until_or_while type, block, expr, pre
783
+ other = type == :until ? :while : :until
667
784
  line = [block && block.line, expr.line].compact.min
668
785
  block, pre = block.last, false if block && block[0] == :begin
669
786
 
670
787
  expr = cond expr
671
- result = if expr.first == :not then
672
- s(:until, expr.last, block, pre)
788
+
789
+ result = unless expr.first == :not and canonicalize_conditions then
790
+ s(type, expr, block, pre)
673
791
  else
674
- s(:while, expr, block, pre)
792
+ s(other, expr.last, block, pre)
675
793
  end
676
794
 
677
795
  result.line = line
678
796
  result
679
797
  end
680
798
 
799
+ def new_when cond, body
800
+ s(:when, cond, body)
801
+ end
802
+
803
+ def new_while block, expr, pre
804
+ new_until_or_while :while, block, expr, pre
805
+ end
806
+
681
807
  def new_xstring str
682
808
  if str then
683
809
  case str[0]
@@ -722,12 +848,11 @@ class RubyParser < Racc::Parser
722
848
  rhs = value_expr rhs
723
849
 
724
850
  case lhs[0]
725
- when :gasgn, :iasgn, :lasgn, :dasgn, :dasgn_curr,
726
- :masgn, :cdecl, :cvdecl, :cvasgn then
851
+ when :gasgn, :iasgn, :lasgn, :masgn, :cdecl, :cvdecl, :cvasgn then
727
852
  lhs << rhs
728
853
  when :attrasgn, :call then
729
854
  args = lhs.pop unless Symbol === lhs.last
730
- lhs << arg_add(args, rhs)
855
+ lhs.concat arg_add(args, rhs)[1..-1]
731
856
  when :const then
732
857
  lhs[0] = :cdecl
733
858
  lhs << rhs
@@ -742,7 +867,7 @@ class RubyParser < Racc::Parser
742
867
  raise "bad val: #{str.inspect}" unless String === str
743
868
 
744
869
  self.file = file
745
- self.lexer.src = str
870
+ self.lexer.src = str.dup
746
871
 
747
872
  @yydebug = ENV.has_key? 'DEBUG'
748
873
 
@@ -808,192 +933,207 @@ class RubyParser < Racc::Parser
808
933
  # do nothing for now
809
934
  end
810
935
 
811
- alias :old_yyerror :yyerror
812
936
  def yyerror msg
813
937
  # for now do nothing with the msg
814
- old_yyerror
938
+ super
815
939
  end
816
- end
817
940
 
818
- class Keyword
819
- class KWtable
820
- attr_accessor :name, :state, :id0, :id1
821
- def initialize(name, id=[], state=nil)
822
- @name = name
823
- @id0, @id1 = id
824
- @state = state
941
+ class Keyword
942
+ class KWtable
943
+ attr_accessor :name, :state, :id0, :id1
944
+ def initialize(name, id=[], state=nil)
945
+ @name = name
946
+ @id0, @id1 = id
947
+ @state = state
948
+ end
825
949
  end
826
- end
827
950
 
828
- ##
829
- # :stopdoc:
830
- #
831
- # :expr_beg = ignore newline, +/- is a sign.
832
- # :expr_end = newline significant, +/- is a operator.
833
- # :expr_arg = newline significant, +/- is a operator.
834
- # :expr_cmdarg = newline significant, +/- is a operator.
835
- # :expr_endarg = newline significant, +/- is a operator.
836
- # :expr_mid = newline significant, +/- is a operator.
837
- # :expr_fname = ignore newline, no reserved words.
838
- # :expr_dot = right after . or ::, no reserved words.
839
- # :expr_class = immediate after class, no here document.
840
-
841
- wordlist = [
842
- ["end", [:kEND, :kEND ], :expr_end ],
843
- ["else", [:kELSE, :kELSE ], :expr_beg ],
844
- ["case", [:kCASE, :kCASE ], :expr_beg ],
845
- ["ensure", [:kENSURE, :kENSURE ], :expr_beg ],
846
- ["module", [:kMODULE, :kMODULE ], :expr_beg ],
847
- ["elsif", [:kELSIF, :kELSIF ], :expr_beg ],
848
- ["def", [:kDEF, :kDEF ], :expr_fname ],
849
- ["rescue", [:kRESCUE, :kRESCUE_MOD ], :expr_mid ],
850
- ["not", [:kNOT, :kNOT ], :expr_beg ],
851
- ["then", [:kTHEN, :kTHEN ], :expr_beg ],
852
- ["yield", [:kYIELD, :kYIELD ], :expr_arg ],
853
- ["for", [:kFOR, :kFOR ], :expr_beg ],
854
- ["self", [:kSELF, :kSELF ], :expr_end ],
855
- ["false", [:kFALSE, :kFALSE ], :expr_end ],
856
- ["retry", [:kRETRY, :kRETRY ], :expr_end ],
857
- ["return", [:kRETURN, :kRETURN ], :expr_mid ],
858
- ["true", [:kTRUE, :kTRUE ], :expr_end ],
859
- ["if", [:kIF, :kIF_MOD ], :expr_beg ],
860
- ["defined?", [:kDEFINED, :kDEFINED ], :expr_arg ],
861
- ["super", [:kSUPER, :kSUPER ], :expr_arg ],
862
- ["undef", [:kUNDEF, :kUNDEF ], :expr_fname ],
863
- ["break", [:kBREAK, :kBREAK ], :expr_mid ],
864
- ["in", [:kIN, :kIN ], :expr_beg ],
865
- ["do", [:kDO, :kDO ], :expr_beg ],
866
- ["nil", [:kNIL, :kNIL ], :expr_end ],
867
- ["until", [:kUNTIL, :kUNTIL_MOD ], :expr_beg ],
868
- ["unless", [:kUNLESS, :kUNLESS_MOD ], :expr_beg ],
869
- ["or", [:kOR, :kOR ], :expr_beg ],
870
- ["next", [:kNEXT, :kNEXT ], :expr_mid ],
871
- ["when", [:kWHEN, :kWHEN ], :expr_beg ],
872
- ["redo", [:kREDO, :kREDO ], :expr_end ],
873
- ["and", [:kAND, :kAND ], :expr_beg ],
874
- ["begin", [:kBEGIN, :kBEGIN ], :expr_beg ],
875
- ["__LINE__", [:k__LINE__, :k__LINE__ ], :expr_end ],
876
- ["class", [:kCLASS, :kCLASS ], :expr_class ],
877
- ["__FILE__", [:k__FILE__, :k__FILE__ ], :expr_end ],
878
- ["END", [:klEND, :klEND ], :expr_end ],
879
- ["BEGIN", [:klBEGIN, :klBEGIN ], :expr_end ],
880
- ["while", [:kWHILE, :kWHILE_MOD ], :expr_beg ],
881
- ["alias", [:kALIAS, :kALIAS ], :expr_fname ],
882
- ].map { |args| KWtable.new(*args) }
883
-
884
- # :startdoc:
885
-
886
- WORDLIST = Hash[*wordlist.map { |o| [o.name, o] }.flatten] unless
887
- defined? WORDLIST
888
-
889
- def self.keyword str
890
- WORDLIST[str]
951
+ ##
952
+ # :stopdoc:
953
+ #
954
+ # :expr_beg = ignore newline, +/- is a sign.
955
+ # :expr_end = newline significant, +/- is a operator.
956
+ # :expr_arg = newline significant, +/- is a operator.
957
+ # :expr_cmdarg = newline significant, +/- is a operator.
958
+ # :expr_endarg = newline significant, +/- is a operator.
959
+ # :expr_mid = newline significant, +/- is a operator.
960
+ # :expr_fname = ignore newline, no reserved words.
961
+ # :expr_dot = right after . or ::, no reserved words.
962
+ # :expr_class = immediate after class, no here document.
963
+
964
+ wordlist = [
965
+ ["end", [:kEND, :kEND ], :expr_end ],
966
+ ["else", [:kELSE, :kELSE ], :expr_beg ],
967
+ ["case", [:kCASE, :kCASE ], :expr_beg ],
968
+ ["ensure", [:kENSURE, :kENSURE ], :expr_beg ],
969
+ ["module", [:kMODULE, :kMODULE ], :expr_beg ],
970
+ ["elsif", [:kELSIF, :kELSIF ], :expr_beg ],
971
+ ["def", [:kDEF, :kDEF ], :expr_fname ],
972
+ ["rescue", [:kRESCUE, :kRESCUE_MOD ], :expr_mid ],
973
+ ["not", [:kNOT, :kNOT ], :expr_beg ],
974
+ ["then", [:kTHEN, :kTHEN ], :expr_beg ],
975
+ ["yield", [:kYIELD, :kYIELD ], :expr_arg ],
976
+ ["for", [:kFOR, :kFOR ], :expr_beg ],
977
+ ["self", [:kSELF, :kSELF ], :expr_end ],
978
+ ["false", [:kFALSE, :kFALSE ], :expr_end ],
979
+ ["retry", [:kRETRY, :kRETRY ], :expr_end ],
980
+ ["return", [:kRETURN, :kRETURN ], :expr_mid ],
981
+ ["true", [:kTRUE, :kTRUE ], :expr_end ],
982
+ ["if", [:kIF, :kIF_MOD ], :expr_beg ],
983
+ ["defined?", [:kDEFINED, :kDEFINED ], :expr_arg ],
984
+ ["super", [:kSUPER, :kSUPER ], :expr_arg ],
985
+ ["undef", [:kUNDEF, :kUNDEF ], :expr_fname ],
986
+ ["break", [:kBREAK, :kBREAK ], :expr_mid ],
987
+ ["in", [:kIN, :kIN ], :expr_beg ],
988
+ ["do", [:kDO, :kDO ], :expr_beg ],
989
+ ["nil", [:kNIL, :kNIL ], :expr_end ],
990
+ ["until", [:kUNTIL, :kUNTIL_MOD ], :expr_beg ],
991
+ ["unless", [:kUNLESS, :kUNLESS_MOD ], :expr_beg ],
992
+ ["or", [:kOR, :kOR ], :expr_beg ],
993
+ ["next", [:kNEXT, :kNEXT ], :expr_mid ],
994
+ ["when", [:kWHEN, :kWHEN ], :expr_beg ],
995
+ ["redo", [:kREDO, :kREDO ], :expr_end ],
996
+ ["and", [:kAND, :kAND ], :expr_beg ],
997
+ ["begin", [:kBEGIN, :kBEGIN ], :expr_beg ],
998
+ ["__LINE__", [:k__LINE__, :k__LINE__ ], :expr_end ],
999
+ ["class", [:kCLASS, :kCLASS ], :expr_class ],
1000
+ ["__FILE__", [:k__FILE__, :k__FILE__ ], :expr_end ],
1001
+ ["END", [:klEND, :klEND ], :expr_end ],
1002
+ ["BEGIN", [:klBEGIN, :klBEGIN ], :expr_end ],
1003
+ ["while", [:kWHILE, :kWHILE_MOD ], :expr_beg ],
1004
+ ["alias", [:kALIAS, :kALIAS ], :expr_fname ],
1005
+ ].map { |args| KWtable.new(*args) }
1006
+
1007
+ # :startdoc:
1008
+
1009
+ WORDLIST = Hash[*wordlist.map { |o| [o.name, o] }.flatten] unless
1010
+ defined? WORDLIST
1011
+
1012
+ def self.keyword str
1013
+ WORDLIST[str]
1014
+ end
891
1015
  end
892
- end
893
1016
 
894
- class Environment
895
- attr_reader :env, :dyn
1017
+ class Environment
1018
+ attr_reader :env, :dyn
896
1019
 
897
- def [] k
898
- self.all[k]
899
- end
1020
+ def [] k
1021
+ self.all[k]
1022
+ end
900
1023
 
901
- def []= k, v
902
- raise "no" if v == true
903
- self.current[k] = v
904
- end
1024
+ def []= k, v
1025
+ raise "no" if v == true
1026
+ self.current[k] = v
1027
+ end
905
1028
 
906
- def all
907
- idx = @dyn.index(false) || 0
908
- @env[0..idx].reverse.inject { |env, scope| env.merge scope }
909
- end
1029
+ def all
1030
+ idx = @dyn.index(false) || 0
1031
+ @env[0..idx].reverse.inject { |env, scope| env.merge scope }
1032
+ end
910
1033
 
911
- def current
912
- @env.first
913
- end
1034
+ def current
1035
+ @env.first
1036
+ end
914
1037
 
915
- def dynamic
916
- idx = @dyn.index false
917
- @env[0...idx].reverse.inject { |env, scope| env.merge scope } || {}
918
- end
1038
+ def dynamic
1039
+ idx = @dyn.index false
1040
+ @env[0...idx].reverse.inject { |env, scope| env.merge scope } || {}
1041
+ end
919
1042
 
920
- def dynamic?
921
- @dyn[0] != false
922
- end
1043
+ def dynamic?
1044
+ @dyn[0] != false
1045
+ end
923
1046
 
924
- def extend dyn = false
925
- @dyn.unshift dyn
926
- @env.unshift({})
927
- @use.unshift({})
928
- end
1047
+ def extend dyn = false
1048
+ @dyn.unshift dyn
1049
+ @env.unshift({})
1050
+ @use.unshift({})
1051
+ end
929
1052
 
930
- def initialize dyn = false
931
- @dyn = []
932
- @env = []
933
- @use = []
934
- self.reset
935
- end
1053
+ def initialize dyn = false
1054
+ @dyn = []
1055
+ @env = []
1056
+ @use = []
1057
+ self.reset
1058
+ end
936
1059
 
937
- def reset
938
- @dyn.clear
939
- @env.clear
940
- @use.clear
941
- self.extend
942
- end
1060
+ def reset
1061
+ @dyn.clear
1062
+ @env.clear
1063
+ @use.clear
1064
+ self.extend
1065
+ end
943
1066
 
944
- def unextend
945
- @dyn.shift
946
- @env.shift
947
- @use.shift
948
- raise "You went too far unextending env" if @env.empty?
949
- end
1067
+ def unextend
1068
+ @dyn.shift
1069
+ @env.shift
1070
+ @use.shift
1071
+ raise "You went too far unextending env" if @env.empty?
1072
+ end
950
1073
 
951
- def use id
952
- @env.each_with_index do |env, i|
953
- if env[id] then
954
- @use[i][id] = true
1074
+ def use id
1075
+ @env.each_with_index do |env, i|
1076
+ if env[id] then
1077
+ @use[i][id] = true
1078
+ end
955
1079
  end
956
1080
  end
957
- end
958
1081
 
959
- def used? id
960
- idx = @dyn.index false # REFACTOR
961
- u = @use[0...idx].reverse.inject { |env, scope| env.merge scope } || {}
962
- u[id]
1082
+ def used? id
1083
+ idx = @dyn.index false # REFACTOR
1084
+ u = @use[0...idx].reverse.inject { |env, scope| env.merge scope } || {}
1085
+ u[id]
1086
+ end
963
1087
  end
964
- end
965
1088
 
966
- class StackState
967
- attr_reader :stack
1089
+ class StackState
1090
+ attr_reader :stack
968
1091
 
969
- def initialize(name)
970
- @name = name
971
- @stack = [false]
972
- end
1092
+ def initialize(name)
1093
+ @name = name
1094
+ @stack = [false]
1095
+ end
973
1096
 
974
- def inspect
975
- "StackState(#{@name}, #{@stack.inspect})"
976
- end
1097
+ def inspect
1098
+ "StackState(#{@name}, #{@stack.inspect})"
1099
+ end
977
1100
 
978
- def is_in_state
979
- @stack.last
980
- end
1101
+ def is_in_state
1102
+ @stack.last
1103
+ end
981
1104
 
982
- def lexpop
983
- raise if @stack.size == 0
984
- a = @stack.pop
985
- b = @stack.pop
986
- @stack.push(a || b)
987
- end
1105
+ def lexpop
1106
+ raise if @stack.size == 0
1107
+ a = @stack.pop
1108
+ b = @stack.pop
1109
+ @stack.push(a || b)
1110
+ end
1111
+
1112
+ def pop
1113
+ r = @stack.pop
1114
+ @stack.push false if @stack.size == 0
1115
+ r
1116
+ end
988
1117
 
989
- def pop
990
- r = @stack.pop
991
- @stack.push false if @stack.size == 0
992
- r
1118
+ def push val
1119
+ @stack.push val
1120
+ end
993
1121
  end
1122
+ end
994
1123
 
995
- def push val
996
- @stack.push val
1124
+ class Ruby19Parser < Racc::Parser
1125
+ include RubyParserStuff
1126
+ end
1127
+
1128
+ class Ruby18Parser < Racc::Parser
1129
+ include RubyParserStuff
1130
+ end
1131
+
1132
+ class RubyParser < Ruby18Parser
1133
+ def initialize
1134
+ super
1135
+ warn "WA\RNING: Deprecated: RubyParser. Use Ruby18Parser or Ruby19Parser"
1136
+ warn " from #{caller.first}"
997
1137
  end
998
1138
  end
999
1139
 
@@ -1022,6 +1162,14 @@ class Sexp
1022
1162
  self.value.to_sym
1023
1163
  end
1024
1164
 
1165
+ def add x
1166
+ raise "no" # TODO: need a test to trigger this
1167
+ end
1168
+
1169
+ def add_all x
1170
+ raise "no" # TODO: need a test to trigger this
1171
+ end
1172
+
1025
1173
  alias :node_type :sexp_type
1026
1174
  alias :values :sexp_body # TODO: retire
1027
1175
  end