opal 0.3.16 → 0.3.17

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 (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) + ";"