opal 0.3.20 → 0.3.21

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.
Files changed (122) hide show
  1. data/.gitignore +2 -7
  2. data/.rspec +2 -0
  3. data/.travis.yml +11 -0
  4. data/Gemfile +8 -2
  5. data/LICENSE +2 -3
  6. data/README.md +106 -239
  7. data/Rakefile +58 -16
  8. data/bin/opal +1 -0
  9. data/core/array.rb +180 -160
  10. data/core/basic_object.rb +8 -4
  11. data/core/boolean.rb +6 -6
  12. data/core/class.rb +9 -15
  13. data/core/dir.rb +89 -0
  14. data/core/enumerable.rb +83 -86
  15. data/core/error.rb +9 -4
  16. data/core/file.rb +85 -0
  17. data/core/hash.rb +67 -67
  18. data/core/kernel.rb +38 -42
  19. data/core/module.rb +57 -54
  20. data/core/numeric.rb +41 -41
  21. data/core/proc.rb +1 -5
  22. data/core/range.rb +11 -11
  23. data/core/regexp.rb +27 -22
  24. data/core/runtime.js +152 -221
  25. data/core/string.rb +86 -73
  26. data/core/time.rb +22 -18
  27. data/docs/post.html +9 -0
  28. data/docs/pre.html +32 -0
  29. data/lib/opal.rb +43 -3
  30. data/lib/opal/builder.rb +9 -26
  31. data/lib/opal/grammar.rb +1 -1
  32. data/lib/opal/grammar.y +1 -1
  33. data/lib/opal/lexer.rb +21 -15
  34. data/lib/opal/parser.rb +100 -111
  35. data/lib/opal/rake_task.rb +66 -0
  36. data/lib/opal/scope.rb +13 -5
  37. data/lib/opal/version.rb +1 -1
  38. data/opal.gemspec +2 -0
  39. data/spec/browser_spec.rb +28 -0
  40. data/spec/builder/lib_name_for_spec.rb +1 -6
  41. data/spec/grammar/alias_spec.rb +1 -1
  42. data/spec/grammar/and_spec.rb +1 -1
  43. data/spec/grammar/array_spec.rb +1 -1
  44. data/spec/grammar/attrasgn_spec.rb +1 -1
  45. data/spec/grammar/begin_spec.rb +1 -1
  46. data/spec/grammar/block_spec.rb +1 -1
  47. data/spec/grammar/break_spec.rb +1 -1
  48. data/spec/grammar/call_spec.rb +1 -1
  49. data/spec/grammar/class_spec.rb +1 -1
  50. data/spec/grammar/const_spec.rb +1 -1
  51. data/spec/grammar/cvar_spec.rb +1 -1
  52. data/spec/grammar/def_spec.rb +1 -1
  53. data/spec/grammar/false_spec.rb +1 -1
  54. data/spec/grammar/file_spec.rb +1 -1
  55. data/spec/grammar/gvar_spec.rb +1 -1
  56. data/spec/grammar/hash_spec.rb +1 -1
  57. data/spec/grammar/iasgn_spec.rb +1 -1
  58. data/spec/grammar/if_spec.rb +1 -1
  59. data/spec/grammar/iter_spec.rb +1 -1
  60. data/spec/grammar/ivar_spec.rb +1 -1
  61. data/spec/grammar/lambda_spec.rb +1 -1
  62. data/spec/grammar/lasgn_spec.rb +1 -1
  63. data/spec/grammar/line_spec.rb +1 -1
  64. data/spec/grammar/lvar_spec.rb +1 -1
  65. data/spec/grammar/masgn_spec.rb +1 -1
  66. data/spec/grammar/module_spec.rb +1 -1
  67. data/spec/grammar/nil_spec.rb +1 -1
  68. data/spec/grammar/not_spec.rb +1 -1
  69. data/spec/grammar/op_asgn1_spec.rb +1 -1
  70. data/spec/grammar/op_asgn2_spec.rb +1 -1
  71. data/spec/grammar/or_spec.rb +1 -1
  72. data/spec/grammar/return_spec.rb +1 -1
  73. data/spec/grammar/sclass_spec.rb +1 -1
  74. data/spec/grammar/self_spec.rb +1 -1
  75. data/spec/grammar/str_spec.rb +1 -1
  76. data/spec/grammar/super_spec.rb +1 -1
  77. data/spec/grammar/true_spec.rb +1 -1
  78. data/spec/grammar/undef_spec.rb +1 -1
  79. data/spec/grammar/unless_spec.rb +1 -1
  80. data/spec/grammar/while_spec.rb +1 -1
  81. data/spec/grammar/xstr_spec.rb +1 -1
  82. data/spec/grammar/yield_spec.rb +1 -1
  83. data/spec/spec_helper.rb +6 -1
  84. data/test/core/array/minus_spec.rb +13 -0
  85. data/test/core/enumerable/drop_while_spec.rb +0 -5
  86. data/test/core/range/case_compare_spec.rb +0 -1
  87. data/test/index.html +1 -1
  88. data/test/index.min.html +12 -0
  89. data/test/language/alias_spec.rb +0 -4
  90. data/test/language/fixtures/next.rb +62 -0
  91. data/test/language/metaclass_spec.rb +4 -4
  92. data/test/language/next_spec.rb +0 -63
  93. data/test/language/send_spec.rb +0 -5
  94. data/test/language/singleton_class_spec.rb +4 -0
  95. data/test/opal/array/subclassing_spec.rb +1 -1
  96. data/test/opal/class/bridge_class_spec.rb +2 -2
  97. data/test/opal/runtime/class_hierarchy_spec.rb +1 -2
  98. data/test/opal/runtime/method_missing_spec.rb +17 -0
  99. data/test/spec_helper.rb +4 -1
  100. metadata +32 -28
  101. data/docs/CNAME +0 -1
  102. data/docs/Rakefile +0 -55
  103. data/docs/css/styles.css +0 -50
  104. data/docs/css/syntax.css +0 -63
  105. data/docs/layout/post.html +0 -3
  106. data/docs/layout/pre.html +0 -11
  107. data/examples/dependencies/.gitignore +0 -1
  108. data/examples/dependencies/Gemfile +0 -6
  109. data/examples/dependencies/README.md +0 -41
  110. data/examples/dependencies/Rakefile +0 -10
  111. data/examples/dependencies/app.rb +0 -19
  112. data/examples/dependencies/build/.gitkeep +0 -0
  113. data/examples/dependencies/index.html +0 -13
  114. data/examples/hello_world/.gitignore +0 -1
  115. data/examples/hello_world/Gemfile +0 -3
  116. data/examples/hello_world/README.md +0 -27
  117. data/examples/hello_world/Rakefile +0 -23
  118. data/examples/hello_world/app.rb +0 -7
  119. data/examples/hello_world/index.html +0 -12
  120. data/lib/opal/builder_task.rb +0 -91
  121. data/spec/builder/build_order_spec.rb +0 -20
  122. data/test/opal/runtime/_methods_spec.rb +0 -48
