opal 0.3.26 → 0.3.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -6
- data/.travis.yml +1 -4
- data/Gemfile +1 -1
- data/README.md +3 -8
- data/Rakefile +26 -3
- data/core/array.rb +33 -91
- data/core/boolean.rb +1 -4
- data/core/class.rb +25 -71
- data/core/error.rb +5 -3
- data/core/hash.rb +3 -2
- data/core/kernel.rb +40 -1
- data/core/load_order +1 -1
- data/core/nil_class.rb +1 -3
- data/core/runtime.js +4 -44
- data/core/template.rb +20 -0
- data/core/{opal-spec → test_runner}/runner.js +0 -6
- data/lib/opal.rb +1 -12
- data/lib/opal/builder.rb +3 -10
- data/lib/opal/lexer.rb +1095 -1110
- data/lib/opal/parser.rb +229 -26
- data/lib/opal/rake_task.rb +3 -3
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +2 -2
- data/spec/core/array/assoc_spec.rb +2 -3
- data/spec/core/array/comparison_spec.rb +16 -0
- data/spec/core/array/constructor_spec.rb +0 -9
- data/spec/core/array/drop_spec.rb +21 -0
- data/spec/core/array/dup_spec.rb +15 -0
- data/spec/core/array/{eql_spec.rb → equal_value_spec.rb} +0 -0
- data/spec/core/array/index_spec.rb +26 -0
- data/spec/core/array/inspect_spec.rb +13 -0
- data/spec/core/array/intersection_spec.rb +22 -0
- data/spec/core/array/join_spec.rb +9 -0
- data/spec/core/array/keep_if_spec.rb +7 -0
- data/spec/core/array/minus_spec.rb +19 -9
- data/spec/core/array/multiply_spec.rb +13 -0
- data/spec/core/array/new_spec.rb +40 -0
- data/spec/core/array/rindex_spec.rb +21 -0
- data/spec/core/array/select_spec.rb +13 -0
- data/spec/core/array/shift_spec.rb +51 -0
- data/spec/core/array/slice_spec.rb +37 -0
- data/spec/core/array/take_spec.rb +21 -0
- data/spec/core/array/take_while_spec.rb +13 -0
- data/spec/core/array/to_a_spec.rb +7 -0
- data/spec/core/array/unshift_spec.rb +29 -0
- data/spec/core/hash/constructor_spec.rb +13 -0
- data/spec/core/hash/default_proc_spec.rb +20 -0
- data/spec/core/hash/default_spec.rb +8 -0
- data/spec/core/hash/delete_spec.rb +11 -0
- data/spec/core/hash/dup_spec.rb +10 -0
- data/spec/core/hash/reject_spec.rb +18 -0
- data/spec/core/hash/to_a_spec.rb +13 -0
- data/spec/core/kernel/Array_spec.rb +10 -0
- data/spec/core/kernel/class_spec.rb +6 -0
- data/spec/core/kernel/equal_spec.rb +12 -0
- data/spec/core/kernel/extend_spec.rb +21 -0
- data/spec/core/kernel/instance_eval_spec.rb +28 -0
- data/spec/core/kernel/instance_variable_get_spec.rb +14 -0
- data/spec/core/kernel/instance_variable_set_spec.rb +10 -0
- data/spec/core/kernel/match_spec.rb +5 -0
- data/spec/core/module/alias_method_spec.rb +10 -0
- data/spec/core/module/ancestors_spec.rb +11 -0
- data/spec/core/module/append_features_spec.rb +14 -0
- data/spec/core/proc/call_spec.rb +21 -0
- data/spec/core/proc/proc_tricks_spec.rb +1 -1
- data/spec/language/alias_spec.rb +1 -1
- data/spec/opal/class/instance_methods_spec.rb +13 -0
- data/spec/opal/kernel/attribute_spec.rb +57 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/test_case.html +13 -0
- metadata +88 -12
- data/core/erb.rb +0 -32
- data/lib/opal/erb_parser.rb +0 -20
- 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
|
-
|
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 =
|
169
|
+
result = result[1];
|
170
170
|
|
171
171
|
delete map[key];
|
172
|
+
return result;
|
172
173
|
}
|
173
174
|
|
174
|
-
return
|
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
data/core/nil_class.rb
CHANGED
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(
|
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 =
|
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
|
-
|
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
|
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
|
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
|
-
|
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, '**/*.
|
34
|
-
elsif
|
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
|
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
|
-
|
17
|
+
attr_reader :line
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
def initialize
|
20
|
+
@lex_state = :expr_beg
|
21
|
+
@cond = 0
|
22
|
+
@cmdarg = 0
|
23
|
+
@line = 1
|
24
|
+
@scopes = []
|
25
25
|
|
26
|
-
|
27
|
-
|
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
|
-
|
46
|
-
|
47
|
-
|
29
|
+
def s(*parts)
|
30
|
+
sexp = Sexp.new(parts)
|
31
|
+
sexp.line = @line
|
32
|
+
sexp
|
33
|
+
end
|
48
34
|
|
49
|
-
|
50
|
-
|
51
|
-
|
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
|
-
|
54
|
-
@block = type == :block
|
55
|
-
@locals = []
|
56
|
-
@parent = nil
|
42
|
+
result
|
57
43
|
end
|
58
44
|
|
59
|
-
def
|
60
|
-
|
45
|
+
def on_error(t, val, vstack)
|
46
|
+
raise OpalParseError, "parse error on value #{val.inspect} (line #{@line})"
|
61
47
|
end
|
62
48
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
false
|
67
|
-
end
|
68
|
-
end
|
49
|
+
class LexerScope
|
50
|
+
attr_reader :locals
|
51
|
+
attr_accessor :parent
|
69
52
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
@scope = scope
|
76
|
-
end
|
53
|
+
def initialize(type)
|
54
|
+
@block = type == :block
|
55
|
+
@locals = []
|
56
|
+
@parent = nil
|
57
|
+
end
|
77
58
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
59
|
+
def add_local(local)
|
60
|
+
@locals << local
|
61
|
+
end
|
82
62
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
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
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
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
|
-
|
101
|
-
|
78
|
+
def pop_scope
|
79
|
+
@scopes.pop
|
80
|
+
@scope = @scopes.last
|
81
|
+
end
|
102
82
|
|
103
|
-
|
104
|
-
|
105
|
-
s
|
83
|
+
def new_block(stmt = nil)
|
84
|
+
s = s(:block)
|
85
|
+
s << stmt if stmt
|
86
|
+
s
|
106
87
|
end
|
107
88
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
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
|
-
|
115
|
-
s = s(:
|
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
|
-
|
119
|
-
|
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
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
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
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
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
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
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
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
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
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
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
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
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
|
-
|
174
|
-
|
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
|
-
|
181
|
-
|
175
|
+
if norm
|
176
|
+
norm.each do |arg|
|
177
|
+
@scope.add_local arg
|
178
|
+
res << arg
|
179
|
+
end
|
180
|
+
end
|
182
181
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
182
|
+
if opt
|
183
|
+
opt[1..-1].each do |_opt|
|
184
|
+
res << _opt[1]
|
185
|
+
end
|
187
186
|
end
|
188
|
-
end
|
189
187
|
|
190
|
-
|
191
|
-
|
192
|
-
|
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
|
-
|
197
|
-
|
198
|
-
|
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
|
-
|
208
|
-
|
209
|
-
|
204
|
+
res << opt if opt
|
205
|
+
|
206
|
+
res
|
210
207
|
end
|
211
208
|
|
212
|
-
|
209
|
+
def new_block_args(norm, opt, rest, block)
|
210
|
+
res = s(:array)
|
213
211
|
|
214
|
-
|
215
|
-
|
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
|
-
|
218
|
-
|
219
|
+
if opt
|
220
|
+
opt[1..-1].each do |_opt|
|
221
|
+
res << s(:lasgn, _opt[1])
|
222
|
+
end
|
223
|
+
end
|
219
224
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
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
|
-
|
228
|
-
|
229
|
-
res << s(:lasgn,
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
248
|
-
|
248
|
+
if recv
|
249
|
+
call.line = recv.line
|
250
|
+
elsif args[1]
|
251
|
+
call.line = args[1].line
|
252
|
+
end
|
249
253
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
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
|
-
|
257
|
-
call.line = recv.line
|
258
|
-
elsif args[1]
|
259
|
-
call.line = args[1].line
|
261
|
+
call
|
260
262
|
end
|
261
263
|
|
262
|
-
|
263
|
-
|
264
|
-
|
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
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
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
|
-
|
278
|
-
|
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
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
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
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
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
|
-
|
326
|
-
|
317
|
+
ref
|
318
|
+
end
|
327
319
|
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
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
|
-
|
343
|
-
|
344
|
-
|
334
|
+
res.line = ref.line
|
335
|
+
res
|
336
|
+
end
|
345
337
|
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
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
|
-
|
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
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
363
|
+
def new_super(args)
|
364
|
+
args = (args || s(:arglist))[1..-1]
|
365
|
+
s(:super, *args)
|
366
|
+
end
|
380
367
|
|
381
|
-
|
382
|
-
|
383
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
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
|
-
|
437
|
-
|
438
|
-
|
428
|
+
def str_append(str, str2)
|
429
|
+
return str2 unless str
|
430
|
+
return str unless str2
|
439
431
|
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
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
|
-
|
452
|
-
|
453
|
-
|
454
|
-
t
|
455
|
-
end
|
443
|
+
def cond_push(n)
|
444
|
+
@cond = (@cond << 1) | (n & 1)
|
445
|
+
end
|
456
446
|
|
457
|
-
|
458
|
-
|
459
|
-
|
447
|
+
def cond_pop
|
448
|
+
@cond = @cond >> 1
|
449
|
+
end
|
460
450
|
|
461
|
-
|
462
|
-
|
463
|
-
|
451
|
+
def cond_lexpop
|
452
|
+
@cond = (@cond >> 1) | (@cond & 1)
|
453
|
+
end
|
464
454
|
|
465
|
-
|
466
|
-
|
467
|
-
|
455
|
+
def cond?
|
456
|
+
(@cond & 1) != 0
|
457
|
+
end
|
468
458
|
|
469
|
-
|
470
|
-
|
471
|
-
|
459
|
+
def cmdarg_push(n)
|
460
|
+
@cmdarg = (@cmdarg << 1) | (n & 1)
|
461
|
+
end
|
472
462
|
|
473
|
-
|
474
|
-
|
475
|
-
|
463
|
+
def cmdarg_pop
|
464
|
+
@cmdarg = @cmdarg >> 1
|
465
|
+
end
|
476
466
|
|
477
|
-
|
478
|
-
|
479
|
-
|
467
|
+
def cmdarg_lexpop
|
468
|
+
@cmdarg = (@cmdarg >> 1) | (@cmdarg & 1)
|
469
|
+
end
|
480
470
|
|
481
|
-
|
482
|
-
|
483
|
-
|
471
|
+
def cmdarg?
|
472
|
+
(@cmdarg & 1) != 0
|
473
|
+
end
|
484
474
|
|
485
|
-
|
486
|
-
|
487
|
-
|
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
|
-
|
490
|
-
|
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
|
-
|
496
|
-
interpolate = str_parse[:interpolate]
|
484
|
+
words = ['w', 'W'].include? str_parse[:beg]
|
497
485
|
|
498
|
-
|
486
|
+
space = true if ['w', 'W'].include?(str_parse[:beg]) and scanner.scan(/\s+/)
|
499
487
|
|
500
|
-
|
488
|
+
# if not end of string, so we must be parsing contents
|
489
|
+
str_buffer = []
|
501
490
|
|
502
|
-
|
503
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
536
|
-
|
537
|
-
|
521
|
+
elsif str_parse[:beg] == '`'
|
522
|
+
@lex_state = :expr_end
|
523
|
+
return :STRING_END, scanner.matched
|
538
524
|
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
525
|
+
elsif str_parse[:beg] == '/'
|
526
|
+
result = scanner.scan(/\w+/)
|
527
|
+
@lex_state = :expr_end
|
528
|
+
return :REGEXP_END, result
|
543
529
|
|
544
|
-
|
545
|
-
|
546
|
-
|
530
|
+
else
|
531
|
+
@lex_state = :expr_end
|
532
|
+
return :STRING_END, scanner.matched
|
533
|
+
end
|
547
534
|
end
|
548
|
-
end
|
549
535
|
|
550
|
-
|
536
|
+
return :SPACE, ' ' if space
|
551
537
|
|
552
|
-
|
553
|
-
|
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
|
-
|
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
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
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
|
-
|
573
|
-
|
574
|
-
|
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
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
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
|
-
|
584
|
-
|
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
|
-
|
615
|
-
|
616
|
-
|
600
|
+
elsif words && scanner.scan(/\s/)
|
601
|
+
scanner.pos -= 1
|
602
|
+
break
|
617
603
|
|
618
|
-
|
619
|
-
|
604
|
+
elsif interpolate && scanner.check(/#(?=[\$\@\{])/)
|
605
|
+
break
|
620
606
|
|
621
|
-
|
622
|
-
|
607
|
+
#elsif scanner.scan(/\\\\/)
|
608
|
+
#c = scanner.matched
|
623
609
|
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
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
|
-
|
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
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
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.
|
657
|
-
|
658
|
-
c = scanner.matched
|
647
|
+
c ||= scanner.matched
|
648
|
+
str_buffer << c
|
659
649
|
end
|
660
650
|
|
661
|
-
|
662
|
-
str_buffer << c
|
651
|
+
raise "reached EOF while in string" if scanner.eos?
|
663
652
|
end
|
664
653
|
|
665
|
-
|
666
|
-
|
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
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
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
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
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
|
-
|
676
|
+
next if [:expr_beg, :expr_dot].include? @lex_state
|
752
677
|
|
753
|
-
|
754
|
-
if scanner.scan(/\=/)
|
678
|
+
cmd_start = true
|
755
679
|
@lex_state = :expr_beg
|
756
|
-
return
|
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
|
-
|
770
|
-
|
771
|
-
|
682
|
+
elsif scanner.scan(/\;/)
|
683
|
+
@lex_state = :expr_beg
|
684
|
+
return ';', ';'
|
772
685
|
|
773
|
-
|
686
|
+
elsif scanner.scan(/\"/)
|
687
|
+
@string_parse = { :beg => '"', :end => '"', :interpolate => true }
|
688
|
+
return :STRING_BEG, scanner.matched
|
774
689
|
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
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
|
-
|
782
|
-
result = scanner.matched
|
736
|
+
return '/', '/'
|
783
737
|
|
784
|
-
|
785
|
-
|
786
|
-
|
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
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
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
|
-
|
812
|
-
cond_lexpop
|
813
|
-
cmdarg_lexpop
|
814
|
-
@lex_state = :expr_end
|
758
|
+
return result, scanner.matched
|
815
759
|
|
816
|
-
|
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
|
-
|
819
|
-
|
820
|
-
|
790
|
+
elsif scanner.scan(/\]/)
|
791
|
+
cond_lexpop
|
792
|
+
cmdarg_lexpop
|
793
|
+
@lex_state = :expr_end
|
794
|
+
return ']', scanner.matched
|
821
795
|
|
822
|
-
|
823
|
-
|
824
|
-
|
796
|
+
elsif scanner.scan(/\}/)
|
797
|
+
cond_lexpop
|
798
|
+
cmdarg_lexpop
|
799
|
+
@lex_state = :expr_end
|
825
800
|
|
826
|
-
|
827
|
-
@lex_state = :expr_dot unless @lex_state == :expr_fname
|
828
|
-
return '.', scanner.matched
|
801
|
+
return '}', scanner.matched
|
829
802
|
|
830
|
-
|
831
|
-
|
832
|
-
|
803
|
+
elsif scanner.scan(/\.\.\./)
|
804
|
+
@lex_state = :expr_beg
|
805
|
+
return '...', scanner.matched
|
833
806
|
|
834
|
-
|
835
|
-
|
807
|
+
elsif scanner.scan(/\.\./)
|
808
|
+
@lex_state = :expr_beg
|
809
|
+
return '..', scanner.matched
|
836
810
|
|
837
|
-
|
838
|
-
|
839
|
-
|
811
|
+
elsif scanner.scan(/\./)
|
812
|
+
@lex_state = :expr_dot unless @lex_state == :expr_fname
|
813
|
+
return '.', scanner.matched
|
840
814
|
|
841
|
-
|
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 '
|
855
|
-
end
|
817
|
+
return :OP_ASGN, '**'
|
856
818
|
|
857
|
-
|
858
|
-
|
859
|
-
@lex_state = :expr_beg
|
860
|
-
return '::@', scanner.matched
|
861
|
-
end
|
819
|
+
elsif scanner.scan(/\*\*/)
|
820
|
+
return '**', '**'
|
862
821
|
|
863
|
-
|
864
|
-
|
822
|
+
elsif scanner.scan(/\*\=/)
|
823
|
+
@lex_state = :expr_beg
|
824
|
+
return :OP_ASGN, '*'
|
865
825
|
|
866
|
-
|
867
|
-
|
868
|
-
|
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
|
-
|
874
|
-
|
875
|
-
|
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
|
-
|
878
|
-
|
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
|
-
|
884
|
-
|
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
|
-
|
887
|
-
|
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
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
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
|
-
|
916
|
-
|
868
|
+
@lex_state = :expr_fname
|
869
|
+
return :SYMBOL_BEG, ':'
|
917
870
|
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
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
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
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
|
-
|
961
|
-
|
962
|
-
|
963
|
-
else
|
901
|
+
return '^', scanner.matched
|
902
|
+
|
903
|
+
elsif scanner.check(/\&/)
|
904
|
+
if scanner.scan(/\&\&\=/)
|
964
905
|
@lex_state = :expr_beg
|
965
|
-
|
966
|
-
|
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
|
-
|
973
|
-
|
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
|
-
|
984
|
-
|
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
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
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
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
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
|
-
|
1010
|
-
|
1011
|
-
|
989
|
+
elsif scanner.scan(/->/)
|
990
|
+
@lex_state = :expr_arg
|
991
|
+
@start_of_lambda = true
|
992
|
+
return [:LAMBDA, scanner.matched]
|
1012
993
|
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
@lex_state
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
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 [
|
1025
|
-
end
|
1013
|
+
return [result, result]
|
1026
1014
|
|
1027
|
-
|
1028
|
-
|
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
|
-
|
1031
|
-
|
1032
|
-
|
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
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
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
|
-
|
1062
|
-
|
1063
|
-
|
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
|
-
|
1070
|
-
|
1071
|
-
|
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
|
-
|
1078
|
-
|
1079
|
-
|
1062
|
+
elsif scanner.scan(/\=\>/)
|
1063
|
+
@lex_state = :expr_beg
|
1064
|
+
return '=>', '=>'
|
1080
1065
|
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1066
|
+
elsif scanner.scan(/\=/)
|
1067
|
+
@lex_state = :expr_beg
|
1068
|
+
return '=', '='
|
1084
1069
|
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
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
|
-
|
1094
|
-
|
1095
|
-
|
1078
|
+
elsif scanner.scan(/\!\~/)
|
1079
|
+
@lex_state = :expr_beg
|
1080
|
+
return '!~', '!~'
|
1096
1081
|
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
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
|
-
|
1106
|
-
|
1107
|
-
|
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
|
-
|
1118
|
-
|
1119
|
-
|
1098
|
+
elsif scanner.scan(/\$[\+\'\`\&!@\"~*$?\/\\:;=.,<>_]/)
|
1099
|
+
@lex_state = :expr_end
|
1100
|
+
return :GVAR, scanner.matched
|
1120
1101
|
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1102
|
+
elsif scanner.scan(/\$\w+/)
|
1103
|
+
@lex_state = :expr_end
|
1104
|
+
return :GVAR, scanner.matched
|
1124
1105
|
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1106
|
+
elsif scanner.scan(/\@\@\w*/)
|
1107
|
+
@lex_state = :expr_end
|
1108
|
+
return :CVAR, scanner.matched
|
1128
1109
|
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1110
|
+
elsif scanner.scan(/\@\w*/)
|
1111
|
+
@lex_state = :expr_end
|
1112
|
+
return :IVAR, scanner.matched
|
1132
1113
|
|
1133
|
-
|
1134
|
-
if @start_of_lambda
|
1135
|
-
@start_of_lambda = false
|
1114
|
+
elsif scanner.scan(/\,/)
|
1136
1115
|
@lex_state = :expr_beg
|
1137
|
-
return
|
1116
|
+
return ',', scanner.matched
|
1138
1117
|
|
1139
|
-
elsif
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
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
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
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
|
-
|
1169
|
-
|
1133
|
+
cond_push 0
|
1134
|
+
cmdarg_push 0
|
1135
|
+
return result, scanner.matched
|
1170
1136
|
|
1171
|
-
|
1172
|
-
|
1173
|
-
if
|
1174
|
-
|
1175
|
-
|
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
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
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
|
-
|
1196
|
-
|
1197
|
-
|
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 :
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
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
|
-
|
1209
|
-
|
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 :
|
1227
|
-
end
|
1217
|
+
return :IF_MOD, matched
|
1228
1218
|
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
1232
|
-
|
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
|
-
|
1235
|
-
|
1236
|
-
@lex_state = :expr_beg
|
1237
|
-
return :UNLESS_MOD, matched
|
1224
|
+
when 'else'
|
1225
|
+
return :ELSE, matched
|
1238
1226
|
|
1239
|
-
|
1240
|
-
|
1227
|
+
when 'elsif'
|
1228
|
+
return :ELSIF, matched
|
1241
1229
|
|
1242
|
-
|
1243
|
-
|
1230
|
+
when 'self'
|
1231
|
+
@lex_state = :expr_end unless @lex_state == :expr_fname
|
1232
|
+
return :SELF, matched
|
1244
1233
|
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1234
|
+
when 'true'
|
1235
|
+
@lex_state = :expr_end
|
1236
|
+
return :TRUE, matched
|
1248
1237
|
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1238
|
+
when 'false'
|
1239
|
+
@lex_state = :expr_end
|
1240
|
+
return :FALSE, matched
|
1252
1241
|
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1242
|
+
when 'nil'
|
1243
|
+
@lex_state = :expr_end
|
1244
|
+
return :NIL, matched
|
1256
1245
|
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1246
|
+
when '__LINE__'
|
1247
|
+
@lex_state = :expr_end
|
1248
|
+
return :LINE, @line.to_s
|
1260
1249
|
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1250
|
+
when '__FILE__'
|
1251
|
+
@lex_state = :expr_end
|
1252
|
+
return :FILE, matched
|
1264
1253
|
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
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
|
-
|
1270
|
-
|
1271
|
-
@lex_state
|
1272
|
-
|
1273
|
-
|
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
|
-
|
1278
|
-
|
1279
|
-
|
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
|
-
|
1284
|
-
|
1285
|
-
|
1272
|
+
when 'case'
|
1273
|
+
@lex_state = :expr_beg
|
1274
|
+
return :CASE, matched
|
1286
1275
|
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1276
|
+
when 'when'
|
1277
|
+
@lex_state = :expr_beg
|
1278
|
+
return :WHEN, matched
|
1290
1279
|
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1280
|
+
when 'or'
|
1281
|
+
@lex_state = :expr_beg
|
1282
|
+
return :OR, matched
|
1294
1283
|
|
1295
|
-
|
1296
|
-
|
1297
|
-
|
1284
|
+
when 'and'
|
1285
|
+
@lex_state = :expr_beg
|
1286
|
+
return :AND, matched
|
1298
1287
|
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1288
|
+
when 'not'
|
1289
|
+
@lex_state = :expr_beg
|
1290
|
+
return :NOT, matched
|
1302
1291
|
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1292
|
+
when 'return'
|
1293
|
+
@lex_state = :expr_mid
|
1294
|
+
return :RETURN, matched
|
1306
1295
|
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
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
|
-
|
1312
|
-
|
1313
|
-
@lex_state = :expr_end
|
1314
|
-
return :IDENTIFIER, matched
|
1315
|
-
end
|
1302
|
+
@lex_state = :expr_mid
|
1303
|
+
return :NEXT, matched
|
1316
1304
|
|
1317
|
-
|
1318
|
-
|
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
|
-
|
1321
|
-
|
1322
|
-
@lex_state = :expr_end
|
1323
|
-
return :IDENTIFIER, matched
|
1324
|
-
end
|
1311
|
+
@lex_state = :expr_mid
|
1312
|
+
return :REDO, matched
|
1325
1313
|
|
1326
|
-
|
1327
|
-
|
1314
|
+
when 'break'
|
1315
|
+
@lex_state = :expr_mid
|
1316
|
+
return :BREAK, matched
|
1328
1317
|
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1318
|
+
when 'super'
|
1319
|
+
@lex_state = :expr_arg
|
1320
|
+
return :SUPER, matched
|
1332
1321
|
|
1333
|
-
|
1334
|
-
|
1335
|
-
return :SUPER, matched
|
1322
|
+
when 'then'
|
1323
|
+
return :THEN, matched
|
1336
1324
|
|
1337
|
-
|
1338
|
-
|
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
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
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
|
-
|
1346
|
-
|
1347
|
-
|
1348
|
-
return :UNTIL_MOD, matched
|
1335
|
+
when 'yield'
|
1336
|
+
@lex_state = :expr_arg
|
1337
|
+
return :YIELD, matched
|
1349
1338
|
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1339
|
+
when 'alias'
|
1340
|
+
@lex_state = :expr_fname
|
1341
|
+
return :ALIAS, matched
|
1342
|
+
end
|
1353
1343
|
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1357
|
-
|
1344
|
+
matched = matched
|
1345
|
+
if scanner.peek(2) != '::' && scanner.scan(/\:/)
|
1346
|
+
return :LABEL, matched
|
1347
|
+
end
|
1358
1348
|
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1362
|
-
|
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
|
-
|
1365
|
-
|
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
|
-
|
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
|
-
|
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
|