opal 0.3.16 → 0.3.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (251) hide show
  1. data/.gitignore +2 -0
  2. data/CHANGELOG.md +12 -0
  3. data/Gemfile +8 -7
  4. data/README.md +21 -13
  5. data/Rakefile +64 -78
  6. data/bin/opal +18 -29
  7. data/core/alpha.rb +2 -9
  8. data/core/array.rb +106 -50
  9. data/core/basic_object.rb +10 -8
  10. data/core/boolean.rb +2 -0
  11. data/core/class.rb +25 -13
  12. data/core/comparable.rb +6 -6
  13. data/core/enumerable.rb +90 -94
  14. data/core/enumerator.rb +3 -3
  15. data/core/hash.rb +86 -46
  16. data/core/kernel.rb +55 -39
  17. data/core/load_order +2 -5
  18. data/core/match_data.rb +1 -1
  19. data/core/module.rb +45 -20
  20. data/core/nil_class.rb +6 -2
  21. data/core/numeric.rb +20 -10
  22. data/core/proc.rb +2 -2
  23. data/core/range.rb +72 -13
  24. data/core/regexp.rb +5 -3
  25. data/core/runtime.js +228 -287
  26. data/core/string.rb +345 -37
  27. data/core/top_self.rb +1 -1
  28. data/lib/opal.rb +13 -91
  29. data/lib/opal/builder.rb +47 -120
  30. data/lib/opal/builder_task.rb +74 -0
  31. data/lib/opal/{parser/grammar.rb → grammar.rb} +1094 -1083
  32. data/lib/opal/{parser/grammar.y → grammar.y} +7 -0
  33. data/lib/opal/{parser/lexer.rb → lexer.rb} +32 -11
  34. data/lib/opal/{parser/parser.rb → parser.rb} +232 -238
  35. data/lib/opal/{parser/scope.rb → scope.rb} +72 -9
  36. data/lib/opal/version.rb +2 -3
  37. data/opal.gemspec +1 -2
  38. data/{core_spec → spec}/core/array/allocate_spec.rb +1 -3
  39. data/{core_spec → spec}/core/array/append_spec.rb +1 -4
  40. data/{core_spec → spec}/core/array/assoc_spec.rb +1 -4
  41. data/{core_spec → spec}/core/array/at_spec.rb +1 -3
  42. data/{core_spec → spec}/core/array/clear_spec.rb +1 -3
  43. data/spec/core/array/clone_spec.rb +15 -0
  44. data/{core_spec/core/array/shared/collect.rb → spec/core/array/collect_spec.rb} +1 -1
  45. data/{core_spec → spec}/core/array/compact_spec.rb +1 -3
  46. data/{core_spec → spec}/core/array/concat_spec.rb +1 -3
  47. data/{core_spec → spec}/core/array/constructor_spec.rb +9 -3
  48. data/{core_spec → spec}/core/array/count_spec.rb +1 -3
  49. data/{core_spec → spec}/core/array/delete_at_spec.rb +1 -4
  50. data/{core_spec → spec}/core/array/delete_if_spec.rb +1 -4
  51. data/{core_spec → spec}/core/array/delete_spec.rb +1 -4
  52. data/{core_spec → spec}/core/array/each_index_spec.rb +1 -4
  53. data/{core_spec → spec}/core/array/each_spec.rb +1 -4
  54. data/{core_spec → spec}/core/array/element_reference_spec.rb +74 -4
  55. data/{core_spec → spec}/core/array/empty_spec.rb +1 -4
  56. data/{core_spec/core/array/shared/eql.rb → spec/core/array/eql_spec.rb} +1 -1
  57. data/{core_spec → spec}/core/array/fetch_spec.rb +1 -4
  58. data/{core_spec → spec}/core/array/first_spec.rb +1 -3
  59. data/{core_spec → spec}/core/array/flatten_spec.rb +1 -3
  60. data/{core_spec → spec}/core/array/include_spec.rb +1 -3
  61. data/{core_spec → spec}/core/array/insert_spec.rb +1 -4
  62. data/{core_spec → spec}/core/array/last_spec.rb +1 -4
  63. data/{core_spec/core/array/shared/length.rb → spec/core/array/length_spec.rb} +1 -1
  64. data/spec/core/array/map_spec.rb +53 -0
  65. data/{core_spec → spec}/core/array/plus_spec.rb +1 -4
  66. data/{core_spec → spec}/core/array/pop_spec.rb +1 -4
  67. data/{core_spec → spec}/core/array/push_spec.rb +1 -4
  68. data/{core_spec → spec}/core/array/rassoc_spec.rb +1 -4
  69. data/{core_spec → spec}/core/array/reject_spec.rb +1 -4
  70. data/{core_spec/core/array/shared/replace.rb → spec/core/array/replace_spec.rb} +1 -1
  71. data/{core_spec → spec}/core/array/reverse_each_spec.rb +1 -4
  72. data/{core_spec → spec}/core/array/reverse_spec.rb +1 -4
  73. data/spec/core/array/size_spec.rb +6 -0
  74. data/spec/core/array/to_ary_spec.rb +6 -0
  75. data/spec/core/array/uniq_spec.rb +22 -0
  76. data/spec/core/array/zip_spec.rb +20 -0
  77. data/{core_spec → spec}/core/class/new_spec.rb +1 -4
  78. data/{core_spec → spec}/core/enumerable/all_spec.rb +1 -4
  79. data/{core_spec → spec}/core/enumerable/any_spec.rb +1 -4
  80. data/{core_spec/core/enumerable/shared/collect.rb → spec/core/enumerable/collect_spec.rb} +1 -1
  81. data/{core_spec → spec}/core/enumerable/count_spec.rb +2 -5
  82. data/{core_spec → spec}/core/enumerable/fixtures/classes.rb +1 -2
  83. data/{core_spec → spec}/core/false/and_spec.rb +1 -3
  84. data/{core_spec → spec}/core/false/inspect_spec.rb +1 -3
  85. data/{core_spec → spec}/core/false/or_spec.rb +1 -3
  86. data/{core_spec → spec}/core/false/to_s_spec.rb +1 -3
  87. data/{core_spec → spec}/core/false/xor_spec.rb +1 -3
  88. data/{core_spec → spec}/core/hash/allocate_spec.rb +1 -3
  89. data/spec/core/hash/assoc_spec.rb +25 -0
  90. data/{core_spec → spec}/core/hash/clear_spec.rb +1 -3
  91. data/{core_spec → spec}/core/hash/clone_spec.rb +1 -3
  92. data/{core_spec → spec}/core/hash/default_spec.rb +1 -3
  93. data/{core_spec → spec}/core/hash/delete_if_spec.rb +1 -3
  94. data/{core_spec → spec}/core/hash/element_reference_spec.rb +1 -3
  95. data/{core_spec → spec}/core/hash/element_set_spec.rb +1 -3
  96. data/spec/core/hash/merge_spec.rb +37 -0
  97. data/{core_spec → spec}/core/hash/new_spec.rb +1 -3
  98. data/{core_spec → spec}/core/matchdata/to_a_spec.rb +1 -3
  99. data/{core_spec → spec}/core/nil/and_spec.rb +1 -4
  100. data/{core_spec → spec}/core/nil/inspect_spec.rb +1 -4
  101. data/{core_spec → spec}/core/nil/nil_spec.rb +1 -4
  102. data/{core_spec → spec}/core/nil/or_spec.rb +1 -4
  103. data/{core_spec → spec}/core/nil/to_a_spec.rb +1 -4
  104. data/{core_spec → spec}/core/nil/to_f_spec.rb +1 -4
  105. data/{core_spec → spec}/core/nil/to_i_spec.rb +1 -4
  106. data/{core_spec → spec}/core/nil/to_s_spec.rb +1 -4
  107. data/{core_spec → spec}/core/nil/xor_spec.rb +1 -4
  108. data/{core_spec → spec}/core/numeric/equal_value_spec.rb +1 -3
  109. data/{core_spec → spec}/core/regexp/match_spec.rb +10 -3
  110. data/{core_spec → spec}/core/symbol/to_proc_spec.rb +1 -3
  111. data/{core_spec → spec}/core/true/and_spec.rb +1 -3
  112. data/{core_spec → spec}/core/true/inspect_spec.rb +1 -3
  113. data/{core_spec → spec}/core/true/or_spec.rb +1 -3
  114. data/{core_spec → spec}/core/true/to_s_spec.rb +1 -3
  115. data/{core_spec → spec}/core/true/xor_spec.rb +1 -3
  116. data/spec/index.html +11 -0
  117. data/{core_spec → spec}/language/alias_spec.rb +1 -3
  118. data/{core_spec → spec}/language/and_spec.rb +1 -4
  119. data/{core_spec → spec}/language/array_spec.rb +1 -4
  120. data/{core_spec → spec}/language/block_spec.rb +20 -3
  121. data/{core_spec → spec}/language/break_spec.rb +40 -3
  122. data/{core_spec → spec}/language/case_spec.rb +1 -4
  123. data/{core_spec → spec}/language/defined_spec.rb +9 -3
  124. data/{core_spec → spec}/language/ensure_spec.rb +38 -3
  125. data/{core_spec → spec}/language/hash_spec.rb +1 -3
  126. data/{core_spec → spec}/language/if_spec.rb +1 -4
  127. data/{core_spec → spec}/language/loop_spec.rb +1 -3
  128. data/spec/language/metaclass_spec.rb +13 -0
  129. data/{core_spec → spec}/language/next_spec.rb +47 -3
  130. data/{core_spec → spec}/language/or_spec.rb +1 -4
  131. data/{core_spec → spec}/language/predefined_spec.rb +1 -3
  132. data/{core_spec/language/regexp/interpolation_spec.rb → spec/language/regexp_spec.rb} +6 -3
  133. data/{core_spec → spec}/language/send_spec.rb +38 -4
  134. data/spec/language/singleton_class_spec.rb +31 -0
  135. data/spec/language/super_spec.rb +188 -0
  136. data/{core_spec → spec}/language/symbol_spec.rb +1 -3
  137. data/{core_spec → spec}/language/undef_spec.rb +1 -3
  138. data/{core_spec → spec}/language/unless_spec.rb +1 -4
  139. data/{core_spec → spec}/language/until_spec.rb +1 -3
  140. data/{core_spec → spec}/language/variables_spec.rb +1 -3
  141. data/{core_spec → spec}/language/while_spec.rb +1 -3
  142. data/{spec → test}/builder/build_source_spec.rb +0 -0
  143. data/{spec → test}/builder/fixtures/build_source/adam.rb +0 -0
  144. data/{spec → test}/builder/fixtures/build_source/bar/a.rb +0 -0
  145. data/{spec → test}/builder/fixtures/build_source/bar/wow/b.rb +0 -0
  146. data/{spec → test}/builder/fixtures/build_source/bar/wow/cow/c.rb +0 -0
  147. data/{spec → test}/builder/fixtures/build_source/beynon.rb +0 -0
  148. data/{spec → test}/builder/fixtures/build_source/charles.js +0 -0
  149. data/{spec → test}/builder/fixtures/build_source/foo/a.rb +0 -0
  150. data/{spec → test}/builder/fixtures/build_source/foo/b.rb +0 -0
  151. data/{spec → test}/builder/fixtures/build_source/foo/x.js +0 -0
  152. data/{spec → test}/builder/fixtures/build_source/foo/y.js +0 -0
  153. data/{spec → test}/grammar/alias_spec.rb +0 -0
  154. data/{spec → test}/grammar/and_spec.rb +0 -0
  155. data/{spec → test}/grammar/array_spec.rb +0 -0
  156. data/{spec → test}/grammar/attrasgn_spec.rb +0 -0
  157. data/{spec → test}/grammar/begin_spec.rb +0 -0
  158. data/{spec → test}/grammar/block_spec.rb +0 -0
  159. data/{spec → test}/grammar/break_spec.rb +0 -0
  160. data/{spec → test}/grammar/call_spec.rb +0 -0
  161. data/{spec → test}/grammar/class_spec.rb +0 -0
  162. data/{spec → test}/grammar/const_spec.rb +0 -0
  163. data/{spec → test}/grammar/cvar_spec.rb +0 -0
  164. data/{spec → test}/grammar/def_spec.rb +0 -0
  165. data/{spec → test}/grammar/false_spec.rb +0 -0
  166. data/{spec → test}/grammar/file_spec.rb +0 -0
  167. data/{spec → test}/grammar/gvar_spec.rb +0 -0
  168. data/{spec → test}/grammar/hash_spec.rb +0 -0
  169. data/{spec → test}/grammar/iasgn_spec.rb +0 -0
  170. data/{spec → test}/grammar/if_spec.rb +0 -0
  171. data/{spec → test}/grammar/iter_spec.rb +0 -0
  172. data/{spec → test}/grammar/ivar_spec.rb +0 -0
  173. data/{spec → test}/grammar/lasgn_spec.rb +0 -0
  174. data/{spec → test}/grammar/line_spec.rb +0 -0
  175. data/{spec → test}/grammar/lvar_spec.rb +0 -0
  176. data/{spec → test}/grammar/masgn_spec.rb +0 -0
  177. data/{spec → test}/grammar/module_spec.rb +0 -0
  178. data/{spec → test}/grammar/nil_spec.rb +0 -0
  179. data/{spec → test}/grammar/not_spec.rb +0 -0
  180. data/{spec → test}/grammar/op_asgn1_spec.rb +0 -0
  181. data/{spec → test}/grammar/op_asgn2_spec.rb +0 -0
  182. data/{spec → test}/grammar/or_spec.rb +0 -0
  183. data/{spec → test}/grammar/return_spec.rb +0 -0
  184. data/{spec → test}/grammar/sclass_spec.rb +0 -0
  185. data/{spec → test}/grammar/self_spec.rb +0 -0
  186. data/{spec → test}/grammar/str_spec.rb +0 -0
  187. data/{spec → test}/grammar/super_spec.rb +0 -0
  188. data/{spec → test}/grammar/true_spec.rb +0 -0
  189. data/{spec → test}/grammar/undef_spec.rb +0 -0
  190. data/{spec → test}/grammar/unless_spec.rb +0 -0
  191. data/{spec → test}/grammar/while_spec.rb +0 -0
  192. data/{spec → test}/grammar/xstr_spec.rb +0 -0
  193. data/{spec → test}/grammar/yield_spec.rb +0 -0
  194. data/{spec → test}/spec_helper.rb +0 -0
  195. metadata +330 -264
  196. data/core/debug.js +0 -59
  197. data/core/debug.rb +0 -35
  198. data/core/dir.rb +0 -90
  199. data/core/file.rb +0 -83
  200. data/core/gemlib.rb +0 -30
  201. data/core/io.rb +0 -44
  202. data/core_spec/README.md +0 -34
  203. data/core_spec/core/array/collect_spec.rb +0 -3
  204. data/core_spec/core/array/element_set_spec.rb +0 -7
  205. data/core_spec/core/array/eql_spec.rb +0 -3
  206. data/core_spec/core/array/equal_value_spec.rb +0 -3
  207. data/core_spec/core/array/fixtures/classes.rb +0 -8
  208. data/core_spec/core/array/length_spec.rb +0 -3
  209. data/core_spec/core/array/map_spec.rb +0 -3
  210. data/core_spec/core/array/replace_spec.rb +0 -3
  211. data/core_spec/core/enumerable/collect_spec.rb +0 -3
  212. data/core_spec/core/enumerable/detect_spec.rb +0 -3
  213. data/core_spec/core/enumerable/find_spec.rb +0 -3
  214. data/core_spec/core/enumerable/first_spec.rb +0 -3
  215. data/core_spec/core/enumerable/shared/entries.rb +0 -7
  216. data/core_spec/core/enumerable/shared/find.rb +0 -49
  217. data/core_spec/core/enumerable/shared/take.rb +0 -31
  218. data/core_spec/core/enumerable/to_a_spec.rb +0 -7
  219. data/core_spec/core/hash/assoc_spec.rb +0 -29
  220. data/core_spec/core/object/is_a_spec.rb +0 -2
  221. data/core_spec/core/object/shared/kind_of.rb +0 -0
  222. data/core_spec/core/regexp/shared/match.rb +0 -11
  223. data/core_spec/language/fixtures/block.rb +0 -19
  224. data/core_spec/language/fixtures/break.rb +0 -39
  225. data/core_spec/language/fixtures/defined.rb +0 -9
  226. data/core_spec/language/fixtures/ensure.rb +0 -37
  227. data/core_spec/language/fixtures/next.rb +0 -46
  228. data/core_spec/language/fixtures/send.rb +0 -36
  229. data/core_spec/language/fixtures/super.rb +0 -43
  230. data/core_spec/language/regexp_spec.rb +0 -7
  231. data/core_spec/language/string_spec.rb +0 -4
  232. data/core_spec/language/super_spec.rb +0 -18
  233. data/core_spec/language/versions/hash_1.9.rb +0 -20
  234. data/core_spec/opal/opal/defined_spec.rb +0 -15
  235. data/core_spec/opal/opal/function_spec.rb +0 -11
  236. data/core_spec/opal/opal/native_spec.rb +0 -16
  237. data/core_spec/opal/opal/null_spec.rb +0 -10
  238. data/core_spec/opal/opal/number_spec.rb +0 -11
  239. data/core_spec/opal/opal/object_spec.rb +0 -16
  240. data/core_spec/opal/opal/string_spec.rb +0 -11
  241. data/core_spec/opal/opal/typeof_spec.rb +0 -9
  242. data/core_spec/opal/opal/undefined_spec.rb +0 -10
  243. data/core_spec/opal/true/case_compare_spec.rb +0 -12
  244. data/core_spec/opal/true/class_spec.rb +0 -10
  245. data/core_spec/release_runner.html +0 -17
  246. data/core_spec/runner.html +0 -16
  247. data/core_spec/spec_helper.rb +0 -23
  248. data/lib/opal/context.rb +0 -269
  249. data/lib/opal/dependency_builder.rb +0 -133
  250. data/lib/opal/environment.rb +0 -87
  251. data/lib/opal/parser/sexp.rb +0 -17
