opal 0.3.26 → 0.3.27

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/.gitignore +1 -6
  2. data/.travis.yml +1 -4
  3. data/Gemfile +1 -1
  4. data/README.md +3 -8
  5. data/Rakefile +26 -3
  6. data/core/array.rb +33 -91
  7. data/core/boolean.rb +1 -4
  8. data/core/class.rb +25 -71
  9. data/core/error.rb +5 -3
  10. data/core/hash.rb +3 -2
  11. data/core/kernel.rb +40 -1
  12. data/core/load_order +1 -1
  13. data/core/nil_class.rb +1 -3
  14. data/core/runtime.js +4 -44
  15. data/core/template.rb +20 -0
  16. data/core/{opal-spec → test_runner}/runner.js +0 -6
  17. data/lib/opal.rb +1 -12
  18. data/lib/opal/builder.rb +3 -10
  19. data/lib/opal/lexer.rb +1095 -1110
  20. data/lib/opal/parser.rb +229 -26
  21. data/lib/opal/rake_task.rb +3 -3
  22. data/lib/opal/version.rb +1 -1
  23. data/opal.gemspec +2 -2
  24. data/spec/core/array/assoc_spec.rb +2 -3
  25. data/spec/core/array/comparison_spec.rb +16 -0
  26. data/spec/core/array/constructor_spec.rb +0 -9
  27. data/spec/core/array/drop_spec.rb +21 -0
  28. data/spec/core/array/dup_spec.rb +15 -0
  29. data/spec/core/array/{eql_spec.rb → equal_value_spec.rb} +0 -0
  30. data/spec/core/array/index_spec.rb +26 -0
  31. data/spec/core/array/inspect_spec.rb +13 -0
  32. data/spec/core/array/intersection_spec.rb +22 -0
  33. data/spec/core/array/join_spec.rb +9 -0
  34. data/spec/core/array/keep_if_spec.rb +7 -0
  35. data/spec/core/array/minus_spec.rb +19 -9
  36. data/spec/core/array/multiply_spec.rb +13 -0
  37. data/spec/core/array/new_spec.rb +40 -0
  38. data/spec/core/array/rindex_spec.rb +21 -0
  39. data/spec/core/array/select_spec.rb +13 -0
  40. data/spec/core/array/shift_spec.rb +51 -0
  41. data/spec/core/array/slice_spec.rb +37 -0
  42. data/spec/core/array/take_spec.rb +21 -0
  43. data/spec/core/array/take_while_spec.rb +13 -0
  44. data/spec/core/array/to_a_spec.rb +7 -0
  45. data/spec/core/array/unshift_spec.rb +29 -0
  46. data/spec/core/hash/constructor_spec.rb +13 -0
  47. data/spec/core/hash/default_proc_spec.rb +20 -0
  48. data/spec/core/hash/default_spec.rb +8 -0
  49. data/spec/core/hash/delete_spec.rb +11 -0
  50. data/spec/core/hash/dup_spec.rb +10 -0
  51. data/spec/core/hash/reject_spec.rb +18 -0
  52. data/spec/core/hash/to_a_spec.rb +13 -0
  53. data/spec/core/kernel/Array_spec.rb +10 -0
  54. data/spec/core/kernel/class_spec.rb +6 -0
  55. data/spec/core/kernel/equal_spec.rb +12 -0
  56. data/spec/core/kernel/extend_spec.rb +21 -0
  57. data/spec/core/kernel/instance_eval_spec.rb +28 -0
  58. data/spec/core/kernel/instance_variable_get_spec.rb +14 -0
  59. data/spec/core/kernel/instance_variable_set_spec.rb +10 -0
  60. data/spec/core/kernel/match_spec.rb +5 -0
  61. data/spec/core/module/alias_method_spec.rb +10 -0
  62. data/spec/core/module/ancestors_spec.rb +11 -0
  63. data/spec/core/module/append_features_spec.rb +14 -0
  64. data/spec/core/proc/call_spec.rb +21 -0
  65. data/spec/core/proc/proc_tricks_spec.rb +1 -1
  66. data/spec/language/alias_spec.rb +1 -1
  67. data/spec/opal/class/instance_methods_spec.rb +13 -0
  68. data/spec/opal/kernel/attribute_spec.rb +57 -0
  69. data/spec/spec_helper.rb +1 -1
  70. data/spec/test_case.html +13 -0
  71. metadata +88 -12
  72. data/core/erb.rb +0 -32
  73. data/lib/opal/erb_parser.rb +0 -20
  74. data/spec/opal/erb/erb_spec.rb +0 -23
data/core/error.rb CHANGED
@@ -3,7 +3,9 @@ class Exception < `Error`
3
3
 
4
4
  def self.new(message = '')
5
5
  %x{
6
- return new Error(message);
6
+ var err = new Error(message);
7
+ err._klass = #{self};
8
+ return err;
7
9
  }
8
10
  end
9
11
 
@@ -12,10 +14,10 @@ class Exception < `Error`
12
14
  var backtrace = #{self}.stack;
13
15
 
14
16
  if (typeof(backtrace) === 'string') {
15
- return backtrace.split("\\n");
17
+ return backtrace.split("\\n").slice(0, 15);
16
18
  }
17
19
  else if (backtrace) {
18
- return backtrace;
20
+ return backtrace.slice(0, 15);
19
21
  }
20
22
 
21
23
  return [];
data/core/hash.rb CHANGED
@@ -166,12 +166,13 @@ class Hash
166
166
  var map = #{self}.map, result;
167
167
 
168
168
  if (result = map[key]) {
169
- result = bucket[1];
169
+ result = result[1];
170
170
 
171
171
  delete map[key];
172
+ return result;
172
173
  }
173
174
 
174
- return result;
175
+ return nil;
175
176
  }
176
177
  end
177
178
 
data/core/kernel.rb CHANGED
@@ -32,6 +32,32 @@ module Kernel
32
32
  }
33
33
  end
34
34
 
35
+ def attribute_get(name)
36
+ %x{
37
+ var meth = '$' + name;
38
+ if (#{self}[meth]) {
39
+ return #{self}[meth]();
40
+ }
41
+
42
+ meth += '?';
43
+ if (#{self}[meth]) {
44
+ return #{self}[meth]()
45
+ }
46
+
47
+ return nil;
48
+ }
49
+ end
50
+
51
+ def attribute_set(name, value)
52
+ %x{
53
+ if (#{self}['$' + name + '=']) {
54
+ return #{self}['$' + name + '='](value);
55
+ }
56
+
57
+ return nil;
58
+ }
59
+ end
60
+
35
61
  def class
36
62
  `return #{self}._klass`
37
63
  end
@@ -83,7 +109,7 @@ module Kernel
83
109
  no_block_given();
84
110
  }
85
111
 
