opal 0.3.41 → 0.3.42

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 (285) hide show
  1. data/.gitignore +2 -0
  2. data/.travis.yml +3 -0
  3. data/CHANGELOG.md +14 -1
  4. data/Gemfile +2 -5
  5. data/Rakefile +41 -3
  6. data/bin/opal +33 -0
  7. data/lib/opal.rb +2 -12
  8. data/lib/opal/core_ext.rb +5 -0
  9. data/lib/opal/grammar.rb +2207 -2138
  10. data/lib/opal/grammar.y +21 -0
  11. data/lib/opal/grammar_helpers.rb +360 -0
  12. data/lib/opal/lexer.rb +55 -401
  13. data/lib/opal/lexer_scope.rb +28 -0
  14. data/lib/opal/parser.rb +155 -171
  15. data/lib/opal/target_scope.rb +257 -0
  16. data/lib/opal/version.rb +1 -1
  17. data/opal.gemspec +6 -2
  18. data/opal/opal-parser.js.erb +3 -2
  19. data/opal/opal.rb +20 -18
  20. data/opal/opal/array.rb +21 -12
  21. data/opal/opal/basic_object.rb +2 -1
  22. data/opal/opal/boolean.rb +3 -0
  23. data/opal/opal/browser_loader.js +57 -0
  24. data/opal/opal/class.rb +51 -13
  25. data/opal/opal/date.rb +1 -20
  26. data/opal/opal/enumerable.rb +66 -33
  27. data/opal/opal/error.rb +2 -0
  28. data/opal/opal/hash.rb +1 -1
  29. data/opal/opal/kernel.rb +14 -3
  30. data/opal/opal/nil_class.rb +4 -0
  31. data/opal/opal/proc.rb +9 -1
  32. data/opal/opal/racc.rb +2 -2
  33. data/opal/opal/regexp.rb +1 -1
  34. data/opal/opal/runtime.js +14 -4
  35. data/opal/opal/string.rb +21 -4
  36. data/opal/opal/time.rb +27 -0
  37. data/spec/core/array/allocate_spec.rb +7 -1
  38. data/spec/core/array/append_spec.rb +18 -3
  39. data/spec/core/array/array_spec.rb +7 -0
  40. data/spec/core/array/assoc_spec.rb +23 -8
  41. data/spec/core/array/at_spec.rb +23 -3
  42. data/spec/core/array/choice_spec.rb +20 -0
  43. data/spec/core/array/clear_spec.rb +45 -4
  44. data/spec/core/array/combination_spec.rb +55 -0
  45. data/spec/core/array/compact_spec.rb +72 -1
  46. data/spec/core/array/constructor_spec.rb +13 -2
  47. data/spec/core/array/count_spec.rb +15 -7
  48. data/spec/core/array/delete_at_spec.rb +44 -1
  49. data/spec/core/array/delete_if_spec.rb +52 -2
  50. data/spec/core/array/delete_spec.rb +83 -2
  51. data/spec/core/array/drop_spec.rb +24 -16
  52. data/spec/core/array/drop_while_spec.rb +17 -0
  53. data/spec/core/array/each_index_spec.rb +11 -1
  54. data/spec/core/array/each_spec.rb +20 -2
  55. data/spec/core/array/empty_spec.rb +4 -1
  56. data/spec/core/array/eql_spec.rb +14 -0
  57. data/spec/core/array/fetch_spec.rb +31 -2
  58. data/spec/core/array/find_index_spec.rb +8 -0
  59. data/spec/core/array/first_spec.rb +45 -8
  60. data/spec/core/array/fixtures/classes.rb +538 -0
  61. data/spec/core/array/flatten_spec.rb +200 -7
  62. data/spec/core/array/frozen_spec.rb +32 -0
  63. data/spec/core/array/include_spec.rb +16 -1
  64. data/spec/core/array/index_spec.rb +5 -25
  65. data/spec/core/array/insert_spec.rb +37 -3
  66. data/spec/core/array/inspect_spec.rb +6 -12
  67. data/spec/core/array/intersection_spec.rb +55 -4
  68. data/spec/core/array/join_spec.rb +29 -4
  69. data/spec/core/array/keep_if_spec.rb +13 -6
  70. data/spec/core/array/last_spec.rb +35 -1
  71. data/spec/core/array/length_spec.rb +7 -4
  72. data/spec/core/array/map_spec.rb +9 -47
  73. data/spec/core/array/minus_spec.rb +68 -4
  74. data/spec/core/array/multiply_spec.rb +138 -6
  75. data/spec/core/array/new_spec.rb +92 -3
  76. data/spec/core/array/ntimes_spec.rb +26 -0
  77. data/spec/core/array/plus_spec.rb +48 -2
  78. data/spec/core/array/pop_spec.rb +159 -39
  79. data/spec/core/array/push_spec.rb +29 -1
  80. data/spec/core/array/rassoc_spec.rb +31 -2
  81. data/spec/core/array/reject_spec.rb +89 -2
  82. data/spec/core/array/replace_spec.rb +7 -29
  83. data/spec/core/array/reverse_each_spec.rb +25 -1
  84. data/spec/core/array/reverse_spec.rb +53 -1
  85. data/spec/core/array/rindex_spec.rb +55 -5
  86. data/spec/core/array/select_spec.rb +35 -8
  87. data/spec/core/array/shared/collect.rb +0 -0
  88. data/spec/core/array/shared/enumeratorize.rb +12 -0
  89. data/spec/core/array/shared/eql.rb +95 -0
  90. data/spec/core/array/shared/index.rb +37 -0
  91. data/spec/core/array/shared/inspect.rb +3 -0
  92. data/spec/core/array/shared/join.rb +7 -0
  93. data/spec/core/array/shared/keep_if.rb +0 -0
  94. data/spec/core/array/shared/length.rb +0 -0
  95. data/spec/core/array/shared/replace.rb +0 -0
  96. data/spec/core/array/shared/slice.rb +0 -0
  97. data/spec/core/array/shift_spec.rb +132 -23
  98. data/spec/core/array/shuffle_spec.rb +82 -6
  99. data/spec/core/array/size_spec.rb +7 -4
  100. data/spec/core/array/slice_spec.rb +132 -1
  101. data/spec/core/array/sort_spec.rb +263 -14
  102. data/spec/core/array/take_spec.rb +24 -16
  103. data/spec/core/array/take_while_spec.rb +14 -10
  104. data/spec/core/array/to_a_spec.rb +18 -1
  105. data/spec/core/array/to_ary_spec.rb +15 -1
  106. data/spec/core/array/try_convert_spec.rb +39 -2
  107. data/spec/core/array/uniq_spec.rb +148 -3
  108. data/spec/core/array/unshift_spec.rb +36 -1
  109. data/spec/core/array/zip_spec.rb +36 -1
  110. data/spec/core/class/new_spec.rb +8 -6
  111. data/spec/core/enumerable/all_spec.rb +37 -9
  112. data/spec/core/enumerable/any_spec.rb +45 -7
  113. data/spec/core/enumerable/collect_spec.rb +4 -1
  114. data/spec/core/enumerable/count_spec.rb +4 -1
  115. data/spec/core/enumerable/detect_spec.rb +2 -2
  116. data/spec/core/enumerable/drop_spec.rb +4 -1
  117. data/spec/core/enumerable/drop_while_spec.rb +4 -1
  118. data/spec/core/enumerable/each_slice_spec.rb +2 -1
  119. data/spec/core/enumerable/each_with_index_spec.rb +4 -1
  120. data/spec/core/enumerable/each_with_object_spec.rb +4 -1
  121. data/spec/core/enumerable/entries_spec.rb +4 -1
  122. data/spec/core/enumerable/find_all_spec.rb +4 -1
  123. data/spec/core/enumerable/find_index_spec.rb +4 -1
  124. data/spec/core/enumerable/find_spec.rb +5 -2
  125. data/spec/core/enumerable/first_spec.rb +4 -1
  126. data/spec/core/enumerable/fixtures/classes.rb +198 -2
  127. data/spec/core/enumerable/grep_spec.rb +4 -1
  128. data/spec/core/enumerable/take_spec.rb +4 -1
  129. data/spec/core/enumerable/to_a_spec.rb +4 -1
  130. data/spec/core/false/and_spec.rb +11 -0
  131. data/spec/core/false/inspect_spec.rb +7 -0
  132. data/spec/core/false/or_spec.rb +11 -0
  133. data/spec/core/false/to_s_spec.rb +7 -0
  134. data/spec/core/false/xor_spec.rb +11 -0
  135. data/spec/core/kernel/rand_spec.rb +5 -5
  136. data/spec/core/module/const_get_spec.rb +4 -4
  137. data/spec/core/module/fixtures/classes.rb +434 -0
  138. data/spec/core/module/method_defined_spec.rb +49 -0
  139. data/spec/core/module/module_function_spec.rb +28 -0
  140. data/spec/core/nil/and_spec.rb +3 -1
  141. data/spec/core/nil/dup_spec.rb +7 -0
  142. data/spec/core/nil/inspect_spec.rb +3 -1
  143. data/spec/core/nil/nil_spec.rb +3 -1
  144. data/spec/core/nil/or_spec.rb +4 -2
  145. data/spec/core/nil/to_a_spec.rb +3 -1
  146. data/spec/core/nil/to_f_spec.rb +3 -1
  147. data/spec/core/nil/to_i_spec.rb +3 -1
  148. data/spec/core/nil/to_s_spec.rb +3 -1
  149. data/spec/core/nil/xor_spec.rb +4 -2
  150. data/spec/core/string/element_reference_spec.rb +14 -1
  151. data/spec/core/string/fixtures/classes.rb +0 -0
  152. data/spec/core/true/and_spec.rb +11 -0
  153. data/spec/core/true/inspect_spec.rb +7 -0
  154. data/spec/core/true/or_spec.rb +11 -0
  155. data/spec/core/true/to_s_spec.rb +7 -0
  156. data/spec/core/true/xor_spec.rb +11 -0
  157. data/spec/{core → core_ext}/array/element_reference_spec.rb +0 -0
  158. data/spec/{core → core_ext}/array/equal_value_spec.rb +0 -0
  159. data/spec/{core → core_ext}/array/fill_spec.rb +0 -0
  160. data/spec/{core → core_ext}/array/reduce_spec.rb +0 -0
  161. data/spec/core_ext/basic_object/send_spec.rb +3 -3
  162. data/spec/{core → core_ext}/boolean/singleton_class_spec.rb +0 -0
  163. data/spec/{core → core_ext}/boolean/to_json_spec.rb +0 -0
  164. data/spec/core_ext/class/_inherited_spec.rb +3 -3
  165. data/spec/core_ext/class/proc_methods_spec.rb +2 -2
  166. data/spec/core_ext/class/singleton_methods_spec.rb +8 -8
  167. data/spec/core_ext/method_missing_spec.rb +3 -3
  168. data/spec/core_ext/native/method_missing_spec.rb +3 -2
  169. data/spec/core_ext/native/to_native_spec.rb +3 -2
  170. data/spec/{core → core_ext}/nil/to_json_spec.rb +0 -0
  171. data/spec/date.rb +0 -0
  172. data/spec/fileutils.rb +0 -0
  173. data/spec/filters/ancestors.rb +4 -0
  174. data/spec/filters/array_delete.rb +3 -0
  175. data/spec/filters/array_fetch.rb +3 -0
  176. data/spec/filters/array_first.rb +3 -0
  177. data/spec/filters/array_flatten.rb +14 -0
  178. data/spec/filters/array_intersection.rb +5 -0
  179. data/spec/filters/array_join.rb +6 -0
  180. data/spec/filters/array_subclasses.rb +4 -0
  181. data/spec/filters/block_args.rb +3 -0
  182. data/spec/filters/coerce_integer.rb +9 -0
  183. data/spec/filters/frozen.rb +4 -0
  184. data/spec/filters/mocks.rb +3 -0
  185. data/spec/filters/should_receive.rb +4 -0
  186. data/spec/filters/tainted.rb +7 -0
  187. data/spec/fixtures/class.rb +124 -0
  188. data/spec/fixtures/class_variables.rb +0 -0
  189. data/spec/fixtures/constants.rb +0 -0
  190. data/spec/grammar/alias_spec.rb +1 -1
  191. data/spec/grammar/def_spec.rb +1 -0
  192. data/spec/grammar/lvar_spec.rb +1 -2
  193. data/spec/grammar/nth_ref_spec.rb +13 -0
  194. data/spec/grammar/sclass_spec.rb +6 -7
  195. data/spec/grammar/str_spec.rb +4 -4
  196. data/spec/grammar/string_spec.rb +8 -0
  197. data/spec/grammar/xstr_spec.rb +4 -4
  198. data/spec/iconv.rb +0 -0
  199. data/spec/language/alias_spec.rb +140 -3
  200. data/spec/language/and_spec.rb +14 -7
  201. data/spec/language/array_spec.rb +57 -5
  202. data/spec/language/block_spec.rb +466 -49
  203. data/spec/language/break_spec.rb +294 -44
  204. data/spec/language/case_spec.rb +151 -3
  205. data/spec/language/class_spec.rb +196 -0
  206. data/spec/language/class_variable_spec.rb +56 -0
  207. data/spec/language/def_spec.rb +507 -4
  208. data/spec/language/defined_spec.rb +19 -7
  209. data/spec/language/ensure_spec.rb +26 -39
  210. data/spec/language/execution_spec.rb +15 -0
  211. data/spec/language/fixtures/array.rb +11 -0
  212. data/spec/language/fixtures/block.rb +57 -0
  213. data/spec/language/fixtures/break.rb +240 -0
  214. data/spec/language/fixtures/ensure.rb +72 -0
  215. data/spec/language/fixtures/literal_lambda.rb +7 -0
  216. data/spec/language/fixtures/metaclass.rb +33 -0
  217. data/spec/language/fixtures/module.rb +24 -0
  218. data/spec/language/fixtures/next.rb +78 -12
  219. data/spec/language/fixtures/return.rb +118 -0
  220. data/spec/language/fixtures/send.rb +110 -0
  221. data/spec/language/fixtures/send_1.9.rb +22 -0
  222. data/spec/language/fixtures/super.rb +308 -0
  223. data/spec/language/fixtures/variables.rb +58 -0
  224. data/spec/language/fixtures/yield.rb +5 -0
  225. data/spec/language/for_spec.rb +192 -0
  226. data/spec/language/hash_spec.rb +29 -5
  227. data/spec/language/if_spec.rb +90 -9
  228. data/spec/language/literal_lambda_spec.rb +1 -47
  229. data/spec/language/loop_spec.rb +39 -2
  230. data/spec/language/metaclass_spec.rb +151 -5
  231. data/spec/language/module_spec.rb +56 -0
  232. data/spec/language/next_spec.rb +370 -12
  233. data/spec/language/not_spec.rb +55 -0
  234. data/spec/language/numbers_spec.rb +56 -0
  235. data/spec/language/or_spec.rb +31 -3
  236. data/spec/language/order_spec.rb +79 -0
  237. data/spec/language/precedence_spec.rb +483 -0
  238. data/spec/language/proc_spec.rb +249 -21
  239. data/spec/language/redo_spec.rb +67 -0
  240. data/spec/language/rescue_spec.rb +121 -0
  241. data/spec/language/retry_spec.rb +56 -0
  242. data/spec/language/return_spec.rb +281 -0
  243. data/spec/language/send_spec.rb +141 -48
  244. data/spec/language/singleton_class_spec.rb +1 -1
  245. data/spec/language/string_spec.rb +11 -0
  246. data/spec/language/super_spec.rb +213 -133
  247. data/spec/language/symbol_spec.rb +2 -1
  248. data/spec/language/undef_spec.rb +3 -1
  249. data/spec/language/unless_spec.rb +6 -2
  250. data/spec/language/until_spec.rb +102 -3
  251. data/spec/language/variables_spec.rb +1212 -16
  252. data/spec/language/versions/array_1.9.rb +39 -0
  253. data/spec/language/versions/case_1.9.rb +20 -0
  254. data/spec/language/versions/hash_1.9.rb +18 -0
  255. data/spec/language/versions/literal_lambda_1.9.rb +143 -0
  256. data/spec/language/versions/not_1.9.rb +22 -0
  257. data/spec/language/versions/send_1.9.rb +241 -0
  258. data/spec/language/versions/symbol_1.9.rb +15 -0
  259. data/spec/language/versions/variables_1.9.rb +8 -0
  260. data/spec/language/while_spec.rb +70 -5
  261. data/spec/language/yield_spec.rb +32 -6
  262. data/spec/mspec/guards/block_device.rb +0 -0
  263. data/spec/mspec/guards/endian.rb +0 -0
  264. data/spec/mspec/helpers/environment.rb +0 -0
  265. data/spec/mspec/helpers/language_version.rb +0 -0
  266. data/spec/mspec/helpers/tmp.rb +0 -0
  267. data/spec/ospec/filter.rb +32 -0
  268. data/spec/ospec/main.rb.erb +18 -0
  269. data/spec/ospec/phantom.rb +97 -0
  270. data/spec/ospec/runner.rb +95 -0
  271. data/spec/ospec/sprockets.js +40 -0
  272. data/spec/pp.rb +3 -0
  273. data/spec/rbconfig.rb +5 -0
  274. data/spec/spec_helper.rb +53 -26
  275. data/spec/yaml.rb +0 -0
  276. metadata +275 -31
  277. data/config.ru +0 -8
  278. data/lib/opal/processor.rb +0 -47
  279. data/lib/opal/scope.rb +0 -236
  280. data/lib/opal/server.rb +0 -94
  281. data/spec/core/boolean/and_spec.rb +0 -17
  282. data/spec/core/boolean/inspect_spec.rb +0 -9
  283. data/spec/core/boolean/or_spec.rb +0 -17
  284. data/spec/core/boolean/to_s_spec.rb +0 -9
  285. data/spec/core/boolean/xor_spec.rb +0 -17