@@ -1062,6 +1062,10 @@ method_call:
1062
1062
  {
1063
1063
  result = new_call val[0], val[2].intern, val[3]
1064
1064
  }
1065
+ | primary_value '.' paren_args
1066
+ {
1067
+ result = new_call val[0], :call, val[2]
1068
+ }
1065
1069
  | primary_value '::' operation2 paren_args
1066
1070
  | primary_value '::' operation3
1067
1071
  | SUPER paren_args
@@ -1182,6 +1186,9 @@ string1:
1182
1186
  result = val[1]
1183
1187
  }
1184
1188
  | STRING
1189
+ {
1190
+ result = s(:str, val[0])
1191
+ }
1185
1192
 
1186
1193
  xstring:
1187
1194
  XSTRING_BEG xstring_contents STRING_END
@@ -1,12 +1,10 @@
1
- require 'opal/parser/grammar'
2
- require 'opal/parser/sexp'
3
-
1
+ require 'opal/grammar'
4
2
  require 'strscan'
5
3
 
6
4
  module Opal
7
5
  class Grammar < Racc::Parser
8
6
 
9
- class LexingError < StandardError; end
7
+ class OpalParseError < StandardError; end
10
8
 
11
9
  attr_reader :line
12
10
 
@@ -21,7 +19,7 @@ module Opal
21
19
  end
