opal 0.3.41 → 0.3.42

Sign up to get free protection for your applications and to get access to all the features.
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'