@@ -1,13 +1,17 @@
1
1
  class Time < `Date`
2
2
  include Comparable
3
3
 
4
+ def self.allocate(t)
5
+ `new Date(t)`
6
+ end
7
+
4
8
  def self.at(seconds, frac = 0)
5
9
  allocate `seconds * 1000 + frac`
6
10
  end
7
11
 
8
12
  def self.new(year, month, day, hour, minute, second, millisecond)
9
13
  %x{
10
- switch (arguments.length) {
14
+ switch (arguments.length - 1) {
11
15
  case 1:
12
16
  return new Date(year);
13
17
  case 2:
@@ -29,7 +33,7 @@ class Time < `Date`
29
33
  end
30
34
 
31
35
  def self.now
32
- allocate
36
+ `new Date()`
33
37
  end
34
38
 
35
39
  def +(other)
@@ -45,7 +49,7 @@ class Time < `Date`
45
49
  end
46
50
 
47
51
  def day
48
- `this.getDate()`
52
+ `#{self}.getDate()`
49
53
  end
50
54
 
51
55
  def eql?(other)
@@ -53,66 +57,66 @@ class Time < `Date`
53
57
  end
54
58
 
55
59
  def friday?
56
- `this.getDay() === 5`
60
+ `#{self}.getDay() === 5`
57
61
  end
58
62
 
59
63
  def hour
60
- `this.getHours()`
64
+ `#{self}.getHours()`
61
65
  end
62
66
 
63
67
  alias mday day
64
68
 
65
69
  def min
66
- `this.getMinutes()`
70
+ `#{self}.getMinutes()`
67
71
  end
68
72
 
69
73
  def mon
70
- `this.getMonth() + 1`
74
+ `#{self}.getMonth() + 1`
71
75
  end
72
76
 
73
77
  def monday?
74
- `this.getDay() === 1`
78
+ `#{self}.getDay() === 1`
75
79
  end
76
80
 
77
81
  alias month mon
78
82
 
79
83
  def saturday?
80
- `this.getDay() === 6`
84
+ `#{self}.getDay() === 6`
81
85
  end
82
86
 
83
87
  def sec
84
- `this.getSeconds()`
88
+ `#{self}.getSeconds()`
85
89
  end
86
90
 
87
91
  def sunday?
88
- `this.getDay() === 0`
92
+ `#{self}.getDay() === 0`
89
93
  end
90
94
 
91
95
  def thursday?
92
- `this.getDay() === 4`
96
+ `#{self}.getDay() === 4`
93
97
  end
94
98
 
95
99
  def to_f
96
- `this.getTime() / 1000`
100
+ `#{self}.getTime() / 1000`
97
101
  end
98
102
 
99
103
  def to_i
100
- `parseInt(this.getTime() / 1000)`
104
+ `parseInt(#{self}.getTime() / 1000)`
101
105
  end
102
106
 
103
107
  def tuesday?
104
- `this.getDay() === 2`
108
+ `#{self}.getDay() === 2`
105
109
  end
106
110
 
107
111
  def wday
108
- `this.getDay()`
112
+ `#{self}.getDay()`
109
113
  end
110
114
 
111
115
  def wednesday?
112
- `this.getDay() === 3`
116
+ `#{self}.getDay() === 3`
113
117
  end
114
118
 
115
119
  def year
116
- `this.getFullYear()`
120
+ `#{self}.getFullYear()`
117
121
  end
118
122
  end
@@ -0,0 +1,9 @@
1
+ </section>
2
+ <footer>
3
+ <p><small>Hosted on <a href="https://pages.github.com">GitHub Pages</a> using the Dinky theme</small></p>
4
+ </footer>
5
+ </div>
6
+ <!--[if !IE]><script>fixScale(document);</script><!--<![endif]-->
7
+
8
+ </body>
9
+ </html>
@@ -0,0 +1,32 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="X-UA-Compatible" content="chrome=1">
6
+ <title>Opal by adambeynon</title>
7
+
8
+ <link rel="stylesheet" href="stylesheets/styles.css">
9
+ <link rel="stylesheet" href="stylesheets/pygment_trac.css">
10
+ <script src="javascripts/scale.fix.js"></script>
11
+ <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
12
+ <!--[if lt IE 9]>
13
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
14
+ <![endif]-->
15
+ </head>
16
+ <body>
17
+ <div class="wrapper">
18
+ <header>
19
+ <h1 class="header">Opal</h1>
20
+ <p class="header">Ruby runtime and library on top of Javascript</p>
21
+
22
+ <ul>
23
+ <li class="download"><a class="buttons" href="https://github.com/adambeynon/opal/zipball/master">Download ZIP</a></li>
24
+ <li class="download"><a class="buttons" href="https://github.com/adambeynon/opal/tarball/master">Download TAR</a></li>
25
+ <li><a class="buttons github" href="https://github.com/adambeynon/opal">View On GitHub</a></li>
26
+ </ul>
27
+
28
+ <p class="header">This project is maintained by <a class="header name" href="https://github.com/adambeynon">adambeynon</a></p>
29
+
30
+
31
+ </header>
32
+ <section>
@@ -1,20 +1,60 @@
1
1
  require 'opal/parser'
2
2
  require 'opal/builder'
3
- require 'opal/builder_task'
4
3
  require 'opal/version'
5
4
 
5
+ # Opal is a ruby to javascript compiler, with a runtime for running
6
+ # in any javascript environment.
6
7
  module Opal
8
+
7
9
  # Parse given string of ruby into javascript
10
+ #
11
+ # Opal.parse "puts 'hello world'"
12
+ # # => "(function() { ... })()"
13
+ #
14
+ # @param [String] str ruby string to parse
15
+ # @param [String] file the filename to use when parsing
16
+ # @return [String] the resulting javascript code
8
17
  def self.parse(str, file='(file)')
9
- js = Parser.new.parse str, file
10
- "(#{js})();"
18
+ "(#{ Parser.new.parse str, file })();"
11
19
  end
12
20
 
13
21
  # Returns opal runtime js code (string)
22
+ #
23
+ # Opal.runtime
24
+ # # => "(function() { Opal = {}; ... })();"
25
+ #
26
+ # @return [String] returns opal runtime/corelib as a string
14
27
  def self.runtime
15
28
  Builder.runtime
16
29
  end
17
30
 
31
+ # Build gem with given name to a string.
32
+ #
33
+ # Opal.build_gem 'opal-spec'
34
+ # # => "... javascript code ..."
35
+ #
36
+ # If the given gem name cannot be found, then an error will be
37
+ # raised
38
+ #
39
+ # @param [String] name the name of the gem
40
+ # @return [String] returns built gem
41
+ def self.build_gem(name)
42
+ spec = Gem::Specification.find_by_name name
43
+ Builder.build(:files => spec.require_paths, :dir => spec.full_gem_path)
44
+ end
45
+
46
+ # Build the given files. Files should be a string of either a full
47
+ # filename, a directory name or even a glob of files to build.
48
+ #
49
+ # Opal.build_files 'spec'
50
+ # # => all spec files in spec dir
51
+ #
52
+ # @param [String] files files to build
53
+ # @return [String]
54
+ def self.build_files(files)
55
+ Builder.build(:files => files)
56
+ end
57
+
18
58
  def self.opal_dir
19
59
  File.expand_path '../..', __FILE__
20
60
  end
@@ -5,12 +5,10 @@ module Opal
5
5
  def self.runtime
6
6
  core_dir = Opal.core_dir
7
7
  load_order = File.join core_dir, 'load_order'
8
- result = []
9
8
  corelib = File.read(load_order).strip.split.map do |c|
10
9
  File.read File.join(core_dir, "#{c}.rb")
11
10
  end
12
11
 
13
- methods = Parser::METHOD_NAMES.map { |f, t| "'#{f}': '$#{t}$'" }
14
12
  runtime = File.read(File.join core_dir, 'runtime.js')
15
13
  corelib = Opal.parse corelib.join("\n"), '(corelib)'
16
14
 
@@ -21,7 +19,6 @@ module Opal
21
19
  "// Released under the MIT License",
22
20
  "(function(undefined) {",
23
21
  runtime,
24
- "var method_names = {#{ methods.join ', ' }};",
25
22
  "Opal.version = #{ Opal::VERSION.inspect };",
26
23
  corelib,
27
24
  "}).call(this);"
@@ -38,19 +35,17 @@ module Opal
38
35
  end
39
36
 
40
37
  def build
41
- unless out = @options[:out]
42
- out = "out.js"
43
- end
44
-
45
- @dir = File.expand_path(@options[:dir] || Dir.getwd)
38
+ @dir = File.expand_path(@options[:dir] || Dir.getwd)
46
39
 
47
40
  files = files_for @sources
48
- FileUtils.mkdir_p File.dirname(out)
49
41
 
50
42
  @files = {}
51
43
  @requires = {}
44
+ @parser = Parser.new
45
+
46
+ files.each { |f| build_file f }
52
47
 
53
- build_to files, out
48
+ build_order(@requires).map { |r| @files[r] }.join("\n")
54
49
  end
55
50
 
56
51
  def files_for(sources)
@@ -68,18 +63,6 @@ module Opal
68
63
  files
69
64
  end
70
65
 
71
- def build_to(files, out)
72
- @parser = Parser.new
73
-
74
- files.each { |file| build_file(file) }
75
-
76
- File.open(out, 'w+') do |o|
77
- build_order(@requires).each do |f|
78
- o.puts @files[f]
79
- end
80
- end
81
- end
82
-
83
66
  # @param [Hash<Array<String>>] files hash of dependencies
84
67
  def build_order(files)
85
68
  all = files.keys
@@ -111,12 +94,12 @@ module Opal
111
94
  if File.extname(file) == '.rb'
112
95
  code = @parser.parse File.read(file), parser_name
113
96
  @requires[lib_name] = @parser.requires
114
- code = "(#{code})();"
115
97
  else
116
- code = File.read file
98
+ code = "function() {\n #{ File.read file }\n}"
99
+ @requires[lib_name] = []
117
100
  end
118
101
 
119
- @files[lib_name] = "// file #{ parser_name }\n#{ code }"
102
+ @files[lib_name] = "// #{ parser_name }\n(#{ code })();"
120
103
  end
121
104
 
122
105
  def parser_name_for(file)
@@ -126,7 +109,7 @@ module Opal
126
109
  def lib_name_for(file)
127
110
  file = file.sub /^#{@dir}\//, ''
128
111
  file = file.chomp File.extname(file)
129
- file.sub /^lib\/(opal\/)?/, ''
112
+ file.sub /^lib\//, ''
130
113
  end
131
114
  end
132
115
  end
@@ -4483,7 +4483,7 @@ def _reduce_376(val, _values, result)
4483
4483
  end
4484
4484
 
4485
4485
  def _reduce_377(val, _values, result)
4486
- result = new_regexp val[1]
4486
+ result = new_regexp val[1], val[2]
4487
4487
 
4488
4488
  result
4489
4489
  end
@@ -1235,7 +1235,7 @@ xstring:
1235
1235
  regexp:
1236
1236
  REGEXP_BEG xstring_contents REGEXP_END
1237
1237
  {
1238
- result = new_regexp val[1]
1238
+ result = new_regexp val[1], val[2]
1239
1239
  }
1240
1240
 
1241
1241
  words:
@@ -94,7 +94,7 @@ module Opal
94
94
  s = compstmt || s(:block)
95
95
 
96
96
  if compstmt
97
- # s = s(:block, compstmt) unless compstmt[0] == :block
97
+ # s = s(:block, compstmt) unless compstmt[0] == :block
98
98
  s.line = compstmt.line
99
99
  end
100
100
 
@@ -117,7 +117,7 @@ module Opal
117
117
  body << s(:nil) if body.size == 1
118
118
  scope.line = body.line
119
119
  args.line = line
120
- s = s(:defn, name.intern, args, scope)
120
+ s = s(:defn, name.to_sym, args, scope)
121
121
  s.line = line
122
122
  s.end_line = @line
123
123
  s
@@ -126,7 +126,7 @@ module Opal
126
126
  def new_defs line, recv, name, args, body
127
127
  scope = s(:scope, body)
128
128
  scope.line = body.line
129
- s = s(:defs, recv, name.intern, args, scope)
129
+ s = s(:defs, recv, name.to_sym, args, scope)
130
130
  s.line = line
131
131
  s.end_line = @line
132
132
  s
@@ -181,19 +181,25 @@ module Opal
181
181
  end
182
182
 
183
183
  if opt
184
- opt[1..-1].each do |opt|
185
- res << opt[1]
184
+ opt[1..-1].each do |_opt|
185
+ res << _opt[1]
186
186
  end
187
187
  end
188
188
 
189
189
  if rest
190
190
  res << rest
191
- @scope.add_local rest.to_s[1..-1].intern
191
+ @scope.add_local begin
192
+ rest.to_s[1..-1].to_sym
193
+ rescue ArgumentError => e
194
+ # Rescue from empty symbol error on Ruby 1.8
195
+ raise unless e.message =~ /empty/
196
+ ''
197
+ end
192
198
  end
193
199
 
194
200
  if block
195
201
  res << block
196
- @scope.add_local block.to_s[1..-1].intern
202
+ @scope.add_local block.to_s[1..-1].to_sym
197
203
  end
198
204
 
199
205
  res << opt if opt
@@ -212,19 +218,19 @@ module Opal
212
218
  end
213
219
 
214
220
  if opt
215
- opt[1..-1].each do |opt|
216
- res << s(:lasgn, opt[1])
221
+ opt[1..-1].each do |_opt|
222
+ res << s(:lasgn, _opt[1])
217
223
  end
218
224
  end
219
225
 
220
226
  if rest
221
- r = rest.to_s[1..-1].intern
227
+ r = rest.to_s[1..-1].to_sym
222
228
  res << s(:splat, s(:lasgn, r))
223
229
  @scope.add_local r
224
230
  end
225
231
 
226
232
  if block
227
- b = block.to_s[1..-1].intern
233
+ b = block.to_s[1..-1].to_sym
228
234
  res << s(:block_pass, s(:lasgn, b))
229
235
  @scope.add_local b
230
236
  end
@@ -381,7 +387,7 @@ module Opal
381
387
  case str[0]
382
388
  when :str
383
389
  str[0] = :lit
384
- str[1] = str[1].intern
390
+ str[1] = str[1].to_sym
385
391
  when :dstr
386
392
  str[0] = :dsym
387
393
  end
@@ -407,11 +413,11 @@ module Opal
407
413
  end
408
414
  end
409
415
 
410
- def new_regexp reg
416
+ def new_regexp reg, ending
411
417
  return s(:lit, //) unless reg
412
418
  case reg[0]
413
419
  when :str
414
- s(:lit, Regexp.new(reg[1]))
420
+ s(:lit, Regexp.new(reg[1], ending))
415
421
  when :evstr
416
422
  res = s(:dregx, "", reg)
417
423
  when :dstr
@@ -525,7 +531,7 @@ module Opal
525
531
  return :STRING_END, scanner.matched
526
532
 
527
533
  elsif str_parse[:beg] == '/'
528
- result = scanner.matched if scanner.scan(/\w+/)
534
+ result = scanner.scan(/\w+/)
529
535
  @lex_state = :expr_end
530
536
  return :REGEXP_END, result
531
537
 
@@ -26,33 +26,6 @@ module Opal
26
26
  const
27
27
  )
28
28
 
29
- METHOD_NAMES = {
30
- :== => 'eq',
31
- :=== => 'eqq',
32
- :[] => 'aref',
33
- :[]= => 'aset',
34
- :~ => 'tild',
35
- :<=> => 'cmp',
36
- :=~ => 'match',
37
- :+ => 'plus',
38
- :- => 'minus',
39
- :/ => 'div',
40
- :* => 'mul',
41
- :< => 'lt',
42
- :<= => 'le',
43
- :> => 'gt',
44
- :>= => 'ge',
45
- :<< => 'lshft',
46
- :>> => 'rshft',
47
- :| => 'or',
48
- :& => 'and',
49
- :^ => 'xor',
50
- :+@ => 'uplus',
51
- :-@ => 'uminus',
52
- :% => 'mod',
53
- :** => 'pow'
54
- }
55
-
56
29
  STATEMENTS = [:xstr, :dxstr]
57
30
 
58
31
  attr_reader :grammar
@@ -64,6 +37,7 @@ module Opal
64
37
  end
65
38
 
66
39
  def initialize(opts = {})
40
+ @debug = true if opts[:debug]
67
41
  end
68
42
 
69
43
  def parse(source, file = '(file)')
@@ -71,7 +45,8 @@ module Opal
71
45
  @requires = []
72
46
  @helpers = {
73
47
  :breaker => true,
74
- :slice => true
48
+ :slice => true,
49
+ :mm => true
75
50
  }
76
51
 
77
52
  @grammar = Grammar.new
@@ -104,10 +79,10 @@ module Opal
104
79
  end
105
80
 
106
81
  def mid_to_jsid(mid)
107
- '$' + if name = METHOD_NAMES[mid.to_sym]
108
- name + '$'
82
+ if RESERVED.include?(mid) or /\=|\+|\-|\*|\/|\!|\?|\<|\>|\&|\||\^|\%|\~|\[/ =~ mid.to_s
83
+ "['#{mid}']"
109
84
  else
110
- mid.sub('!', '$b').sub('?', '$p').sub('=', '$e')
85
+ '.' + mid
111
86
  end
112
87
  end
113
88
 
@@ -129,26 +104,13 @@ module Opal
129
104
  vars << "self = __opal.top"
130
105
  vars << "__scope = __opal"
131
106
  vars << "nil = __opal.nil"
132
- vars << "def = #{current_self}._klass.prototype" if @scope.defines_defn
107
+ vars << "def = #{current_self}.$k.prototype" if @scope.defines_defn
133
108
  vars.concat @helpers.keys.map { |h| "__#{h} = __opal.#{h}" }
134
109
 
135
- code = "var #{vars.join ', '};\n" + @scope.to_vars + "\n" + code
136
- end
137
-
138
- pre = "function() {\n"
139
- post = ""
140
-
141
- uniques = []
142
-
143
- # @unique.times { |i| uniques << "TMP_#{i+1}" }
144
-
145
- unless uniques.empty?
146
- post += ";var #{uniques.join ', '};"
110
+ code = "#{INDENT}var #{vars.join ', '};\n" + INDENT + @scope.to_vars + "\n" + code
147
111
  end
148
112
 
149
- post += "\n}"
150
-
151
- pre + code + post
113
+ "function() {\n#{ code }\n}"
152
114
  end
153
115
 
154
116
  def in_scope(type)
@@ -234,7 +196,7 @@ module Opal
234
196
  sexp[1] = returns sexp[1]
235
197
  sexp
236
198
  when :while
237
- sexp[2] = returns(sexp[2])
199
+ # sexp[2] = returns(sexp[2])
238
200
  sexp
239
201
  when :return
240
202
  sexp
@@ -304,8 +266,8 @@ module Opal
304
266
  l = process recv, :expr
305
267
  r = process arg, :expr
306
268
 
307
- "(%s = %s, %s = %s, typeof(%s) === 'number' ? %s %s %s : %s.%s(%s))" %
308
- [a, l, b, r, a, a, meth.to_s, b, a, mid, b]
269
+ "(%s = %s, %s = %s, typeof(%s) === 'number' ? %s %s %s : %s.$m%s(%s, %s))" %
270
+ [a, l, b, r, a, a, meth.to_s, b, a, mid, a, b]
309
271
  end
310
272
  end
311
273
  end
@@ -394,7 +356,7 @@ module Opal
394
356
  when :call
395
357
  mid = mid_to_jsid part[2].to_s
396
358
  recv = part[1] ? process(part[1], :expr) : current_self
397
- "(#{recv}.#{mid} ? 'method' : nil)"
359
+ "(#{recv}.$m#{mid} ? 'method' : nil)"
398
360
  when :xstr
399
361
  "(typeof(#{process part, :expression}) !== 'undefined')"
400
362
  else
@@ -428,7 +390,7 @@ module Opal
428
390
 
429
391
  if args.last[0] == :block_pass
430
392
  block_arg = args.pop
431
- block_arg = block_arg[1][1].intern
393
+ block_arg = block_arg[1][1].to_sym
432
394
  end
433
395
 
434
396
  if args.last[0] == :splat
@@ -450,7 +412,7 @@ module Opal
450
412
 
451
413
  if splat
452
414
  params << splat
453
- code += "#{splat} = __slice.call(arguments, #{len - 1});"
415
+ code += "#{splat} = __slice.call(arguments, #{len});"
454
416
  end
455
417
 
456
418
  if block_arg
@@ -469,7 +431,7 @@ module Opal
469
431
  code += "\n#@indent" + process(body, :stmt)
470
432
 
471
433
  if @scope.defines_defn
472
- @scope.add_temp 'def = (this._isObject ? this._klass.prototype : this.prototype)'
434
+ @scope.add_temp 'def = (self._isObject ? self.$m : self.$m_tbl)'
473
435
  end
474
436
 
475
437
  code = "\n#@indent#{@scope.to_vars}\n#@indent#{code}"
@@ -489,9 +451,9 @@ module Opal
489
451
  end
490
452
 
491
453
  def js_block_args(sexp)
492
- sexp.map do |arg|
493
- a = arg[1].intern
494
- a = "#{a}$".intern if RESERVED.include? a.to_s
454
+ ['self'] + sexp.map do |arg|
455
+ a = arg[1].to_sym
456
+ a = "#{a}$".to_sym if RESERVED.include? a.to_s
495
457
  @scope.add_arg a
496
458
  a
497
459
  end
@@ -525,7 +487,7 @@ module Opal
525
487
 
526
488
  attrs.each do |attr|
527
489
  mid = attr[1]
528
- ivar = "@#{mid}".intern
490
+ ivar = "@#{mid}".to_sym
529
491
  pre = @scope.proto
530
492
 
531
493
  unless meth == :attr_writer
@@ -533,7 +495,7 @@ module Opal
533
495
  end
534
496
 
535
497
  unless meth == :attr_reader
536
- mid = "#{mid}=".intern
498
+ mid = "#{mid}=".to_sym
537
499
  out << process(s(:defn, mid, s(:args, :val), s(:scope,
538
500
  s(:iasgn, ivar, s(:lvar, :val)))), :stmt)
539
501
  end
@@ -548,7 +510,7 @@ module Opal
548
510
  func = args[2][1]
549
511
 
550
512
  @scope.methods << meth
551
- "%s.%s = %s.%s" % [@scope.proto, meth, @scope.proto, func]
513
+ "%s%s = %s.%s" % [@scope.proto, meth, @scope.proto, func]
552
514
  end
553
515
 
554
516
  # s(:call, recv, :mid, s(:arglist))
@@ -573,10 +535,10 @@ module Opal
573
535
  if path and path[0] == :str
574
536
  path_name = path[1].sub(/^opal\//, '')
575
537
  @requires << path_name
576
- return "nil"
538
+ return ""
577
539
  else
578
- warn "Opal cannot do dynamic requires"
579
- return "nil"
540
+ # warn "Opal cannot do dynamic requires"
541
+ return ""
580
542
  end
581
543
  end
582
544
 
@@ -591,30 +553,36 @@ module Opal
591
553
  recv ||= [:self]
592
554
 
593
555
  if block
594
- tmprecv = @scope.new_temp
556
+ tmpproc = @scope.new_temp
595
557
  elsif splat and recv != [:self] and recv[0] != :lvar
596
- tmprecv = @scope.new_temp
558
+ tmpproc = @scope.new_temp
597
559
  end
598
560
 
599
- recv_code = process recv, :recv
600
561
  args = ""
601
562
 
602
- @scope.queue_temp tmprecv if tmprecv
563
+ with_temp do |tmprecv|
564
+ recv_code = process recv, :recv
603
565
 
604
- args = process arglist, :expr
566
+ arglist.insert 1, s(:js_tmp, tmprecv)
567
+ args = process arglist, :expr
605
568
 
606
- if block
607
- dispatch = "(%s = %s, %s.%s._p = %s, %s.%s" %
608
- [tmprecv, recv_code, tmprecv, mid, block, tmprecv, mid]
569
+ result = if block
570
+ dispatch = "(%s = %s, %s.$m%s._p = %s, %s.$m%s" %
571
+ [tmprecv, recv_code, tmprecv, mid, block, tmprecv, mid]
609
572
 
610
- if splat
611
- "%s.apply(%s, %s))" % [dispatch, tmprecv, args]
573
+ if splat
574
+ "%s.apply(null, %s))" % [dispatch, args]
575
+ else
576
+ "%s(%s))" % [dispatch, args]
577
+ end
612
578
  else
613
- "%s(%s))" % [dispatch, args]
579
+ m_missing = " || __mm(#{meth.to_s.inspect})" if @debug
580
+ dispatch = "((#{tmprecv} = #{recv_code}).$m#{mid}#{ m_missing })"
581
+ splat ? "#{dispatch}.apply(null, #{args})" : "#{dispatch}(#{args})"
614
582
  end
615
- else
616
- dispatch = tmprecv ? "(#{tmprecv} = #{recv_code}).#{mid}" : "#{recv_code}.#{mid}"
617
- splat ? "#{dispatch}.apply(#{tmprecv || recv_code}, #{args})" : "#{dispatch}(#{args})"
583
+
584
+ @scope.queue_temp tmpproc if tmpproc
585
+ result
618
586
  end
619
587
  end
620
588
 
@@ -688,7 +656,7 @@ module Opal
688
656
  indent do
689
657
  in_scope(:class) do
690
658
  @scope.name = name
691
- @scope.add_temp "#{ @scope.proto } = #{name}.prototype", "__scope = #{name}._scope"
659
+ @scope.add_temp "#{ @scope.proto } = #{name}.prototype", "#{ @scope.m_tbl } = #{name}.$m_tbl", "__scope = #{name}._scope"
692
660
  @scope.donates_methods = true
693
661
  body = process body, :stmt
694
662
  code = @indent + @scope.to_vars + "\n\n#@indent" + body
@@ -709,14 +677,15 @@ module Opal
709
677
  recv = sexp[0]
710
678
  body = sexp[1]
711
679
  code = nil
712
- base = process recv, :expr
713
680
 
714
681
  in_scope(:sclass) do
715
- @scope.add_temp '__scope = this._scope'
682
+ @scope.add_temp '__scope = self._scope'
716
683
  code = @scope.to_vars + process(body, :stmt)
717
684
  end
718
685
 
719
- "(function(){#{ code }}).call(#{ base }.$singleton_class())"
686
+ call = s(:call, recv, :singleton_class, s(:arglist))
687
+
688
+ "(function(self){#{ code }})(#{ process call, :expr })"
720
689
  end
721
690
 
722
691
  # s(:module, cid, body)
@@ -742,7 +711,7 @@ module Opal
742
711
  indent do
743
712
  in_scope(:module) do
744
713
  @scope.name = name
745
- @scope.add_temp "#{ @scope.proto } = #{name}.prototype", "__scope = #{name}._scope"
714
+ @scope.add_temp "#{ @scope.m_tbl } = #{name}.$m_tbl", "__scope = #{name}._scope"
746
715
  @scope.donates_methods = true
747
716
  body = process body, :stmt
748
717
  code = @indent + @scope.to_vars + "\n\n#@indent" + body + "\n#@indent" + @scope.to_donate_methods
@@ -765,7 +734,7 @@ module Opal
765
734
  # FIXME: maybe add this to donate(). it will be undefined, so
766
735
  # when added to includees it will actually undefine methods there
767
736
  # too.
768
- "delete #{ @scope.proto }.#{jsid}"
737
+ "delete #{ @scope.m_tbl }#{jsid}"
769
738
  end
770
739
 
771
740
  # s(:defn, mid, s(:args), s(:scope))
@@ -800,13 +769,14 @@ module Opal
800
769
  code = ''
801
770
  params = nil
802
771
  scope_name = nil
772
+ uses_super = nil
803
773
 
804
774
  # opt args if last arg is sexp
805
775
  opt = args.pop if Array === args.last
806
776
 
807
777
  # block name &block
808
778
  if args.last.to_s[0] == '&'
809
- block_name = args.pop[1..-1].intern
779
+ block_name = args.pop[1..-1].to_sym
810
780
  end
811
781
 
812
782
  # splat args *splat
@@ -814,9 +784,9 @@ module Opal
814
784
  if args.last == :*
815
785
  args.pop
816
786
  else
817
- splat = args[-1].to_s[1..-1].intern
787
+ splat = args[-1].to_s[1..-1].to_sym
818
788
  args[-1] = splat
819
- len = args.length - 2
789
+ len = args.length - 1
820
790
  end
821
791
  end
822
792
 
@@ -857,6 +827,8 @@ module Opal
857
827
  code = blk + code
858
828
  end
859
829
 
830
+ uses_super = @scope.uses_super
831
+
860
832
  code = "#@indent#{@scope.to_vars}" + code
861
833
  end
862
834
  end
@@ -873,18 +845,28 @@ module Opal
873
845
 
874
846
  if recvr
875
847
  if smethod
876
- @scope.smethods << jsid
877
- "#{ comment }#{ @scope.name }.#{jsid} = #{defcode}"
848
+ @scope.smethods << mid.to_s
849
+ "#{ comment }#{ @scope.name }.$m#{jsid} = #{defcode}"
878
850
  else
879
- "#{recv}.$singleton_class().prototype.#{jsid} = #{defcode}"
851
+ # "#{ recv }#{ jsid } = #{ defcode }"
852
+ @helpers[:defs] = true
853
+ "__defs(#{recv}, #{mid.to_s.inspect}, #{defcode})"
880
854
  end
881
855
  elsif @scope.class_scope?
882
- @scope.methods << jsid
883
- "#{ comment }#{ @scope.proto }.#{jsid} = #{defcode}"
856
+ @scope.methods << mid.to_s
857
+ if uses_super
858
+ @scope.add_temp uses_super
859
+ uses_super = "#{uses_super} = #{@scope.m_tbl}#{jsid};\n#@indent"
860
+ end
861
+ "#{ comment }#{uses_super}#{ @scope.m_tbl }#{jsid} = #{defcode}"
884
862
  elsif @scope.type == :iter
885
- "def.#{jsid} = #{defcode}"
863
+ "def#{jsid} = #{defcode}"
864
+ elsif @scope.type == :top
865
+ @helpers[:defs] = true
866
+ "__defs(#{current_self}, #{mid.to_s.inspect}, #{defcode})"
886
867
  else
887
- "def.#{jsid} = #{defcode}"
868
+ @helpers[:defs] = true
869
+ "__defs(#{current_self}, #{mid.to_s.inspect}, #{defcode})"
888
870
  end
889
871
  end
890
872
 
@@ -905,11 +887,11 @@ module Opal
905
887
  end
906
888
 
907
889
  def process_args(exp, level)
908
- args = []
890
+ args = ['self']
909
891
 
910
892
  until exp.empty?
911
- a = exp.shift.intern
912
- a = "#{a}$".intern if RESERVED.include? a.to_s
893
+ a = exp.shift.to_sym
894
+ a = "#{a}$".to_sym if RESERVED.include? a.to_s
913
895
  @scope.add_arg a
914
896
  args << a
915
897
  end
@@ -931,7 +913,7 @@ module Opal
931
913
  elsif @scope.top?
932
914
  'self'
933
915
  else
934
- 'this'
916
+ 'self'
935
917
  end
936
918
  end
937
919
 
@@ -1065,9 +1047,10 @@ module Opal
1065
1047
 
1066
1048
  if [:class, :module].include? @scope.type
1067
1049
  @scope.methods << new
1068
- "%s.%s = %s.%s" % [@scope.proto, new, @scope.proto, old]
1050
+ "%s%s = %s%s" % [@scope.m_tbl, new, @scope.m_tbl, old]
1069
1051
  else
1070
- "def.%s = def.%s" % [new, old]
1052
+ current = current_self
1053
+ "%s.$m_tbl%s = %s.$m_tbl%s" % [current, new, current, old]
1071
1054
  end
1072
1055
  end
1073
1056
 
@@ -1118,7 +1101,7 @@ module Opal
1118
1101
  def process_lasgn(sexp, level)
1119
1102
  lvar = sexp[0]
1120
1103
  rhs = sexp[1]
1121
- lvar = "#{lvar}$".intern if RESERVED.include? lvar.to_s
1104
+ lvar = "#{lvar}$".to_sym if RESERVED.include? lvar.to_s
1122
1105
  @scope.add_local lvar
1123
1106
  res = "#{lvar} = #{process rhs, :expr}"
1124
1107
  level == :recv ? "(#{res})" : res
@@ -1215,7 +1198,7 @@ module Opal
1215
1198
  if String === p
1216
1199
  p.inspect
1217
1200
  elsif p.first == :evstr
1218
- process p.last, :expr
1201
+ "(" + process(p.last, :expr) + ")"
1219
1202
  elsif p.first == :str
1220
1203
  p.last.inspect
1221
1204
  else
@@ -1366,8 +1349,8 @@ module Opal
1366
1349
  call = handle_yield_call sexp, level
1367
1350
 
1368
1351
  with_temp do |tmp|
1369
- "return %s = #{call}, %s === __breaker ? __breaker.$v : %s" %
1370
- [tmp, tmp, tmp]
1352
+ "return %s = #{call}, %s === __breaker ? %s : %s" %
1353
+ [tmp, tmp, tmp, tmp]
1371
1354
  end
1372
1355
  end
1373
1356
 
@@ -1375,12 +1358,12 @@ module Opal
1375
1358
  @scope.uses_block!
1376
1359
 
1377
1360
  splat = sexp.any? { |s| s.first == :splat }
1378
- sexp.unshift s(:js_tmp, '__context') unless splat
1361
+ sexp.unshift s(:js_tmp, '__context') # self
1379
1362
  args = process_arglist sexp, level
1380
1363
 
1381
1364
  y = @scope.block_name || '__yield'
1382
1365
 
1383
- splat ? "#{y}.apply(__context, #{args})" : "#{y}.call(#{args})"
1366
+ splat ? "#{y}.apply(null, #{args})" : "#{y}(#{args})"
1384
1367
  end
1385
1368
 
1386
1369
  def process_break(exp, level)
@@ -1505,7 +1488,7 @@ module Opal
1505
1488
  #
1506
1489
  # s(:super, arg1, arg2, ...)
1507
1490
  def process_super(sexp, level)
1508
- args = []
1491
+ args = ['self']
1509
1492
  until sexp.empty?
1510
1493
  args << process(sexp.shift, :expr)
1511
1494
  end
@@ -1517,22 +1500,28 @@ module Opal
1517
1500
  #
1518
1501
  # s(:zsuper)
1519
1502
  def process_zsuper(exp, level)
1520
- js_super "__slice.call(arguments)"
1503
+ js_super "[self].concat(__slice.call(arguments))"
1521
1504
  end
1522
1505
 
1523
1506
  def js_super args
1524
- if @scope.type == :def
1507
+ if @scope.def_in_class?
1508
+ mid = @scope.mid.to_s
1509
+ # jsid = mid_to_jsid @scope.mid.to_s
1510
+ @scope.uses_super = "super_#{mid}"
1511
+ "super_#{mid}.apply(null, #{ args })"
1512
+
1513
+ elsif @scope.type == :def
1525
1514
  identity = @scope.identify!
1526
1515
  cls_name = @scope.parent.name
1527
1516
  jsid = mid_to_jsid @scope.mid.to_s
1528
- base = @scope.defs ? '' : ".prototype"
1517
+ base = @scope.defs ? '' : ".$m_tbl"
1529
1518
 
1530
- "%s._super%s.%s.apply(this, %s)" % [cls_name, base, jsid, args]
1519
+ "%s.$s%s%s.apply(this, %s)" % [cls_name, base, jsid, args]
1531
1520
 
1532
1521
  elsif @scope.type == :iter
1533
1522
  chain, defn, mid = @scope.get_super_chain
1534
1523
  trys = chain.map { |c| "#{c}._sup" }.join ' || '
1535
- "(#{trys} || this._klass._super._proto[#{mid}]).apply(this, #{args})"
1524
+ "(#{trys} || this.$k.$s.$m_tbl[#{mid}]).apply(this, #{args})"
1536
1525
 
1537
1526
  else
1538
1527
  raise "Cannot call super() from outside a method block"