22
20
 
23
21
  def s *parts
24
- sexp = Sexp.new *parts
22
+ sexp = parts
25
23
  sexp.line = @line
26
24
  sexp
27
25
  end
@@ -37,6 +35,10 @@ module Opal
37
35
  result
38
36
  end
39
37
 
38
+ def on_error(t, val, vstack)
39
+ raise OpalParseError, "parse error on value #{val.inspect} (line #{@line})"
40
+ end
41
+
40
42
  class LexerScope
41
43
  attr_reader :locals
42
44
  attr_accessor :parent
@@ -140,7 +142,7 @@ module Opal
140
142
 
141
143
  def new_sclass expr, body
142
144
  scope = s(:scope)
143
- scope << body unless body.size == 1
145
+ scope << body #unless body.size == 1
144
146
  scope.line = body.line
145
147
  s = s(:sclass, expr, scope)
146
148
  s
@@ -224,7 +226,7 @@ module Opal
224
226
  if block
225
227
  b = block.to_s[1..-1].intern
226
228
  res << s(:block_pass, s(:lasgn, b))
227
- @scope.add_local r
229
+ @scope.add_local b
228
230
  end
229
231
 
230
232
  res << opt if opt
@@ -435,8 +437,8 @@ module Opal
435
437
 
436
438
  def next_token
437
439
  t = get_next_token
438
- #puts "returning token #{t.inspect}"
439
- #t[1] = { :value => t[1], :line => @line }
440
+ # puts "returning token #{t.inspect}"
441
+ # t[1] = { :value => t[1], :line => @line }
440
442
  t
441
443
  end
442
444
 
@@ -1005,7 +1007,26 @@ module Opal
1005
1007
  return [result, result]
1006
1008
 
1007
1009
  elsif scanner.scan(/\?/)
1008
- @lex_state = :expr_beg if [:expr_end, :expr_endarg].include?(@lex_state)
1010
+ # FIXME: :expr_arg shouldnt really be here
1011
+ if [:expr_end, :expr_endarg, :expr_arg].include?(@lex_state)
1012
+ @lex_state = :expr_beg
1013
+ return '?', scanner.matched
1014
+ end
1015
+
1016
+ #if scanner.scan(/\\/)
1017
+ #c = if scanner.scan(/n/)
1018
+ #"\n"
1019
+ #else
1020
+ #scanner.scan(/./)
1021
+ #scanner.matched
1022
+ #end
1023
+ #else
1024
+ #c = scanner.scan(/./)
1025
+ #end
1026
+
1027
+ #@lex_state = :expr_end
1028
+ #return :STRING, c
1029
+ @lex_state = :expr_beg
1009
1030
  return '?', scanner.matched
1010
1031
 
1011
1032
  elsif scanner.scan(/\=\=\=/)
@@ -1331,7 +1352,7 @@ module Opal
1331
1352
  end
1332
1353
  return [false, false] if scanner.eos?
1333
1354
 
1334
- raise LexingError, "Unexpected content in parsing stream `#{scanner.peek 5}`"
1355
+ raise OpalParseError, "Unexpected content in parsing stream `#{scanner.peek 5}`"
1335
1356
  end
1336
1357
  end
1337
1358
  end
@@ -1,18 +1,19 @@
1
- require 'opal/parser/lexer'
2
- require 'opal/parser/grammar'
3
- require 'opal/parser/scope'
1
+ require 'opal/lexer'
2
+ require 'opal/grammar'
3
+ require 'opal/scope'
4
+
5
+ class Array
6
+ attr_accessor :line
7
+ attr_accessor :end_line
8
+ end
4
9
 
5
10
  module Opal
6
11
  class OpalParseError < Exception; end
7
12
 
8
13
  class Parser
9
- def self.to_syms(ary)
10
- ary.map &:to_sym
11
- end
12
-
13
14
  INDENT = ' '
14
15
 
15
- LEVEL = to_syms(%w[statement statement_closure list expression receiver])
16
+ LEVEL = [:statement, :statement_closure, :list, :expression, :receiver]
16
17
 
17
18
  # Maths operators
18
19
  MATH = %w(+ - / * %)
@@ -20,7 +21,7 @@ module Opal
20
21
  # Comparison operators
21
22
  COMPARE = %w(< <= > >=)
22
23
 
23
- # All operators that can be optimized in method calls
24
+ # All Operators that can be optimized in method calls
24
25
  CALL_OPERATORS = MATH + COMPARE