86
- return block.call(#{self});
112
+ return block.call(#{self}, #{self});
87
113
  }
88
114
  end
89
115
 
@@ -213,6 +239,19 @@ module Kernel
213
239
 
214
240
  def singleton_class
215
241
  %x{
242
+ if (#{self}._isClass) {
243
+ if (#{self}._singleton) {
244
+ return #{self}._singleton;
245
+ }
246
+
247
+ var meta = new __opal.Class;
248
+ meta._klass = __opal.Class;
249
+ #{self}._singleton = meta;
250
+ meta.prototype = #{self};
251
+
252
+ return meta;
253
+ }
254
+
216
255
  if (!#{self}._isObject) {
217
256
  return #{self}._klass;
218
257
  }
data/core/load_order CHANGED
@@ -15,4 +15,4 @@ proc
15
15
  range
16
16
  time
17
17
  json
18
- erb
18
+ template
data/core/nil_class.rb CHANGED
@@ -48,6 +48,4 @@ class NilClass
48
48
  def to_s
49
49
  ''
50
50
  end
51
- end
52
-
53
- NIL = nil
51
+ end
data/core/runtime.js CHANGED
@@ -7,9 +7,6 @@ function Object(){}
7
7
  // Class' class
8
8
  function Class(){}
9
9
 
10
- // Modules are just classes that cannot be instantiated
11
- var Module = Class;
12
-
13
10
  // the class of nil
14
11
  function NilClass(){}
15
12
 
@@ -38,38 +35,6 @@ Opal.cvars = {};
38
35
  // Globals table
39
36
  Opal.gvars = {};
40
37
 
41
- // Runtime method used to either define a new class, or re-open an old
42
- // class. The base may be an object (rather than a class), which is
43
- // always the case when defining classes in the top level as the top
44
- // level is just the 'main' Object instance.
45
- //
46
- // The given ruby code:
47
- //
48
- // class Foo
49
- // 42
50
- // end
51
- //
52
- // class Bar < Foo
53
- // 3.142
54
- // end
55
- //
56
- // Would be compiled to something like:
57
- //
58
- // var __klass = Opal.klass;
59
- //
60
- // __klass(this, null, 'Foo', function() {
61
- // return 42;
62
- // });
63
- //
64
- // __klass(this, __scope.Foo, 'Bar', function() {
65
- // return 3.142;
66
- // });
67
- //
68
- // @param [RubyObject] base the scope in which to define the class
69
- // @param [RubyClass] superklass the superklass, may be null
70
- // @param [String] id the name for the class
71
- // @param [Function] body the class body
72
- // @return returns last value from running body
73
38
  Opal.klass = function(base, superklass, id, constructor) {
74
39
  var klass;
75
40
  if (base._isObject) {
@@ -121,7 +86,7 @@ Opal.module = function(base, id, constructor) {
121
86
  klass = base._scope[id];
122
87
  }
123
88
  else {
124
- klass = boot_class(Module, constructor);
89
+ klass = boot_class(Class, constructor);
125
90
  klass._name = (base === Object ? id : base._name + '::' + id);
126
91
 
127
92
  klass._isModule = true;
@@ -227,7 +192,7 @@ var bridge_class = function(constructor) {
227
192
  constructor['$==='] = module_eqq;
228
193
  constructor.$to_s = module_to_s;
229
194
 
230
- var smethods = constructor._smethods = Module._methods.slice();
195
+ var smethods = constructor._smethods = Class._methods.slice();
231
196
  for (var i = 0, length = smethods.length; i < length; i++) {
232
197
  var m = smethods[i];
233
198
  constructor[m] = Object[m];
@@ -256,14 +221,9 @@ boot_defclass('Object', Object);
256
221
  boot_defclass('Class', Class, Object);
257
222
 
258
223
  Class.prototype = Function.prototype;
259
-
260
224
  Object._klass = Class._klass = Class;
261
225
 
262
- Module._donate = function(defined) {
263
- // ...
264
- };
265
-
266
- // Implementation of Module#===
226
+ // Implementation of Class#===
267
227
  function module_eqq(object) {
268
228
  if (object == null) {
269
229
  return false;
@@ -282,7 +242,7 @@ function module_eqq(object) {
282
242
  return false;
283
243
  }
284
244
 
285
- // Implementation of Module#to_s
245
+ // Implementation of Class#to_s
286
246
  function module_to_s() {
287
247
  return this._name;
288
248
  }
data/core/template.rb ADDED
@@ -0,0 +1,20 @@
1
+ class Template
2
+ @_cache = {}
3
+ def self.[](name)
4
+ @_cache[name]
5
+ end
6
+
7
+ def self.[]=(name, instance)
8
+ @_cache[name] = instance
9
+ end
10
+
11
+ def initialize(name, &body)
12
+ @body = body
13
+ @name = name
14
+ Template[name] = self
15
+ end
16
+
17
+ def render(ctx=self)
18
+ ctx.instance_eval(&@body)
19
+ end
20
+ end
@@ -1,10 +1,4 @@
1
1
  var args = phantom.args;
2
-
3
- if (args.length !== 1) {
4
- console.log("Usage: " + phantom.scriptName + " <URL>");
5
- phantom.exit(1);
6
- }
7
-
8
2
  var page = require('webpage').create();
9
3
 
10
4
  page.onConsoleMessage = function(msg) {
data/lib/opal.rb CHANGED
@@ -1,15 +1,4 @@
1
- unless Symbol.instance_methods.include?(:[])
2
- unless String == Symbol
3
- class Symbol
4
- def []key
5
- to_s[key]
6
- end
7
- end
8
- end
9
- end
10
-
11
1
  require 'opal/parser'
12
- require 'opal/erb_parser'
13
2
  require 'opal/builder'
14
3
  require 'opal/version'
15
4
 
@@ -26,7 +15,7 @@ module Opal
26
15
  # @param [String] file the filename to use when parsing
27
16
  # @return [String] the resulting javascript code
28
17
  def self.parse(str, file='(file)')
29
- "(#{ Parser.new.parse str, file })();"
18
+ Parser.new.parse str, file
30
19
  end
31
20
 
32
21
  # Returns opal runtime js code (string)
data/lib/opal/builder.rb CHANGED
@@ -30,8 +30,8 @@ module Opal
30
30
  sources.each do |s|
31
31
  s = File.expand_path(File.join @dir, s)
32
32
  if File.directory? s
33
- files.push *Dir[File.join(s, '**/*.{rb,js,erb}')]
34
- elsif %w(.rb .js .erb).include? File.extname(s)
33
+ files.push *Dir[File.join(s, '**/*.rb')]
34
+ elsif File.extname(s) == '.rb'
35
35
  files << s
36
36
  end
37
37
  end
@@ -70,16 +70,9 @@ module Opal
70
70
  if File.extname(file) == '.rb'
71
71
  code = @parser.parse File.read(file), lib_name
72
72
  @requires[lib_name] = @parser.requires
73
- elsif File.extname(file) == '.erb'
74
- template_name = lib_name_for(file).chomp(File.extname(file))
75
- code = Opal::ERBParser.new.parse File.read(file), template_name
76
- @requires[lib_name] = []
77
- else # javascript
78
- code = "function() {\n #{ File.read file }\n}"
79
- @requires[lib_name] = []
80
73
  end
81
74
 
82
- @files[lib_name] = "// #{ parser_name }\n(#{ code })();"
75
+ @files[lib_name] = "// #{ parser_name }\n#{ code }"
83
76
  end
84
77
 
85
78
  def parser_name_for(file)
data/lib/opal/lexer.rb CHANGED
@@ -14,1376 +14,1361 @@ module Opal
14
14
 
15
15
  class Grammar < Racc::Parser
16
16
 
17
- attr_reader :line
17
+ attr_reader :line
18
18
 
19
- def initialize
20
- @lex_state = :expr_beg
21
- @cond = 0
22
- @cmdarg = 0
23
- @line = 1
24
- @scopes = []
19
+ def initialize
20
+ @lex_state = :expr_beg
21
+ @cond = 0
22
+ @cmdarg = 0
23
+ @line = 1
24
+ @scopes = []
25
25
 
26
- @string_parse_stack = []
27
- end
28
-
29
- def s(*parts)
30
- sexp = Sexp.new(parts)
31
- sexp.line = @line
32
- sexp
33
- end
34
-
35
- def parse(source, file = '(string)')
36
- @file = file
37
- @scanner = StringScanner.new source
38
- push_scope
39
- result = do_parse
40
- pop_scope
41
-
42
- result
43
- end
26
+ @string_parse_stack = []
27
+ end
44
28
 
45
- def on_error(t, val, vstack)
46
- raise OpalParseError, "parse error on value #{val.inspect} (line #{@line})"
47
- end
29
+ def s(*parts)
30
+ sexp = Sexp.new(parts)
31
+ sexp.line = @line
32
+ sexp
33
+ end
48
34
 
49
- class LexerScope
50
- attr_reader :locals
51
- attr_accessor :parent
35
+ def parse(source, file = '(string)')
36
+ @file = file
37
+ @scanner = StringScanner.new source
38
+ push_scope
39
+ result = do_parse
40
+ pop_scope
52
41
 
53
- def initialize type
54
- @block = type == :block
55
- @locals = []
56
- @parent = nil
42
+ result
57
43
  end
58
44
 
59
- def add_local local
60
- @locals << local
45
+ def on_error(t, val, vstack)
46
+ raise OpalParseError, "parse error on value #{val.inspect} (line #{@line})"
61
47
  end
62
48
 
63
- def has_local? local
64
- return true if @locals.include? local
65
- return @parent.has_local?(local) if @parent and @block
66
- false
67
- end
68
- end
49
+ class LexerScope
50
+ attr_reader :locals
51
+ attr_accessor :parent
69
52
 
70
- def push_scope type = nil
71
- top = @scopes.last
72
- scope = LexerScope.new type
73
- scope.parent = top
74
- @scopes << scope
75
- @scope = scope
76
- end
53
+ def initialize(type)
54
+ @block = type == :block
55
+ @locals = []
56
+ @parent = nil
57
+ end
77
58
 
78
- def pop_scope
79
- @scopes.pop
80
- @scope = @scopes.last
81
- end
59
+ def add_local(local)
60
+ @locals << local
61
+ end
82
62
 
83
- def new_block stmt = nil
84
- s = s(:block)
85
- s << stmt if stmt
86
- s
87
- end
63
+ def has_local?(local)
64
+ return true if @locals.include? local
65
+ return @parent.has_local?(local) if @parent and @block
66
+ false
67
+ end
68
+ end
88
69
 
89
- def new_compstmt block
90
- if block.size == 1
91
- nil
92
- elsif block.size == 2
93
- block[1]
94
- else
95
- block.line = block[1].line
96
- block
70
+ def push_scope(type = nil)
71
+ top = @scopes.last
72
+ scope = LexerScope.new type
73
+ scope.parent = top
74
+ @scopes << scope
75
+ @scope = scope
97
76
  end
98
- end
99
77
 
100
- def new_body(compstmt, res, els, ens)
101
- s = compstmt || s(:block)
78
+ def pop_scope
79
+ @scopes.pop
80
+ @scope = @scopes.last
81
+ end
102
82
 
103
- if compstmt
104
- # s = s(:block, compstmt) unless compstmt[0] == :block
105
- s.line = compstmt.line
83
+ def new_block(stmt = nil)
84
+ s = s(:block)
85
+ s << stmt if stmt
86
+ s
106
87
  end
107
88
 
108
- if res
109
- s = s(:rescue, s)
110
- res.each { |r| s << r }
111
- s << els if els
89
+ def new_compstmt(block)
90
+ if block.size == 1
91
+ nil
92
+ elsif block.size == 2
93
+ block[1]
94
+ else
95
+ block.line = block[1].line
96
+ block
97
+ end
112
98
  end
113
99
 
114
- if ens
115
- s = s(:ensure, s, ens)
100
+ def new_body(compstmt, res, els, ens)
101
+ s = compstmt || s(:block)
102
+ s.line = compstmt.line if compstmt
103
+
104
+ if res
105
+ s = s(:rescue, s)
106
+ res.each { |r| s << r }
107
+ s << els if els
108
+ end
109
+
110
+ ens ? s(:ensure, s, ens) : s
116
111
  end
117
112
 
118
- s
119
- end
113
+ def new_defn(line, name, args, body)
114
+ body = s(:block, body) if body[0] != :block
115
+ scope = s(:scope, body)
116
+ body << s(:nil) if body.size == 1
117
+ scope.line = body.line
118
+ args.line = line
119
+ s = s(:defn, name.to_sym, args, scope)
120
+ s.line = line
121
+ s.end_line = @line
122
+ s
123
+ end
120
124
 
121
- def new_defn line, name, args, body
122
- body = s(:block, body) if body[0] != :block
123
- scope = s(:scope, body)
124
- body << s(:nil) if body.size == 1
125
- scope.line = body.line
126
- args.line = line
127
- s = s(:defn, name.to_sym, args, scope)
128
- s.line = line
129
- s.end_line = @line
130
- s
131
- end
125
+ def new_defs(line, recv, name, args, body)
126
+ scope = s(:scope, body)
127
+ scope.line = body.line
128
+ s = s(:defs, recv, name.to_sym, args, scope)
129
+ s.line = line
130
+ s.end_line = @line
131
+ s
132
+ end
132
133
 
133
- def new_defs line, recv, name, args, body
134
- scope = s(:scope, body)
135
- scope.line = body.line
136
- s = s(:defs, recv, name.to_sym, args, scope)
137
- s.line = line
138
- s.end_line = @line
139
- s
140
- end
134
+ def new_class(path, sup, body)
135
+ scope = s(:scope)
136
+ scope << body unless body.size == 1
137
+ scope.line = body.line
138
+ s = s(:class, path, sup, scope)
139
+ s
140
+ end
141
141
 
142
- def new_class path, sup, body
143
- scope = s(:scope)
144
- scope << body unless body.size == 1
145
- scope.line = body.line
146
- s = s(:class, path, sup, scope)
147
- s
148
- end
142
+ def new_sclass(expr, body)
143
+ scope = s(:scope)
144
+ scope << body #unless body.size == 1
145
+ scope.line = body.line
146
+ s = s(:sclass, expr, scope)
147
+ s
148
+ end
149
149
 
150
- def new_sclass expr, body
151
- scope = s(:scope)
152
- scope << body #unless body.size == 1
153
- scope.line = body.line
154
- s = s(:sclass, expr, scope)
155
- s
156
- end
150
+ def new_module(path, body)
151
+ scope = s(:scope)
152
+ scope << body unless body.size == 1
153
+ scope.line = body.line
154
+ s = s(:module, path, scope)
155
+ s
156
+ end
157
157
 
158
- def new_module path, body
159
- scope = s(:scope)
160
- scope << body unless body.size == 1
161
- scope.line = body.line
162
- s = s(:module, path, scope)
163
- s
164
- end
158
+ def new_iter(call, args, body)
159
+ s = s(:iter, call, args)
160
+ s << body if body
161
+ s.end_line = @line
162
+ s
163
+ end
165
164
 
166
- def new_iter call, args, body
167
- s = s(:iter, call, args)
168
- s << body if body
169
- s.end_line = @line
170
- s
171
- end
165
+ def new_if(expr, stmt, tail)
166
+ s = s(:if, expr, stmt, tail)
167
+ s.line = expr.line
168
+ s.end_line = @line
169
+ s
170
+ end
172
171
 
173
- def new_if expr, stmt, tail
174
- s = s(:if, expr, stmt, tail)
175
- s.line = expr.line
176
- s.end_line = @line
177
- s
178
- end
172
+ def new_args(norm, opt, rest, block)
173
+ res = s(:args)
179
174
 
180
- def new_args norm, opt, rest, block
181
- res = s(:args)
175
+ if norm
176
+ norm.each do |arg|
177
+ @scope.add_local arg
178
+ res << arg
179
+ end
180
+ end
182
181
 
183
- if norm
184
- norm.each do |arg|
185
- @scope.add_local arg
186
- res << arg
182
+ if opt
183
+ opt[1..-1].each do |_opt|
184
+ res << _opt[1]
185
+ end
187
186
  end
188
- end
189
187
 
190
- if opt
191
- opt[1..-1].each do |_opt|
192
- res << _opt[1]
188
+ if rest
189
+ res << rest
190
+ @scope.add_local begin
191
+ rest.to_s[1..-1].to_sym
192
+ rescue ArgumentError => e
193
+ # Rescue from empty symbol error on Ruby 1.8
194
+ raise unless e.message =~ /empty/
195
+ ''
196
+ end
193
197
  end
194
- end
195
198
 
196
- if rest
197
- res << rest
198
- @scope.add_local begin
199
- rest.to_s[1..-1].to_sym
200
- rescue ArgumentError => e
201
- # Rescue from empty symbol error on Ruby 1.8
202
- raise unless e.message =~ /empty/
203
- ''
199
+ if block
200
+ res << block
201
+ @scope.add_local block.to_s[1..-1].to_sym
204
202
  end
205
- end
206
203
 
207
- if block
208
- res << block
209
- @scope.add_local block.to_s[1..-1].to_sym
204
+ res << opt if opt
205
+
206
+ res
210
207
  end
211
208
 
212
- res << opt if opt
209
+ def new_block_args(norm, opt, rest, block)
210
+ res = s(:array)
213
211
 
214
- res
215
- end
212
+ if norm
213
+ norm.each do |arg|
214
+ @scope.add_local arg
215
+ res << s(:lasgn, arg)
216
+ end
217
+ end
216
218
 
217
- def new_block_args norm, opt, rest, block
218
- res = s(:array)
219
+ if opt
220
+ opt[1..-1].each do |_opt|
221
+ res << s(:lasgn, _opt[1])
222
+ end
223
+ end
219
224
 
220
- if norm
221
- norm.each do |arg|
222
- @scope.add_local arg
223
- res << s(:lasgn, arg)
225
+ if rest
226
+ r = rest.to_s[1..-1].to_sym
227
+ res << s(:splat, s(:lasgn, r))
228
+ @scope.add_local r
224
229
  end
225
- end
226
230
 
227
- if opt
228
- opt[1..-1].each do |_opt|
229
- res << s(:lasgn, _opt[1])
231
+ if block
232
+ b = block.to_s[1..-1].to_sym
233
+ res << s(:block_pass, s(:lasgn, b))
234
+ @scope.add_local b
230
235
  end
231
- end
232
236
 
233
- if rest
234
- r = rest.to_s[1..-1].to_sym
235
- res << s(:splat, s(:lasgn, r))
236
- @scope.add_local r
237
- end
237
+ res << opt if opt
238
238
 
239
- if block
240
- b = block.to_s[1..-1].to_sym
241
- res << s(:block_pass, s(:lasgn, b))
242
- @scope.add_local b
239
+ res.size == 2 && norm ? res[1] : s(:masgn, res)
243
240
  end
244
241
 
245
- res << opt if opt
242
+ def new_call(recv, meth, args = nil)
243
+ call = s(:call, recv, meth)
244
+ args = s(:arglist) unless args
245
+ args[0] = :arglist if args[0] == :array
246
+ call << args
246
247
 
247
- res.size == 2 && norm ? res[1] : s(:masgn, res)
248
- end
248
+ if recv
249
+ call.line = recv.line
250
+ elsif args[1]
251
+ call.line = args[1].line
252
+ end
249
253
 
250
- def new_call recv, meth, args = nil
251
- call = s(:call, recv, meth)
252
- args = s(:arglist) unless args
253
- args[0] = :arglist if args[0] == :array
254
- call << args
254
+ # fix arglist spilling over into next line if no args
255
+ if args.length == 1
256
+ args.line = call.line
257
+ else
258
+ args.line = args[1].line
259
+ end
255
260
 
256
- if recv
257
- call.line = recv.line
258
- elsif args[1]
259
- call.line = args[1].line
261
+ call
260
262
  end
261
263
 
262
- # fix arglist spilling over into next line if no args
263
- if args.length == 1
264
- args.line = call.line
265
- else
266
- args.line = args[1].line
264
+ def add_block_pass(arglist, block)
265
+ arglist << block if block
266
+ arglist
267
267
  end
268
268
 
269
- call
270
- end
271
-
272
- def add_block_pass arglist, block
273
- arglist << block if block
274
- arglist
275
- end
269
+ def new_op_asgn(op, lhs, rhs)
270
+ case op
271
+ when :"||"
272
+ result = s(:op_asgn_or, new_gettable(lhs))
273
+ result << (lhs << rhs)
274
+ when :"&&"
275
+ result = s(:op_asgn_and, new_gettable(lhs))
276
+ result << (lhs << rhs)
277
+ else
278
+ result = lhs
279
+ result << new_call(new_gettable(lhs), op, s(:arglist, rhs))
280
+
281
+ end
276
282
 
277
- def new_op_asgn op, lhs, rhs
278
- case op
279
- when :"||"
280
- result = s(:op_asgn_or, new_gettable(lhs))
281
- result << (lhs << rhs)
282
- when :"&&"
283
- result = s(:op_asgn_and, new_gettable(lhs))
284
- result << (lhs << rhs)
285
- else
286
- result = lhs
287
- result << new_call(new_gettable(lhs), op, s(:arglist, rhs))
288
-
283
+ result.line = lhs.line
284
+ result
289
285
  end
290
286
 
291
- result.line = lhs.line
292
- result
293
- end
294
-
295
- def new_assign lhs, rhs
296
- case lhs[0]
297
- when :iasgn, :cdecl, :lasgn, :gasgn, :cvdecl
298
- lhs << rhs
299
- lhs
300
- when :call, :attrasgn
301
- lhs.last << rhs
302
- lhs
303
- else
304
- raise "Bad lhs for new_assign: #{lhs[0]}"
287
+ def new_assign(lhs, rhs)
288
+ case lhs[0]
289
+ when :iasgn, :cdecl, :lasgn, :gasgn, :cvdecl
290
+ lhs << rhs
291
+ lhs
292
+ when :call, :attrasgn
293
+ lhs.last << rhs
294
+ lhs
295
+ else
296
+ raise "Bad lhs for new_assign: #{lhs[0]}"
297
+ end
305
298
  end
306
- end
307
299
 
308
- def new_assignable ref
309
- case ref[0]
310
- when :ivar
311
- ref[0] = :iasgn
312
- when :const
313
- ref[0] = :cdecl
314
- when :identifier
315
- @scope.add_local ref[1] unless @scope.has_local? ref[1]
316
- ref[0] = :lasgn
317
- when :gvar
318
- ref[0] = :gasgn
319
- when :cvar
320
- ref[0] = :cvdecl
321
- else
322
- raise "Bad new_assignable type: #{ref[0]}"
323
- end
300
+ def new_assignable(ref)
301
+ case ref[0]
302
+ when :ivar
303
+ ref[0] = :iasgn
304
+ when :const
305
+ ref[0] = :cdecl
306
+ when :identifier
307
+ @scope.add_local ref[1] unless @scope.has_local? ref[1]
308
+ ref[0] = :lasgn
309
+ when :gvar
310
+ ref[0] = :gasgn
311
+ when :cvar
312
+ ref[0] = :cvdecl
313
+ else
314
+ raise "Bad new_assignable type: #{ref[0]}"
315
+ end
324
316
 
325
- ref
326
- end
317
+ ref
318
+ end
327
319
 
328
- def new_gettable ref
329
- res = case ref[0]
330
- when :lasgn
331
- s(:lvar, ref[1])
332
- when :iasgn
333
- s(:ivar, ref[1])
334
- when :gasgn
335
- s(:gvar, ref[1])
336
- when :cvdecl
337
- s(:cvar, ref[1])
338
- else
339
- raise "Bad new_gettable ref: #{ref[0]}"
340
- end
320
+ def new_gettable(ref)
321
+ res = case ref[0]
322
+ when :lasgn
323
+ s(:lvar, ref[1])
324
+ when :iasgn
325
+ s(:ivar, ref[1])
326
+ when :gasgn
327
+ s(:gvar, ref[1])
328
+ when :cvdecl
329
+ s(:cvar, ref[1])
330
+ else
331
+ raise "Bad new_gettable ref: #{ref[0]}"
332
+ end
341
333
 
342
- res.line = ref.line
343
- res
344
- end
334
+ res.line = ref.line
335
+ res
336
+ end
345
337
 
346
- def new_var_ref ref
347
- case ref[0]
348
- when :self, :nil, :true, :false, :line, :file
349
- ref
350
- when :const
351
- ref
352
- when :ivar, :gvar, :cvar
353
- ref
354
- when :lit
355
- # this is when we passed __LINE__ which is converted into :lit
356
- ref
357
- when :str
358
- # returns for __FILE__ as it is converted into str
359
- ref
360
- when :identifier
361
- if @scope.has_local? ref[1]
362
- s(:lvar, ref[1])
338
+ def new_var_ref(ref)
339
+ case ref[0]
340
+ when :self, :nil, :true, :false, :line, :file
341
+ ref
342
+ when :const
343
+ ref
344
+ when :ivar, :gvar, :cvar
345
+ ref
346
+ when :lit
347
+ # this is when we passed __LINE__ which is converted into :lit
348
+ ref
349
+ when :str
350
+ # returns for __FILE__ as it is converted into str
351
+ ref
352
+ when :identifier
353
+ if @scope.has_local? ref[1]
354
+ s(:lvar, ref[1])
355
+ else
356
+ s(:call, nil, ref[1], s(:arglist))
357
+ end
363
358
  else
364
- s(:call, nil, ref[1], s(:arglist))
359
+ raise "Bad var_ref type: #{ref[0]}"
365
360
  end
366
- else
367
- raise "Bad var_ref type: #{ref[0]}"
368
361
  end
369
- end
370
-
371
- def new_super args
372
- args = (args || s(:arglist))[1..-1]
373
- s(:super, *args)
374
- end
375
362
 
376
- def new_yield args
377
- args = (args || s(:arglist))[1..-1]
378
- s(:yield, *args)
379
- end
363
+ def new_super(args)
364
+ args = (args || s(:arglist))[1..-1]
365
+ s(:super, *args)
366
+ end
380
367
 
381
- def new_xstr str
382
- return s(:xstr, '') unless str
383
- case str[0]
384
- when :str then str[0] = :xstr
385
- when :dstr then str[0] = :dxstr
386
- when :evstr then str = s(:dxstr, '', str)
368
+ def new_yield(args)
369
+ args = (args || s(:arglist))[1..-1]
370
+ s(:yield, *args)
387
371
  end
388
372
 
389
- str
390
- end
373
+ def new_xstr(str)
374
+ return s(:xstr, '') unless str
375
+ case str[0]
376
+ when :str then str[0] = :xstr
377
+ when :dstr then str[0] = :dxstr
378
+ when :evstr then str = s(:dxstr, '', str)
379
+ end
391
380
 
392
- def new_dsym str
393
- return s(:nil) unless str
394
- case str[0]
395
- when :str
396
- str[0] = :lit
397
- str[1] = str[1].to_sym
398
- when :dstr
399
- str[0] = :dsym
381
+ str
400
382
  end
401
383
 
402
- str
403
- end
384
+ def new_dsym(str)
385
+ return s(:nil) unless str
386
+ case str[0]
387
+ when :str
388
+ str[0] = :lit
389
+ str[1] = str[1].to_sym
390
+ when :dstr
391
+ str[0] = :dsym
392
+ end
404
393
 
405
- def new_str str
406
- # cover empty strings
407
- return s(:str, "") unless str
408
- # catch s(:str, "", other_str)
409
- if str.size == 3 and str[1] == "" and str[0] == :str
410
- return str[2]
411
- # catch s(:str, "content", more_content)
412
- elsif str[0] == :str && str.size > 3
413
- str[0] = :dstr
414
- str
415
- # top level evstr should be a dstr
416
- elsif str[0] == :evstr
417
- s(:dstr, "", str)
418
- else
419
394
  str
420
395
  end
421
- end
422
396
 
423
- def new_regexp reg, ending
424
- return s(:lit, //) unless reg
425
- case reg[0]
426
- when :str
427
- s(:lit, Regexp.new(reg[1], ending))
428
- when :evstr
429
- res = s(:dregx, "", reg)
430
- when :dstr
431
- reg[0] = :dregx
432
- reg
397
+ def new_str(str)
398
+ # cover empty strings
399
+ return s(:str, "") unless str
400
+ # catch s(:str, "", other_str)
401
+ if str.size == 3 and str[1] == "" and str[0] == :str
402
+ return str[2]
403
+ # catch s(:str, "content", more_content)
404
+ elsif str[0] == :str && str.size > 3
405
+ str[0] = :dstr
406
+ str
407
+ # top level evstr should be a dstr
408
+ elsif str[0] == :evstr
409
+ s(:dstr, "", str)
410
+ else
411
+ str
412
+ end
413
+ end
414
+
415
+ def new_regexp(reg, ending)
416
+ return s(:lit, //) unless reg
417
+ case reg[0]
418
+ when :str
419
+ s(:lit, Regexp.new(reg[1], ending))
420
+ when :evstr
421
+ res = s(:dregx, "", reg)
422
+ when :dstr
423
+ reg[0] = :dregx
424
+ reg
425
+ end
433
426
  end
434
- end
435
427
 
436
- def str_append str, str2
437
- return str2 unless str
438
- return str unless str2
428
+ def str_append(str, str2)
429
+ return str2 unless str
430
+ return str unless str2
439
431
 
440
- if str.first == :evstr
441
- str = s(:dstr, "", str)
442
- elsif str.first == :str
443
- str = s(:dstr, str[1])
444
- else
445
- #puts str.first
432
+ if str.first == :evstr
433
+ str = s(:dstr, "", str)
434
+ elsif str.first == :str
435
+ str = s(:dstr, str[1])
436
+ else
437
+ #puts str.first
438
+ end
439
+ str << str2
440
+ str
446
441
  end
447
- str << str2
448
- str
449
- end
450
442
 
451
- def next_token
452
- t = get_next_token
453
- # puts "returning token #{t.inspect}"
454
- t
455
- end
443
+ def cond_push(n)
444
+ @cond = (@cond << 1) | (n & 1)
445
+ end
456
446
 
457
- def cond_push(n)
458
- @cond = (@cond << 1) | (n & 1)
459
- end
447
+ def cond_pop
448
+ @cond = @cond >> 1
449
+ end
460
450
 
461
- def cond_pop
462
- @cond = @cond >> 1
463
- end
451
+ def cond_lexpop
452
+ @cond = (@cond >> 1) | (@cond & 1)
453
+ end
464
454
 
465
- def cond_lexpop
466
- @cond = (@cond >> 1) | (@cond & 1)
467
- end
455
+ def cond?
456
+ (@cond & 1) != 0
457
+ end
468
458
 
469
- def cond?
470
- (@cond & 1) != 0
471
- end
459
+ def cmdarg_push(n)
460
+ @cmdarg = (@cmdarg << 1) | (n & 1)
461
+ end
472
462
 
473
- def cmdarg_push(n)
474
- @cmdarg = (@cmdarg << 1) | (n & 1)
475
- end
463
+ def cmdarg_pop
464
+ @cmdarg = @cmdarg >> 1
465
+ end
476
466
 
477
- def cmdarg_pop
478
- @cmdarg = @cmdarg >> 1
479
- end
467
+ def cmdarg_lexpop
468
+ @cmdarg = (@cmdarg >> 1) | (@cmdarg & 1)
469
+ end
480
470
 
481
- def cmdarg_lexpop
482
- @cmdarg = (@cmdarg >> 1) | (@cmdarg & 1)
483
- end
471
+ def cmdarg?
472
+ (@cmdarg & 1) != 0
473
+ end
484
474
 
485
- def cmdarg?
486
- (@cmdarg & 1) != 0
487
- end
475
+ def next_string_token
476
+ # str_parse, scanner = current_string_parse, @scanner
477
+ str_parse = @string_parse
478
+ scanner = @scanner
479
+ space = false
488
480
 
489
- def next_string_token
490
- # str_parse, scanner = current_string_parse, @scanner
491
- str_parse = @string_parse
492
- scanner = @scanner
493
- space = false
481
+ # everything bar single quote and lower case bare wrds can interpolate
482
+ interpolate = str_parse[:interpolate]
494
483
 
495
- # everything bar single quote and lower case bare wrds can interpolate
496
- interpolate = str_parse[:interpolate]
484
+ words = ['w', 'W'].include? str_parse[:beg]
497
485
 
498
- words = ['w', 'W'].include? str_parse[:beg]
486
+ space = true if ['w', 'W'].include?(str_parse[:beg]) and scanner.scan(/\s+/)
499
487
 
500
- space = true if ['w', 'W'].include?(str_parse[:beg]) and scanner.scan(/\s+/)
488
+ # if not end of string, so we must be parsing contents
489
+ str_buffer = []
501
490
 
502
- # if not end of string, so we must be parsing contents
503
- str_buffer = []
491
+ # see if we can read end of string/xstring/regecp markers
492
+ # if scanner.scan /#{str_parse[:end]}/
493
+ if scanner.scan Regexp.new(Regexp.escape(str_parse[:end]))
494
+ if words && !str_parse[:done_last_space]#&& space
495
+ str_parse[:done_last_space] = true
496
+ scanner.pos -= 1
497
+ return :SPACE, ' '
498
+ end
499
+ @string_parse = nil
504
500
 
505
- # see if we can read end of string/xstring/regecp markers
506
- # if scanner.scan /#{str_parse[:end]}/
507
- if scanner.scan Regexp.new(Regexp.escape(str_parse[:end]))
508
- if words && !str_parse[:done_last_space]#&& space
509
- str_parse[:done_last_space] = true
510
- scanner.pos -= 1
511
- return :SPACE, ' '
512
- end
513
- @string_parse = nil
501
+ # return :SPACE, ' ' if words && space
514
502
 
515
- # return :SPACE, ' ' if words && space
503
+ # if in %Q{, we should balance { with } before ending.
504
+ if str_parse[:balance]
505
+ if str_parse[:nesting] == 0
506
+ @lex_state = :expr_end
507
+ return :STRING_END, scanner.matched
508
+ else
509
+ #puts "nesting not 0!"
510
+ #puts str_parse[:nesting]
511
+ str_buffer << scanner.matched
512
+ str_parse[:nesting] -= 1
513
+ # make sure we carry on string parse (its set to nil above)
514
+ @string_parse = str_parse
515
+ end
516
516
 
517
- # if in %Q{, we should balance { with } before ending.
518
- if str_parse[:balance]
519
- if str_parse[:nesting] == 0
517
+ elsif ['"', "'"].include? str_parse[:beg]
520
518
  @lex_state = :expr_end
521
519
  return :STRING_END, scanner.matched
522
- else
523
- #puts "nesting not 0!"
524
- #puts str_parse[:nesting]
525
- str_buffer << scanner.matched
526
- str_parse[:nesting] -= 1
527
- # make sure we carry on string parse (its set to nil above)
528
- @string_parse = str_parse
529
- end
530
-
531
- elsif ['"', "'"].include? str_parse[:beg]
532
- @lex_state = :expr_end
533
- return :STRING_END, scanner.matched
534
520
 
535
- elsif str_parse[:beg] == '`'
536
- @lex_state = :expr_end
537
- return :STRING_END, scanner.matched
521
+ elsif str_parse[:beg] == '`'
522
+ @lex_state = :expr_end
523
+ return :STRING_END, scanner.matched
538
524
 
539
- elsif str_parse[:beg] == '/'
540
- result = scanner.scan(/\w+/)
541
- @lex_state = :expr_end
542
- return :REGEXP_END, result
525
+ elsif str_parse[:beg] == '/'
526
+ result = scanner.scan(/\w+/)
527
+ @lex_state = :expr_end
528
+ return :REGEXP_END, result
543
529
 
544
- else
545
- @lex_state = :expr_end
546
- return :STRING_END, scanner.matched
530
+ else
531
+ @lex_state = :expr_end
532
+ return :STRING_END, scanner.matched
533
+ end
547
534
  end
548
- end
549
535
 
550
- return :SPACE, ' ' if space
536
+ return :SPACE, ' ' if space
551
537
 
552
- if str_parse[:balance] and scanner.scan Regexp.new(Regexp.escape(str_parse[:beg]))
553
- #puts "matced beg balance!"
554
- str_buffer << scanner.matched
555
- str_parse[:nesting] += 1
556
- elsif scanner.check(/#[@$]/)
557
- scanner.scan(/#/)
558
- if interpolate
559
- return :STRING_DVAR, scanner.matched
560
- else
538
+ if str_parse[:balance] and scanner.scan Regexp.new(Regexp.escape(str_parse[:beg]))
539
+ #puts "matced beg balance!"
561
540
  str_buffer << scanner.matched
562
- end
541
+ str_parse[:nesting] += 1
542
+ elsif scanner.check(/#[@$]/)
543
+ scanner.scan(/#/)
544
+ if interpolate
545
+ return :STRING_DVAR, scanner.matched
546
+ else
547
+ str_buffer << scanner.matched
548
+ end
563
549
 
564
- elsif scanner.scan(/#\{/)
565
- if interpolate
566
- # we are into ruby code, so stop parsing content (for now)
567
- return :STRING_DBEG, scanner.matched
568
- else
569
- str_buffer << scanner.matched
550
+ elsif scanner.scan(/#\{/)
551
+ if interpolate
552
+ # we are into ruby code, so stop parsing content (for now)
553
+ return :STRING_DBEG, scanner.matched
554
+ else
555
+ str_buffer << scanner.matched
556
+ end
557
+
558
+ # causes error, so we will just collect it later on with other text
559
+ elsif scanner.scan(/\#/)
560
+ str_buffer << '#'
570
561
  end
571
562
 
572
- # causes error, so we will just collect it later on with other text
573
- elsif scanner.scan(/\#/)
574
- str_buffer << '#'
563
+ add_string_content str_buffer, str_parse
564
+ complete_str = str_buffer.join ''
565
+ @line += complete_str.count("\n")
566
+ return :STRING_CONTENT, complete_str
575
567
  end
576
568
 
577
- add_string_content str_buffer, str_parse
578
- complete_str = str_buffer.join ''
579
- @line += complete_str.count("\n")
580
- return :STRING_CONTENT, complete_str
581
- end
569
+ def add_string_content(str_buffer, str_parse)
570
+ scanner = @scanner
571
+ # regexp for end of string/regexp
572
+ # end_str_re = /#{str_parse[:end]}/
573
+ end_str_re = Regexp.new(Regexp.escape(str_parse[:end]))
574
+ # can be interpolate
575
+ interpolate = str_parse[:interpolate]
576
+
577
+ words = ['W', 'w'].include? str_parse[:beg]
578
+
579
+ until scanner.eos?
580
+ c = nil
581
+ handled = true
582
+
583
+ if scanner.check end_str_re
584
+ # eos
585
+ # if its just balancing, add it ass normal content..
586
+ if str_parse[:balance] && (str_parse[:nesting] != 0)
587
+ # we only checked above, so actually scan it
588
+ scanner.scan end_str_re
589
+ c = scanner.matched
590
+ str_parse[:nesting] -= 1
591
+ else
592
+ # not balancing, so break (eos!)
593
+ break
594
+ end
582
595
 
583
- def add_string_content(str_buffer, str_parse)
584
- scanner = @scanner
585
- # regexp for end of string/regexp
586
- # end_str_re = /#{str_parse[:end]}/
587
- end_str_re = Regexp.new(Regexp.escape(str_parse[:end]))
588
- # can be interpolate
589
- interpolate = str_parse[:interpolate]
590
-
591
- words = ['W', 'w'].include? str_parse[:beg]
592
-
593
- until scanner.eos?
594
- c = nil
595
- handled = true
596
-
597
- if scanner.check end_str_re
598
- # eos
599
- # if its just balancing, add it ass normal content..
600
- if str_parse[:balance] && (str_parse[:nesting] != 0)
601
- # we only checked above, so actually scan it
602
- scanner.scan end_str_re
596
+ elsif str_parse[:balance] and scanner.scan Regexp.new(Regexp.escape(str_parse[:beg]))
597
+ str_parse[:nesting] += 1
603
598
  c = scanner.matched
604
- str_parse[:nesting] -= 1
605
- else
606
- # not balancing, so break (eos!)
607
- break
608
- end
609
-
610
- elsif str_parse[:balance] and scanner.scan Regexp.new(Regexp.escape(str_parse[:beg]))
611
- str_parse[:nesting] += 1
612
- c = scanner.matched
613
599
 
614
- elsif words && scanner.scan(/\s/)
615
- scanner.pos -= 1
616
- break
600
+ elsif words && scanner.scan(/\s/)
601
+ scanner.pos -= 1
602
+ break
617
603
 
618
- elsif interpolate && scanner.check(/#(?=[\$\@\{])/)
619
- break
604
+ elsif interpolate && scanner.check(/#(?=[\$\@\{])/)
605
+ break
620
606
 
621
- #elsif scanner.scan(/\\\\/)
622
- #c = scanner.matched
607
+ #elsif scanner.scan(/\\\\/)
608
+ #c = scanner.matched
623
609
 
624
- elsif scanner.scan(/\\/)
625
- if str_parse[:regexp]
626
- if scanner.scan(/(.)/)
627
- c = "\\" + scanner.matched
610
+ elsif scanner.scan(/\\/)
611
+ if str_parse[:regexp]
612
+ if scanner.scan(/(.)/)
613
+ c = "\\" + scanner.matched
614
+ end
615
+ else
616
+ c = if scanner.scan(/n/)
617
+ "\n"
618
+ elsif scanner.scan(/r/)
619
+ "\r"
620
+ elsif scanner.scan(/\n/)
621
+ "\n"
622
+ else
623
+ # escaped char doesnt need escaping, so just return it
624
+ scanner.scan(/./)
625
+ scanner.matched
626
+ end
628
627
  end
629
628
  else
630
- c = if scanner.scan(/n/)
631
- "\n"
632
- elsif scanner.scan(/r/)
633
- "\r"
634
- elsif scanner.scan(/\n/)
635
- "\n"
636
- else
637
- # escaped char doesnt need escaping, so just return it
638
- scanner.scan(/./)
639
- scanner.matched
640
- end
629
+ handled = false
641
630
  end
642
- else
643
- handled = false
644
- end
645
631
 
646
- unless handled
647
- reg = if words
648
- Regexp.new("[^#{Regexp.escape str_parse[:end]}\#\0\n\ \\\\]+|.")
649
- elsif str_parse[:balance]
650
- #puts "using tis regexp"
651
- Regexp.new("[^#{Regexp.escape str_parse[:end]}#{Regexp.escape str_parse[:beg]}\#\0\\\\]+|.")
652
- else
653
- Regexp.new("[^#{Regexp.escape str_parse[:end]}\#\0\\\\]+|.")
654
- end
632
+ unless handled
633
+ reg = if words
634
+ Regexp.new("[^#{Regexp.escape str_parse[:end]}\#\0\n\ \\\\]+|.")
635
+ elsif str_parse[:balance]
636
+ #puts "using tis regexp"
637
+ Regexp.new("[^#{Regexp.escape str_parse[:end]}#{Regexp.escape str_parse[:beg]}\#\0\\\\]+|.")
638
+ else
639
+ Regexp.new("[^#{Regexp.escape str_parse[:end]}\#\0\\\\]+|.")
640
+ end
641
+
642
+ scanner.scan reg
643
+ #puts scanner.matched
644
+ c = scanner.matched
645
+ end
655
646
 
656
- scanner.scan reg
657
- #puts scanner.matched
658
- c = scanner.matched
647
+ c ||= scanner.matched
648
+ str_buffer << c
659
649
  end
660
650
 
661
- c ||= scanner.matched
662
- str_buffer << c
651
+ raise "reached EOF while in string" if scanner.eos?
663
652
  end
664
653
 
665
- raise "reached EOF while in string" if scanner.eos?
666
- end
654
+ def next_token
655
+ # if we are trying to parse a string, then delegate to that
656
+ return next_string_token if @string_parse
667
657
 
668
- def get_next_token
669
- if @string_parse
670
- return next_string_token
671
- end
658
+ # scanner, space_seen, cmd_start, c = @scanner, false, false, ''
659
+ scanner = @scanner
660
+ space_seen = false
661
+ cmd_start = false
662
+ c = ''
672
663
 
673
- # scanner, space_seen, cmd_start, c = @scanner, false, false, ''
674
- scanner = @scanner
675
- space_seen = false
676
- cmd_start = false
677
- c = ''
678
-
679
- while true
680
- if scanner.scan(/\ |\t|\r/)
681
- space_seen = true
682
- next
683
-
684
- elsif scanner.scan(/(\n|#)/)
685
- c = scanner.matched
686
- if c == '#' then scanner.scan(/(.*)/) else @line += 1; end
687
-
688
- scanner.scan(/(\n+)/)
689
- @line += scanner.matched.length if scanner.matched
690
-
691
- next if [:expr_beg, :expr_dot].include? @lex_state
692
-
693
- cmd_start = true
694
- @lex_state = :expr_beg
695
- return '\\n', '\\n'
696
-
697
- elsif scanner.scan(/\;/)
698
- @lex_state = :expr_beg
699
- return ';', ';'
700
-
701
- elsif scanner.scan(/\"/)
702
- @string_parse = { :beg => '"', :end => '"', :interpolate => true }
703
- return :STRING_BEG, scanner.matched
704
-
705
- elsif scanner.scan(/\'/)
706
- @string_parse = { :beg => "'", :end => "'" }
707
- return :STRING_BEG, scanner.matched
708
-
709
- elsif scanner.scan(/\`/)
710
- @string_parse = { :beg => "`", :end => "`", :interpolate => true }
711
- return :XSTRING_BEG, scanner.matched
712
-
713
- elsif scanner.scan(/\%W/)
714
- start_word = scanner.scan(/./)
715
- end_word = { '(' => ')', '[' => ']', '{' => '}' }[start_word] || start_word
716
- @string_parse = { :beg => 'W', :end => end_word, :interpolate => true }
717
- scanner.scan(/\s*/)
718
- return :WORDS_BEG, scanner.matched
719
-
720
- elsif scanner.scan(/\%w/)
721
- start_word = scanner.scan(/./)
722
- end_word = { '(' => ')', '[' => ']', '{' => '}' }[start_word] || start_word
723
- @string_parse = { :beg => 'w', :end => end_word }
724
- scanner.scan(/\s*/)
725
- return :AWORDS_BEG, scanner.matched
726
-
727
- elsif scanner.scan(/\%[Qq]/)
728
- interpolate = scanner.matched.end_with? 'Q'
729
- start_word = scanner.scan(/./)
730
- end_word = { '(' => ')', '[' => ']', '{' => '}' }[start_word] || start_word
731
- @string_parse = { :beg => start_word, :end => end_word, :balance => true, :nesting => 0, :interpolate => interpolate }
732
- return :STRING_BEG, scanner.matched
733
-
734
- elsif scanner.scan(/\%x/)
735
- start_word = scanner.scan(/./)
736
- end_word = { '(' => ')', '[' => ']', '{' => '}' }[start_word] || start_word
737
- @string_parse = { :beg => start_word, :end => end_word, :balance => true, :nesting => 0, :interpolate => true }
738
- return :XSTRING_BEG, scanner.matched
739
-
740
- elsif scanner.scan(/\//)
741
- if [:expr_beg, :expr_mid].include? @lex_state
742
- @string_parse = { :beg => '/', :end => '/', :interpolate => true, :regexp => true }
743
- return :REGEXP_BEG, scanner.matched
744
- elsif scanner.scan(/\=/)
745
- @lex_state = :expr_beg
746
- return :OP_ASGN, '/'
747
- elsif @lex_state == :expr_fname
748
- @lex_state = :expr_end
749
- end
664
+ while true
665
+ if scanner.scan(/\ |\t|\r/)
666
+ space_seen = true
667
+ next
668
+
669
+ elsif scanner.scan(/(\n|#)/)
670
+ c = scanner.matched
671
+ if c == '#' then scanner.scan(/(.*)/) else @line += 1; end
672
+
673
+ scanner.scan(/(\n+)/)
674
+ @line += scanner.matched.length if scanner.matched
750
675
 
751
- return '/', '/'
676
+ next if [:expr_beg, :expr_dot].include? @lex_state
752
677
 
753
- elsif scanner.scan(/\%/)
754
- if scanner.scan(/\=/)
678
+ cmd_start = true
755
679
  @lex_state = :expr_beg
756
- return :OP_ASGN, '%'
757
- end
758
- @lex_state = @lex_state == :expr_fname ? :expr_end : :expr_beg
759
- return '%', '%'
760
-
761
- elsif scanner.scan(/\(/)
762
- result = scanner.matched
763
- if [:expr_beg, :expr_mid].include? @lex_state
764
- result = :PAREN_BEG
765
- elsif space_seen
766
- result = '('
767
- end
680
+ return '\\n', '\\n'
768
681
 
769
- @lex_state = :expr_beg
770
- cond_push 0
771
- cmdarg_push 0
682
+ elsif scanner.scan(/\;/)
683
+ @lex_state = :expr_beg
684
+ return ';', ';'
772
685
 
773
- return result, scanner.matched
686
+ elsif scanner.scan(/\"/)
687
+ @string_parse = { :beg => '"', :end => '"', :interpolate => true }
688
+ return :STRING_BEG, scanner.matched
774
689
 
775
- elsif scanner.scan(/\)/)
776
- cond_lexpop
777
- cmdarg_lexpop
778
- @lex_state = :expr_end
779
- return ')', scanner.matched
690
+ elsif scanner.scan(/\'/)
691
+ @string_parse = { :beg => "'", :end => "'" }
692
+ return :STRING_BEG, scanner.matched
693
+
694
+ elsif scanner.scan(/\`/)
695
+ @string_parse = { :beg => "`", :end => "`", :interpolate => true }
696
+ return :XSTRING_BEG, scanner.matched
697
+
698
+ elsif scanner.scan(/\%W/)
699
+ start_word = scanner.scan(/./)
700
+ end_word = { '(' => ')', '[' => ']', '{' => '}' }[start_word] || start_word
701
+ @string_parse = { :beg => 'W', :end => end_word, :interpolate => true }
702
+ scanner.scan(/\s*/)
703
+ return :WORDS_BEG, scanner.matched
704
+
705
+ elsif scanner.scan(/\%w/)
706
+ start_word = scanner.scan(/./)
707
+ end_word = { '(' => ')', '[' => ']', '{' => '}' }[start_word] || start_word
708
+ @string_parse = { :beg => 'w', :end => end_word }
709
+ scanner.scan(/\s*/)
710
+ return :AWORDS_BEG, scanner.matched
711
+
712
+ elsif scanner.scan(/\%[Qq]/)
713
+ interpolate = scanner.matched.end_with? 'Q'
714
+ start_word = scanner.scan(/./)
715
+ end_word = { '(' => ')', '[' => ']', '{' => '}' }[start_word] || start_word
716
+ @string_parse = { :beg => start_word, :end => end_word, :balance => true, :nesting => 0, :interpolate => interpolate }
717
+ return :STRING_BEG, scanner.matched
718
+
719
+ elsif scanner.scan(/\%x/)
720
+ start_word = scanner.scan(/./)
721
+ end_word = { '(' => ')', '[' => ']', '{' => '}' }[start_word] || start_word
722
+ @string_parse = { :beg => start_word, :end => end_word, :balance => true, :nesting => 0, :interpolate => true }
723
+ return :XSTRING_BEG, scanner.matched
724
+
725
+ elsif scanner.scan(/\//)
726
+ if [:expr_beg, :expr_mid].include? @lex_state
727
+ @string_parse = { :beg => '/', :end => '/', :interpolate => true, :regexp => true }
728
+ return :REGEXP_BEG, scanner.matched
729
+ elsif scanner.scan(/\=/)
730
+ @lex_state = :expr_beg
731
+ return :OP_ASGN, '/'
732
+ elsif @lex_state == :expr_fname
733
+ @lex_state = :expr_end
734
+ end
780
735
 
781
- elsif scanner.scan(/\[/)
782
- result = scanner.matched
736
+ return '/', '/'
783
737
 
784
- if [:expr_fname, :expr_dot].include? @lex_state
785
- @lex_state = :expr_arg
786
- if scanner.scan(/\]=/)
787
- return '[]=', '[]='
788
- elsif scanner.scan(/\]/)
789
- return '[]', '[]'
790
- else
791
- raise "Unexpected '[' token"
738
+ elsif scanner.scan(/\%/)
739
+ if scanner.scan(/\=/)
740
+ @lex_state = :expr_beg
741
+ return :OP_ASGN, '%'
792
742
  end
793
- elsif [:expr_beg, :expr_mid].include?(@lex_state) || space_seen
794
- @lex_state = :expr_beg
795
- cond_push 0
796
- cmdarg_push 0
797
- return '[', scanner.matched
798
- else
743
+ @lex_state = @lex_state == :expr_fname ? :expr_end : :expr_beg
744
+ return '%', '%'
745
+
746
+ elsif scanner.scan(/\(/)
747
+ result = scanner.matched
748
+ if [:expr_beg, :expr_mid].include? @lex_state
749
+ result = :PAREN_BEG
750
+ elsif space_seen
751
+ result = '('
752
+ end
753
+
799
754
  @lex_state = :expr_beg
800
755
  cond_push 0
801
756
  cmdarg_push 0
802
- return '[@', scanner.matched
803
- end
804
-
805
- elsif scanner.scan(/\]/)
806
- cond_lexpop
807
- cmdarg_lexpop
808
- @lex_state = :expr_end
809
- return ']', scanner.matched
810
757
 
811
- elsif scanner.scan(/\}/)
812
- cond_lexpop
813
- cmdarg_lexpop
814
- @lex_state = :expr_end
758
+ return result, scanner.matched
815
759
 
816
- return '}', scanner.matched
760
+ elsif scanner.scan(/\)/)
761
+ cond_lexpop
762
+ cmdarg_lexpop
763
+ @lex_state = :expr_end
764
+ return ')', scanner.matched
765
+
766
+ elsif scanner.scan(/\[/)
767
+ result = scanner.matched
768
+
769
+ if [:expr_fname, :expr_dot].include? @lex_state
770
+ @lex_state = :expr_arg
771
+ if scanner.scan(/\]=/)
772
+ return '[]=', '[]='
773
+ elsif scanner.scan(/\]/)
774
+ return '[]', '[]'
775
+ else
776
+ raise "Unexpected '[' token"
777
+ end
778
+ elsif [:expr_beg, :expr_mid].include?(@lex_state) || space_seen
779
+ @lex_state = :expr_beg
780
+ cond_push 0
781
+ cmdarg_push 0
782
+ return '[', scanner.matched
783
+ else
784
+ @lex_state = :expr_beg
785
+ cond_push 0
786
+ cmdarg_push 0
787
+ return '[@', scanner.matched
788
+ end
817
789
 
818
- elsif scanner.scan(/\.\.\./)
819
- @lex_state = :expr_beg
820
- return '...', scanner.matched
790
+ elsif scanner.scan(/\]/)
791
+ cond_lexpop
792
+ cmdarg_lexpop
793
+ @lex_state = :expr_end
794
+ return ']', scanner.matched
821
795
 
822
- elsif scanner.scan(/\.\./)
823
- @lex_state = :expr_beg
824
- return '..', scanner.matched
796
+ elsif scanner.scan(/\}/)
797
+ cond_lexpop
798
+ cmdarg_lexpop
799
+ @lex_state = :expr_end
825
800
 
826
- elsif scanner.scan(/\./)
827
- @lex_state = :expr_dot unless @lex_state == :expr_fname
828
- return '.', scanner.matched
801
+ return '}', scanner.matched
829
802
 
830
- elsif scanner.scan(/\*\*\=/)
831
- @lex_state = :expr_beg
832
- return :OP_ASGN, '**'
803
+ elsif scanner.scan(/\.\.\./)
804
+ @lex_state = :expr_beg
805
+ return '...', scanner.matched
833
806
 
834
- elsif scanner.scan(/\*\*/)
835
- return '**', '**'
807
+ elsif scanner.scan(/\.\./)
808
+ @lex_state = :expr_beg
809
+ return '..', scanner.matched
836
810
 
837
- elsif scanner.scan(/\*\=/)
838
- @lex_state = :expr_beg
839
- return :OP_ASGN, '*'
811
+ elsif scanner.scan(/\./)
812
+ @lex_state = :expr_dot unless @lex_state == :expr_fname
813
+ return '.', scanner.matched
840
814
 
841
- elsif scanner.scan(/\*/)
842
- result = scanner.matched
843
- if @lex_state == :expr_fname
844
- @lex_state = :expr_end
845
- return '*', result
846
- elsif space_seen && scanner.check(/\S/)
847
- @lex_state = :expr_beg
848
- return :SPLAT, result
849
- elsif [:expr_beg, :expr_mid].include? @lex_state
850
- @lex_state = :expr_beg
851
- return :SPLAT, result
852
- else
815
+ elsif scanner.scan(/\*\*\=/)
853
816
  @lex_state = :expr_beg
854
- return '*', result
855
- end
817
+ return :OP_ASGN, '**'
856
818
 
857
- elsif scanner.scan(/\:\:/)
858
- if [:expr_beg, :expr_mid, :expr_class].include? @lex_state
859
- @lex_state = :expr_beg
860
- return '::@', scanner.matched
861
- end
819
+ elsif scanner.scan(/\*\*/)
820
+ return '**', '**'
862
821
 
863
- @lex_state = :expr_dot
864
- return '::', scanner.matched
822
+ elsif scanner.scan(/\*\=/)
823
+ @lex_state = :expr_beg
824
+ return :OP_ASGN, '*'
865
825
 
866
- elsif scanner.scan(/\:/)
867
- if [:expr_end, :expr_endarg].include?(@lex_state) || scanner.check(/\s/)
868
- unless scanner.check(/\w/)
826
+ elsif scanner.scan(/\*/)
827
+ result = scanner.matched
828
+ if @lex_state == :expr_fname
829
+ @lex_state = :expr_end
830
+ return '*', result
831
+ elsif space_seen && scanner.check(/\S/)
832
+ @lex_state = :expr_beg
833
+ return :SPLAT, result
834
+ elsif [:expr_beg, :expr_mid].include? @lex_state
835
+ @lex_state = :expr_beg
836
+ return :SPLAT, result
837
+ else
869
838
  @lex_state = :expr_beg
870
- return ':', ':'
839
+ return '*', result
871
840
  end
872
841
 
873
- @lex_state = :expr_fname
874
- return :SYMBOL_BEG, ':'
875
- end
842
+ elsif scanner.scan(/\:\:/)
843
+ if [:expr_beg, :expr_mid, :expr_class].include? @lex_state
844
+ @lex_state = :expr_beg
845
+ return '::@', scanner.matched
846
+ end
876
847
 
877
- if scanner.scan(/\'/)
878
- @string_parse = { :beg => "'", :end => "'" }
879
- elsif scanner.scan(/\"/)
880
- @string_parse = { :beg => '"', :end => '"', :interpolate => true }
881
- end
848
+ @lex_state = :expr_dot
849
+ return '::', scanner.matched
882
850
 
883
- @lex_state = :expr_fname
884
- return :SYMBOL_BEG, ':'
851
+ elsif scanner.scan(/\:/)
852
+ if [:expr_end, :expr_endarg].include?(@lex_state) || scanner.check(/\s/)
853
+ unless scanner.check(/\w/)
854
+ @lex_state = :expr_beg
855
+ return ':', ':'
856
+ end
885
857
 
886
- elsif scanner.check(/\|/)
887
- if scanner.scan(/\|\|\=/)
888
- @lex_state = :expr_beg
889
- return :OP_ASGN, '||'
890
- elsif scanner.scan(/\|\|/)
891
- @lex_state = :expr_beg
892
- return '||', '||'
893
- elsif scanner.scan(/\|\=/)
894
- @lex_state = :expr_beg
895
- return :OP_ASGN, '|'
896
- elsif scanner.scan(/\|/)
897
- if @lex_state == :expr_fname
898
- @lex_state = :expr_end
899
- return '|', scanner.matched
900
- else
901
- @lex_state = :expr_beg
902
- return '|', scanner.matched
858
+ @lex_state = :expr_fname
859
+ return :SYMBOL_BEG, ':'
903
860
  end
904
- end
905
861
 
906
- elsif scanner.scan(/\^\=/)
907
- @lex_state = :exor_beg
908
- return :OP_ASGN, '^'
909
- elsif scanner.scan(/\^/)
910
- if @lex_state == :expr_fname
911
- @lex_state = :expr_end
912
- return '^', scanner.matched
913
- end
862
+ if scanner.scan(/\'/)
863
+ @string_parse = { :beg => "'", :end => "'" }
864
+ elsif scanner.scan(/\"/)
865
+ @string_parse = { :beg => '"', :end => '"', :interpolate => true }
866
+ end
914
867
 
915
- @lex_state = :expr_beg
916
- return '^', scanner.matched
868
+ @lex_state = :expr_fname
869
+ return :SYMBOL_BEG, ':'
917
870
 
918
- elsif scanner.check(/\&/)
919
- if scanner.scan(/\&\&\=/)
920
- @lex_state = :expr_beg
921
- return :OP_ASGN, '&&'
922
- elsif scanner.scan(/\&\&/)
923
- @lex_state = :expr_beg
924
- return '&&', scanner.matched
925
- elsif scanner.scan(/\&\=/)
926
- @lex_state = :expr_beg
927
- return :OP_ASGN, '&'
928
- elsif scanner.scan(/\&/)
929
- if space_seen && !scanner.check(/\s/) && (@lex_state == :expr_cmdarg || @lex_state == :expr_arg)
930
- return '&@', '&'
931
- elsif [:expr_beg, :expr_mid].include? @lex_state
932
- return '&@', '&'
933
- else
934
- return '&', '&'
871
+ elsif scanner.check(/\|/)
872
+ if scanner.scan(/\|\|\=/)
873
+ @lex_state = :expr_beg
874
+ return :OP_ASGN, '||'
875
+ elsif scanner.scan(/\|\|/)
876
+ @lex_state = :expr_beg
877
+ return '||', '||'
878
+ elsif scanner.scan(/\|\=/)
879
+ @lex_state = :expr_beg
880
+ return :OP_ASGN, '|'
881
+ elsif scanner.scan(/\|/)
882
+ if @lex_state == :expr_fname
883
+ @lex_state = :expr_end
884
+ return '|', scanner.matched
885
+ else
886
+ @lex_state = :expr_beg
887
+ return '|', scanner.matched
888
+ end
935
889
  end
936
- end
937
890
 
938
- elsif scanner.check(/\</)
939
- if scanner.scan(/\<\<\=/)
940
- @lex_state = :expr_beg
941
- return :OP_ASGN, '<<'
942
- elsif scanner.scan(/\<\</)
891
+ elsif scanner.scan(/\^\=/)
892
+ @lex_state = :exor_beg
893
+ return :OP_ASGN, '^'
894
+ elsif scanner.scan(/\^/)
943
895
  if @lex_state == :expr_fname
944
896
  @lex_state = :expr_end
945
- return '<<', '<<'
946
- elsif ![:expr_end, :expr_dot, :expr_endarg, :expr_class].include?(@lex_state) && space_seen
947
- if scanner.scan(/(-?)(\w+)/)
948
- heredoc = scanner[2]
949
- # for now just scrap rest of line + skip down one line for
950
- # string content
951
- scanner.scan(/.*\n/)
952
- @string_parse = { :beg => heredoc, :end => heredoc, :interpolate => true }
953
- return :STRING_BEG, heredoc
954
- end
955
- @lex_state = :expr_beg
956
- return '<<', '<<'
897
+ return '^', scanner.matched
957
898
  end
899
+
958
900
  @lex_state = :expr_beg
959
- return '<<', '<<'
960
- elsif scanner.scan(/\<\=\>/)
961
- if @lex_state == :expr_fname
962
- @lex_state = :expr_end
963
- else
901
+ return '^', scanner.matched
902
+
903
+ elsif scanner.check(/\&/)
904
+ if scanner.scan(/\&\&\=/)
964
905
  @lex_state = :expr_beg
965
- end
966
- return '<=>', '<=>'
967
- elsif scanner.scan(/\<\=/)
968
- if @lex_state == :expr_fname
969
- @lex_state = :expr_end
970
- else
906
+ return :OP_ASGN, '&&'
907
+ elsif scanner.scan(/\&\&/)
971
908
  @lex_state = :expr_beg
972
- end
973
- return '<=', '<='
974
- elsif scanner.scan(/\</)
975
- if @lex_state == :expr_fname
976
- @lex_state = :expr_end
977
- else
909
+ return '&&', scanner.matched
910
+ elsif scanner.scan(/\&\=/)
978
911
  @lex_state = :expr_beg
912
+ return :OP_ASGN, '&'
913
+ elsif scanner.scan(/\&/)
914
+ if space_seen && !scanner.check(/\s/) && (@lex_state == :expr_cmdarg || @lex_state == :expr_arg)
915
+ return '&@', '&'
916
+ elsif [:expr_beg, :expr_mid].include? @lex_state
917
+ return '&@', '&'
918
+ else
919
+ return '&', '&'
920
+ end
979
921
  end
980
- return '<', '<'
981
- end
982
922
 
983
- elsif scanner.check(/\>/)
984
- if scanner.scan(/\>\>\=/)
985
- return :OP_ASGN, '>>'
986
- elsif scanner.scan(/\>\>/)
987
- return '>>', '>>'
988
- elsif scanner.scan(/\>\=/)
989
- if @lex_state == :expr_fname
990
- @lex_state = :expr_end
991
- else
923
+ elsif scanner.check(/\</)
924
+ if scanner.scan(/\<\<\=/)
992
925
  @lex_state = :expr_beg
993
- end
994
- return '>=', scanner.matched
995
- elsif scanner.scan(/\>/)
996
- if @lex_state == :expr_fname
997
- @lex_state = :expr_end
998
- else
926
+ return :OP_ASGN, '<<'
927
+ elsif scanner.scan(/\<\</)
928
+ if @lex_state == :expr_fname
929
+ @lex_state = :expr_end
930
+ return '<<', '<<'
931
+ elsif ![:expr_end, :expr_dot, :expr_endarg, :expr_class].include?(@lex_state) && space_seen
932
+ if scanner.scan(/(-?)(\w+)/)
933
+ heredoc = scanner[2]
934
+ # for now just scrap rest of line + skip down one line for
935
+ # string content
936
+ scanner.scan(/.*\n/)
937
+ @string_parse = { :beg => heredoc, :end => heredoc, :interpolate => true }
938
+ return :STRING_BEG, heredoc
939
+ end
940
+ @lex_state = :expr_beg
941
+ return '<<', '<<'
942
+ end
999
943
  @lex_state = :expr_beg
944
+ return '<<', '<<'
945
+ elsif scanner.scan(/\<\=\>/)
946
+ if @lex_state == :expr_fname
947
+ @lex_state = :expr_end
948
+ else
949
+ @lex_state = :expr_beg
950
+ end
951
+ return '<=>', '<=>'
952
+ elsif scanner.scan(/\<\=/)
953
+ if @lex_state == :expr_fname
954
+ @lex_state = :expr_end
955
+ else
956
+ @lex_state = :expr_beg
957
+ end
958
+ return '<=', '<='
959
+ elsif scanner.scan(/\</)
960
+ if @lex_state == :expr_fname
961
+ @lex_state = :expr_end
962
+ else
963
+ @lex_state = :expr_beg
964
+ end
965
+ return '<', '<'
1000
966
  end
1001
- return '>', '>'
1002
- end
1003
967
 
1004
- elsif scanner.scan(/->/)
1005
- @lex_state = :expr_arg
1006
- @start_of_lambda = true
1007
- return [:LAMBDA, scanner.matched]
968
+ elsif scanner.check(/\>/)
969
+ if scanner.scan(/\>\>\=/)
970
+ return :OP_ASGN, '>>'
971
+ elsif scanner.scan(/\>\>/)
972
+ return '>>', '>>'
973
+ elsif scanner.scan(/\>\=/)
974
+ if @lex_state == :expr_fname
975
+ @lex_state = :expr_end
976
+ else
977
+ @lex_state = :expr_beg
978
+ end
979
+ return '>=', scanner.matched
980
+ elsif scanner.scan(/\>/)
981
+ if @lex_state == :expr_fname
982
+ @lex_state = :expr_end
983
+ else
984
+ @lex_state = :expr_beg
985
+ end
986
+ return '>', '>'
987
+ end
1008
988
 
1009
- elsif scanner.scan(/[+-]/)
1010
- result = scanner.matched
1011
- sign = result + '@'
989
+ elsif scanner.scan(/->/)
990
+ @lex_state = :expr_arg
991
+ @start_of_lambda = true
992
+ return [:LAMBDA, scanner.matched]
1012
993
 
1013
- if @lex_state == :expr_beg || @lex_state == :expr_mid
1014
- @lex_state = :expr_mid
1015
- return [sign, sign]
1016
- elsif @lex_state == :expr_fname
1017
- @lex_state = :expr_end
1018
- return [:IDENTIFIER, result + scanner.matched] if scanner.scan(/@/)
1019
- return [result, result]
1020
- end
994
+ elsif scanner.scan(/[+-]/)
995
+ result = scanner.matched
996
+ sign = result + '@'
997
+
998
+ if @lex_state == :expr_beg || @lex_state == :expr_mid
999
+ @lex_state = :expr_mid
1000
+ return [sign, sign]
1001
+ elsif @lex_state == :expr_fname
1002
+ @lex_state = :expr_end
1003
+ return [:IDENTIFIER, result + scanner.matched] if scanner.scan(/@/)
1004
+ return [result, result]
1005
+ end
1006
+
1007
+ if scanner.scan(/\=/)
1008
+ @lex_state = :expr_beg
1009
+ return [:OP_ASGN, result]
1010
+ end
1021
1011
 
1022
- if scanner.scan(/\=/)
1023
1012
  @lex_state = :expr_beg
1024
- return [:OP_ASGN, result]
1025
- end
1013
+ return [result, result]
1026
1014
 
1027
- @lex_state = :expr_beg
1028
- return [result, result]
1015
+ elsif scanner.scan(/\?/)
1016
+ # FIXME: :expr_arg shouldnt really be here
1017
+ if [:expr_end, :expr_endarg, :expr_arg].include?(@lex_state)
1018
+ @lex_state = :expr_beg
1019
+ return '?', scanner.matched
1020
+ end
1029
1021
 
1030
- elsif scanner.scan(/\?/)
1031
- # FIXME: :expr_arg shouldnt really be here
1032
- if [:expr_end, :expr_endarg, :expr_arg].include?(@lex_state)
1022
+ #if scanner.scan(/\\/)
1023
+ #c = if scanner.scan(/n/)
1024
+ #"\n"
1025
+ #else
1026
+ #scanner.scan(/./)
1027
+ #scanner.matched
1028
+ #end
1029
+ #else
1030
+ #c = scanner.scan(/./)
1031
+ #end
1032
+
1033
+ #@lex_state = :expr_end
1034
+ #return :STRING, c
1033
1035
  @lex_state = :expr_beg
1034
1036
  return '?', scanner.matched
1035
- end
1036
1037
 
1037
- #if scanner.scan(/\\/)
1038
- #c = if scanner.scan(/n/)
1039
- #"\n"
1040
- #else
1041
- #scanner.scan(/./)
1042
- #scanner.matched
1043
- #end
1044
- #else
1045
- #c = scanner.scan(/./)
1046
- #end
1047
-
1048
- #@lex_state = :expr_end
1049
- #return :STRING, c
1050
- @lex_state = :expr_beg
1051
- return '?', scanner.matched
1052
-
1053
- elsif scanner.scan(/\=\=\=/)
1054
- if @lex_state == :expr_fname
1055
- @lex_state = :expr_end
1038
+ elsif scanner.scan(/\=\=\=/)
1039
+ if @lex_state == :expr_fname
1040
+ @lex_state = :expr_end
1041
+ return '===', '==='
1042
+ end
1043
+ @lex_state = :expr_beg
1056
1044
  return '===', '==='
1057
- end
1058
- @lex_state = :expr_beg
1059
- return '===', '==='
1060
1045
 
1061
- elsif scanner.scan(/\=\=/)
1062
- if @lex_state == :expr_fname
1063
- @lex_state = :expr_end
1046
+ elsif scanner.scan(/\=\=/)
1047
+ if @lex_state == :expr_fname
1048
+ @lex_state = :expr_end
1049
+ return '==', '=='
1050
+ end
1051
+ @lex_state = :expr_beg
1064
1052
  return '==', '=='
1065
- end
1066
- @lex_state = :expr_beg
1067
- return '==', '=='
1068
1053
 
1069
- elsif scanner.scan(/\=\~/)
1070
- if @lex_state == :expr_fname
1071
- @lex_state = :expr_end
1054
+ elsif scanner.scan(/\=\~/)
1055
+ if @lex_state == :expr_fname
1056
+ @lex_state = :expr_end
1057
+ return '=~', '=~'
1058
+ end
1059
+ @lex_state = :expr_beg
1072
1060
  return '=~', '=~'
1073
- end
1074
- @lex_state = :expr_beg
1075
- return '=~', '=~'
1076
1061
 
1077
- elsif scanner.scan(/\=\>/)
1078
- @lex_state = :expr_beg
1079
- return '=>', '=>'
1062
+ elsif scanner.scan(/\=\>/)
1063
+ @lex_state = :expr_beg
1064
+ return '=>', '=>'
1080
1065
 
1081
- elsif scanner.scan(/\=/)
1082
- @lex_state = :expr_beg
1083
- return '=', '='
1066
+ elsif scanner.scan(/\=/)
1067
+ @lex_state = :expr_beg
1068
+ return '=', '='
1084
1069
 
1085
- elsif scanner.scan(/\!\=/)
1086
- if @lex_state == :expr_fname
1087
- @lex_state == :expr_end
1070
+ elsif scanner.scan(/\!\=/)
1071
+ if @lex_state == :expr_fname
1072
+ @lex_state == :expr_end
1073
+ return '!=', '!='
1074
+ end
1075
+ @lex_state = :expr_beg
1088
1076
  return '!=', '!='
1089
- end
1090
- @lex_state = :expr_beg
1091
- return '!=', '!='
1092
1077
 
1093
- elsif scanner.scan(/\!\~/)
1094
- @lex_state = :expr_beg
1095
- return '!~', '!~'
1078
+ elsif scanner.scan(/\!\~/)
1079
+ @lex_state = :expr_beg
1080
+ return '!~', '!~'
1096
1081
 
1097
- elsif scanner.scan(/\!/)
1098
- if @lex_state == :expr_fname
1099
- @lex_state = :expr_end
1082
+ elsif scanner.scan(/\!/)
1083
+ if @lex_state == :expr_fname
1084
+ @lex_state = :expr_end
1085
+ return '!', '!'
1086
+ end
1087
+ @lex_state = :expr_beg
1100
1088
  return '!', '!'
1101
- end
1102
- @lex_state = :expr_beg
1103
- return '!', '!'
1104
1089
 
1105
- elsif scanner.scan(/\~/)
1106
- if @lex_state == :expr_fname
1107
- @lex_state = :expr_end
1090
+ elsif scanner.scan(/\~/)
1091
+ if @lex_state == :expr_fname
1092
+ @lex_state = :expr_end
1093
+ return '~', '~'
1094
+ end
1095
+ @lex_state = :expr_beg
1108
1096
  return '~', '~'
1109
- end
1110
- @lex_state = :expr_beg
1111
- return '~', '~'
1112
-
1113
- elsif scanner.scan(/\$[\+\'\`\&!@\"~*$?\/\\:;=.,<>_]/)
1114
- @lex_state = :expr_end
1115
- return :GVAR, scanner.matched
1116
1097
 
1117
- elsif scanner.scan(/\$\w+/)
1118
- @lex_state = :expr_end
1119
- return :GVAR, scanner.matched
1098
+ elsif scanner.scan(/\$[\+\'\`\&!@\"~*$?\/\\:;=.,<>_]/)
1099
+ @lex_state = :expr_end
1100
+ return :GVAR, scanner.matched
1120
1101
 
1121
- elsif scanner.scan(/\@\@\w*/)
1122
- @lex_state = :expr_end
1123
- return :CVAR, scanner.matched
1102
+ elsif scanner.scan(/\$\w+/)
1103
+ @lex_state = :expr_end
1104
+ return :GVAR, scanner.matched
1124
1105
 
1125
- elsif scanner.scan(/\@\w*/)
1126
- @lex_state = :expr_end
1127
- return :IVAR, scanner.matched
1106
+ elsif scanner.scan(/\@\@\w*/)
1107
+ @lex_state = :expr_end
1108
+ return :CVAR, scanner.matched
1128
1109
 
1129
- elsif scanner.scan(/\,/)
1130
- @lex_state = :expr_beg
1131
- return ',', scanner.matched
1110
+ elsif scanner.scan(/\@\w*/)
1111
+ @lex_state = :expr_end
1112
+ return :IVAR, scanner.matched
1132
1113
 
1133
- elsif scanner.scan(/\{/)
1134
- if @start_of_lambda
1135
- @start_of_lambda = false
1114
+ elsif scanner.scan(/\,/)
1136
1115
  @lex_state = :expr_beg
1137
- return [:LAMBEG, scanner.matched]
1116
+ return ',', scanner.matched
1138
1117
 
1139
- elsif [:expr_end, :expr_arg, :expr_cmdarg].include? @lex_state
1140
- result = :LCURLY
1141
- elsif @lex_state == :expr_endarg
1142
- result = :LBRACE_ARG
1143
- else
1144
- result = '{'
1145
- end
1118
+ elsif scanner.scan(/\{/)
1119
+ if @start_of_lambda
1120
+ @start_of_lambda = false
1121
+ @lex_state = :expr_beg
1122
+ return [:LAMBEG, scanner.matched]
1146
1123
 
1147
- @lex_state = :expr_beg
1148
- cond_push 0
1149
- cmdarg_push 0
1150
- return result, scanner.matched
1151
-
1152
- elsif scanner.check(/[0-9]/)
1153
- @lex_state = :expr_end
1154
- if scanner.scan(/[\d_]+\.[\d_]+\b/)
1155
- return [:FLOAT, scanner.matched.gsub(/_/, '').to_f]
1156
- elsif scanner.scan(/[\d_]+\b/)
1157
- return [:INTEGER, scanner.matched.gsub(/_/, '').to_i]
1158
- elsif scanner.scan(/0(x|X)(\d|[a-f]|[A-F])+/)
1159
- return [:INTEGER, scanner.matched.to_i]
1160
- else
1161
- raise "Lexing error on numeric type: `#{scanner.peek 5}`"
1162
- end
1124
+ elsif [:expr_end, :expr_arg, :expr_cmdarg].include? @lex_state
1125
+ result = :LCURLY
1126
+ elsif @lex_state == :expr_endarg
1127
+ result = :LBRACE_ARG
1128
+ else
1129
+ result = '{'
1130
+ end
1163
1131
 
1164
- elsif scanner.scan(/(\w)+[\?\!]?/)
1165
- matched = scanner.matched
1166
- if scanner.peek(2) != '::' && scanner.scan(/:/)
1167
1132
  @lex_state = :expr_beg
1168
- return :LABEL, "#{matched}"
1169
- end
1133
+ cond_push 0
1134
+ cmdarg_push 0
1135
+ return result, scanner.matched
1170
1136
 
1171
- case matched
1172
- when 'class'
1173
- if @lex_state == :expr_dot
1174
- @lex_state = :expr_end
1175
- return :IDENTIFIER, matched
1137
+ elsif scanner.check(/[0-9]/)
1138
+ @lex_state = :expr_end
1139
+ if scanner.scan(/[\d_]+\.[\d_]+\b/)
1140
+ return [:FLOAT, scanner.matched.gsub(/_/, '').to_f]
1141
+ elsif scanner.scan(/[\d_]+\b/)
1142
+ return [:INTEGER, scanner.matched.gsub(/_/, '').to_i]
1143
+ elsif scanner.scan(/0(x|X)(\d|[a-f]|[A-F])+/)
1144
+ return [:INTEGER, scanner.matched.to_i]
1145
+ else
1146
+ raise "Lexing error on numeric type: `#{scanner.peek 5}`"
1176
1147
  end
1177
- @lex_state = :expr_class
1178
- return :CLASS, matched
1179
-
1180
- when 'module'
1181
- return :IDENTIFIER, matched if @lex_state == :expr_dot
1182
- @lex_state = :expr_class
1183
- return :MODULE, matched
1184
1148
 
1185
- when 'defined?'
1186
- return :IDENTIFIER, matched if @lex_state == :expr_dot
1187
- @lex_state = :expr_arg
1188
- return :DEFINED, 'defined?'
1189
-
1190
- when 'def'
1191
- @lex_state = :expr_fname
1192
- @scope_line = @line
1193
- return :DEF, matched
1149
+ elsif scanner.scan(/(\w)+[\?\!]?/)
1150
+ matched = scanner.matched
1151
+ if scanner.peek(2) != '::' && scanner.scan(/:/)
1152
+ @lex_state = :expr_beg
1153
+ return :LABEL, "#{matched}"
1154
+ end
1194
1155
 
1195
- when 'undef'
1196
- @lex_state = :expr_fname
1197
- return :UNDEF, matched
1156
+ case matched
1157
+ when 'class'
1158
+ if @lex_state == :expr_dot
1159
+ @lex_state = :expr_end
1160
+ return :IDENTIFIER, matched
1161
+ end
1162
+ @lex_state = :expr_class
1163
+ return :CLASS, matched
1164
+
1165
+ when 'module'
1166
+ return :IDENTIFIER, matched if @lex_state == :expr_dot
1167
+ @lex_state = :expr_class
1168
+ return :MODULE, matched
1169
+
1170
+ when 'defined?'
1171
+ return :IDENTIFIER, matched if @lex_state == :expr_dot
1172
+ @lex_state = :expr_arg
1173
+ return :DEFINED, 'defined?'
1174
+
1175
+ when 'def'
1176
+ @lex_state = :expr_fname
1177
+ @scope_line = @line
1178
+ return :DEF, matched
1179
+
1180
+ when 'undef'
1181
+ @lex_state = :expr_fname
1182
+ return :UNDEF, matched
1183
+
1184
+ when 'end'
1185
+ if [:expr_dot, :expr_fname].include? @lex_state
1186
+ @lex_state = :expr_end
1187
+ return :IDENTIFIER, matched
1188
+ end
1198
1189
 
1199
- when 'end'
1200
- if [:expr_dot, :expr_fname].include? @lex_state
1201
1190
  @lex_state = :expr_end
1202
- return :IDENTIFIER, matched
1203
- end
1204
-
1205
- @lex_state = :expr_end
1206
- return :END, matched
1191
+ return :END, matched
1192
+
1193
+ when 'do'
1194
+ #puts cond?
1195
+ #puts cmdarg?
1196
+ #nputs @lex_state
1197
+ if @start_of_lambda
1198
+ @start_of_lambda = false
1199
+ @lex_state = :expr_beg
1200
+ return [:DO_LAMBDA, scanner.matched]
1201
+ elsif cond?
1202
+ @lex_state = :expr_beg
1203
+ return :DO_COND, matched
1204
+ elsif cmdarg? && @lex_state != :expr_cmdarg
1205
+ @lex_state = :expr_beg
1206
+ return :DO_BLOCK, matched
1207
+ elsif @lex_state == :expr_endarg
1208
+ return :DO_BLOCK, matched
1209
+ else
1210
+ @lex_state = :expr_beg
1211
+ return :DO, matched
1212
+ end
1207
1213
 
1208
- when 'do'
1209
- #puts cond?
1210
- #puts cmdarg?
1211
- #nputs @lex_state
1212
- if @start_of_lambda
1213
- @start_of_lambda = false
1214
- @lex_state = :expr_beg
1215
- return [:DO_LAMBDA, scanner.matched]
1216
- elsif cond?
1217
- @lex_state = :expr_beg
1218
- return :DO_COND, matched
1219
- elsif cmdarg? && @lex_state != :expr_cmdarg
1220
- @lex_state = :expr_beg
1221
- return :DO_BLOCK, matched
1222
- elsif @lex_state == :expr_endarg
1223
- return :DO_BLOCK, matched
1224
- else
1214
+ when 'if'
1215
+ return :IF, matched if @lex_state == :expr_beg
1225
1216
  @lex_state = :expr_beg
1226
- return :DO, matched
1227
- end
1217
+ return :IF_MOD, matched
1228
1218
 
1229
- when 'if'
1230
- return :IF, matched if @lex_state == :expr_beg
1231
- @lex_state = :expr_beg
1232
- return :IF_MOD, matched
1219
+ when 'unless'
1220
+ return :UNLESS, matched if @lex_state == :expr_beg
1221
+ @lex_state = :expr_beg
1222
+ return :UNLESS_MOD, matched
1233
1223
 
1234
- when 'unless'
1235
- return :UNLESS, matched if @lex_state == :expr_beg
1236
- @lex_state = :expr_beg
1237
- return :UNLESS_MOD, matched
1224
+ when 'else'
1225
+ return :ELSE, matched
1238
1226
 
1239
- when 'else'
1240
- return :ELSE, matched
1227
+ when 'elsif'
1228
+ return :ELSIF, matched
1241
1229
 
1242
- when 'elsif'
1243
- return :ELSIF, matched
1230
+ when 'self'
1231
+ @lex_state = :expr_end unless @lex_state == :expr_fname
1232
+ return :SELF, matched
1244
1233
 
1245
- when 'self'
1246
- @lex_state = :expr_end unless @lex_state == :expr_fname
1247
- return :SELF, matched
1234
+ when 'true'
1235
+ @lex_state = :expr_end
1236
+ return :TRUE, matched
1248
1237
 
1249
- when 'true'
1250
- @lex_state = :expr_end
1251
- return :TRUE, matched
1238
+ when 'false'
1239
+ @lex_state = :expr_end
1240
+ return :FALSE, matched
1252
1241
 
1253
- when 'false'
1254
- @lex_state = :expr_end
1255
- return :FALSE, matched
1242
+ when 'nil'
1243
+ @lex_state = :expr_end
1244
+ return :NIL, matched
1256
1245
 
1257
- when 'nil'
1258
- @lex_state = :expr_end
1259
- return :NIL, matched
1246
+ when '__LINE__'
1247
+ @lex_state = :expr_end
1248
+ return :LINE, @line.to_s
1260
1249
 
1261
- when '__LINE__'
1262
- @lex_state = :expr_end
1263
- return :LINE, @line.to_s
1250
+ when '__FILE__'
1251
+ @lex_state = :expr_end
1252
+ return :FILE, matched
1264
1253
 
1265
- when '__FILE__'
1266
- @lex_state = :expr_end
1267
- return :FILE, matched
1254
+ when 'begin'
1255
+ if [:expr_dot, :expr_fname].include? @lex_state
1256
+ @lex_state = :expr_end
1257
+ return :IDENTIFIER, matched
1258
+ end
1259
+ @lex_state = :expr_beg
1260
+ return :BEGIN, matched
1268
1261
 
1269
- when 'begin'
1270
- if [:expr_dot, :expr_fname].include? @lex_state
1271
- @lex_state = :expr_end
1272
- return :IDENTIFIER, matched
1273
- end
1274
- @lex_state = :expr_beg
1275
- return :BEGIN, matched
1262
+ when 'rescue'
1263
+ return :IDENTIFIER, matched if [:expr_dot, :expr_fname].include? @lex_state
1264
+ return :RESCUE, matched if @lex_state == :expr_beg
1265
+ @lex_state = :expr_beg
1266
+ return :RESCUE_MOD, matched
1276
1267
 
1277
- when 'rescue'
1278
- return :IDENTIFIER, matched if [:expr_dot, :expr_fname].include? @lex_state
1279
- return :RESCUE, matched if @lex_state == :expr_beg
1280
- @lex_state = :expr_beg
1281
- return :RESCUE_MOD, matched
1268
+ when 'ensure'
1269
+ @lex_state = :expr_beg
1270
+ return :ENSURE, matched
1282
1271
 
1283
- when 'ensure'
1284
- @lex_state = :expr_beg
1285
- return :ENSURE, matched
1272
+ when 'case'
1273
+ @lex_state = :expr_beg
1274
+ return :CASE, matched
1286
1275
 
1287
- when 'case'
1288
- @lex_state = :expr_beg
1289
- return :CASE, matched
1276
+ when 'when'
1277
+ @lex_state = :expr_beg
1278
+ return :WHEN, matched
1290
1279
 
1291
- when 'when'
1292
- @lex_state = :expr_beg
1293
- return :WHEN, matched
1280
+ when 'or'
1281
+ @lex_state = :expr_beg
1282
+ return :OR, matched
1294
1283
 
1295
- when 'or'
1296
- @lex_state = :expr_beg
1297
- return :OR, matched
1284
+ when 'and'
1285
+ @lex_state = :expr_beg
1286
+ return :AND, matched
1298
1287
 
1299
- when 'and'
1300
- @lex_state = :expr_beg
1301
- return :AND, matched
1288
+ when 'not'
1289
+ @lex_state = :expr_beg
1290
+ return :NOT, matched
1302
1291
 
1303
- when 'not'
1304
- @lex_state = :expr_beg
1305
- return :NOT, matched
1292
+ when 'return'
1293
+ @lex_state = :expr_mid
1294
+ return :RETURN, matched
1306
1295
 
1307
- when 'return'
1308
- @lex_state = :expr_mid
1309
- return :RETURN, matched
1296
+ when 'next'
1297
+ if @lex_state == :expr_dot || @lex_state == :expr_fname
1298
+ @lex_state = :expr_end
1299
+ return :IDENTIFIER, matched
1300
+ end
1310
1301
 
1311
- when 'next'
1312
- if @lex_state == :expr_dot || @lex_state == :expr_fname
1313
- @lex_state = :expr_end
1314
- return :IDENTIFIER, matched
1315
- end
1302
+ @lex_state = :expr_mid
1303
+ return :NEXT, matched
1316
1304
 
1317
- @lex_state = :expr_mid
1318
- return :NEXT, matched
1305
+ when 'redo'
1306
+ if @lex_state == :expr_dot || @lex_state == :expr_fname
1307
+ @lex_state = :expr_end
1308
+ return :IDENTIFIER, matched
1309
+ end
1319
1310
 
1320
- when 'redo'
1321
- if @lex_state == :expr_dot || @lex_state == :expr_fname
1322
- @lex_state = :expr_end
1323
- return :IDENTIFIER, matched
1324
- end
1311
+ @lex_state = :expr_mid
1312
+ return :REDO, matched
1325
1313
 
1326
- @lex_state = :expr_mid
1327
- return :REDO, matched
1314
+ when 'break'
1315
+ @lex_state = :expr_mid
1316
+ return :BREAK, matched
1328
1317
 
1329
- when 'break'
1330
- @lex_state = :expr_mid
1331
- return :BREAK, matched
1318
+ when 'super'
1319
+ @lex_state = :expr_arg
1320
+ return :SUPER, matched
1332
1321
 
1333
- when 'super'
1334
- @lex_state = :expr_arg
1335
- return :SUPER, matched
1322
+ when 'then'
1323
+ return :THEN, matched
1336
1324
 
1337
- when 'then'
1338
- return :THEN, matched
1325
+ when 'while'
1326
+ return :WHILE, matched if @lex_state == :expr_beg
1327
+ @lex_state = :expr_beg
1328
+ return :WHILE_MOD, matched
1339
1329
 
1340
- when 'while'
1341
- return :WHILE, matched if @lex_state == :expr_beg
1342
- @lex_state = :expr_beg
1343
- return :WHILE_MOD, matched
1330
+ when 'until'
1331
+ return :UNTIL, matched if @lex_state == :expr_beg
1332
+ @lex_state = :expr_beg
1333
+ return :UNTIL_MOD, matched
1344
1334
 
1345
- when 'until'
1346
- return :UNTIL, matched if @lex_state == :expr_beg
1347
- @lex_state = :expr_beg
1348
- return :UNTIL_MOD, matched
1335
+ when 'yield'
1336
+ @lex_state = :expr_arg
1337
+ return :YIELD, matched
1349
1338
 
1350
- when 'yield'
1351
- @lex_state = :expr_arg
1352
- return :YIELD, matched
1339
+ when 'alias'
1340
+ @lex_state = :expr_fname
1341
+ return :ALIAS, matched
1342
+ end
1353
1343
 
1354
- when 'alias'
1355
- @lex_state = :expr_fname
1356
- return :ALIAS, matched
1357
- end
1344
+ matched = matched
1345
+ if scanner.peek(2) != '::' && scanner.scan(/\:/)
1346
+ return :LABEL, matched
1347
+ end
1358
1348
 
1359
- matched = matched
1360
- if scanner.peek(2) != '::' && scanner.scan(/\:/)
1361
- return :LABEL, matched
1362
- end
1349
+ if @lex_state == :expr_fname
1350
+ if scanner.scan(/\=/)
1351
+ @lex_state = :expr_end
1352
+ return :IDENTIFIER, matched + scanner.matched
1353
+ end
1354
+ end
1363
1355
 
1364
- if @lex_state == :expr_fname
1365
- if scanner.scan(/\=/)
1356
+ if [:expr_beg, :expr_dot, :expr_mid, :expr_arg, :expr_cmdarg].include? @lex_state
1357
+ # old:
1358
+ #@lex_state = :expr_cmdarg
1359
+ # new:
1360
+ @lex_state = cmd_start ? :expr_cmdarg : :expr_arg
1361
+ else
1366
1362
  @lex_state = :expr_end
1367
- return :IDENTIFIER, matched + scanner.matched
1368
1363
  end
1369
- end
1370
1364
 
1371
- if [:expr_beg, :expr_dot, :expr_mid, :expr_arg, :expr_cmdarg].include? @lex_state
1372
- # old:
1373
- #@lex_state = :expr_cmdarg
1374
- # new:
1375
- @lex_state = cmd_start ? :expr_cmdarg : :expr_arg
1376
- else
1377
- @lex_state = :expr_end
1378
- end
1365
+ return [matched =~ /[A-Z]/ ? :CONSTANT : :IDENTIFIER, matched]
1379
1366
 
1380
- return [matched =~ /[A-Z]/ ? :CONSTANT : :IDENTIFIER, matched]
1367
+ end
1368
+ return [false, false] if scanner.eos?
1381
1369
 
1370
+ raise OpalParseError, "Unexpected content in parsing stream `#{scanner.peek 5}`"
1382
1371
  end
1383
- return [false, false] if scanner.eos?
1384
-
1385
- raise OpalParseError, "Unexpected content in parsing stream `#{scanner.peek 5}`"
1386
1372
  end
1387
1373
  end
1388
1374
  end
1389
- end