data/lib/opal/grammar.y CHANGED
@@ -591,6 +591,11 @@ aref_args:
591
591
  {
592
592
  result = val[0]
593
593
  }
594
+ | args ',' assocs trailer
595
+ {
596
+ val[0] << s(:hash, *val[2])
597
+ result = val[0]
598
+ }
594
599
  | assocs trailer
595
600
  {
596
601
  result = s(:array, s(:hash, *val[0]))
@@ -776,6 +781,15 @@ primary:
776
781
  {
777
782
  result = s(:defined, val[3])
778
783
  }
784
+ | NOT '(' expr ')'
785
+ {
786
+ result = s(:not, val[2])
787
+ result.line = val[2].line
788
+ }
789
+ | NOT '(' ')'
790
+ {
791
+ result = s(:not, s(:nil))
792
+ }
779
793
  | operation brace_block
780
794
  {
781
795
  result = val[1]
@@ -1014,6 +1028,10 @@ block_var_args:
1014
1028
  {
1015
1029
  result = new_block_args val[0], nil, val[2], val[3]
1016
1030
  }
1031
+ | f_arg ','
1032
+ {
1033
+ result = new_block_args val[0], nil, nil, nil
1034
+ }
1017
1035
  | f_arg opt_f_block_arg
1018
1036
  {
1019
1037
  result = new_block_args val[0], nil, nil, val[1]
@@ -1448,6 +1466,9 @@ var_lhs:
1448
1466
 
1449
1467
  backref:
1450
1468
  NTH_REF
1469
+ {
1470
+ result = s(:nth_ref, val[0])
1471
+ }
1451
1472
  | BACK_REF
1452
1473
 
1453
1474
  superclass:
@@ -0,0 +1,360 @@
1
+ module Opal
2
+ class Grammar < Racc::Parser
3
+
4
+ def new_block(stmt = nil)
5
+ s = s(:block)
6
+ s << stmt if stmt
7
+ s
8
+ end
9
+
10
+ def new_compstmt(block)
11
+ if block.size == 1
12
+ nil
13
+ elsif block.size == 2
14
+ block[1]
15
+ else
16
+ block.line = block[1].line
17
+ block
18
+ end
19
+ end
20
+
21
+ def new_body(compstmt, res, els, ens)
22
+ s = compstmt || s(:block)
23
+ s.line = compstmt.line if compstmt
24
+
25
+ if res
26
+ s = s(:rescue, s)
27
+ res.each { |r| s << r }
28
+ s << els if els
29
+ end
30
+
31
+ ens ? s(:ensure, s, ens) : s
32
+ end
33
+
34
+ def new_defn(line, name, args, body)
35
+ body = s(:block, body) if body[0] != :block
36
+ scope = s(:scope, body)
37
+ body << s(:nil) if body.size == 1
38
+ scope.line = body.line
39
+ args.line = line
40
+ s = s(:defn, name.to_sym, args, scope)
41
+ s.line = line
42
+ s.end_line = @line
43
+ s
44
+ end
45
+
46
+ def new_defs(line, recv, name, args, body)
47
+ scope = s(:scope, body)
48
+ scope.line = body.line
49
+ s = s(:defs, recv, name.to_sym, args, scope)
50
+ s.line = line
51
+ s.end_line = @line
52
+ s
53
+ end
54
+
55
+ def new_class(path, sup, body)
56
+ scope = s(:scope)
57
+ scope << body unless body.size == 1
58
+ scope.line = body.line
59
+ s = s(:class, path, sup, scope)
60
+ s
61
+ end
62
+
63
+ def new_sclass(expr, body)
64
+ scope = s(:scope)
65
+ scope << body #unless body.size == 1
66
+ scope.line = body.line
67
+ s = s(:sclass, expr, scope)
68
+ s
69
+ end
70
+
71
+ def new_module(path, body)
72
+ scope = s(:scope)
73
+ scope << body unless body.size == 1
74
+ scope.line = body.line
75
+ s = s(:module, path, scope)
76
+ s
77
+ end
78
+
79
+ def new_iter(call, args, body)
80
+ s = s(:iter, call, args)
81
+ s << body if body
82
+ s.end_line = @line
83
+ s
84
+ end
85
+
86
+ def new_if(expr, stmt, tail)
87
+ s = s(:if, expr, stmt, tail)
88
+ s.line = expr.line
89
+ s.end_line = @line
90
+ s
91
+ end
92
+
93
+ def new_args(norm, opt, rest, block)
94
+ res = s(:args)
95
+
96
+ if norm
97
+ norm.each do |arg|
98
+ @scope.add_local arg
99
+ res << arg
100
+ end
101
+ end
102
+
103
+ if opt
104
+ opt[1..-1].each do |_opt|
105
+ res << _opt[1]
106
+ end
107
+ end
108
+
109
+ if rest
110
+ res << rest
111
+ rest_str = rest.to_s[1..-1]
112
+ @scope.add_local rest_str.to_sym unless rest_str.empty?
113
+ end
114
+
115
+ if block
116
+ res << block
117
+ @scope.add_local block.to_s[1..-1].to_sym
118
+ end
119
+
120
+ res << opt if opt
121
+
122
+ res
123
+ end
124
+
125
+ def new_block_args(norm, opt, rest, block)
126
+ res = s(:array)
127
+
128
+ if norm
129
+ norm.each do |arg|
130
+ @scope.add_local arg
131
+ res << s(:lasgn, arg)
132
+ end
133
+ end
134
+
135
+ if opt
136
+ opt[1..-1].each do |_opt|
137
+ res << s(:lasgn, _opt[1])
138
+ end
139
+ end
140
+
141
+ if rest
142
+ r = rest.to_s[1..-1].to_sym
143
+ res << s(:splat, s(:lasgn, r))
144
+ @scope.add_local r
145
+ end
146
+
147
+ if block
148
+ b = block.to_s[1..-1].to_sym
149
+ res << s(:block_pass, s(:lasgn, b))
150
+ @scope.add_local b
151
+ end
152
+
153
+ res << opt if opt
154
+
155
+ res.size == 2 && norm ? res[1] : s(:masgn, res)
156
+ end
157
+
158
+ def new_call(recv, meth, args = nil)
159
+ call = s(:call, recv, meth)
160
+ args = s(:arglist) unless args
161
+ args[0] = :arglist if args[0] == :array
162
+ call << args
163
+
164
+ if recv
165
+ call.line = recv.line
166
+ elsif args[1]
167
+ call.line = args[1].line
168
+ end
169
+
170
+ # fix arglist spilling over into next line if no args
171
+ if args.length == 1
172
+ args.line = call.line
173
+ else
174
+ args.line = args[1].line
175
+ end
176
+
177
+ call
178
+ end
179
+
180
+ def add_block_pass(arglist, block)
181
+ arglist << block if block
182
+ arglist
183
+ end
184
+
185
+ def new_op_asgn(op, lhs, rhs)
186
+ case op
187
+ when :"||"
188
+ result = s(:op_asgn_or, new_gettable(lhs))
189
+ result << (lhs << rhs)
190
+ when :"&&"
191
+ result = s(:op_asgn_and, new_gettable(lhs))
192
+ result << (lhs << rhs)
193
+ else
194
+ result = lhs
195
+ result << new_call(new_gettable(lhs), op, s(:arglist, rhs))
196
+
197
+ end
198
+
199
+ result.line = lhs.line
200
+ result
201
+ end
202
+
203
+ def new_assign(lhs, rhs)
204
+ case lhs[0]
205
+ when :iasgn, :cdecl, :lasgn, :gasgn, :cvdecl, :nth_ref
206
+ lhs << rhs
207
+ lhs
208
+ when :call, :attrasgn
209
+ lhs.last << rhs
210
+ lhs
211
+ else
212
+ raise "Bad lhs for new_assign: #{lhs[0]}"
213
+ end
214
+ end
215
+
216
+ def new_assignable(ref)
217
+ case ref[0]
218
+ when :ivar
219
+ ref[0] = :iasgn
220
+ when :const
221
+ ref[0] = :cdecl
222
+ when :identifier
223
+ @scope.add_local ref[1] unless @scope.has_local? ref[1]
224
+ ref[0] = :lasgn
225
+ when :gvar
226
+ ref[0] = :gasgn
227
+ when :cvar
228
+ ref[0] = :cvdecl
229
+ else
230
+ raise "Bad new_assignable type: #{ref[0]}"
231
+ end
232
+
233
+ ref
234
+ end
235
+
236
+ def new_gettable(ref)
237
+ res = case ref[0]
238
+ when :lasgn
239
+ s(:lvar, ref[1])
240
+ when :iasgn
241
+ s(:ivar, ref[1])
242
+ when :gasgn
243
+ s(:gvar, ref[1])
244
+ when :cvdecl
245
+ s(:cvar, ref[1])
246
+ else
247
+ raise "Bad new_gettable ref: #{ref[0]}"
248
+ end
249
+
250
+ res.line = ref.line
251
+ res
252
+ end
253
+
254
+ def new_var_ref(ref)
255
+ case ref[0]
256
+ when :self, :nil, :true, :false, :line, :file
257
+ ref
258
+ when :const
259
+ ref
260
+ when :ivar, :gvar, :cvar
261
+ ref
262
+ when :lit
263
+ # this is when we passed __LINE__ which is converted into :lit
264
+ ref
265
+ when :str
266
+ # returns for __FILE__ as it is converted into str
267
+ ref
268
+ when :identifier
269
+ if @scope.has_local? ref[1]
270
+ s(:lvar, ref[1])
271
+ else
272
+ s(:call, nil, ref[1], s(:arglist))
273
+ end
274
+ else
275
+ raise "Bad var_ref type: #{ref[0]}"
276
+ end
277
+ end
278
+
279
+ def new_super(args)
280
+ args = (args || s(:arglist))[1..-1]
281
+ s(:super, *args)
282
+ end
283
+
284
+ def new_yield(args)
285
+ args = (args || s(:arglist))[1..-1]
286
+ s(:yield, *args)
287
+ end
288
+
289
+ def new_xstr(str)
290
+ return s(:xstr, '') unless str
291
+ case str[0]
292
+ when :str then str[0] = :xstr
293
+ when :dstr then str[0] = :dxstr
294
+ when :evstr then str = s(:dxstr, '', str)
295
+ end
296
+
297
+ str
298
+ end
299
+
300
+ def new_dsym(str)
301
+ return s(:nil) unless str
302
+ case str[0]
303
+ when :str
304
+ str[0] = :lit
305
+ str[1] = str[1].to_sym
306
+ when :dstr
307
+ str[0] = :dsym
308
+ end
309
+
310
+ str
311
+ end
312
+
313
+ def new_str(str)
314
+ # cover empty strings
315
+ return s(:str, "") unless str
316
+ # catch s(:str, "", other_str)
317
+ if str.size == 3 and str[1] == "" and str[0] == :str
318
+ return str[2]
319
+ # catch s(:str, "content", more_content)
320
+ elsif str[0] == :str && str.size > 3
321
+ str[0] = :dstr
322
+ str
323
+ # top level evstr should be a dstr
324
+ elsif str[0] == :evstr
325
+ s(:dstr, "", str)
326
+ else
327
+ str
328
+ end
329
+ end
330
+
331
+ def new_regexp(reg, ending)
332
+ return s(:lit, //) unless reg
333
+ case reg[0]
334
+ when :str
335
+ s(:lit, Regexp.new(reg[1], ending))
336
+ when :evstr
337
+ s(:dregx, "", reg)
338
+ when :dstr
339
+ reg[0] = :dregx
340
+ reg
341
+ end
342
+ end
343
+
344
+ def str_append(str, str2)
345
+ return str2 unless str
346
+ return str unless str2
347
+
348
+ if str.first == :evstr
349
+ str = s(:dstr, "", str)
350
+ elsif str.first == :str
351
+ str = s(:dstr, str[1])
352
+ else
353
+ #puts str.first
354
+ end
355
+ str << str2
356
+ str
357
+ end
358
+ end
359
+ end
360
+
data/lib/opal/lexer.rb CHANGED
@@ -1,11 +1,9 @@
1
+ require 'opal/core_ext'
1
2
  require 'opal/grammar'
3
+ require 'opal/grammar_helpers'
4
+ require 'opal/lexer_scope'
2
5
  require 'strscan'
3
6
 
4
- class Array
5
- attr_accessor :line
6
- attr_accessor :end_line
7
- end
8
-
9
7
  module Opal
10
8
 
11
9
  class Grammar < Racc::Parser
@@ -39,34 +37,7 @@ module Opal
39
37
  end
40
38
 
41
39
  def on_error(t, val, vstack)
42
- raise "parse error on value #{val.inspect} :#{@file}:#{@line}"
43
- end
44
-
45
- # LexerScope is used during lexing to keep track of local variables
46
- # created inside a scope. A lexer scope can be asked if it has a local
47
- # variable defined, and it can also check its parent scope if applicable.
48
- #
49
- # A LexerScope is created automatically as a new scope is entered during
50
- # the lexing stage.
51
- class LexerScope
52
- attr_reader :locals
53
- attr_accessor :parent
54
-
55
- def initialize(type)
56
- @block = type == :block
57
- @locals = []
58
- @parent = nil
59
- end
60
-
61
- def add_local(local)
62
- @locals << local
63
- end
64
-
65
- def has_local?(local)
66
- return true if @locals.include? local
67
- return @parent.has_local?(local) if @parent and @block
68
- false
69
- end
40
+ raise "parse error on value #{val.inspect} (#{token_to_str(t) || '?'}) :#{@file}:#{@line}"
70
41
  end
71
42
 
72
43
  def push_scope(type = nil)
@@ -82,360 +53,6 @@ module Opal
82
53
  @scope = @scopes.last
83
54
  end
84
55
 
85
- def new_block(stmt = nil)
86
- s = s(:block)
87
- s << stmt if stmt
88
- s
89
- end
90
-
91
- def new_compstmt(block)
92
- if block.size == 1
93
- nil
94
- elsif block.size == 2
95
- block[1]
96
- else
97
- block.line = block[1].line
98
- block
99
- end
100
- end
101
-
102
- def new_body(compstmt, res, els, ens)
103
- s = compstmt || s(:block)
104
- s.line = compstmt.line if compstmt
105
-
106
- if res
107
- s = s(:rescue, s)
108
- res.each { |r| s << r }
109
- s << els if els
110
- end
111
-
112
- ens ? s(:ensure, s, ens) : s
113
- end
114
-
115
- def new_defn(line, name, args, body)
116
- body = s(:block, body) if body[0] != :block
117
- scope = s(:scope, body)
118
- body << s(:nil) if body.size == 1
119
- scope.line = body.line
120
- args.line = line
121
- s = s(:defn, name.to_sym, args, scope)
122
- s.line = line
123
- s.end_line = @line
124
- s
125
- end
126
-
127
- def new_defs(line, recv, name, args, body)
128
- scope = s(:scope, body)
129
- scope.line = body.line
130
- s = s(:defs, recv, name.to_sym, args, scope)
131
- s.line = line
132
- s.end_line = @line
133
- s
134
- end
135
-
136
- def new_class(path, sup, body)
137
- scope = s(:scope)
138
- scope << body unless body.size == 1
139
- scope.line = body.line
140
- s = s(:class, path, sup, scope)
141
- s
142
- end
143
-
144
- def new_sclass(expr, body)
145
- scope = s(:scope)
146
- scope << body #unless body.size == 1
147
- scope.line = body.line
148
- s = s(:sclass, expr, scope)
149
- s
150
- end
151
-
152
- def new_module(path, body)
153
- scope = s(:scope)
154
- scope << body unless body.size == 1
155
- scope.line = body.line
156
- s = s(:module, path, scope)
157
- s
158
- end
159
-
160
- def new_iter(call, args, body)
161
- s = s(:iter, call, args)
162
- s << body if body
163
- s.end_line = @line
164
- s
165
- end
166
-
167
- def new_if(expr, stmt, tail)
168
- s = s(:if, expr, stmt, tail)
169
- s.line = expr.line
170
- s.end_line = @line
171
- s
172
- end
173
-
174
- def new_args(norm, opt, rest, block)
175
- res = s(:args)
176
-
177
- if norm
178
- norm.each do |arg|
179
- @scope.add_local arg
180
- res << arg
181
- end
182
- end
183
-
184
- if opt
185
- opt[1..-1].each do |_opt|
186
- res << _opt[1]
187
- end
188
- end
189
-
190
- if rest
191
- res << rest
192
- rest_str = rest.to_s[1..-1]
193
- @scope.add_local rest_str.to_sym unless rest_str.empty?
194
- end
195
-
196
- if block
197
- res << block
198
- @scope.add_local block.to_s[1..-1].to_sym
199
- end
200
-
201
- res << opt if opt
202
-
203
- res
204
- end
205
-
206
- def new_block_args(norm, opt, rest, block)
207
- res = s(:array)
208
-
209
- if norm
210
- norm.each do |arg|
211
- @scope.add_local arg
212
- res << s(:lasgn, arg)
213
- end
214
- end
215
-
216
- if opt
217
- opt[1..-1].each do |_opt|
218
- res << s(:lasgn, _opt[1])
219
- end
220
- end
221
-
222
- if rest
223
- r = rest.to_s[1..-1].to_sym
224
- res << s(:splat, s(:lasgn, r))
225
- @scope.add_local r
226
- end
227
-
228
- if block
229
- b = block.to_s[1..-1].to_sym
230
- res << s(:block_pass, s(:lasgn, b))
231
- @scope.add_local b
232
- end
233
-
234
- res << opt if opt
235
-
236
- res.size == 2 && norm ? res[1] : s(:masgn, res)
237
- end
238
-
239
- def new_call(recv, meth, args = nil)
240
- call = s(:call, recv, meth)
241
- args = s(:arglist) unless args
242
- args[0] = :arglist if args[0] == :array
243
- call << args
244
-
245
- if recv
246
- call.line = recv.line
247
- elsif args[1]
248
- call.line = args[1].line
249
- end
250
-
251
- # fix arglist spilling over into next line if no args
252
- if args.length == 1
253
- args.line = call.line
254
- else
255
- args.line = args[1].line
256
- end
257
-
258
- call
259
- end
260
-
261
- def add_block_pass(arglist, block)
262
- arglist << block if block
263
- arglist
264
- end
265
-
266
- def new_op_asgn(op, lhs, rhs)
267
- case op
268
- when :"||"
269
- result = s(:op_asgn_or, new_gettable(lhs))
270
- result << (lhs << rhs)
271
- when :"&&"
272
- result = s(:op_asgn_and, new_gettable(lhs))
273
- result << (lhs << rhs)
274
- else
275
- result = lhs
276
- result << new_call(new_gettable(lhs), op, s(:arglist, rhs))
277
-
278
- end
279
-
280
- result.line = lhs.line
281
- result
282
- end
283
-
284
- def new_assign(lhs, rhs)
285
- case lhs[0]
286
- when :iasgn, :cdecl, :lasgn, :gasgn, :cvdecl
287
- lhs << rhs
288
- lhs
289
- when :call, :attrasgn
290
- lhs.last << rhs
291
- lhs
292
- else
293
- raise "Bad lhs for new_assign: #{lhs[0]}"
294
- end
295
- end
296
-
297
- def new_assignable(ref)
298
- case ref[0]
299
- when :ivar
300
- ref[0] = :iasgn
301
- when :const
302
- ref[0] = :cdecl
303
- when :identifier
304
- @scope.add_local ref[1] unless @scope.has_local? ref[1]
305
- ref[0] = :lasgn
306
- when :gvar
307
- ref[0] = :gasgn
308
- when :cvar
309
- ref[0] = :cvdecl
310
- else
311
- raise "Bad new_assignable type: #{ref[0]}"
312
- end
313
-
314
- ref
315
- end
316
-
317
- def new_gettable(ref)
318
- res = case ref[0]
319
- when :lasgn
320
- s(:lvar, ref[1])
321
- when :iasgn
322
- s(:ivar, ref[1])
323
- when :gasgn
324
- s(:gvar, ref[1])
325
- when :cvdecl
326
- s(:cvar, ref[1])
327
- else
328
- raise "Bad new_gettable ref: #{ref[0]}"
329
- end
330
-
331
- res.line = ref.line
332
- res
333
- end
334
-
335
- def new_var_ref(ref)
336
- case ref[0]
337
- when :self, :nil, :true, :false, :line, :file
338
- ref
339
- when :const
340
- ref
341
- when :ivar, :gvar, :cvar
342
- ref
343
- when :lit
344
- # this is when we passed __LINE__ which is converted into :lit
345
- ref
346
- when :str
347
- # returns for __FILE__ as it is converted into str
348
- ref
349
- when :identifier
350
- if @scope.has_local? ref[1]
351
- s(:lvar, ref[1])
352
- else
353
- s(:call, nil, ref[1], s(:arglist))
354
- end
355
- else
356
- raise "Bad var_ref type: #{ref[0]}"
357
- end
358
- end
359
-
360
- def new_super(args)
361
- args = (args || s(:arglist))[1..-1]
362
- s(:super, *args)
363
- end
364
-
365
- def new_yield(args)
366
- args = (args || s(:arglist))[1..-1]
367
- s(:yield, *args)
368
- end
369
-
370
- def new_xstr(str)
371
- return s(:xstr, '') unless str
372
- case str[0]
373
- when :str then str[0] = :xstr
374
- when :dstr then str[0] = :dxstr
375
- when :evstr then str = s(:dxstr, '', str)
376
- end
377
-
378
- str
379
- end
380
-
381
- def new_dsym(str)
382
- return s(:nil) unless str
383
- case str[0]
384
- when :str
385
- str[0] = :lit
386
- str[1] = str[1].to_sym
387
- when :dstr
388
- str[0] = :dsym
389
- end
390
-
391
- str
392
- end
393
-
394
- def new_str(str)
395
- # cover empty strings
396
- return s(:str, "") unless str
397
- # catch s(:str, "", other_str)
398
- if str.size == 3 and str[1] == "" and str[0] == :str
399
- return str[2]
400
- # catch s(:str, "content", more_content)
401
- elsif str[0] == :str && str.size > 3
402
- str[0] = :dstr
403
- str
404
- # top level evstr should be a dstr
405
- elsif str[0] == :evstr
406
- s(:dstr, "", str)
407
- else
408
- str
409
- end
410
- end
411
-
412
- def new_regexp(reg, ending)
413
- return s(:lit, //) unless reg
414
- case reg[0]
415
- when :str
416
- s(:lit, Regexp.new(reg[1], ending))
417
- when :evstr
418
- res = s(:dregx, "", reg)
419
- when :dstr
420
- reg[0] = :dregx
421
- reg
422
- end
423
- end
424
-
425
- def str_append(str, str2)
426
- return str2 unless str
427
- return str unless str2
428
-
429
- if str.first == :evstr
430
- str = s(:dstr, "", str)
431
- elsif str.first == :str
432
- str = s(:dstr, str[1])
433
- else
434
- #puts str.first
435
- end
436
- str << str2
437
- str
438
- end
439
56
 
440
57
  def cond_push(n)
441
58
  @cond = (@cond << 1) | (n & 1)
@@ -495,19 +112,17 @@ module Opal
495
112
  end
496
113
  @string_parse = nil
497
114
 
498
- # return :SPACE, ' ' if words && space
499
-
500
- # if in %Q{, we should balance { with } before ending.
501
115
  if str_parse[:balance]
502
116
  if str_parse[:nesting] == 0
503
117
  @lex_state = :expr_end
118
+
119
+ if str_parse[:regexp]
120
+ return :REGEXP_END, scanner.matched
121
+ end
504
122
  return :STRING_END, scanner.matched
505
123
  else
506
- #puts "nesting not 0!"
507
- #puts str_parse[:nesting]
508
124
  str_buffer << scanner.matched
509
125
  str_parse[:nesting] -= 1
510
- # make sure we carry on string parse (its set to nil above)
511
126
  @string_parse = str_parse
512
127
  end
513
128
 
@@ -519,7 +134,7 @@ module Opal
519
134
  @lex_state = :expr_end
520
135
  return :STRING_END, scanner.matched
521
136
 
522
- elsif str_parse[:beg] == '/'
137
+ elsif str_parse[:beg] == '/' || str_parse[:regexp]
523
138
  result = scanner.scan(/\w+/)
524
139
  @lex_state = :expr_end
525
140
  return :REGEXP_END, result
@@ -533,7 +148,6 @@ module Opal
533
148
  return :SPACE, ' ' if space
534
149
 
535
150
  if str_parse[:balance] and scanner.scan Regexp.new(Regexp.escape(str_parse[:beg]))
536
- #puts "matced beg balance!"
537
151
  str_buffer << scanner.matched
538
152
  str_parse[:nesting] += 1
539
153
  elsif scanner.check(/#[@$]/)
@@ -616,6 +230,8 @@ module Opal
616
230
  "\r"
617
231
  elsif scanner.scan(/\n/)
618
232
  "\n"
233
+ elsif scanner.scan(/t/)
234
+ "\t"
619
235
  else
620
236
  # escaped char doesnt need escaping, so just return it
621
237
  scanner.scan(/./)
@@ -719,6 +335,12 @@ module Opal
719
335
  @string_parse = { :beg => start_word, :end => end_word, :balance => true, :nesting => 0, :interpolate => true }
720
336
  return :XSTRING_BEG, scanner.matched
721
337
 
338
+ elsif scanner.scan(/\%r/)
339
+ start_word = scanner.scan(/./)
340
+ end_word = { '(' => ')', '[' => ']', '{' => '}' }[start_word] || start_word
341
+ @string_parse = { :beg => start_word, :end => end_word, :regexp => true, :balance => true, :nesting => 0, :interpolate => true }
342
+ return :REGEXP_BEG, scanner.matched
343
+
722
344
  elsif scanner.scan(/\//)
723
345
  if [:expr_beg, :expr_mid].include? @lex_state
724
346
  @string_parse = { :beg => '/', :end => '/', :interpolate => true, :regexp => true }
@@ -743,10 +365,26 @@ module Opal
743
365
  if scanner.scan(/\=/)
744
366
  @lex_state = :expr_beg
745
367
  return :OP_ASGN, '%'
368
+ elsif scanner.check(/[^\s]/)
369
+ if @lex_state == :expr_beg or (@lex_state == :expr_arg && space_seen)
370
+ interpolate = true
371
+ start_word = scanner.scan(/./)
372
+ end_word = { '(' => ')', '[' => ']', '{' => '}' }[start_word] || start_word
373
+ @string_parse = { :beg => start_word, :end => end_word, :balance => true, :nesting => 0, :interpolate => interpolate }
374
+ return :STRING_BEG, scanner.matched
375
+ end
746
376
  end
747
377
  @lex_state = @lex_state == :expr_fname ? :expr_end : :expr_beg
748
378
  return '%', '%'
749
379
 
380
+ elsif scanner.scan(/\\/)
381
+ if scanner.scan(/\r?\n/)
382
+ space_seen = true
383
+ next
384
+ end
385
+
386
+ raise SyntaxError, "backslash must appear before newline :#{@file}:#{@line}"
387
+
750
388
  elsif scanner.scan(/\(/)
751
389
  result = scanner.matched
752
390
  if [:expr_beg, :expr_mid].include? @lex_state
@@ -1113,9 +751,24 @@ module Opal
1113
751
  @lex_state = :expr_beg
1114
752
  return '~', '~'
1115
753
 
1116
- elsif scanner.scan(/\$[\+\'\`\&!@\"~*$?\/\\:;=.,<>_]/)
1117
- @lex_state = :expr_end
1118
- return :GVAR, scanner.matched
754
+ elsif scanner.check(/\$/)
755
+ if scanner.scan(/\$([1-9]\d*)/)
756
+ @lex_state = :expr_end
757
+ return :NTH_REF, scanner.matched.sub('$', '')
758
+
759
+ elsif scanner.scan(/(\$_)(\w+)/)
760
+ @lex_state = :expr_end
761
+ return :GVAR, scanner.matched
762
+
763
+ elsif scanner.scan(/\$[\+\'\`\&!@\"~*$?\/\\:;=.,<>_]/)
764
+ @lex_state = :expr_end
765
+ return :GVAR, scanner.matched
766
+ elsif scanner.scan(/\$\w+/)
767
+ @lex_state = :expr_end
768
+ return :GVAR, scanner.matched
769
+ else
770
+ raise "Bad gvar name: #{scanner.peek(5).inspect}"
771
+ end
1119
772
 
1120
773
  elsif scanner.scan(/\$\w+/)
1121
774
  @lex_state = :expr_end
@@ -1158,8 +811,8 @@ module Opal
1158
811
  return [:FLOAT, scanner.matched.gsub(/_/, '').to_f]
1159
812
  elsif scanner.scan(/[\d_]+\b/)
1160
813
  return [:INTEGER, scanner.matched.gsub(/_/, '').to_i]
1161
- elsif scanner.scan(/0(x|X)(\d|[a-f]|[A-F])+/)
1162
- return [:INTEGER, scanner.matched.to_i]
814
+ elsif scanner.scan(/0(x|X)(\d|[a-f]|[A-F]|_)+/)
815
+ return [:INTEGER, scanner.matched.to_i(16)]
1163
816
  else
1164
817
  raise "Lexing error on numeric type: `#{scanner.peek 5}`"
1165
818
  end
@@ -1307,7 +960,7 @@ module Opal
1307
960
  return :AND, matched
1308
961
 
1309
962
  when 'not'
1310
- @lex_state = :expr_beg
963
+ @lex_state = :expr_arg
1311
964
  return :NOT, matched
1312
965
 
1313
966
  when 'return'
@@ -1341,6 +994,7 @@ module Opal
1341
994
  return :SUPER, matched
1342
995
 
1343
996
  when 'then'
997
+ @lex_state = :expr_beg
1344
998
  return :THEN, matched
1345
999
 
1346
1000
  when 'while'