25
26
 
26
27
  # Reserved javascript keywords - we cannot create variables with the
@@ -76,7 +77,13 @@ module Opal
76
77
  singleton: 0x0800
77
78
  }
78
79
 
79
- STATEMENTS = to_syms(%w[xstr dxstr])
80
+ STATEMENTS = [:xstr, :dxstr]
81
+
82
+ attr_reader :grammar
83
+
84
+ def self.parse(str)
85
+ self.new.parse str
86
+ end
80
87
 
81
88
  def initialize(opts = {})
82
89
  @debug = opts[:debug] or false
@@ -85,34 +92,26 @@ module Opal
85
92
  def parse(source, file = '(file)')
86
93
  @file = file
87
94
  @helpers = {
88
- :breaker => true, :no_proc => true, :klass => true, :const_get => true,
89
- :slice => true
95
+ :breaker => true,
96
+ :klass => true,
97
+ :const_get => true,
98
+ :slice => true
99
+ # :nil => true
90
100
  }
91
101
 
92
- parser = Grammar.new
102
+ @grammar = Grammar.new
93
103
  reset
94
-
95
- # Debug mode always uses FILE for sending methods which have stack traces
96
- @uses_file = true if @debug
97
-
98
- # $send is needed in debug mode
99
- @helpers[:send] = true if @debug
100
-
101
- begin
102
- top parser.parse(source, file)
103
- rescue Exception => e
104
- raise OpalParseError.new("#{e.message} in #{file}:#{parser.line}")
105
- end
104
+ top @grammar.parse(source, file)
106
105
  end
107
106
 
108
107
  def s(*parts)
109
- sexp = Sexp.new *parts
108
+ sexp = parts
110
109
  sexp.line = @line
111
110
  sexp
112
111
  end
113
112
 
114
113
  def reset
115
- @line = 1
114
+ @line = 1
116
115
  @indent = ''
117
116
  @unique = 0
118
117
  end
@@ -135,19 +134,20 @@ module Opal
135
134
  vars = []
136
135
 
137
136
  in_scope(:top) do
138
- code = process s(:scope, sexp), :statement
137
+ indent {
138
+ code = @indent + process(s(:scope, sexp), :statement)
139
+ }
139
140
 
140
- vars << "FILE = $opal.FILE" if @uses_file
141
- vars << "nil = $opal.nil"
142
- vars << "$const = $opal.constants"
143
- vars.concat @scope.locals.map { |t| "#{t}" }
144
- vars.concat @scope.temps.map { |t| t }
145
- vars.concat @helpers.keys.map { |h| "$#{h} = $opal.#{h}" }
141
+ vars << "__scope = Opal.constants"
142
+ vars << "nil = Opal.nil"
143
+ # vars.concat @scope.locals.map { |t| "#{t}" }
144
+ # vars.concat @scope.temps.map { |t| t }
145
+ vars.concat @helpers.keys.map { |h| "__#{h} = Opal.#{h}" }
146
146
 
147
- code = "var #{vars.join ', '};" + code unless vars.empty?
147
+ code = "var #{vars.join ', '};\n" + @scope.to_vars + "\n" + code
148
148
  end
149
149
 
150
- pre = "(function($opal) {"
150
+ pre = "(function() {\n"
151
151
  post = ""
152
152
 
153
153
  uniques = []
@@ -158,7 +158,7 @@ module Opal
158
158
  post += ";var #{uniques.join ', '};"
159
159
  end
160
160
 
161
- post += "\n}).call(opal.top, opal);"
161
+ post += "\n}).call(Opal.top);\n"
162
162
 
163
163
  pre + code + post
164
164
  end
@@ -167,7 +167,7 @@ module Opal
167
167
  return unless block_given?
168
168
 
169
169
  parent = @scope
170
- @scope = Scope.new(type).tap { |s| s.parent = parent }
170
+ @scope = Scope.new(type, self).tap { |s| s.parent = parent }
171
171
  yield @scope
172
172
 
173
173
  @scope = parent
@@ -203,24 +203,13 @@ module Opal
203
203
  end
204
204
 
205
205
  def process(sexp, level)
206
+ # puts "PROCESS: (#{level})"
207
+ # puts " #{sexp.inspect}"
206
208
  type = sexp.shift
207
209
 
208
210
  raise "Unsupported sexp: #{type}" unless respond_to? type
209
211
 
210
- line = fix_line sexp.line
211
- code = __send__ type, sexp, level
212
- line + code
213
- end
214
-
215
- def fix_line(line)
216
- res = ""
217
-
218
- if @line < line
219
- res = "\n" * (line - @line)
220
- res += @indent
221
- @line = line
222
- end
223
- res
212
+ __send__ type, sexp, level
224
213
  end
225
214
 
226
215
  def returns(sexp)
@@ -277,11 +266,11 @@ module Opal
277
266
  until sexp.empty?
278
267
  stmt = sexp.shift
279
268
  expr = expression?(stmt) and LEVEL.index(level) < LEVEL.index(:list)
280
- result << process(stmt, level)
281
- result << ";" if expr
269
+ code = process(stmt, level)
270
+ result << (expr ? "#{code};" : code)
282
271
  end
283
272
 
284
- result.join
273
+ result.join "\n#@indent"
285
274
  end
286
275
 
287
276
  def scope(sexp, level)
@@ -302,12 +291,6 @@ module Opal
302
291
  sexp.shift.to_s
303
292
  end
304
293
 
305
- # s(:js_block_given)
306
- def js_block_given(sexp, level)
307
- @scope.uses_block!
308
- "$block_given"
309
- end
310
-
311
294
  def js_operator_call(sexp, level)
312
295
  recv = sexp[0]
313
296
  meth = sexp[1]
@@ -329,41 +312,10 @@ module Opal
329
312
  res
330
313
  end
331
314
 
332
- def js_compile_time_helpers(exp, level)
333
- recv = exp[0]
334
- meth = exp[1]
335
- args = exp[2]
336
-
337
- arg = args[1] || raise("No argument given to compile helper: #{meth}")
338
- arg = process arg, :expression
339
- tmp = @scope.new_temp
340
-
341
- res = case meth
342
- when :object?
343
- "(!!(#{tmp} = #{arg}, #{tmp} != null && #{tmp}.$klass))"
344
- when :native?
345
- "(!!(#{tmp} = #{arg}, #{tmp} == null || !#{tmp}.$klass))"
346
- when :string?
347
- "(typeof #{arg} === 'string')"
348
- when :number?
349
- "(typeof #{arg} === 'number')"
350
- when :function?
351
- "(typeof #{arg} === 'function')"
352
- when :defined?
353
- "((#{tmp} = typeof(#{arg})) === 'undefined' ? nil : #{tmp})"
354
- when :undefined?
355
- "(typeof(#{arg}) === 'undefined')"
356
- when :null?
357
- "(#{arg} === null)"
358
- when :typeof
359
- "(typeof(#{arg}))"
360
- else
361
- raise "Bad compile time helper: #{meth}"
362
- end
363
-
364
- @scope.queue_temp tmp
365
-
366
- res
315
+ # s(:js_block_given)
316
+ def js_block_given(sexp, level)
317
+ @scope.uses_block!
318
+ "!!#{@scope.block_name}"
367
319
  end
368
320
 
369
321
  # s(:lit, 1)
@@ -378,7 +330,8 @@ module Opal
378
330
  when Regexp
379
331
  val == // ? /^/.inspect : val.inspect
380
332
  when Range
381
- "$opal.range(#{val.begin}, #{val.end}, #{val.exclude_end?})"
333
+ @helpers[:range] = true
334
+ "__range(#{val.begin}, #{val.end}, #{val.exclude_end?})"
382
335
  else
383
336
  raise "Bad lit: #{val.inspect}"
384
337
  end
@@ -398,8 +351,14 @@ module Opal
398
351
  "(new RegExp(#{parts.join ' + '}))"
399
352
  end
400
353
 
