opal 0.3.2 → 0.3.6
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/README.md +85 -127
- data/bin/opal +3 -3
- data/lib/core.rb +114 -0
- data/{gems/core/lib → lib}/core/array.rb +68 -187
- data/{gems/core/lib → lib}/core/basic_object.rb +22 -5
- data/lib/core/class.rb +38 -0
- data/{gems/core/lib → lib}/core/dir.rb +1 -1
- data/lib/core/enumerable.rb +33 -0
- data/{gems/core/lib → lib}/core/error.rb +1 -4
- data/{gems/core/lib → lib}/core/false_class.rb +0 -0
- data/{gems/core/lib → lib}/core/file.rb +11 -3
- data/{gems/core/lib → lib}/core/hash.rb +12 -0
- data/{gems/core/lib → lib}/core/kernel.rb +114 -86
- data/lib/core/match_data.rb +33 -0
- data/lib/core/module.rb +97 -0
- data/{gems/core/lib → lib}/core/nil_class.rb +0 -0
- data/{gems/core/lib → lib}/core/numeric.rb +5 -0
- data/{gems/core/lib → lib}/core/object.rb +0 -0
- data/{gems/core/lib → lib}/core/proc.rb +13 -3
- data/{gems/core/lib → lib}/core/range.rb +10 -0
- data/{gems/core/lib → lib}/core/regexp.rb +33 -1
- data/{gems/core/lib → lib}/core/string.rb +25 -10
- data/{gems/core/lib → lib}/core/symbol.rb +3 -3
- data/{gems/core/lib → lib}/core/top_self.rb +0 -0
- data/{gems/core/lib → lib}/core/true_class.rb +0 -0
- data/lib/dev.rb +169 -0
- data/{gems/ospec/lib → lib}/ospec.rb +1 -0
- data/lib/ospec/autorun.rb +8 -0
- data/{gems/ospec/lib → lib}/ospec/dsl.rb +2 -2
- data/{gems/ospec/lib → lib}/ospec/example.rb +0 -0
- data/{gems/ospec/lib → lib}/ospec/example/before_and_after_hooks.rb +0 -0
- data/{gems/ospec/lib → lib}/ospec/example/errors.rb +0 -0
- data/{gems/ospec/lib → lib}/ospec/example/example_group.rb +0 -0
- data/{gems/ospec/lib → lib}/ospec/example/example_group_factory.rb +0 -3
- data/{gems/ospec/lib → lib}/ospec/example/example_group_hierarchy.rb +4 -3
- data/{gems/ospec/lib → lib}/ospec/example/example_group_methods.rb +1 -1
- data/{gems/ospec/lib → lib}/ospec/example/example_group_proxy.rb +3 -2
- data/{gems/ospec/lib → lib}/ospec/example/example_methods.rb +1 -1
- data/{gems/ospec/lib → lib}/ospec/example/example_proxy.rb +7 -7
- data/{gems/ospec/lib → lib}/ospec/expectations.rb +0 -0
- data/{gems/ospec/lib → lib}/ospec/expectations/errors.rb +0 -0
- data/{gems/ospec/lib → lib}/ospec/expectations/fail_with.rb +4 -3
- data/{gems/ospec/lib → lib}/ospec/expectations/handler.rb +6 -0
- data/lib/ospec/helpers/scratch.rb +18 -0
- data/{gems/ospec/lib → lib}/ospec/matchers.rb +2 -2
- data/{gems/ospec/lib → lib}/ospec/matchers/be.rb +0 -0
- data/{gems/ospec/lib → lib}/ospec/matchers/generated_descriptions.rb +0 -0
- data/{gems/ospec/lib → lib}/ospec/matchers/operator_matcher.rb +2 -0
- data/lib/ospec/matchers/raise_error.rb +38 -0
- data/lib/ospec/runner.rb +90 -0
- data/{gems/ospec/lib → lib}/ospec/runner/example_group_runner.rb +10 -13
- data/lib/ospec/runner/formatter/html_formatter.rb +139 -0
- data/{gems/ospec/lib → lib}/ospec/runner/formatter/terminal_formatter.rb +0 -0
- data/{gems/ospec/lib → lib}/ospec/runner/options.rb +1 -3
- data/{gems/ospec/lib → lib}/ospec/runner/reporter.rb +0 -9
- data/lib/racc/parser.rb +165 -0
- data/lib/strscan.rb +52 -0
- data/{lib → opal_lib}/opal.rb +2 -0
- data/opal_lib/opal/build_methods.rb +51 -0
- data/opal_lib/opal/builder.rb +164 -0
- data/opal_lib/opal/bundle.rb +70 -0
- data/opal_lib/opal/command.rb +68 -0
- data/{lib → opal_lib}/opal/context.rb +21 -9
- data/{lib → opal_lib}/opal/context/console.rb +0 -2
- data/opal_lib/opal/context/file_system.rb +34 -0
- data/{lib → opal_lib}/opal/context/loader.rb +26 -8
- data/opal_lib/opal/gem.rb +84 -0
- data/{lib → opal_lib}/opal/rake/builder_task.rb +2 -2
- data/opal_lib/opal/rake/spec_task.rb +32 -0
- data/{lib → opal_lib}/opal/ruby/nodes.rb +730 -109
- data/{lib → opal_lib}/opal/ruby/parser.rb +90 -23
- data/opal_lib/opal/ruby/ruby_parser.rb +4862 -0
- data/opal_lib/opal/ruby/ruby_parser.y +1454 -0
- data/opal_lib/opal/version.rb +4 -0
- data/runtime/class.js +359 -0
- data/runtime/debug.js +84 -0
- data/runtime/fs.js +199 -0
- data/runtime/init.js +558 -0
- data/runtime/loader.js +351 -0
- data/runtime/module.js +109 -0
- data/runtime/post.js +10 -0
- data/runtime/pre.js +7 -0
- data/runtime/runtime.js +351 -0
- metadata +88 -175
- data/.gitignore +0 -7
- data/Changelog +0 -31
- data/LICENSE +0 -75
- data/Rakefile +0 -86
- data/gems/core/README.md +0 -14
- data/gems/core/Rakefile +0 -8
- data/gems/core/core.gemspec +0 -13
- data/gems/core/lib/core.rb +0 -34
- data/gems/core/lib/core/class.rb +0 -31
- data/gems/core/lib/core/module.rb +0 -100
- data/gems/core/lib/core/vm.rb +0 -16
- data/gems/core/spec/core/array/append_spec.rb +0 -30
- data/gems/core/spec/core/array/assoc_spec.rb +0 -29
- data/gems/core/spec/core/array/at_spec.rb +0 -37
- data/gems/core/spec/core/array/clear_spec.rb +0 -22
- data/gems/core/spec/core/array/collect_bang_spec.rb +0 -27
- data/gems/core/spec/core/array/collect_spec.rb +0 -27
- data/gems/core/spec/core/array/compact_spec.rb +0 -41
- data/gems/core/spec/core/array/concat_spec.rb +0 -15
- data/gems/core/spec/core/array/constructor_spec.rb +0 -14
- data/gems/core/spec/core/array/each_spec.rb +0 -9
- data/gems/core/spec/core/array/element_reference_spec.rb +0 -4
- data/gems/core/spec/core/array/first_spec.rb +0 -35
- data/gems/core/spec/core/array/include_spec.rb +0 -9
- data/gems/core/spec/core/array/join_spec.rb +0 -6
- data/gems/core/spec/core/array/last_spec.rb +0 -51
- data/gems/core/spec/core/array/length_spec.rb +0 -6
- data/gems/core/spec/core/array/map_spec.rb +0 -33
- data/gems/core/spec/core/array/reverse_spec.rb +0 -6
- data/gems/core/spec/core/builtin_constants/builtin_constants_spec.rb +0 -7
- data/gems/core/spec/core/false/and_spec.rb +0 -10
- data/gems/core/spec/core/false/inspect_spec.rb +0 -6
- data/gems/core/spec/core/false/or_spec.rb +0 -10
- data/gems/core/spec/core/false/to_s_spec.rb +0 -6
- data/gems/core/spec/core/false/xor_spec.rb +0 -10
- data/gems/core/spec/core/file/join_spec.rb +0 -19
- data/gems/core/spec/core/hash/assoc_spec.rb +0 -32
- data/gems/core/spec/core/kernel/instance_eval_spec.rb +0 -0
- data/gems/core/spec/core/kernel/loop_spec.rb +0 -24
- data/gems/core/spec/core/kernel/raise_spec.rb +0 -0
- data/gems/core/spec/core/module/attr_accessor_spec.rb +0 -28
- data/gems/core/spec/core/number/lt_spec.rb +0 -12
- data/gems/core/spec/core/string/sub_spec.rb +0 -24
- data/gems/core/spec/core/true/and_spec.rb +0 -10
- data/gems/core/spec/core/true/inspect_spec.rb +0 -6
- data/gems/core/spec/core/true/or_spec.rb +0 -10
- data/gems/core/spec/core/true/to_s_spec.rb +0 -6
- data/gems/core/spec/core/true/xor_spec.rb +0 -10
- data/gems/core/spec/language/and_spec.rb +0 -61
- data/gems/core/spec/language/array_spec.rb +0 -68
- data/gems/core/spec/language/block_spec.rb +0 -38
- data/gems/core/spec/language/break_spec.rb +0 -36
- data/gems/core/spec/language/case_spec.rb +0 -103
- data/gems/core/spec/language/def_spec.rb +0 -21
- data/gems/core/spec/language/eigenclass_spec.rb +0 -60
- data/gems/core/spec/language/file_spec.rb +0 -13
- data/gems/core/spec/language/fixtures/block.rb +0 -21
- data/gems/core/spec/language/fixtures/super.rb +0 -293
- data/gems/core/spec/language/hash_spec.rb +0 -29
- data/gems/core/spec/language/if_spec.rb +0 -54
- data/gems/core/spec/language/loop_spec.rb +0 -11
- data/gems/core/spec/language/metaclass_spec.rb +0 -21
- data/gems/core/spec/language/method_spec.rb +0 -124
- data/gems/core/spec/language/next_spec.rb +0 -25
- data/gems/core/spec/language/or_spec.rb +0 -34
- data/gems/core/spec/language/redo_spec.rb +0 -24
- data/gems/core/spec/language/regexp_spec.rb +0 -26
- data/gems/core/spec/language/rescue_spec.rb +0 -20
- data/gems/core/spec/language/return_spec.rb +0 -47
- data/gems/core/spec/language/string_spec.rb +0 -25
- data/gems/core/spec/language/super_spec.rb +0 -32
- data/gems/core/spec/language/until_spec.rb +0 -157
- data/gems/core/spec/language/variables_spec.rb +0 -155
- data/gems/core/spec/language/while_spec.rb +0 -163
- data/gems/core/spec/spec_helper.rb +0 -5
- data/gems/core_fs/README.md +0 -19
- data/gems/dev/Rakefile +0 -5
- data/gems/dev/lib/dev.js +0 -99
- data/gems/dev/lib/dev/generator.js +0 -1264
- data/gems/dev/lib/dev/parser.js +0 -979
- data/gems/dev/lib/dev/ruby_parser.js +0 -1088
- data/gems/dev/lib/dev/ruby_parser.y +0 -1267
- data/gems/dev/lib/dev/string_scanner.js +0 -38
- data/gems/dev/tools/racc2js/README.md +0 -39
- data/gems/dev/tools/racc2js/math_parser.js +0 -222
- data/gems/dev/tools/racc2js/math_parser.rb +0 -133
- data/gems/dev/tools/racc2js/math_parser.y +0 -28
- data/gems/dev/tools/racc2js/parser.js +0 -218
- data/gems/dev/tools/racc2js/racc2js.rb +0 -153
- data/gems/json/README.md +0 -4
- data/gems/json/json.gemspec +0 -14
- data/gems/json/lib/json.rb +0 -64
- data/gems/json/lib/json/ext.rb +0 -51
- data/gems/json/lib/json/json2.js +0 -481
- data/gems/ospec/README.md +0 -0
- data/gems/ospec/lib/ospec/autorun.rb +0 -3
- data/gems/ospec/lib/ospec/runner.rb +0 -40
- data/gems/ospec/lib/ospec/runner/formatter/html_formatter.rb +0 -91
- data/gems/ospec/ospec.gemspec +0 -0
- data/gems/rquery/README.md +0 -9
- data/gems/rquery/lib/rquery.rb +0 -10
- data/gems/rquery/lib/rquery/ajax.rb +0 -4
- data/gems/rquery/lib/rquery/css.rb +0 -96
- data/gems/rquery/lib/rquery/document.rb +0 -25
- data/gems/rquery/lib/rquery/element.rb +0 -292
- data/gems/rquery/lib/rquery/event.rb +0 -108
- data/gems/rquery/lib/rquery/jquery.js +0 -8177
- data/gems/rquery/lib/rquery/request.rb +0 -138
- data/gems/rquery/lib/rquery/response.rb +0 -49
- data/gems/rquery/rquery.gemspec +0 -16
- data/lib/opal.js +0 -1597
- data/lib/opal/builder.rb +0 -117
- data/lib/opal/bundle.rb +0 -131
- data/lib/opal/command.rb +0 -11
- data/lib/opal/context/file_system.rb +0 -19
- data/lib/opal/gem.rb +0 -153
- data/lib/opal/ruby/ruby_parser.rb +0 -5170
- data/lib/opal/ruby/ruby_parser.y +0 -1298
- data/opal.gemspec +0 -15
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
module Opal
|
|
2
|
+
class RubyParser < Racc::Parser
|
|
2
3
|
|
|
3
4
|
# Indent for generated code scopes; 2 spaces, never use tabs
|
|
4
5
|
INDENT = ' '
|
|
@@ -90,6 +91,28 @@ class Opal::RubyParser < Racc::Parser
|
|
|
90
91
|
@temp_queue = []
|
|
91
92
|
# ivars..we need to make sure these exist (make sure they are nil if new)
|
|
92
93
|
@ivars = []
|
|
94
|
+
|
|
95
|
+
# keep tabs on whether in while loop or not
|
|
96
|
+
@while_scope = 0
|
|
97
|
+
@while_scope_stack = []
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def push_while_scope(while_scope)
|
|
101
|
+
@while_scope_stack << while_scope
|
|
102
|
+
@while_scope += 1
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def pop_while_scope
|
|
106
|
+
@while_scope_stack.pop
|
|
107
|
+
@while_scope -= 1
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def in_while_scope?
|
|
111
|
+
@while_scope > 0
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def while_scope
|
|
115
|
+
@while_scope_stack.last
|
|
93
116
|
end
|
|
94
117
|
|
|
95
118
|
def ensure_ivar(name)
|
|
@@ -163,45 +186,76 @@ class Opal::RubyParser < Racc::Parser
|
|
|
163
186
|
# keep track of the current line number in the generator
|
|
164
187
|
attr_accessor :line
|
|
165
188
|
|
|
189
|
+
# expose top level options... useful for certain nodes to know if we are
|
|
190
|
+
# debug mode etc
|
|
191
|
+
attr_reader :opts
|
|
192
|
+
|
|
166
193
|
def initialize(statements)
|
|
167
194
|
super nil, statements
|
|
168
195
|
@file_helpers = []
|
|
169
196
|
@line = 1
|
|
170
197
|
@mm_ids = []
|
|
198
|
+
|
|
199
|
+
@symbol_refs = {}
|
|
200
|
+
@symbol_count = 1
|
|
201
|
+
|
|
202
|
+
@regexp_refs = []
|
|
171
203
|
end
|
|
172
204
|
|
|
173
|
-
# Register a method name that needs to be called to $opal.mm. This method
|
|
174
|
-
# will remove duplicates.
|
|
175
205
|
def register_mm_id(mid)
|
|
176
206
|
@mm_ids << mid unless @mm_ids.include? mid
|
|
177
207
|
end
|
|
178
208
|
|
|
209
|
+
def register_symbol(sym)
|
|
210
|
+
if ref = @symbol_refs[sym]
|
|
211
|
+
ref
|
|
212
|
+
else
|
|
213
|
+
ref = @symbol_refs[sym] = "$symbol_#{@symbol_count}"
|
|
214
|
+
@symbol_count += 1
|
|
215
|
+
ref
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
179
219
|
def generate(opts, level)
|
|
220
|
+
@opts = opts
|
|
180
221
|
code = []
|
|
181
|
-
|
|
222
|
+
@statements.returns
|
|
223
|
+
# code << super(opts, level)
|
|
224
|
+
code << @statements.generate(opts, level)
|
|
225
|
+
|
|
226
|
+
pre = 'function $$(){'
|
|
227
|
+
post = "\n}\n"
|
|
228
|
+
# post = "\n\n}\nvar nil, $ac, $super, $break, $class, $def, $symbol, $range, "
|
|
229
|
+
# post += '$hash, $B, Qtrue, Qfalse, $cg;'
|
|
230
|
+
# local vars... only if we used any..
|
|
231
|
+
unless @scope_vars.empty?
|
|
232
|
+
post += "var #{@scope_vars.join ', '};"
|
|
233
|
+
end
|
|
182
234
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
235
|
+
post += 'var nil = $rb.Qnil, $ac = $rb.ac, $super = $rb.S, $break = $rb.B, '
|
|
236
|
+
post += '$class = $rb.dc, $defn = $rb.dm, $defs = $rb.ds, $symbol = $rb.Y, '
|
|
237
|
+
post += '$hash = $rb.H, $B = $rb.P, Qtrue = $rb.Qtrue, Qfalse = $rb.Qfalse, '
|
|
238
|
+
post += '$cg = $rb.cg, $range = $rb.G'
|
|
187
239
|
|
|
188
|
-
#
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
pre += mm_ids
|
|
240
|
+
# symbols
|
|
241
|
+
@symbol_refs.each do |val, sym|
|
|
242
|
+
post += ", #{sym} = $symbol('#{val}')"
|
|
192
243
|
end
|
|
193
244
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
245
|
+
post += ';'
|
|
246
|
+
|
|
247
|
+
if @mm_ids.length > 0
|
|
248
|
+
post += "$rb.mm(['#{ @mm_ids.join "', '" }']);"
|
|
197
249
|
end
|
|
198
250
|
|
|
199
251
|
# ivars
|
|
200
252
|
@ivars.each do |ivar|
|
|
201
|
-
|
|
253
|
+
post += "if (self['#{ivar}'] == undefined) { self['#{ivar}'] = nil; }"
|
|
202
254
|
end
|
|
203
255
|
|
|
204
|
-
|
|
256
|
+
post += "return $$();\n"
|
|
257
|
+
|
|
258
|
+
pre + code.join('') + post
|
|
205
259
|
end
|
|
206
260
|
end
|
|
207
261
|
|
|
@@ -229,7 +283,7 @@ class Opal::RubyParser < Racc::Parser
|
|
|
229
283
|
return NilNode.new.generate(opts, level) if @nodes.empty?
|
|
230
284
|
|
|
231
285
|
@nodes.each do |node|
|
|
232
|
-
node_code = node.process opts,
|
|
286
|
+
node_code = node.process opts, level
|
|
233
287
|
|
|
234
288
|
if level <= LEVEL_TOP_CLOSURE
|
|
235
289
|
# to prevent lots of trailing whitespace when we generate statements
|
|
@@ -274,6 +328,8 @@ class Opal::RubyParser < Racc::Parser
|
|
|
274
328
|
|
|
275
329
|
class NumericNode < BaseNode
|
|
276
330
|
|
|
331
|
+
attr_accessor :value
|
|
332
|
+
|
|
277
333
|
def initialize(val)
|
|
278
334
|
@line = val[:line]
|
|
279
335
|
@value = val[:value]
|
|
@@ -292,7 +348,7 @@ class Opal::RubyParser < Racc::Parser
|
|
|
292
348
|
end
|
|
293
349
|
|
|
294
350
|
def generate(opts, level)
|
|
295
|
-
|
|
351
|
+
opts[:top].register_symbol @value
|
|
296
352
|
end
|
|
297
353
|
end
|
|
298
354
|
|
|
@@ -315,8 +371,6 @@ class Opal::RubyParser < Racc::Parser
|
|
|
315
371
|
def mid_to_jsid(id)
|
|
316
372
|
return ".$m['#{id}']" if /[\!\=\?\+\-\*\/\^\&\%\@\|\[\]\<\>\~]/ =~ id
|
|
317
373
|
|
|
318
|
-
# FIXME: if our id is a reserved word in js, we need to also wrap it in
|
|
319
|
-
# brackets.
|
|
320
374
|
return ".$m['#{id}']" if js_reserved_words.include? id
|
|
321
375
|
|
|
322
376
|
# default we just do .method_name
|
|
@@ -332,26 +386,48 @@ class Opal::RubyParser < Racc::Parser
|
|
|
332
386
|
end
|
|
333
387
|
|
|
334
388
|
def generate(opts, level)
|
|
335
|
-
|
|
389
|
+
# Special handlers
|
|
390
|
+
if @recv.is_a? NumericNode and @mid == '-@'
|
|
391
|
+
@recv.value = "-#{@recv.value}"
|
|
392
|
+
return @recv.generate opts, level
|
|
393
|
+
|
|
394
|
+
elsif @mid == "block_given?"
|
|
395
|
+
# name = opts[:scope].set_uses_block
|
|
396
|
+
return "($yy == $y.y ? Qfalse : Qtrue)"
|
|
397
|
+
end
|
|
336
398
|
|
|
337
|
-
|
|
338
|
-
|
|
399
|
+
code = ''
|
|
400
|
+
arg_res = []
|
|
401
|
+
recv = nil
|
|
402
|
+
mid = @mid
|
|
339
403
|
tmp_recv = opts[:scope].temp_local
|
|
340
404
|
|
|
405
|
+
opts[:top].register_mm_id @mid
|
|
406
|
+
|
|
341
407
|
# receiver
|
|
342
408
|
if @recv.is_a? NumericNode
|
|
343
409
|
recv = "(#{@recv.process opts, LEVEL_EXPR})"
|
|
344
410
|
elsif @recv
|
|
345
411
|
recv = @recv.process opts, LEVEL_EXPR
|
|
346
412
|
else
|
|
347
|
-
recv = SelfNode.new
|
|
413
|
+
@recv = SelfNode.new
|
|
414
|
+
recv = "self"
|
|
415
|
+
mid = '$' + mid
|
|
348
416
|
end
|
|
349
417
|
|
|
350
|
-
|
|
351
|
-
|
|
418
|
+
mid = mid_to_jsid(mid)
|
|
419
|
+
|
|
420
|
+
if @recv.is_a? SelfNode
|
|
421
|
+
recv_code = recv
|
|
422
|
+
recv_arg = recv
|
|
423
|
+
elsif @recv.is_a?(IdentifierNode) and @recv.local_variable?(opts)
|
|
424
|
+
recv_code = recv
|
|
425
|
+
recv_arg = recv
|
|
426
|
+
else
|
|
427
|
+
recv_code = "(#{tmp_recv} = #{recv})"
|
|
428
|
+
recv_arg = "#{tmp_recv}"
|
|
429
|
+
end
|
|
352
430
|
|
|
353
|
-
# Register our method_id to ensure $opal.mm gets it
|
|
354
|
-
opts[:top].register_mm_id @mid
|
|
355
431
|
|
|
356
432
|
args = @args
|
|
357
433
|
# normal args
|
|
@@ -367,18 +443,13 @@ class Opal::RubyParser < Racc::Parser
|
|
|
367
443
|
end
|
|
368
444
|
|
|
369
445
|
if @block
|
|
370
|
-
# tmp_self = opts[:scope].temp_local
|
|
371
|
-
tmp_args = opts[:scope].temp_local
|
|
372
446
|
block = @block.generate opts, LEVEL_TOP
|
|
373
|
-
arg_res.unshift
|
|
447
|
+
arg_res.unshift recv_arg
|
|
374
448
|
|
|
375
|
-
code = "(
|
|
376
|
-
code += "
|
|
377
|
-
code += ", ($block.f = #{tmp_recv}#{mid}).apply(#{tmp_recv}, #{tmp_args}))"
|
|
449
|
+
code = "($B.f = #{recv_code}#{mid}, ($B.p ="
|
|
450
|
+
code += "#{block}).$proc =[self], $B.f)(#{arg_res.join ', '})"
|
|
378
451
|
|
|
379
452
|
opts[:scope].queue_temp tmp_recv
|
|
380
|
-
opts[:scope].queue_temp tmp_args
|
|
381
|
-
|
|
382
453
|
code
|
|
383
454
|
|
|
384
455
|
# &to_proc. Note, this must not reassign the $self for the proc.. we are
|
|
@@ -386,16 +457,12 @@ class Opal::RubyParser < Racc::Parser
|
|
|
386
457
|
#
|
|
387
458
|
# FIXME need to actually call to_proc.
|
|
388
459
|
elsif args[3]
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
arg_res.unshift tmp_recv
|
|
460
|
+
arg_res.unshift recv_arg
|
|
392
461
|
|
|
393
|
-
code = "(
|
|
394
|
-
code += "
|
|
395
|
-
code += ", ($block.f = #{tmp_recv}#{mid}).apply(#{tmp_recv}, #{tmp_args}))"
|
|
462
|
+
code = "($B.p = #{args[3].process opts, LEVEL_LIST}, "
|
|
463
|
+
code += "$B.f = #{recv_code}#{mid})(#{arg_res.join ', '})"
|
|
396
464
|
|
|
397
465
|
opts[:scope].queue_temp tmp_recv
|
|
398
|
-
opts[:scope].queue_temp tmp_args
|
|
399
466
|
|
|
400
467
|
code
|
|
401
468
|
|
|
@@ -403,22 +470,20 @@ class Opal::RubyParser < Racc::Parser
|
|
|
403
470
|
else
|
|
404
471
|
# splat args
|
|
405
472
|
if args[1]
|
|
406
|
-
arg_res.unshift
|
|
473
|
+
arg_res.unshift recv_arg
|
|
407
474
|
splat = args[1].generate(opts, LEVEL_EXPR)
|
|
408
|
-
splat_args = arg_res.empty? ? splat : "[#{arg_res.join ', '}].concat(#{splat})"
|
|
475
|
+
splat_args = arg_res.empty? ? "#{splat}" : "[#{arg_res.join ', '}].concat(#{splat})"
|
|
409
476
|
# when using splat, our this val for apply may need a tmp var
|
|
410
477
|
# to save just outputting it twice (have to follow recv path twice)
|
|
411
478
|
splat_recv = recv
|
|
412
|
-
result = "
|
|
479
|
+
result = "#{recv_code}" + mid + ".apply(nil, #{splat_args})"
|
|
413
480
|
|
|
414
481
|
opts[:scope].queue_temp tmp_recv
|
|
415
482
|
result
|
|
416
483
|
else
|
|
417
|
-
arg_res.unshift
|
|
484
|
+
arg_res.unshift recv_arg
|
|
418
485
|
|
|
419
|
-
result = "
|
|
420
|
-
|
|
421
|
-
# requeue the tmp receiver as we are done with it and return
|
|
486
|
+
result = "#{recv_code}#{mid}(#{arg_res.join(', ')})"
|
|
422
487
|
opts[:scope].queue_temp tmp_recv
|
|
423
488
|
result
|
|
424
489
|
end
|
|
@@ -466,7 +531,7 @@ class Opal::RubyParser < Racc::Parser
|
|
|
466
531
|
if @base.nil?
|
|
467
532
|
code += SelfNode.new.generate(opts, level)
|
|
468
533
|
else
|
|
469
|
-
code +=
|
|
534
|
+
code += @base.generate(opts, level)
|
|
470
535
|
end
|
|
471
536
|
|
|
472
537
|
code += ', '
|
|
@@ -479,9 +544,14 @@ class Opal::RubyParser < Racc::Parser
|
|
|
479
544
|
|
|
480
545
|
# scope
|
|
481
546
|
scope = { :indent => opts[:indent] + INDENT, :top => opts[:top], :scope => self }
|
|
547
|
+
@statements.returns
|
|
482
548
|
stmt = @statements.generate scope, LEVEL_TOP
|
|
483
549
|
|
|
484
|
-
|
|
550
|
+
if @scope_vars.empty?
|
|
551
|
+
code += ('function(self) { ' + stmt)
|
|
552
|
+
else
|
|
553
|
+
code += "function(self) {var #{@scope_vars.join ', '};#{stmt}"
|
|
554
|
+
end
|
|
485
555
|
|
|
486
556
|
# fix line ending
|
|
487
557
|
code += fix_line_number opts, @end_line
|
|
@@ -495,7 +565,6 @@ class Opal::RubyParser < Racc::Parser
|
|
|
495
565
|
|
|
496
566
|
def initialize(cls, path, sup, body, _end)
|
|
497
567
|
super nil, body
|
|
498
|
-
@scope_vars << 'self = this'
|
|
499
568
|
@line = cls[:line]
|
|
500
569
|
@base = path[0]
|
|
501
570
|
@cls_name = path[1]
|
|
@@ -507,7 +576,7 @@ class Opal::RubyParser < Racc::Parser
|
|
|
507
576
|
code = '$class('
|
|
508
577
|
|
|
509
578
|
# base
|
|
510
|
-
code += (@base.nil? ? SelfNode.new.generate(opts, level) :
|
|
579
|
+
code += (@base.nil? ? SelfNode.new.generate(opts, level) : @base.generate(opts, level))
|
|
511
580
|
code += ', '
|
|
512
581
|
|
|
513
582
|
# superclass
|
|
@@ -519,8 +588,14 @@ class Opal::RubyParser < Racc::Parser
|
|
|
519
588
|
|
|
520
589
|
# scope
|
|
521
590
|
scope = { :indent => opts[:indent] + INDENT, :top => opts[:top], :scope => self }
|
|
591
|
+
@statements.returns
|
|
522
592
|
stmt = @statements.generate scope, level
|
|
523
|
-
|
|
593
|
+
|
|
594
|
+
if @scope_vars.empty?
|
|
595
|
+
code += "function(self) {#{stmt}"
|
|
596
|
+
else
|
|
597
|
+
code += "function(self) { var #{@scope_vars.join ', '};#{stmt}"
|
|
598
|
+
end
|
|
524
599
|
|
|
525
600
|
# fix trailing line number
|
|
526
601
|
code += fix_line_number opts, @end_line
|
|
@@ -530,6 +605,41 @@ class Opal::RubyParser < Racc::Parser
|
|
|
530
605
|
end
|
|
531
606
|
end
|
|
532
607
|
|
|
608
|
+
class ClassShiftNode < ScopeNode
|
|
609
|
+
|
|
610
|
+
def initialize(cls, expr, body, endn)
|
|
611
|
+
super nil, body
|
|
612
|
+
@line = cls[:line]
|
|
613
|
+
@expr = expr
|
|
614
|
+
@end_line = endn[:line]
|
|
615
|
+
end
|
|
616
|
+
|
|
617
|
+
def generate(opts, level)
|
|
618
|
+
code = '$class('
|
|
619
|
+
|
|
620
|
+
# base
|
|
621
|
+
code += @expr.generate(opts, level)
|
|
622
|
+
code += ', nil, nil, '
|
|
623
|
+
|
|
624
|
+
# scope
|
|
625
|
+
scope = { :indent => opts[:indent] + INDENT, :top => opts[:top], :scope => self }
|
|
626
|
+
@statements.returns
|
|
627
|
+
stmt = @statements.generate scope, level
|
|
628
|
+
|
|
629
|
+
if @scope_vars.empty?
|
|
630
|
+
code += "function(self) {#{stmt}"
|
|
631
|
+
else
|
|
632
|
+
code += "function(self) { var #{@scope_vars.join ', '};#{stmt}"
|
|
633
|
+
end
|
|
634
|
+
|
|
635
|
+
# fix trailing line number
|
|
636
|
+
code += fix_line_number opts, @end_line
|
|
637
|
+
|
|
638
|
+
code += opts[:indent] + '}, 1)'
|
|
639
|
+
code
|
|
640
|
+
end
|
|
641
|
+
end
|
|
642
|
+
|
|
533
643
|
class DefNode < ScopeNode
|
|
534
644
|
|
|
535
645
|
def initialize(defn, singleton, fname, args, body, endn)
|
|
@@ -544,11 +654,11 @@ class Opal::RubyParser < Racc::Parser
|
|
|
544
654
|
end
|
|
545
655
|
|
|
546
656
|
def generate(opts, level)
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
657
|
+
if @singleton
|
|
658
|
+
code = "$defs(#{@singleton.generate opts, level}, "
|
|
659
|
+
else
|
|
660
|
+
code = "$defn(self, "
|
|
661
|
+
end
|
|
552
662
|
|
|
553
663
|
# method id
|
|
554
664
|
code += "'#{@fname[:value]}', "
|
|
@@ -571,6 +681,8 @@ class Opal::RubyParser < Racc::Parser
|
|
|
571
681
|
end
|
|
572
682
|
end
|
|
573
683
|
|
|
684
|
+
arity = method_args.length
|
|
685
|
+
|
|
574
686
|
# optional args
|
|
575
687
|
if args[1]
|
|
576
688
|
args[1].each do |arg|
|
|
@@ -582,23 +694,27 @@ class Opal::RubyParser < Racc::Parser
|
|
|
582
694
|
|
|
583
695
|
# rest args
|
|
584
696
|
if args[2]
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
697
|
+
if args[2][:value] != "*"
|
|
698
|
+
param_variable args[2][:value]
|
|
699
|
+
method_args << args[2][:value]
|
|
700
|
+
pre_code += "#{args[2][:value]} = [].slice.call(arguments, #{method_args.length});"
|
|
701
|
+
end
|
|
588
702
|
end
|
|
589
703
|
|
|
704
|
+
arity = (-arity) - 1 if args[1] or args[2]
|
|
705
|
+
|
|
590
706
|
# block arg
|
|
591
707
|
if args[3]
|
|
592
708
|
param_variable args[3][:value]
|
|
593
709
|
@block_arg_name = args[3][:value]
|
|
710
|
+
pre_code += "var #{args[3][:value]} = (($yy == $y.y) ? nil: $yy);"
|
|
594
711
|
end
|
|
595
712
|
|
|
596
713
|
@body.returns
|
|
597
714
|
stmt = @body.generate scope, LEVEL_TOP
|
|
598
|
-
|
|
599
715
|
method_args.unshift 'self'
|
|
600
716
|
|
|
601
|
-
code += "function(#{method_args.join ', '}) {
|
|
717
|
+
code += "function(#{method_args.join ', '}) {"
|
|
602
718
|
|
|
603
719
|
# local vars... only if we used any..
|
|
604
720
|
unless @scope_vars.empty?
|
|
@@ -607,19 +723,23 @@ class Opal::RubyParser < Racc::Parser
|
|
|
607
723
|
|
|
608
724
|
# ivars
|
|
609
725
|
@ivars.each do |ivar|
|
|
610
|
-
pre_code += "
|
|
726
|
+
pre_code += "self['#{ivar}']==undefined&&(self['#{ivar}']=nil);"
|
|
611
727
|
end
|
|
612
728
|
|
|
613
|
-
# block
|
|
729
|
+
# block support
|
|
614
730
|
if @block_arg_name
|
|
615
|
-
|
|
616
|
-
|
|
731
|
+
|
|
732
|
+
block_code = "var $y = $B, $yy, $ys, $yb = $y.b;"
|
|
733
|
+
block_code += "if ($y.f == arguments.callee) { $yy = $y.p; }"
|
|
734
|
+
block_code += "else { $yy = $y.y; }"
|
|
735
|
+
block_code += "$y.f = nil ;$ys = $yy.$proc[0];"
|
|
736
|
+
pre_code = block_code + pre_code
|
|
617
737
|
end
|
|
618
738
|
|
|
619
739
|
code += (pre_code + stmt)
|
|
620
740
|
|
|
621
741
|
# fix trailing end and 0/1 for normal/singleton
|
|
622
|
-
code += (fix_line_number(opts, @end_line) + "}, #{
|
|
742
|
+
code += (fix_line_number(opts, @end_line) + "}, #{arity})")
|
|
623
743
|
|
|
624
744
|
code
|
|
625
745
|
end
|
|
@@ -685,8 +805,8 @@ class Opal::RubyParser < Racc::Parser
|
|
|
685
805
|
class ArrayNode < BaseNode
|
|
686
806
|
|
|
687
807
|
def initialize(parts, begn, endn)
|
|
688
|
-
@line = begn[:line]
|
|
689
|
-
@end_line = endn[:line]
|
|
808
|
+
@line = begn[:line] || 0
|
|
809
|
+
@end_line = endn[:line] || 0
|
|
690
810
|
@args = parts
|
|
691
811
|
end
|
|
692
812
|
|
|
@@ -694,15 +814,23 @@ class Opal::RubyParser < Racc::Parser
|
|
|
694
814
|
# on a new line are indented to that of the array beg/end
|
|
695
815
|
def generate(opts, level)
|
|
696
816
|
parts = @args[0].map { |arg| arg.process opts, LEVEL_LIST }
|
|
697
|
-
"[#{parts.join ', '}#{fix_line_number opts, @end_line}]"
|
|
817
|
+
code = "[#{parts.join ', '}#{fix_line_number opts, @end_line}]"
|
|
818
|
+
|
|
819
|
+
if @args[1]
|
|
820
|
+
res = "#{code}.concat(#{@args[1].generate opts, LEVEL_EXPR})"
|
|
821
|
+
else
|
|
822
|
+
res = code
|
|
823
|
+
end
|
|
824
|
+
|
|
825
|
+
res
|
|
698
826
|
end
|
|
699
827
|
end
|
|
700
828
|
|
|
701
829
|
class HashNode < BaseNode
|
|
702
830
|
|
|
703
831
|
def initialize(parts, begn, endn)
|
|
704
|
-
@line = begn[:line]
|
|
705
|
-
@end_line = endn[:line]
|
|
832
|
+
@line = begn[:line] || 0
|
|
833
|
+
@end_line = endn[:line] || 0
|
|
706
834
|
@parts = parts
|
|
707
835
|
end
|
|
708
836
|
|
|
@@ -715,6 +843,7 @@ class Opal::RubyParser < Racc::Parser
|
|
|
715
843
|
class IfNode < BaseNode
|
|
716
844
|
|
|
717
845
|
def initialize(begn, expr, stmt, tail, endn)
|
|
846
|
+
@type = begn[:value]
|
|
718
847
|
@line = begn[:line]
|
|
719
848
|
@end_line = endn[:line]
|
|
720
849
|
@expr = expr
|
|
@@ -740,9 +869,12 @@ class Opal::RubyParser < Racc::Parser
|
|
|
740
869
|
end
|
|
741
870
|
|
|
742
871
|
def generate(opts, level)
|
|
743
|
-
code
|
|
872
|
+
code = ''
|
|
873
|
+
done_else = false
|
|
874
|
+
tail = nil
|
|
875
|
+
old_indent = opts[:indent]
|
|
744
876
|
|
|
745
|
-
opts[:indent]
|
|
877
|
+
opts[:indent] = opts[:indent] + INDENT
|
|
746
878
|
|
|
747
879
|
# stmt_level is level_top, unless we are an expression.. then it is level_top_closure..
|
|
748
880
|
stmt_level = (level == LEVEL_EXPR ? LEVEL_TOP_CLOSURE : LEVEL_TOP)
|
|
@@ -752,20 +884,27 @@ class Opal::RubyParser < Racc::Parser
|
|
|
752
884
|
@level_expr = true
|
|
753
885
|
end
|
|
754
886
|
|
|
755
|
-
|
|
887
|
+
expr = @expr.generate opts, LEVEL_EXPR
|
|
888
|
+
expr = "(#{expr})" if @expr.is_a? NumericNode
|
|
889
|
+
|
|
890
|
+
# code += "if ((#{@expr.generate opts, LEVEL_EXPR}).$r) {#{@stmt.process opts, stmt_level}"
|
|
891
|
+
code += "if (#{@type == 'if' ? '' : '!'}#{expr}.$r) {#{@stmt.process opts, stmt_level}"
|
|
756
892
|
|
|
757
893
|
@tail.each do |tail|
|
|
758
894
|
opts[:indent] = old_indent
|
|
759
|
-
code
|
|
895
|
+
code = code + fix_line_number(opts, tail[0][:line])
|
|
760
896
|
|
|
761
897
|
if tail[0][:value] == 'elsif'
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
code +=
|
|
898
|
+
expr = tail[1].generate opts, LEVEL_EXPR
|
|
899
|
+
expr = "(#{expr})" if tail[1].is_a? NumericNode
|
|
900
|
+
code += "} else if (#{expr}.$r) {"
|
|
901
|
+
# code += "} else if ((#{tail[1].generate opts, LEVEL_EXPR}).$r) {"
|
|
902
|
+
opts[:indent] = opts[:indent] + INDENT
|
|
903
|
+
code = code + tail[2].process(opts, stmt_level)
|
|
765
904
|
else
|
|
766
905
|
done_else = true
|
|
767
906
|
code += '} else {'
|
|
768
|
-
opts[:indent]
|
|
907
|
+
opts[:indent] = opts[:indent] + INDENT
|
|
769
908
|
code += tail[1].process(opts, stmt_level)
|
|
770
909
|
end
|
|
771
910
|
end
|
|
@@ -780,11 +919,92 @@ class Opal::RubyParser < Racc::Parser
|
|
|
780
919
|
code += (fix_line_number(opts, @end_line) + '}')
|
|
781
920
|
|
|
782
921
|
# if we were an expression, we need to wrap ourself as closure
|
|
922
|
+
code = "(function() {#{code}})()" if level == LEVEL_EXPR
|
|
923
|
+
code
|
|
924
|
+
end
|
|
925
|
+
end
|
|
926
|
+
|
|
927
|
+
class CaseNode < BaseNode
|
|
928
|
+
|
|
929
|
+
def initialize(begn, expr, body, endn)
|
|
930
|
+
@line = begn[:line]
|
|
931
|
+
@expr = expr
|
|
932
|
+
@body = body
|
|
933
|
+
@end_line = endn[:line]
|
|
934
|
+
end
|
|
935
|
+
|
|
936
|
+
def returns
|
|
937
|
+
@body.each do |part|
|
|
938
|
+
if part[0][:value] == 'when'
|
|
939
|
+
part[2].returns
|
|
940
|
+
else
|
|
941
|
+
part[1].returns
|
|
942
|
+
end
|
|
943
|
+
end
|
|
944
|
+
self
|
|
945
|
+
end
|
|
946
|
+
|
|
947
|
+
def generate(opts, level)
|
|
948
|
+
code = ''
|
|
949
|
+
done_else = false
|
|
950
|
+
tail = nil
|
|
951
|
+
old_indent = opts[:indent]
|
|
952
|
+
|
|
953
|
+
opts[:indent] = opts[:indent] + INDENT
|
|
954
|
+
|
|
955
|
+
stmt_level = (level == LEVEL_EXPR ? LEVEL_TOP_CLOSURE : LEVEL_TOP)
|
|
956
|
+
|
|
957
|
+
if stmt_level == LEVEL_TOP_CLOSURE
|
|
958
|
+
returns
|
|
959
|
+
@level_expr = true
|
|
960
|
+
end
|
|
961
|
+
|
|
962
|
+
expr = @expr.generate opts, LEVEL_EXPR
|
|
963
|
+
case_ref = opts[:scope].temp_local
|
|
964
|
+
|
|
965
|
+
code += "#{case_ref} = #{expr};"
|
|
966
|
+
|
|
967
|
+
@body.each_with_index do |part, idx|
|
|
968
|
+
opts[:indent] = old_indent
|
|
969
|
+
code += fix_line_number opts, part[0][:line]
|
|
970
|
+
|
|
971
|
+
if part[0][:value] == 'when'
|
|
972
|
+
code += (idx == 0 ? "if" : "} else if")
|
|
973
|
+
parts = part[1].map do |expr|
|
|
974
|
+
CallNode.new(expr,
|
|
975
|
+
{:value => '===' },
|
|
976
|
+
[[TempNode.new(case_ref)]]
|
|
977
|
+
).generate(opts, LEVEL_EXPR) + '.$r'
|
|
978
|
+
end
|
|
979
|
+
opts[:indent] = opts[:indent] + INDENT
|
|
980
|
+
code += " (#{parts.join ' || '}) {#{part[2].process opts, stmt_level}"
|
|
981
|
+
else
|
|
982
|
+
code += "} else {#{part[1].process opts, stmt_level}"
|
|
983
|
+
end
|
|
984
|
+
end
|
|
985
|
+
|
|
986
|
+
opts[:indent] = old_indent
|
|
987
|
+
|
|
988
|
+
opts[:scope].queue_temp case_ref
|
|
989
|
+
code += (fix_line_number(opts, @end_line) + '}')
|
|
990
|
+
|
|
783
991
|
code = "(function() {#{code})()" if level == LEVEL_EXPR
|
|
784
992
|
code
|
|
785
993
|
end
|
|
786
994
|
end
|
|
787
995
|
|
|
996
|
+
class TempNode < BaseNode
|
|
997
|
+
|
|
998
|
+
def initialize(val)
|
|
999
|
+
@val = val
|
|
1000
|
+
@line = 0
|
|
1001
|
+
end
|
|
1002
|
+
|
|
1003
|
+
def generate(opts, level)
|
|
1004
|
+
@val
|
|
1005
|
+
end
|
|
1006
|
+
end
|
|
1007
|
+
|
|
788
1008
|
class ConstantNode < BaseNode
|
|
789
1009
|
|
|
790
1010
|
def initialize(name)
|
|
@@ -797,7 +1017,7 @@ class Opal::RubyParser < Racc::Parser
|
|
|
797
1017
|
end
|
|
798
1018
|
|
|
799
1019
|
def generate(opts, level)
|
|
800
|
-
"
|
|
1020
|
+
"$cg(#{SelfNode.new.generate opts, level}, '#{@name}')"
|
|
801
1021
|
end
|
|
802
1022
|
end
|
|
803
1023
|
|
|
@@ -811,7 +1031,7 @@ class Opal::RubyParser < Racc::Parser
|
|
|
811
1031
|
|
|
812
1032
|
def generate(opts, level)
|
|
813
1033
|
# FIXME This should really be 'const at'.. const_get will relook all the way up chain
|
|
814
|
-
"
|
|
1034
|
+
"$cg(#{@lhs.generate opts, level}, '#{@name}')"
|
|
815
1035
|
end
|
|
816
1036
|
end
|
|
817
1037
|
|
|
@@ -840,17 +1060,22 @@ class Opal::RubyParser < Racc::Parser
|
|
|
840
1060
|
return "#{SelfNode.new.generate(opts, level)}['#{@lhs.value}'] = #{@rhs.generate(opts, LEVEL_EXPR)}"
|
|
841
1061
|
|
|
842
1062
|
elsif @lhs.is_a? GvarNode
|
|
843
|
-
return "
|
|
1063
|
+
return "$rb.gs('#{@lhs.value}', #{@rhs.generate(opts, LEVEL_EXPR)})"
|
|
844
1064
|
|
|
845
1065
|
elsif @lhs.is_a? IdentifierNode
|
|
846
1066
|
opts[:scope].ensure_variable @lhs.value
|
|
1067
|
+
|
|
1068
|
+
# optimize yield assigning
|
|
1069
|
+
if @rhs.is_a?(YieldNode) and level == LEVEL_TOP
|
|
1070
|
+
return @rhs.generate_assign(opts, @lhs)
|
|
1071
|
+
end
|
|
847
1072
|
return @lhs.value + " = " + @rhs.generate(opts, LEVEL_EXPR)
|
|
848
1073
|
|
|
849
1074
|
elsif @lhs.is_a? ArefNode
|
|
850
1075
|
return AsetNode.new(@lhs.recv, @lhs.arefs, @rhs).process(opts, level)
|
|
851
1076
|
|
|
852
1077
|
elsif @lhs.is_a? ConstantNode
|
|
853
|
-
return "
|
|
1078
|
+
return "$rb.cs(self, '#{@lhs.value}', #{@rhs.generate(opts, LEVEL_EXPR)})"
|
|
854
1079
|
|
|
855
1080
|
elsif @lhs.is_a? CallNode
|
|
856
1081
|
return CallNode.new(@lhs.recv, { :value => @lhs.mid + '=', :line => @line }, [[@rhs]]).generate(opts, level);
|
|
@@ -861,6 +1086,54 @@ class Opal::RubyParser < Racc::Parser
|
|
|
861
1086
|
end
|
|
862
1087
|
end
|
|
863
1088
|
|
|
1089
|
+
class MlhsAssignNode < BaseNode
|
|
1090
|
+
|
|
1091
|
+
def initialize(node, lhs, rhs)
|
|
1092
|
+
@line = node[:line]
|
|
1093
|
+
@lhs = lhs
|
|
1094
|
+
@rhs = rhs
|
|
1095
|
+
end
|
|
1096
|
+
|
|
1097
|
+
def generate(opts, level)
|
|
1098
|
+
@lhs.inspect
|
|
1099
|
+
@generator_opts = opts
|
|
1100
|
+
'(' + generate_mlhs_context(@lhs, @rhs) + ')'
|
|
1101
|
+
end
|
|
1102
|
+
|
|
1103
|
+
def generate_mlhs_context(arr, rhs)
|
|
1104
|
+
puts "mlhs node at #@line"
|
|
1105
|
+
parts = []
|
|
1106
|
+
|
|
1107
|
+
tmp_recv = @generator_opts[:scope].temp_local
|
|
1108
|
+
tmp_len = @generator_opts[:scope].temp_local
|
|
1109
|
+
rhs_code = rhs.generate @generator_opts, LEVEL_EXPR
|
|
1110
|
+
|
|
1111
|
+
parts << "#{tmp_recv} = #{rhs_code}"
|
|
1112
|
+
parts << "(#{tmp_recv}.$flags & $rb.T_ARRAY) || (#{tmp_recv} = [#{tmp_recv}])"
|
|
1113
|
+
parts << "#{tmp_len} = #{tmp_recv}.length"
|
|
1114
|
+
|
|
1115
|
+
if arr[0]
|
|
1116
|
+
arr[0].each_with_index do |part, idx|
|
|
1117
|
+
if part.is_a? Array
|
|
1118
|
+
parts.push generate_mlhs_context part, rhs
|
|
1119
|
+
else
|
|
1120
|
+
assign = AssignNode.new part, TempNode.new("#{tmp_recv}[#{idx}]")
|
|
1121
|
+
code = assign.generate @generator_opts, LEVEL_EXPR
|
|
1122
|
+
parts.push "#{idx} < #{tmp_len} ? #{code} : nil"
|
|
1123
|
+
# parts.push assign.generate @generator_opts, LEVE<D-/>L_EXPR
|
|
1124
|
+
end
|
|
1125
|
+
end
|
|
1126
|
+
end
|
|
1127
|
+
|
|
1128
|
+
parts << tmp_recv
|
|
1129
|
+
|
|
1130
|
+
@generator_opts[:scope].queue_temp tmp_recv
|
|
1131
|
+
@generator_opts[:scope].queue_temp tmp_len
|
|
1132
|
+
|
|
1133
|
+
parts.join ', '
|
|
1134
|
+
end
|
|
1135
|
+
end
|
|
1136
|
+
|
|
864
1137
|
class OpAsgnNode < BaseNode
|
|
865
1138
|
|
|
866
1139
|
def initialize(asgn, lhs, rhs)
|
|
@@ -900,7 +1173,6 @@ class Opal::RubyParser < Racc::Parser
|
|
|
900
1173
|
end
|
|
901
1174
|
|
|
902
1175
|
class IdentifierNode < BaseNode
|
|
903
|
-
|
|
904
1176
|
attr_reader :value
|
|
905
1177
|
|
|
906
1178
|
def initialize(val)
|
|
@@ -908,6 +1180,10 @@ class Opal::RubyParser < Racc::Parser
|
|
|
908
1180
|
@value = val[:value]
|
|
909
1181
|
end
|
|
910
1182
|
|
|
1183
|
+
def local_variable?(opts)
|
|
1184
|
+
opts[:scope].find_variable(@value) ? true : false
|
|
1185
|
+
end
|
|
1186
|
+
|
|
911
1187
|
def generate(opts, level)
|
|
912
1188
|
if opts[:scope].find_variable @value
|
|
913
1189
|
@value
|
|
@@ -943,6 +1219,8 @@ class Opal::RubyParser < Racc::Parser
|
|
|
943
1219
|
elsif @parts.length == 1
|
|
944
1220
|
if @parts[0][0] == 'string_content'
|
|
945
1221
|
@join + @parts[0][1][:value] + @join
|
|
1222
|
+
elsif @parts[0][0] == 'string_dbegin'
|
|
1223
|
+
CallNode.new(@parts[0][1], { :value => 'to_s', :line => 0 }, [[]]).generate(opts, level)
|
|
946
1224
|
end
|
|
947
1225
|
|
|
948
1226
|
else
|
|
@@ -1006,6 +1284,18 @@ class Opal::RubyParser < Racc::Parser
|
|
|
1006
1284
|
args[0].each do |arg|
|
|
1007
1285
|
param_variable arg[:value]
|
|
1008
1286
|
method_args << arg[:value]
|
|
1287
|
+
|
|
1288
|
+
# Argument checking.. If normal args are required but not passed
|
|
1289
|
+
# they just default to nil. Lambdas have the same effect as
|
|
1290
|
+
# methods, so we check this by wrapping lambdas in an anon
|
|
1291
|
+
# function that knows the arity of this block. So here, make all
|
|
1292
|
+
# norm args nil if not present.
|
|
1293
|
+
#
|
|
1294
|
+
# Also, this is optional, and can be turned on/off for
|
|
1295
|
+
# performance gains.
|
|
1296
|
+
if true
|
|
1297
|
+
pre_code += "if (#{arg[:value]} === undefined) { #{arg[:value]} = nil; }"
|
|
1298
|
+
end
|
|
1009
1299
|
end
|
|
1010
1300
|
end
|
|
1011
1301
|
|
|
@@ -1015,17 +1305,26 @@ class Opal::RubyParser < Racc::Parser
|
|
|
1015
1305
|
opt_arg_name = arg[0][:value]
|
|
1016
1306
|
param_variable opt_arg_name
|
|
1017
1307
|
method_args << arg[0][:value]
|
|
1018
|
-
pre_code += "if (#{opt_arg_name}
|
|
1308
|
+
pre_code += "if (#{opt_arg_name} === undefined) { #{opt_arg_name} = #{arg[1].generate(opts, level)};}"
|
|
1019
1309
|
end
|
|
1020
1310
|
end
|
|
1021
1311
|
|
|
1022
1312
|
# rest args
|
|
1023
1313
|
if args[2]
|
|
1314
|
+
# ignore rest arg if it is anonymous
|
|
1315
|
+
unless args[2][:value] == '*'
|
|
1024
1316
|
rest_arg_name = args[2][:value]
|
|
1025
1317
|
# FIXME if we just pass '*', then we make a tmp variable name for it..
|
|
1026
1318
|
param_variable rest_arg_name
|
|
1027
1319
|
method_args << rest_arg_name
|
|
1028
|
-
pre_code += "#{rest_arg_name} = [].slice.call(
|
|
1320
|
+
pre_code += "#{rest_arg_name} = [].slice.call($A, #{method_args.length});"
|
|
1321
|
+
end
|
|
1322
|
+
end
|
|
1323
|
+
|
|
1324
|
+
# block arg
|
|
1325
|
+
if args[3]
|
|
1326
|
+
param_variable args[3][:value]
|
|
1327
|
+
@block_arg_name = args[3][:value]
|
|
1029
1328
|
end
|
|
1030
1329
|
end
|
|
1031
1330
|
|
|
@@ -1033,13 +1332,33 @@ class Opal::RubyParser < Racc::Parser
|
|
|
1033
1332
|
stmt = @stmt.process scope, LEVEL_TOP
|
|
1034
1333
|
method_args.unshift 'self'
|
|
1035
1334
|
|
|
1335
|
+
block_var = opts[:scope].temp_local
|
|
1336
|
+
# code += "(#{block_var} = "
|
|
1337
|
+
|
|
1036
1338
|
code += "function(#{method_args.join ', '}) {"
|
|
1037
|
-
|
|
1339
|
+
|
|
1038
1340
|
unless @scope_vars.empty?
|
|
1039
1341
|
code += " var #{@scope_vars.join ', '};"
|
|
1040
1342
|
end
|
|
1041
1343
|
|
|
1344
|
+
# block arg
|
|
1345
|
+
if @block_arg_name
|
|
1346
|
+
pre_code += "var $yield, #@block_arg_name; if ($B.f == arguments.callee && $B.p != nil) { #@block_arg_name = "
|
|
1347
|
+
pre_code += "$yield = $B.p; } else { #@block_arg_name = nil; "
|
|
1348
|
+
pre_code += "$yield = $B.y; } $B.p = $B.f = nil;"
|
|
1349
|
+
pre_code += "var $yself = $yield.$proc[0];"
|
|
1350
|
+
|
|
1351
|
+
stmt = "try{" + stmt
|
|
1352
|
+
|
|
1353
|
+
# catch break statements
|
|
1354
|
+
stmt += "} catch (__err__) {if(__err__.$keyword == 2) {return __err__.$value;} throw __err__;}"
|
|
1355
|
+
end
|
|
1356
|
+
|
|
1042
1357
|
code += (pre_code + stmt + fix_line_number(opts, @end_line) + "}")
|
|
1358
|
+
|
|
1359
|
+
# code += ", #{block_var}.$arity = 0, #{block_var}.$meth = null"
|
|
1360
|
+
# code += ", #{block_var})"
|
|
1361
|
+
opts[:scope].queue_temp block_var
|
|
1043
1362
|
code
|
|
1044
1363
|
end
|
|
1045
1364
|
end
|
|
@@ -1123,7 +1442,8 @@ class Opal::RubyParser < Racc::Parser
|
|
|
1123
1442
|
end
|
|
1124
1443
|
|
|
1125
1444
|
def generate(opts, level)
|
|
1126
|
-
(@arefs[0]
|
|
1445
|
+
@arefs[0] || (@arefs[0] = [])
|
|
1446
|
+
@arefs[0] << @val
|
|
1127
1447
|
CallNode.new(@recv, { :line => @line, :value => '[]='}, @arefs ).generate(opts, level)
|
|
1128
1448
|
end
|
|
1129
1449
|
end
|
|
@@ -1160,36 +1480,239 @@ class Opal::RubyParser < Racc::Parser
|
|
|
1160
1480
|
end
|
|
1161
1481
|
end
|
|
1162
1482
|
|
|
1163
|
-
class
|
|
1483
|
+
class YieldNode < BaseNode
|
|
1484
|
+
|
|
1485
|
+
def initialize(start, args)
|
|
1486
|
+
@line = start[:line]
|
|
1487
|
+
@args = args
|
|
1488
|
+
end
|
|
1489
|
+
|
|
1490
|
+
# Get basic yielding code yield(yself,...)
|
|
1491
|
+
def yield_code(opts)
|
|
1492
|
+
block_code = "$yy"
|
|
1493
|
+
|
|
1494
|
+
parts = []
|
|
1495
|
+
|
|
1496
|
+
if @args[0]
|
|
1497
|
+
@args[0].each { |arg| parts << arg.generate(opts, LEVEL_EXPR) }
|
|
1498
|
+
end
|
|
1499
|
+
|
|
1500
|
+
if @args[1]
|
|
1501
|
+
parts.unshift '$ys'
|
|
1502
|
+
code = "#{block_code}(null, [#{parts.join ', '}].concat(#{@args[1].generate(opts, LEVEL_EXPR)}))"
|
|
1503
|
+
else
|
|
1504
|
+
parts.unshift '$ys'
|
|
1505
|
+
code = "#{block_code}(#{parts.join ', '})"
|
|
1506
|
+
end
|
|
1164
1507
|
|
|
1165
|
-
|
|
1166
|
-
@line = given[:line]
|
|
1508
|
+
code
|
|
1167
1509
|
end
|
|
1168
1510
|
|
|
1169
1511
|
def generate(opts, level)
|
|
1170
|
-
|
|
1171
|
-
|
|
1512
|
+
# need to get block from nearest method
|
|
1513
|
+
block = opts[:scope].set_uses_block
|
|
1514
|
+
code = yield_code opts
|
|
1515
|
+
|
|
1516
|
+
if level == LEVEL_TOP
|
|
1517
|
+
"if (#{code} == $yb) { return $yb.$value; }"
|
|
1518
|
+
else
|
|
1519
|
+
# basically we need to return out of this method and we are not
|
|
1520
|
+
# top level so we will need to throw and error which is caught
|
|
1521
|
+
# directly inside this method which just returns the break
|
|
1522
|
+
# value. We should warn that the given code is going to cause
|
|
1523
|
+
# a try/catch statement to be added to check for this. i.e. this
|
|
1524
|
+
# can/should be optimized out in the source code
|
|
1525
|
+
tmp = opts[:scope].temp_local
|
|
1526
|
+
"((#{tmp} = #{code}) == $yb ? $break() : #{tmp})"
|
|
1527
|
+
end
|
|
1528
|
+
end
|
|
1529
|
+
|
|
1530
|
+
# special generator for assigning to variable. We know we will be
|
|
1531
|
+
# top level if this is called.
|
|
1532
|
+
def generate_assign(opts, lhs)
|
|
1533
|
+
"if ((#{lhs.value} = #{yield_code opts}) == $yb) { return $yb.$value; }"
|
|
1172
1534
|
end
|
|
1173
1535
|
end
|
|
1174
1536
|
|
|
1175
|
-
class
|
|
1537
|
+
class BreakNode < BaseNode
|
|
1176
1538
|
|
|
1177
1539
|
def initialize(start, args)
|
|
1178
1540
|
@line = start[:line]
|
|
1179
1541
|
@args = args
|
|
1180
1542
|
end
|
|
1181
1543
|
|
|
1544
|
+
# as we either throw or return ourself we can ignore the
|
|
1545
|
+
# request to return ourself if last statement
|
|
1546
|
+
def returns
|
|
1547
|
+
self
|
|
1548
|
+
end
|
|
1549
|
+
|
|
1182
1550
|
def generate(opts, level)
|
|
1183
|
-
|
|
1184
|
-
|
|
1551
|
+
code = []
|
|
1552
|
+
|
|
1553
|
+
if @args[0]
|
|
1554
|
+
@args[0].each { |arg| code << arg.generate(opts, LEVEL_EXPR) }
|
|
1555
|
+
end
|
|
1556
|
+
|
|
1557
|
+
case code.length
|
|
1558
|
+
when 0
|
|
1559
|
+
code = "nil"
|
|
1560
|
+
when 1
|
|
1561
|
+
code = code[0]
|
|
1562
|
+
else
|
|
1563
|
+
code = '[' + code.join(', ') + ']'
|
|
1564
|
+
end
|
|
1565
|
+
|
|
1566
|
+
if opts[:scope].in_while_scope?
|
|
1567
|
+
while_scope = opts[:scope].while_scope
|
|
1568
|
+
tmp_break_val = while_scope.set_captures_break
|
|
1569
|
+
"#{tmp_break_val} = #{code}; break"
|
|
1570
|
+
elsif opts[:scope].is_a? BlockNode
|
|
1571
|
+
if level == LEVEL_TOP
|
|
1572
|
+
"return ($B.b.$value = #{code}, $B.b)"
|
|
1573
|
+
else
|
|
1574
|
+
# block must have a try/catch wrapper inside to detect
|
|
1575
|
+
# breaks and return the break value if a break is fired.
|
|
1576
|
+
# We should also warn that the ruby code is not optimized
|
|
1577
|
+
# and suggest it is reconfigured to avoid the (possibly)
|
|
1578
|
+
# expensive try/catch block.
|
|
1579
|
+
"$break(#{code})"
|
|
1580
|
+
end
|
|
1581
|
+
else
|
|
1582
|
+
"$break(#{code})"
|
|
1583
|
+
end
|
|
1584
|
+
end
|
|
1585
|
+
end
|
|
1586
|
+
|
|
1587
|
+
class NextNode < BaseNode
|
|
1588
|
+
|
|
1589
|
+
def initialize(start, args)
|
|
1590
|
+
@line = start[:line]
|
|
1591
|
+
@args = args
|
|
1592
|
+
end
|
|
1593
|
+
|
|
1594
|
+
def returns
|
|
1595
|
+
self
|
|
1596
|
+
end
|
|
1597
|
+
|
|
1598
|
+
def generate(opts, level)
|
|
1599
|
+
code = []
|
|
1600
|
+
|
|
1601
|
+
if @args[0]
|
|
1602
|
+
@args[0].each { |arg| code << arg.generate(opts, LEVEL_EXPR) }
|
|
1603
|
+
end
|
|
1604
|
+
|
|
1605
|
+
case code.length
|
|
1606
|
+
when 0
|
|
1607
|
+
code = "nil"
|
|
1608
|
+
when 1
|
|
1609
|
+
code = code[0]
|
|
1610
|
+
else
|
|
1611
|
+
code = '[' + code.join(', ') + ']'
|
|
1612
|
+
end
|
|
1613
|
+
|
|
1614
|
+
if opts[:scope].in_while_scope?
|
|
1615
|
+
"continue"
|
|
1616
|
+
else
|
|
1617
|
+
# if in block
|
|
1618
|
+
"return #{code}"
|
|
1619
|
+
# else if in while/until loop
|
|
1620
|
+
|
|
1621
|
+
end
|
|
1622
|
+
end
|
|
1623
|
+
end
|
|
1624
|
+
|
|
1625
|
+
class RedoNode < BaseNode
|
|
1626
|
+
|
|
1627
|
+
def initialize(start)
|
|
1628
|
+
@line = start[:line]
|
|
1629
|
+
end
|
|
1630
|
+
|
|
1631
|
+
def generate(opts, level)
|
|
1632
|
+
if opts[:scope].in_while_scope?
|
|
1633
|
+
"#{opts[:scope].while_scope.redo_var} = true"
|
|
1634
|
+
else
|
|
1635
|
+
"REDO()"
|
|
1636
|
+
end
|
|
1637
|
+
end
|
|
1638
|
+
end
|
|
1639
|
+
|
|
1640
|
+
class WhileNode < BaseNode
|
|
1641
|
+
|
|
1642
|
+
attr_reader :redo_var
|
|
1643
|
+
|
|
1644
|
+
def initialize(begn, exp, stmt, endn)
|
|
1645
|
+
@line = begn[:line]
|
|
1646
|
+
@type = begn[:value]
|
|
1647
|
+
@expr = exp
|
|
1648
|
+
@stmt = stmt
|
|
1649
|
+
@end_line = endn[:line]
|
|
1650
|
+
end
|
|
1651
|
+
|
|
1652
|
+
def returns
|
|
1653
|
+
@returns = true
|
|
1654
|
+
self
|
|
1655
|
+
end
|
|
1656
|
+
|
|
1657
|
+
def set_captures_break
|
|
1658
|
+
tmp = @current_scope.temp_local
|
|
1659
|
+
@captures_break = tmp
|
|
1660
|
+
end
|
|
1661
|
+
|
|
1662
|
+
def generate(opts, level)
|
|
1663
|
+
@current_scope = opts[:scope]
|
|
1664
|
+
stmt_level = (level == LEVEL_EXPR ? LEVEL_TOP_CLOSURE : LEVEL_TOP)
|
|
1665
|
+
truthy = @type == 'while' ? '' : '!'
|
|
1666
|
+
|
|
1667
|
+
if stmt_level == LEVEL_TOP_CLOSURE
|
|
1668
|
+
returns
|
|
1669
|
+
@level_expr = true
|
|
1670
|
+
end
|
|
1671
|
+
|
|
1672
|
+
@redo_var = eval_expr = opts[:scope].temp_local
|
|
1673
|
+
code = "#{eval_expr} = false; while (#{eval_expr} || #{truthy}("
|
|
1674
|
+
code += @expr.generate opts, LEVEL_EXPR
|
|
1675
|
+
code += ").$r) {#{eval_expr} = false;"
|
|
1676
|
+
|
|
1677
|
+
opts[:scope].push_while_scope self
|
|
1678
|
+
|
|
1679
|
+
code += @stmt.process opts, LEVEL_TOP
|
|
1185
1680
|
|
|
1186
|
-
|
|
1681
|
+
opts[:scope].pop_while_scope
|
|
1682
|
+
|
|
1683
|
+
code += fix_line_number opts, @end_line
|
|
1684
|
+
code += "}"
|
|
1685
|
+
|
|
1686
|
+
opts[:scope].queue_temp eval_expr
|
|
1687
|
+
|
|
1688
|
+
return_value = "nil"
|
|
1689
|
+
|
|
1690
|
+
if @captures_break
|
|
1691
|
+
code = "#@captures_break = nil; #{code}"
|
|
1692
|
+
opts[:scope].queue_temp @captures_break
|
|
1693
|
+
return_value = @captures_break
|
|
1694
|
+
end
|
|
1695
|
+
|
|
1696
|
+
code = "(function() {#{code} return #{return_value};})()" if stmt_level == LEVEL_TOP_CLOSURE
|
|
1697
|
+
code
|
|
1698
|
+
end
|
|
1699
|
+
end
|
|
1700
|
+
|
|
1701
|
+
class SuperNode < BaseNode
|
|
1702
|
+
|
|
1703
|
+
def initialize(start, args)
|
|
1704
|
+
@line = start[:line]
|
|
1705
|
+
@args = args
|
|
1706
|
+
end
|
|
1707
|
+
|
|
1708
|
+
def generate(opts, level)
|
|
1709
|
+
parts = []
|
|
1187
1710
|
|
|
1188
1711
|
if @args[0]
|
|
1189
1712
|
@args[0].each { |arg| parts << arg.generate(opts, LEVEL_EXPR) }
|
|
1190
1713
|
end
|
|
1191
1714
|
|
|
1192
|
-
"
|
|
1715
|
+
"$super(arguments.callee, self, [#{parts.join ', '}])"
|
|
1193
1716
|
end
|
|
1194
1717
|
end
|
|
1195
1718
|
|
|
@@ -1214,6 +1737,9 @@ class Opal::RubyParser < Racc::Parser
|
|
|
1214
1737
|
else
|
|
1215
1738
|
# this really should return array of return vals
|
|
1216
1739
|
code = NilNode.new.generate opts, level
|
|
1740
|
+
code = []
|
|
1741
|
+
args[0].each { |arg| code << arg.generate(opts, LEVEL_EXPR) }
|
|
1742
|
+
code = code = '[' + code.join(', ') + ']'
|
|
1217
1743
|
end
|
|
1218
1744
|
|
|
1219
1745
|
# if we are in a block, we need to throw return to nearest mthod
|
|
@@ -1241,16 +1767,16 @@ class Opal::RubyParser < Racc::Parser
|
|
|
1241
1767
|
def generate(opts, level)
|
|
1242
1768
|
code = "try {"
|
|
1243
1769
|
old_indent = opts[:indent]
|
|
1244
|
-
opts[:indent]
|
|
1770
|
+
opts[:indent] = opts[:indent] + INDENT
|
|
1245
1771
|
|
|
1246
1772
|
code += @body.process opts, LEVEL_TOP
|
|
1247
1773
|
code += "} catch (__err__) {"
|
|
1248
1774
|
|
|
1249
1775
|
@body.opt_rescue.each do |res|
|
|
1250
1776
|
code += "#{fix_line_number opts, res[0][:line]}if (true){"
|
|
1251
|
-
opts[:indent]
|
|
1252
|
-
opts[:scope].ensure_variable res[2].value
|
|
1253
|
-
code += (res[2].value + " = __err__;")
|
|
1777
|
+
opts[:indent] = opts[:indent] + INDENT
|
|
1778
|
+
opts[:scope].ensure_variable res[2].value if res[2]
|
|
1779
|
+
code += (res[2].value + " = __err__;") if res[2]
|
|
1254
1780
|
code += "#{res[3].process opts, LEVEL_TOP}}"
|
|
1255
1781
|
opts[:indent] = old_indent + INDENT
|
|
1256
1782
|
end
|
|
@@ -1262,6 +1788,20 @@ class Opal::RubyParser < Racc::Parser
|
|
|
1262
1788
|
end
|
|
1263
1789
|
end
|
|
1264
1790
|
|
|
1791
|
+
class TernaryNode < BaseNode
|
|
1792
|
+
|
|
1793
|
+
def initialize(expr, truthy, falsy)
|
|
1794
|
+
@line = expr.line
|
|
1795
|
+
@expr = expr
|
|
1796
|
+
@true = truthy
|
|
1797
|
+
@false = falsy
|
|
1798
|
+
end
|
|
1799
|
+
|
|
1800
|
+
def generate(opts, level)
|
|
1801
|
+
"(#{@expr.generate opts, LEVEL_EXPR}.$r ? #{@true.generate opts, LEVEL_EXPR} : #{@false.generate opts, LEVEL_EXPR})"
|
|
1802
|
+
end
|
|
1803
|
+
end
|
|
1804
|
+
|
|
1265
1805
|
class GvarNode < BaseNode
|
|
1266
1806
|
|
|
1267
1807
|
attr_reader :value
|
|
@@ -1272,7 +1812,7 @@ class Opal::RubyParser < Racc::Parser
|
|
|
1272
1812
|
end
|
|
1273
1813
|
|
|
1274
1814
|
def generate(opts, level)
|
|
1275
|
-
"
|
|
1815
|
+
"$rb.gg('#{@value}')"
|
|
1276
1816
|
end
|
|
1277
1817
|
end
|
|
1278
1818
|
|
|
@@ -1295,8 +1835,89 @@ class Opal::RubyParser < Racc::Parser
|
|
|
1295
1835
|
end
|
|
1296
1836
|
|
|
1297
1837
|
def generate(opts, level)
|
|
1298
|
-
@val
|
|
1838
|
+
"(#{@val})"
|
|
1839
|
+
end
|
|
1840
|
+
end
|
|
1841
|
+
|
|
1842
|
+
class RegexpNode < BaseNode
|
|
1843
|
+
|
|
1844
|
+
def initialize(begn, parts)
|
|
1845
|
+
@line = begn[:line]
|
|
1846
|
+
@parts = parts
|
|
1847
|
+
end
|
|
1848
|
+
|
|
1849
|
+
def generate(opts, level)
|
|
1850
|
+
parts = @parts.map do |part|
|
|
1851
|
+
if part[0] == 'string_content'
|
|
1852
|
+
part[1][:value]
|
|
1853
|
+
elsif part[0] == 'string_dbegin'
|
|
1854
|
+
part[1].generate opts, LEVEL_EXPR
|
|
1855
|
+
end
|
|
1856
|
+
end
|
|
1857
|
+
|
|
1858
|
+
"/#{parts.join ''}/"
|
|
1859
|
+
end
|
|
1860
|
+
end
|
|
1861
|
+
|
|
1862
|
+
class WordsNode < BaseNode
|
|
1863
|
+
|
|
1864
|
+
def initialize(begn, parts, endn)
|
|
1865
|
+
@line = begn[:line]
|
|
1866
|
+
@parts = parts
|
|
1867
|
+
@end_line = endn[:line]
|
|
1868
|
+
end
|
|
1869
|
+
|
|
1870
|
+
def generate(opts, level)
|
|
1871
|
+
parts = @parts.map do |part|
|
|
1872
|
+
if part[0] == 'string_content'
|
|
1873
|
+
part[1][:value].inspect
|
|
1874
|
+
else
|
|
1875
|
+
CallNode.new(part[1], {:value => 'to_s', :line => @line }, []).generate(opts, LEVEL_EXPR)
|
|
1876
|
+
end
|
|
1877
|
+
end
|
|
1878
|
+
|
|
1879
|
+
'[' + parts.join(', ') + ']'
|
|
1880
|
+
end
|
|
1881
|
+
end
|
|
1882
|
+
|
|
1883
|
+
class RangeNode < BaseNode
|
|
1884
|
+
|
|
1885
|
+
def initialize(range, beg, last)
|
|
1886
|
+
@line = beg.line
|
|
1887
|
+
@beg = beg
|
|
1888
|
+
@last = last
|
|
1889
|
+
@range = range[:value]
|
|
1890
|
+
@end_line = last.line
|
|
1891
|
+
end
|
|
1892
|
+
|
|
1893
|
+
def generate(opts, level)
|
|
1894
|
+
beg = @beg.generate opts, LEVEL_EXPR
|
|
1895
|
+
last = @last.generate opts, LEVEL_EXPR
|
|
1896
|
+
excl = @range == '...'
|
|
1897
|
+
"$range(#{beg}, #{last}, #{excl})"
|
|
1898
|
+
end
|
|
1899
|
+
end
|
|
1900
|
+
|
|
1901
|
+
class UndefNode < BaseNode
|
|
1902
|
+
|
|
1903
|
+
def initialize(start, parts)
|
|
1904
|
+
@line = start[:line]
|
|
1905
|
+
@parts = parts
|
|
1906
|
+
end
|
|
1907
|
+
|
|
1908
|
+
def generate(opts, level)
|
|
1909
|
+
parts = @parts.map do |a|
|
|
1910
|
+
if a.is_a? SymbolNode
|
|
1911
|
+
a.generate opts, level
|
|
1912
|
+
else
|
|
1913
|
+
'"' + a[:value] + '"'
|
|
1914
|
+
end
|
|
1915
|
+
end
|
|
1916
|
+
parts.unshift 'self'
|
|
1917
|
+
"$rb.um(#{parts.join ', '})"
|
|
1299
1918
|
end
|
|
1300
1919
|
end
|
|
1301
1920
|
end
|
|
1921
|
+
end
|
|
1922
|
+
|
|
1302
1923
|
|