401
- def dot2 exp, level
402
- "$opal.range(#{process exp[0], :expression}, #{process exp[1], :expression}, false)"
354
+ def dot2(sexp, level)
355
+ @helpers[:range] = true
356
+ "__range(#{process sexp[0], :expression}, #{process sexp[1], :expression}, false)"
357
+ end
358
+
359
+ def dot3(sexp, level)
360
+ @helpers[:range] = true
361
+ "__range(#{process sexp[0], :expression}, #{process sexp[1], :expression}, true)"
403
362
  end
404
363
 
405
364
  # s(:str, "string")
@@ -407,7 +366,7 @@ module Opal
407
366
  str = sexp.shift
408
367
  if str == @file
409
368
  @uses_file = true
410
- "FILE"
369
+ "'FILE'"
411
370
  else
412
371
  str.inspect
413
372
  end
@@ -435,20 +394,18 @@ module Opal
435
394
 
436
395
  # s(:not, sexp)
437
396
  def not(sexp, level)
438
- tmp = @scope.new_temp
439
- code = "((#{tmp} = #{process sexp.shift, :expression}) === false || #{tmp} === nil)"
440
- @scope.queue_temp tmp
397
+ code = "!#{process sexp.shift, :expression}"
441
398
  code
442
399
  end
443
400
 
444
401
  def block_pass(exp, level)
445
402
  pass = process exp.shift, level
446
-
403
+ return "(#{pass} || function(){})"
447
404
  tmp = @scope.new_temp
448
405
 
449
406
  to_proc = process(s(:call, s(:js_tmp, tmp), :to_proc, s(:arglist)), :expression)
450
407
 
451
- code = "(#{tmp} = #{pass}, (typeof(#{tmp}) === 'function' || #{tmp} == nil ? #{tmp} : #{to_proc}))"
408
+ code = "(#{tmp} = #{pass}, (typeof(#{tmp}) === 'function' || #{tmp} == null ? #{tmp} : #{to_proc}))"
452
409
 
453
410
  @scope.queue_temp tmp
454
411
 
@@ -465,13 +422,15 @@ module Opal
465
422
  body = returns body
466
423
  code = ""
467
424
  params = nil
425
+ scope_name = nil
468
426
 
469
427
  args = nil if Fixnum === args # argh
470
428
  args ||= s(:masgn, s(:array))
471
429
  args = args.first == :lasgn ? s(:array, args) : args[1]
472
430
 
473
431
  if args.last[0] == :block_pass
474
- args.pop
432
+ block_arg = args.pop
433
+ block_arg = block_arg[1][1].intern
475
434
  end
476
435
 
477
436
  if args.last[0] == :splat
@@ -483,25 +442,36 @@ module Opal
483
442
  indent do
484
443
  in_scope(:iter) do
485
444
  args[1..-1].each do |arg|
486
- arg = arg[1]
487
- arg = "#{arg}$" if RESERVED.include? arg.to_s
488
- code += "if (#{arg} === undefined) {#{arg} = nil; }"
445
+ arg = arg[1]
446
+ arg = "#{arg}$" if RESERVED.include? arg.to_s
447
+ code += "if (#{arg} == null) #{arg} = nil;\n"
489
448
  end
490
449
 
491
450
  params = js_block_args(args[1..-1])
451
+ # params.unshift '_$'
492
452
 
493
453
  if splat
494
454
  params << splat
495
- code += "#{splat} = $slice.call(arguments, #{len - 1});"
455
+ code += "#{splat} = __slice.call(arguments, #{len - 1});"
496
456
  end
497
457
 
498
- code += process body, :statement
458
+ if block_arg
459
+ @scope.add_arg block_arg
460
+ code += "var #{block_arg} = _$ || nil, $context = #{block_arg}.$S;"
461
+ end
462
+
463
+ code += "\n#@indent" + process(body, :statement)
464
+
465
+ code = "\n#@indent#{@scope.to_vars}\n#@indent#{code}"
499
466
 
500
- code = @scope.to_vars + code
467
+ scope_name = @scope.identity
501
468
  end
502
469
  end
503
470
 
504
- call << "function(#{params.join ', '}) {#{code}#{fix_line sexp.end_line}}"
471
+ itercode = "function(#{params.join ', '}) {\n#{code}\n#@indent}"
472
+ itercode = "#{scope_name} = #{itercode}" if scope_name
473
+ call << itercode
474
+
505
475
  process call, level
506
476
  end
507
477
 
@@ -527,6 +497,15 @@ module Opal
527
497
  return process(s(:call, recv, mid, arglist), level)
528
498
  end
529
499
 
500
+ # s(:math_op, :op, lhs, rhs)
501
+ def math_op(exp, level)
502
+ op = exp[0]
503
+ lhs = exp[1]
504
+ rhs = exp[2]
505
+
506
+ "#{process lhs, level} #{op} #{process rhs, level}"
507
+ end
508
+
530
509
  # s(:call, recv, :mid, s(:arglist))
531
510
  # s(:call, nil, :mid, s(:arglist))
532
511
  def call(sexp, level)
@@ -538,63 +517,45 @@ module Opal
538
517
  mid = mid_to_jsid meth.to_s
539
518
 
540
519
  return js_operator_call(sexp, level) if CALL_OPERATORS.include? meth.to_s
541
- return js_compile_time_helpers(sexp, level) if recv && recv == [:const, :Opal]
542
520
  return js_block_given(sexp, level) if meth == :block_given?
543
- return "undefined" if meth == :undefined
544
521
 
545
522
  splat = arglist[1..-1].any? { |a| a.first == :splat }
546
523
 
547
- if Sexp === arglist.last and arglist.last.first == :block_pass
548
- tmpproc = @scope.new_temp
549
- tmprecv = @scope.new_temp
550
- block = process arglist.pop, :expression
524
+ if Array === arglist.last and arglist.last.first == :block_pass
525
+ tmpmeth = @scope.new_temp
526
+ block = process s(:js_tmp, process(arglist.pop, :expression)), :expression
551
527
  elsif iter
552
- tmpproc = @scope.new_temp
528
+ tmpmeth = @scope.new_temp
529
+ block = iter
530
+ end
531
+
532
+ recv ||= [:self]
533
+
534
+ if block
553
535
  tmprecv = @scope.new_temp
554
- block = iter
555
- elsif splat or @debug
536
+ elsif splat and recv != [:self] and recv[0] != :lvar
556
537
  tmprecv = @scope.new_temp
557
538
  end
539
+
540
+ recv_code = process recv, :receiver
541
+ args = ""
558
542
 
559
- args = ""
560
-
561
- recv_code = recv.nil? ? 'this' : process(recv, :receiver)
543
+ @scope.queue_temp tmprecv if tmprecv
544
+ @scope.queue_temp tmpmeth if tmpmeth
562
545
 
563
- if @debug
564
- if iter
565
- debugblock = "(#{tmpproc}=#{block},#{tmpproc}.$S=this, #{tmpproc})"
566
- elsif block
567
- debugblock = block
568
- else
569
- debugblock = 'null'
570
- end
571
- arglist.insert 1, s(:js_tmp, recv_code), s(:js_tmp, debugblock), s(:js_tmp, mid.inspect)
546
+ if tmpmeth and !splat
547
+ arglist.insert 1, s(:js_tmp, tmprecv)
572
548
  end
573
549
 
574
550
  args = process arglist, :expression
575
551
 
576
- @scope.queue_temp tmprecv if tmprecv
577
- @scope.queue_temp tmpproc if tmpproc
578
-
579
- if @debug
580
- splat ? "$send.apply(null, #{args})" : "$send(#{args})"
581
- elsif @method_missing
582
- pre = "((#{tmprecv}=#{recv_code}).#{mid} || $opal.mm('#{mid}'))."
583
- splat ? "#{pre}apply(#{tmprecv}, #{args})" : "#{pre}call(#{tmprecv}#{args == '' ? '' : ", #{args}"})"
552
+ if tmpmeth
553
+ dispatch = "(((#{tmpmeth} = (#{tmprecv} = #{recv_code})"
554
+ dispatch += ".#{mid})._p = #{block})._s = this, #{tmpmeth})"
555
+ splat ? "#{dispatch}.apply(#{tmprecv}, #{args})" : "#{dispatch}.call(#{args})"
584
556
  else
585
- if block
586
- if iter
587
- call = "(#{tmpproc}=(#{tmprecv}=#{recv_code}).#{mid}, (#{tmpproc}.$P = #{block}).$S = this, #{tmpproc})"
588
- else # block_pass
589
- call = "(#{tmpproc}=(#{tmprecv}=#{recv_code}).#{mid}, #{tmpproc}.$P = #{block}, #{tmpproc})"
590
- end
591
-
592
- args = ", #{args}" unless args.empty?
593
- splat ? "#{call}.apply(#{tmprecv}#{args})" : "#{call}.call(#{tmprecv}#{args})"
594
-
595
- else
596
- splat ? "(#{tmprecv}=#{recv_code}).#{mid}.apply(#{tmprecv}, #{args})" : "#{recv_code}.#{mid}(#{args})"
597
- end
557
+ dispatch = tmprecv ? "(#{tmprecv} = #{recv_code}).#{mid}" : "#{recv_code}.#{mid}"
558
+ splat ? "#{dispatch}.apply(#{tmprecv || recv_code}, #{args})" : "#{dispatch}(#{args})"
598
559
  end
599
560
  end
600
561
 
@@ -657,23 +618,23 @@ module Opal
657
618
  name = cid[2].to_s.inspect
658
619
  elsif cid[0] == :colon3
659
620
  donates_methods = (cid[1] === :Object || cid[1] === :BasicObject)
660
- base = '$opal.Object'
621
+ base = 'opal.Object'
661
622
  name = cid[1].to_s.inspect
662
623
  else
663
624
  raise "Bad receiver in class"
664
625
  end
665
626
 
666
- sup = sup ? process(sup, :expression) : 'nil'
627
+ sup = sup ? process(sup, :expression) : 'null'
667
628
 
668
629
  indent do
669
630
  in_scope(:class) do
670
631
  @scope.donates_methods = donates_methods
671
- code = @scope.to_vars + process(body, :statement)
672
- code += @scope.to_donate_methods if @scope.donates_methods
632
+ code = @indent + @scope.to_vars + "\n#@indent" + process(body, :statement)
633
+ code += "\n#{@scope.to_donate_methods}" if @scope.donates_methods
673
634
  end
674
635
  end
675
636
 
676
- "$klass(#{base}, #{sup}, #{name}, function() {#{code}#{fix_line sexp.end_line}}, 0)"
637
+ "__klass(#{base}, #{sup}, #{name}, function() {\n#{code}\n#@indent}, 0)"
677
638
  end
678
639
 
679
640
  # s(:sclass, recv, body)
@@ -687,7 +648,7 @@ module Opal
687
648
  code = @scope.to_vars + process(body, :statement)
688
649
  end
689
650
 
690
- "$klass(#{base}, nil, nil, function() {#{code}}, 2)"
651
+ "__klass(#{base}, null, null, function() {#{code}}, 2)"
691
652
  end
692
653
 
693
654
  # s(:module, cid, body)
@@ -703,7 +664,7 @@ module Opal
703
664
  base = process(cid[1], :expression)
704
665
  name = cid[2].to_s.inspect
705
666
  elsif cid[0] == :colon3
706
- base = '$opal.Object'
667
+ base = 'opal.Object'
707
668
  name = cid[1].to_s.inspect
708
669
  else
709
670
  raise "Bad receiver in class"
@@ -712,15 +673,15 @@ module Opal
712
673
  indent do
713
674
  in_scope(:module) do
714
675
  @scope.donates_methods = true
715
- code = @scope.to_vars + process(body, :statement) + @scope.to_donate_methods
676
+ code = @indent + @scope.to_vars + "\n#@indent" + process(body, :statement) + "\n#@indent" + @scope.to_donate_methods
716
677
  end
717
678
  end
718
679
 
719
- "$klass(#{base}, nil, #{name}, function() {#{code}#{fix_line sexp.end_line}}, 1)"
680
+ "__klass(#{base}, null, #{name}, function() {\n#{code}\n#@indent}, 1)"
720
681
  end
721
682
 
722
683
  def undef(exp, level)
723
- "$opal.undef(this, #{process exp.shift, :expression})"
684
+ "opal.undef(this, #{process exp.shift, :expression})"
724
685
  end
725
686
 
726
687
  # s(:defn, mid, s(:args), s(:scope))
@@ -744,10 +705,11 @@ module Opal
744
705
  mid = mid_to_jsid mid.to_s
745
706
 
746
707
  if recvr
747
- type = '$opal.defs'
708
+ @helpers[:defs] = true
709
+ type = '__defs'
748
710
  recv = process(recvr, :expression)
749
711
  else
750
- type = '$opal.defn'
712
+ type = 'Opal.defn'
751
713
  recv = 'this'
752
714
  end
753
715
 
@@ -756,7 +718,7 @@ module Opal
756
718
  scope_name = nil
757
719
 
758
720
  # opt args if last arg is sexp
759
- opt = args.pop if Sexp === args.last
721
+ opt = args.pop if Array === args.last
760
722
 
761
723
  # block name &block
762
724
  if args.last.to_s[0] == '&'
@@ -774,52 +736,50 @@ module Opal
774
736
  end
775
737
  end
776
738
 
777
- aritycode = arity_check(args, opt, splat) if @debug && false
739
+ # aritycode = arity_check(args, opt, splat) if @debug && false
778
740
 
779
741
  indent do
780
742
  in_scope(:def) do
781
- params = process args, :expression
743
+ @scope.mid = mid
782
744
 
783
745
  if block_name
784
- @scope.add_arg block_name
785
746
  @scope.uses_block!
786
747
  end
787
748
 
749
+ yielder = block_name || '__yield'
750
+ @scope.block_name = yielder
751
+
752
+ params = process args, :expression
753
+
788
754
  opt[1..-1].each do |o|
789
755
  next if o[2][2] == :undefined
790
756
  id = process s(:lvar, o[1]), :expression
791
- code += "if (#{id} === undefined) { #{process o, :expression}; }"
757
+ code += "if (#{id} == null) {\n#@indent#{INDENT}#{process o, :expression};\n#@indent}"
792
758
  end if opt
793
759
 
794
- code += "#{splat} = $slice.call(arguments, #{len});" if splat
795
- code += process(stmts, :statement)
796
-
797
- if @scope.uses_block?
798
- scope_name = @scope.name = unique_temp
799
- blk = "var $yield = #{scope_name}.$P;"
800
- blk += "if ($yield) { var $context = $yield.$S"
801
- blk += ", $block_given = true"
802
- blk += ", #{block_name} = $yield" if block_name
803
- blk += "; #{scope_name}.$P = null; }"
760
+ code += "#{splat} = __slice.call(arguments, #{len});" if splat
761
+ code += "\n#@indent" + process(stmts, :statement)
804
762
 
805
- blk += "else { $yield = $no_proc"
806
- blk += ", #{block_name} = nil" if block_name
807
- blk += "; }"
763
+ # Returns the identity name if identified, nil otherwise
764
+ scope_name = @scope.identity
808
765
 
766
+ if @scope.uses_block?
767
+ @scope.add_local '__context'
768
+ @scope.add_local yielder
769
+ blk = "\n#{@indent}if (#{yielder} = #{scope_name}._p) {\n#{@indent + INDENT}__context = #{yielder}._s"
770
+ blk += ";\n#{@indent + INDENT}#{scope_name}._p = null;\n#{@indent}}"
809
771
  code = blk + code
810
772
  end
811
773
 
812
- code = aritycode.to_s + code
813
-
814
774
  if @scope.catches_break?
815
- code = "try {#{code}} catch (e) { if (e === $breaker) { return e.$v; }; throw e;}"
775
+ # code = "try {#{code}} catch (e) { if (e === __breaker) { return e.$v; }; throw e;}"
816
776
  end
817
777
 
818
- code = @scope.to_vars + code
778
+ code = "#@indent#{@scope.to_vars}" + code
819
779
  end
820
780
  end
821
781
 
822
- defcode = "#{"#{scope_name} = " if scope_name}function(#{params}) {#{code}#{fix_line end_line}}"
782
+ defcode = "#{"#{scope_name} = " if scope_name}function(#{params}) {\n#{code}\n#@indent}"
823
783
 
824
784
  if @debug
825
785
  "#{type}(#{recv}, '#{mid}', #{defcode}, FILE, #{line})"
@@ -846,9 +806,9 @@ module Opal
846
806
 
847
807
  aritycode = "var $arity = arguments.length; if ($arity !== 0) { $arity -= 1; }"
848
808
  if arity < 0 # splat or opt args
849
- aritycode + "if ($arity < #{-(arity + 1)}) { $opal.arg_error($arity, #{arity}); }"
809
+ aritycode + "if ($arity < #{-(arity + 1)}) { opal.arg_error($arity, #{arity}); }"
850
810
  else
851
- aritycode + "if ($arity !== #{arity}) { $opal.arg_error($arity, #{arity}); }"
811
+ aritycode + "if ($arity !== #{arity}) { opal.arg_error($arity, #{arity}); }"
852
812
  end
853
813
  end
854
814
 
@@ -872,13 +832,16 @@ module Opal
872
832
 
873
833
  # s(:true) # => true
874
834
  # s(:false) # => false
875
- # s(:nil) # => nil
876
- %w(true false nil).each do |name|
835
+ %w(true false).each do |name|
877
836
  define_method name do |exp, level|
878
837
  name
879
838
  end
880
839
  end
881
840
 
841
+ def nil(*)
842
+ "nil"
843
+ end
844
+
882
845
  # s(:array [, sexp [, sexp]])
883
846
  def array(sexp, level)
884
847
  return '[]' if sexp.empty?
@@ -914,7 +877,7 @@ module Opal
914
877
 
915
878
  # s(:hash, key1, val1, key2, val2...)
916
879
  def hash(sexp, level)
917
- "$opal.hash(#{sexp.map { |p| process p, :expression }.join ', '})"
880
+ "Opal.hash(#{sexp.map { |p| process p, :expression }.join ', '})"
918
881
  end
919
882
 
920
883
  # s(:while, exp, block, true)
@@ -995,9 +958,10 @@ module Opal
995
958
  #
996
959
  # s(:alias, s(:lit, :foo), s(:lit, :bar))
997
960
  def alias(exp, level)
961
+ @helpers['alias'] = true
998
962
  new = exp[0]
999
963
  old = exp[1]
1000
- "$opal.alias(this, #{process new, :expression}, #{process old, :expression})"
964
+ "__alias(this, #{process new, :expression}, #{process old, :expression})"
1001
965
  end
1002
966
 
1003
967
  def masgn(sexp, level)
@@ -1023,11 +987,11 @@ module Opal
1023
987
 
1024
988
  if l.first == :splat
1025
989
  s = l[1]
1026
- s << s(:js_tmp, "$slice.call(#{tmp}, #{idx})")
990
+ s << s(:js_tmp, "__slice.call(#{tmp}, #{idx})")
1027
991
  code << process(s, :expression)
1028
992
  else
1029
993
  if idx >= len
1030
- l << s(:js_tmp, "(#{tmp}[#{idx}] === undefined ? nil : #{tmp}[#{idx}])")
994
+ l << s(:js_tmp, "(#{tmp}[#{idx}] == null ? nil : #{tmp}[#{idx}])")
1031
995
  else
1032
996
  l << s(:js_tmp, "#{tmp}[#{idx}]")
1033
997
  end
@@ -1049,7 +1013,8 @@ module Opal
1049
1013
  rhs = sexp[1]
1050
1014
  lvar = "#{lvar}$".intern if RESERVED.include? lvar.to_s
1051
1015
  @scope.add_local lvar
1052
- "#{lvar} = #{process rhs, :expression}"
1016
+ res = "#{lvar} = #{process rhs, :expression}"
1017
+ level == :receiver ? "(#{res})" : res
1053
1018
  end
1054
1019
 
1055
1020
  # s(:lvar, :lvar)
@@ -1079,25 +1044,24 @@ module Opal
1079
1044
  # s(:gvar, gvar)
1080
1045
  def gvar(sexp, level)
1081
1046
  gvar = sexp.shift.to_s
1082
- tmp = @scope.new_temp
1083
- code = "((#{tmp} = $opal.gvars[#{gvar.inspect}]) == null ? nil : #{tmp})"
1084
- @scope.queue_temp tmp
1085
- code
1047
+ @helpers['gvars'] = true
1048
+ "__gvars[#{gvar.inspect}]"
1086
1049
  end
1087
1050
 
1088
1051
  # s(:gasgn, :gvar, rhs)
1089
1052
  def gasgn(sexp, level)
1090
1053
  gvar = sexp[0]
1091
1054
  rhs = sexp[1]
1092
- "($opal.gvars[#{gvar.to_s.inspect}] = #{process rhs, :expression})"
1055
+ @helpers['gvars'] = true
1056
+ "__gvars[#{gvar.to_s.inspect}] = #{process rhs, :expression}"
1093
1057
  end
1094
1058
 
1095
1059
  # s(:const, :const)
1096
1060
  def const(sexp, level)
1097
1061
  if @debug
1098
- "$opal.const_get($const, #{sexp.shift.to_s.inspect})"
1062
+ "Opal.const_get(__scope, #{sexp.shift.to_s.inspect})"
1099
1063
  else
1100
- "$const.#{sexp.shift}"
1064
+ "__scope.#{sexp.shift}"
1101
1065
  end
1102
1066
  end
1103
1067
 
@@ -1105,7 +1069,7 @@ module Opal
1105
1069
  def cdecl(sexp, level)
1106
1070
  const = sexp[0]
1107
1071
  rhs = sexp[1]
1108
- "$const.#{const} = #{process rhs, :expression}"
1072
+ "__scope.#{const} = #{process rhs, :expression}"
1109
1073
  end
1110
1074
 
1111
1075
  # s(:return [val])
@@ -1134,7 +1098,7 @@ module Opal
1134
1098
  if String === p
1135
1099
  p.to_s
1136
1100
  elsif p.first == :evstr
1137
- process p.last, :expression
1101
+ process p.last, :statement
1138
1102
  elsif p.first == :str
1139
1103
  p.last.to_s
1140
1104
  else
@@ -1153,7 +1117,7 @@ module Opal
1153
1117
  if String === p
1154
1118
  p.inspect
1155
1119
  elsif p.first == :evstr
1156
- process(s(:call, p.last, :to_s, s(:arglist)), :expression)
1120
+ process p.last, :expression
1157
1121
  elsif p.first == :str
1158
1122
  p.last.inspect
1159
1123
  else
@@ -1161,7 +1125,8 @@ module Opal
1161
1125
  end
1162
1126
  end
1163
1127
 
1164
- "(#{parts.join ' + '})"
1128
+ res = parts.join ' + '
1129
+ level == :receiver ? "(#{res})" : res
1165
1130
  end
1166
1131
 
1167
1132
  def dsym(sexp, level)
@@ -1182,19 +1147,19 @@ module Opal
1182
1147
 
1183
1148
  # s(:if, test, truthy, falsy)
1184
1149
  def if(sexp, level)
1185
- test = sexp[0]
1150
+ test = sexp[0]
1186
1151
  truthy = sexp[1]
1187
- falsy = sexp[2]
1152
+ falsy = sexp[2]
1188
1153
 
1189
1154
  if level == :expression or level == :receiver
1190
1155
  truthy = returns(truthy || s(:nil))
1191
1156
  falsy = returns(falsy || s(:nil))
1192
1157
  end
1193
1158
 
1194
- code = "if (#{js_truthy test}) {"
1195
- indent { code += process(truthy, :statement) } if truthy
1196
- indent { code += "} else {#{process falsy, :statement}" } if falsy
1197
- code += "#{fix_line sexp.end_line}}"
1159
+ code = "if (#{js_truthy test}) {\n"
1160
+ indent { code += @indent + process(truthy, :statement) } if truthy
1161
+ indent { code += "\n#@indent} else {\n#@indent#{process falsy, :statement}" } if falsy
1162
+ code += "\n#@indent}"
1198
1163
 
1199
1164
  code = "(function() { #{code}; return nil; }).call(this)" if level == :expression or level == :receiver
1200
1165
 
@@ -1237,8 +1202,8 @@ module Opal
1237
1202
  }
1238
1203
  end
1239
1204
 
1240
- code = "(#{tmp} = #{process lhs, :expression}, #{tmp} !== false && "
1241
- code += "#{tmp} != nil ? #{process rhs, :expression} : #{tmp})"
1205
+ code = "((#{tmp} = #{process lhs, :expression}, #{tmp} !== false && "
1206
+ code += "#{tmp} !== nil) ? #{process rhs, :expression} : #{tmp})"
1242
1207
  @scope.queue_temp tmp
1243
1208
 
1244
1209
  code
@@ -1258,7 +1223,7 @@ module Opal
1258
1223
  end
1259
1224
 
1260
1225
  code = "(#{tmp} = #{process lhs, :expression}, #{tmp} !== false && "
1261
- code += "#{tmp} != nil ? #{tmp} : #{process rhs, :expression})"
1226
+ code += "#{tmp} !== nil ? #{tmp} : #{process rhs, :expression})"
1262
1227
  @scope.queue_temp tmp
1263
1228
 
1264
1229
  code
@@ -1266,25 +1231,35 @@ module Opal
1266
1231
 
1267
1232
  # s(:yield, arg1, arg2)
1268
1233
  def yield(sexp, level)
1234
+ # puts sexp.inspect
1235
+ # puts level.inspect
1269
1236
  @scope.uses_block!
1270
1237
  splat = sexp.any? { |s| s.first == :splat }
1271
- sexp.unshift s(:js_tmp, '$context') unless splat
1238
+ # sexp.unshift s(:js_tmp, 'null')
1239
+ sexp.unshift s(:js_tmp, '__context') unless splat
1272
1240
  args = arglist(sexp, level)
1273
1241
 
1242
+ yielder = @scope.block_name || '__yield'
1243
+
1274
1244
  call = if splat
1275
- "$yield.apply($context, #{args})"
1245
+ "#{yielder}.apply(__context, #{args})"
1276
1246
  else
1277
- "$yield.call(#{args})"
1247
+ "#{yielder}.call(#{args})"
1278
1248
  end
1279
1249
 
1280
- if level == :receiver or level == :expression
1281
- tmp = @scope.new_temp
1282
- @scope.catches_break!
1283
- code = "((#{tmp} = #{call}) === $breaker ? #{tmp}.$t() : #{tmp})"
1284
- @scope.queue_temp tmp
1285
- else
1250
+ # FIXME: yield as an expression (when used with js_return) should have the
1251
+ # right action. We should then warn when used as an expression in other cases
1252
+ # that we would need to use a try/catch/throw block (which is slow and bad
1253
+ # mmmkay).
1254
+
1255
+ # if level == :receiver or level == :expression
1256
+ # tmp = @scope.new_temp
1257
+ # @scope.catches_break!
1258
+ # code = "((#{tmp} = #{call}) === __breaker ? #{tmp}.$t() : #{tmp})"
1259
+ # @scope.queue_temp tmp
1260
+ # else
1286
1261
  code = call
1287
- end
1262
+ # end
1288
1263
 
1289
1264
  code
1290
1265
  end
@@ -1298,7 +1273,7 @@ module Opal
1298
1273
  "break;"
1299
1274
  end
1300
1275
  else
1301
- "return ($breaker.$v = #{val}, $breaker)"
1276
+ "return (__breaker.$v = #{val}, __breaker)"
1302
1277
  end
1303
1278
  end
1304
1279
 
@@ -1379,7 +1354,7 @@ module Opal
1379
1354
  # s(:cvar, name)
1380
1355
  def cvar(exp, level)
1381
1356
  tmp = @scope.new_temp
1382
- code = "((#{tmp} = $opal.cvars[#{exp.shift.to_s.inspect}]) == null ? nil : #{tmp})"
1357
+ code = "((#{tmp} = Opal.cvars[#{exp.shift.to_s.inspect}]) == null ? null : #{tmp})"
1383
1358
  @scope.queue_temp tmp
1384
1359
  code
1385
1360
  end
@@ -1388,11 +1363,11 @@ module Opal
1388
1363
  #
1389
1364
  # s(:cvasgn, :@@name, rhs)
1390
1365
  def cvasgn(exp, level)
1391
- "($opal.cvars[#{exp.shift.to_s.inspect}] = #{process exp.shift, :expression})"
1366
+ "(Opal.cvars[#{exp.shift.to_s.inspect}] = #{process exp.shift, :expression})"
1392
1367
  end
1393
1368
 
1394
1369
  def cvdecl(exp, level)
1395
- "($opal.cvars[#{exp.shift.to_s.inspect}] = #{process exp.shift, :expression})"
1370
+ "(Opal.cvars[#{exp.shift.to_s.inspect}] = #{process exp.shift, :expression})"
1396
1371
  end
1397
1372
 
1398
1373
  # BASE::NAME
@@ -1401,11 +1376,11 @@ module Opal
1401
1376
  def colon2(sexp, level)
1402
1377
  base = sexp[0]
1403
1378
  name = sexp[1]
1404
- "$opal.const_get((#{process base, :expression}).$const, #{name.to_s.inspect})"
1379
+ "Opal.const_get((#{process base, :expression})._scope, #{name.to_s.inspect})"
1405
1380
  end
1406
1381
 
1407
1382
  def colon3(exp, level)
1408
- "$opal.const_get($opal.Object, #{exp.shift.to_s.inspect})"
1383
+ "Opal.const_get(Opal.Object._scope, #{exp.shift.to_s.inspect})"
1409
1384
  end
1410
1385
 
1411
1386
  # super a, b, c
@@ -1416,14 +1391,33 @@ module Opal
1416
1391
  until sexp.empty?
1417
1392
  args << process(sexp.shift, :expression)
1418
1393
  end
1419
- "$opal.zuper(arguments.callee, this, [#{args.join ', '}])"
1394
+
1395
+ # args.unshift 'null'
1396
+
1397
+ js_super "[#{ args.join ', ' }]"
1420
1398
  end
1421
1399
 
1422
1400
  # super
1423
1401
  #
1424
1402
  # s(:zsuper)
1425
1403
  def zsuper(exp, level)
1426
- "$opal.zuper(arguments.callee, this, [])"
1404
+
1405
+ js_super "__slice.call(arguments)"
1406
+ end
1407
+
1408
+ def js_super args
1409
+ if @scope.type == :def
1410
+ mid = @scope.mid
1411
+ identity = @scope.identify!
1412
+ "Opal.zuper(#{identity}, '#{mid}', this, #{args})"
1413
+
1414
+ elsif @scope.type == :iter
1415
+ chain, defn, mid = @scope.get_super_chain
1416
+ "Opal.dsuper([#{chain.join ', '}], #{defn}, #{mid}, this, #{args})"
1417
+
1418
+ else
1419
+ raise "Cannot call super() from outside a method block"
1420
+ end
1427
1421
  end
1428
1422
 
1429
1423
  # a ||= rhs
@@ -1511,7 +1505,7 @@ module Opal
1511
1505
  }.join ', '
1512
1506
  err = "true" if err.empty?
1513
1507
 
1514
- if Sexp === args.last and [:lasgn, :iasgn].include? args.last.first
1508
+ if Array === args.last and [:lasgn, :iasgn].include? args.last.first
1515
1509
  val = args.last
1516
1510
  val[2] = s(:js_tmp, "$err")
1517
1511
  val = process(val, :expression) + ";"