opal 0.3.19 → 0.3.20

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 (66) hide show
  1. data/.gitignore +3 -1
  2. data/Gemfile +3 -2
  3. data/README.md +304 -48
  4. data/Rakefile +1 -2
  5. data/core/alpha.rb +2 -1
  6. data/core/array.rb +92 -96
  7. data/core/basic_object.rb +1 -10
  8. data/core/boolean.rb +6 -18
  9. data/core/class.rb +9 -10
  10. data/core/comparable.rb +1 -1
  11. data/core/enumerable.rb +11 -11
  12. data/core/enumerator.rb +2 -10
  13. data/core/error.rb +16 -31
  14. data/core/hash.rb +32 -36
  15. data/core/json.rb +50 -0
  16. data/core/kernel.rb +48 -57
  17. data/core/load_order +3 -5
  18. data/core/module.rb +37 -35
  19. data/core/nil_class.rb +4 -0
  20. data/core/numeric.rb +10 -30
  21. data/core/proc.rb +1 -1
  22. data/core/range.rb +3 -4
  23. data/core/regexp.rb +21 -6
  24. data/core/runtime.js +278 -370
  25. data/core/string.rb +21 -37
  26. data/core/struct.rb +11 -3
  27. data/core/time.rb +44 -37
  28. data/lib/opal.rb +3 -3
  29. data/lib/opal/builder.rb +48 -27
  30. data/lib/opal/builder_task.rb +3 -20
  31. data/lib/opal/grammar.rb +18 -13
  32. data/lib/opal/grammar.y +7 -4
  33. data/lib/opal/parser.rb +290 -199
  34. data/lib/opal/scope.rb +187 -176
  35. data/lib/opal/version.rb +1 -1
  36. data/test/core/kernel/define_singleton_method_spec.rb +21 -0
  37. data/test/core/time/at_spec.rb +7 -0
  38. data/test/core/time/day_spec.rb +5 -0
  39. data/test/core/time/friday_spec.rb +9 -0
  40. data/test/core/time/hour_spec.rb +5 -0
  41. data/test/core/time/min_spec.rb +5 -0
  42. data/test/core/time/monday_spec.rb +9 -0
  43. data/test/core/time/month_spec.rb +5 -0
  44. data/test/core/time/now_spec.rb +5 -0
  45. data/test/core/time/saturday_spec.rb +9 -0
  46. data/test/index.html +2 -1
  47. data/test/language/singleton_class_spec.rb +0 -16
  48. data/test/opal/array/to_json_spec.rb +7 -0
  49. data/test/opal/boolean/singleton_class_spec.rb +9 -0
  50. data/test/opal/boolean/to_json_spec.rb +9 -0
  51. data/test/opal/hash/to_json_spec.rb +9 -0
  52. data/test/opal/json/parse_spec.rb +31 -0
  53. data/test/opal/kernel/to_json_spec.rb +5 -0
  54. data/test/opal/nil/to_json_spec.rb +5 -0
  55. data/test/opal/numeric/to_json_spec.rb +6 -0
  56. data/test/opal/runtime/call_spec.rb +16 -0
  57. data/test/opal/runtime/defined_spec.rb +11 -0
  58. data/test/opal/runtime/super_spec.rb +16 -0
  59. data/test/opal/string/to_json_spec.rb +6 -0
  60. data/test/spec_helper.rb +1 -3
  61. metadata +48 -15
  62. data/core/dir.rb +0 -89
  63. data/core/file.rb +0 -85
  64. data/core/match_data.rb +0 -35
  65. data/core/rational.rb +0 -16
  66. data/test/core/file/expand_path_spec.rb +0 -20
@@ -3,6 +3,10 @@ module Kernel
3
3
  false
4
4
  end
5
5
 
6
+ def ==(other)
7
+ `this === other`
8
+ end
9
+
6
10
  def ===(other)
7
11
  `this == other`
8
12
  end
@@ -39,8 +43,12 @@ module Kernel
39
43
  no_block_given();
40
44
  }
41
45
 
46
+ var jsid = mid_to_jsid(name);
47
+ body._jsid = jsid;
48
+ body._sup = this[jsid]
49
+
42
50
  // FIXME: need to donate()
43
- this.$singleton_class()._proto[mid_to_jsid(name)] = body;
51
+ this.$singleton_class().prototype[jsid] = body;
44
52
 
45
53
  return this;
46
54
  }
@@ -53,17 +61,13 @@ module Kernel
53
61
  def extend(*mods)
54
62
  %x{
55
63
  for (var i = 0, length = mods.length; i < length; i++) {
56
- include_module(singleton_class(this), mods[i]);
64
+ this.$singleton_class().$include(mods[i]);
57
65
  }
58
66
 
59
67
  return this;
60
68
  }
61
69
  end
62
70
 
63
- def format(string, *arguments)
64
- raise NotImplementedError
65
- end
66
-
67
71
  def hash
68
72
  `this._id`
69
73
  end
@@ -132,7 +136,7 @@ module Kernel
132
136
  %x{
133
137
  while (true) {
134
138
  if (block.call(__context) === __breaker) {
135
- return breaker.$v;
139
+ return __breaker.$v;
136
140
  }
137
141
  }
138
142
 
@@ -148,14 +152,6 @@ module Kernel
148
152
  `this._id || (this._id = unique_id++)`
149
153
  end
150
154
 
151
- def print(*strs)
152
- puts *strs
153
- end
154
-
155
- def private(*)
156
- # does nothing. here for documenting code
157
- end
158
-
159
155
  def proc(&block)
160
156
  %x{
161
157
  if (block === nil) {
@@ -166,45 +162,32 @@ module Kernel
166
162
  }
167
163
  end
168
164
 
169
- def protected(*)
170
- # does nothing. here for documenting code
171
- end
172
-
173
- def public(*)
174
- # does nothing. here for documenting code
175
- end
176
-
177
165
  def puts(*strs)
178
166
  %x{
179
167
  for (var i = 0; i < strs.length; i++) {
180
- var obj = strs[i];
181
- console.log(#{ `obj`.to_s });
168
+ console.log(#{ `strs[i]`.to_s });
182
169
  }
183
170
  }
184
171
  nil
185
172
  end
186
173
 
187
- alias sprintf format
174
+ alias print puts
188
175
 
189
- def raise(exception, string = undefined)
176
+ def raise(exception, string)
190
177
  %x{
191
178
  if (typeof(exception) === 'string') {
192
179
  exception = #{RuntimeError.new exception};
193
180
  }
194
- else if (#{!exception.is_a? Exception}) {
195
- exception = #{`exception`.new string};
181
+ else if (!#{exception.is_a? Exception}) {
182
+ exception = #{exception.new string};
196
183
  }
197
184
 
198
185
  throw exception;
199
186
  }
200
187
  end
201
188
 
202
- def rand(max = undefined)
203
- `max === undefined ? Math.random() : Math.floor(Math.random() * max)`
204
- end
205
-
206
- def require(path)
207
- `Opal.require(path)`
189
+ def rand(max)
190
+ `max == null ? Math.random() : Math.floor(Math.random() * max)`
208
191
  end
209
192
 
210
193
  def respond_to?(name)
@@ -213,38 +196,40 @@ module Kernel
213
196
 
214
197
  def singleton_class
215
198
  %x{
216
- var obj = this, klass;
217
-
218
- if (obj._isObject) {
219
- if (obj._isNumber || obj._isString) {
220
- throw RubyTypeError.$new("can't define singleton");
221
- }
199
+ if (!this._isObject) {
200
+ return this._real;
222
201
  }
223
202
 
224
- if ((obj._klass._isSingleton) && obj._klass.__attached__ == obj) {
225
- klass = obj._klass;
203
+ if (this._klass._isSingleton) {
204
+ return this._klass;
226
205
  }
227
206
  else {
228
- var class_id = obj._klass._name;
229
- klass = make_metaclass(obj, obj._klass);
230
- }
207
+ var orig_class = this._klass,
208
+ class_id = "#<Class:#<" + orig_class._name + ":" + orig_class._id + ">>";
209
+
210
+ function _Singleton() {};
211
+ var meta = boot_class(orig_class, _Singleton);
212
+ meta._name = class_id;
231
213
 
232
- return klass;
214
+ meta._isSingleton = true;
215
+ meta.prototype = this;
216
+ this._klass = meta;
217
+ meta._klass = orig_class._real;
218
+
219
+ return meta;
220
+ }
233
221
  }
234
222
  end
235
223
 
236
224
  def tap(&block)
237
- %x{
238
- if (block === nil) {
239
- no_block_given();
240
- }
225
+ `if (block === nil) no_block_given();`
241
226
 
242
- if (block.call(__context, this) === __breaker) {
243
- return __breaker.$v;
244
- }
227
+ yield self
228
+ self
229
+ end
245
230
 
246
- return this;
247
- }
231
+ def to_json
232
+ to_s.to_json
248
233
  end
249
234
 
250
235
  def to_proc
@@ -254,4 +239,10 @@ module Kernel
254
239
  def to_s
255
240
  `return "#<" + this._klass._real._name + ":0x" + (this._id * 400487).toString(16) + ">";`
256
241
  end
257
- end
242
+
243
+ def enum_for (method = :each, *args)
244
+ Enumerator.new(self, method, *args)
245
+ end
246
+
247
+ alias to_enum enum_for
248
+ end
@@ -1,10 +1,10 @@
1
1
  alpha
2
- basic_object
3
2
  module
3
+ class
4
+ basic_object
4
5
  kernel
5
6
  object
6
7
  top_self
7
- class
8
8
  boolean
9
9
  nil_class
10
10
  enumerable
@@ -18,8 +18,6 @@ proc
18
18
  range
19
19
  error
20
20
  regexp
21
- match_data
22
21
  time
23
22
  struct
24
- file
25
- dir
23
+ json
@@ -1,27 +1,6 @@
1
1
  class Module
2
- def ===(object)
3
- %x{
4
-
5
- if (object == null) {
6
- return false;
7
- }
8
-
9
- var search = object._klass;
10
-
11
- while (search) {
12
- if (search === this) {
13
- return true;
14
- }
15
-
16
- search = search._super;
17
- }
18
-
19
- return false;
20
- }
21
- end
22
-
23
2
  def alias_method(newname, oldname)
24
- `this._proto[mid_to_jsid(newname)] = this._proto[mid_to_jsid(oldname)]`
3
+ `this.prototype[mid_to_jsid(newname)] = this.prototype[mid_to_jsid(oldname)]`
25
4
  self
26
5
  end
27
6
 
@@ -55,8 +34,10 @@ class Module
55
34
  klass.$included_modules = [];
56
35
  }
57
36
 
58
- if (klass.$included_modules.indexOf(module) != -1) {
59
- return;
37
+ for (var idx = 0, length = klass.$included_modules.length; idx < length; idx++) {
38
+ if (klass.$included_modules[idx] === module) {
39
+ return;
40
+ }
60
41
  }
61
42
 
62
43
  klass.$included_modules.push(module);
@@ -67,8 +48,8 @@ class Module
67
48
 
68
49
  module.$included_in.push(klass);
69
50
 
70
- var donator = module._alloc.prototype,
71
- prototype = klass._proto,
51
+ var donator = module.prototype,
52
+ prototype = klass.prototype,
72
53
  methods = module._methods;
73
54
 
74
55
  for (var i = 0, length = methods.length; i < length; i++) {
@@ -77,7 +58,7 @@ class Module
77
58
  }
78
59
 
79
60
  if (klass.$included_in) {
80
- __donate(klass, methods.slice(), true);
61
+ klass._donate(methods.slice(), true);
81
62
  }
82
63
  }
83
64
 
@@ -90,22 +71,22 @@ class Module
90
71
  if (getter) {
91
72
  var get_jsid = mid_to_jsid(name);
92
73
 
93
- klass._alloc.prototype[get_jsid] = function() {
74
+ klass.prototype[get_jsid] = function() {
94
75
  var res = this[name];
95
76
  return res == null ? nil : res;
96
77
  };
97
78
 
98
- __donate(klass, [get_jsid]);
79
+ klass._donate([get_jsid]);
99
80
  }
100
81
 
101
82
  if (setter) {
102
83
  var set_jsid = mid_to_jsid(name + '=');
103
84
 
104
- klass._alloc.prototype[set_jsid] = function(val) {
85
+ klass.prototype[set_jsid] = function(val) {
105
86
  return this[name] = val;
106
87
  };
107
88
 
108
- __donate(klass, [set_jsid]);
89
+ klass._donate([set_jsid]);
109
90
  }
110
91
  }
111
92
  }
@@ -154,9 +135,10 @@ class Module
154
135
 
155
136
  var jsid = mid_to_jsid(name);
156
137
  block._jsid = jsid;
138
+ block._sup = this.prototype[jsid];
157
139
 
158
- this._alloc.prototype[jsid] = block;
159
- __donate(this, [jsid]);
140
+ this.prototype[jsid] = block;
141
+ this._donate([jsid]);
160
142
 
161
143
  return nil;
162
144
  }
@@ -167,10 +149,14 @@ class Module
167
149
  var i = mods.length - 1, mod;
168
150
  while (i >= 0) {
169
151
  mod = mods[i];
152
+ i--;
153
+
154
+ if (mod === this) {
155
+ continue;
156
+ }
170
157
  define_iclass(this, mod);
171
158
  mod.$append_features(this);
172
159
  mod.$included(this);
173
- i--;
174
160
  }
175
161
 
176
162
  return this;
@@ -203,5 +189,21 @@ class Module
203
189
 
204
190
  alias public_instance_methods instance_methods
205
191
 
192
+ def singleton_class
193
+ %x{
194
+ if (this._klass._isSingleton) {
195
+ return this._klass;
196
+ }
197
+ else {
198
+ var meta = new __opal.Class;
199
+ this._klass = meta;
200
+ meta._isSingleton = true;
201
+ meta.prototype = this;
202
+
203
+ return meta;
204
+ }
205
+ }
206
+ end
207
+
206
208
  alias to_s name
207
- end
209
+ end
@@ -37,6 +37,10 @@ class NilClass
37
37
 
38
38
  alias to_f to_i
39
39
 
40
+ def to_json
41
+ 'null'
42
+ end
43
+
40
44
  def to_s
41
45
  ''
42
46
  end
@@ -1,6 +1,6 @@
1
1
  class Numeric < `Number`
2
2
  %x{
3
- def._isNumber = true;
3
+ Numeric_prototype._isNumber = true;
4
4
  }
5
5
 
6
6
  include Comparable
@@ -84,7 +84,7 @@ class Numeric < `Number`
84
84
  def <=>(other)
85
85
  %x{
86
86
  if (typeof(other) !== 'number') {
87
- return null;
87
+ return nil;
88
88
  }
89
89
 
90
90
  return this < other ? -1 : (this > other ? 1 : 0);
@@ -144,7 +144,7 @@ class Numeric < `Number`
144
144
  end
145
145
 
146
146
  def nonzero?
147
- `this.valueOf() === 0 ? null : this`
147
+ `this.valueOf() === 0 ? nil : this`
148
148
  end
149
149
 
150
150
  def odd?
@@ -162,7 +162,7 @@ class Numeric < `Number`
162
162
  alias succ next
163
163
 
164
164
  def times(&block)
165
- return enum_for :times unless block
165
+ return enum_for :times unless block_given?
166
166
 
167
167
  %x{
168
168
  for (var i = 0; i <= this; i++) {
@@ -183,6 +183,10 @@ class Numeric < `Number`
183
183
  `parseInt(this)`
184
184
  end
185
185
 
186
+ def to_json
187
+ `this.toString()`
188
+ end
189
+
186
190
  def to_s(base = 10)
187
191
  `this.toString()`
188
192
  end
@@ -202,30 +206,6 @@ class Numeric < `Number`
202
206
  end
203
207
 
204
208
  def zero?
205
- `this.valueOf() === 0`
206
- end
207
- end
208
-
209
- class Integer
210
- def self.===(obj)
211
- %x{
212
- if (typeof(obj) !== 'number') {
213
- return false;
214
- }
215
-
216
- return other % 1 === 0;
217
- }
218
- end
219
- end
220
-
221
- class Float
222
- def self.===(obj)
223
- %x{
224
- if (typeof(obj) !== 'number') {
225
- return false;
226
- }
227
-
228
- return obj % 1 !== 0;
229
- }
209
+ `this == 0`
230
210
  end
231
- end
211
+ end
@@ -1,6 +1,6 @@
1
1
  class Proc < `Function`
2
2
  %x{
3
- def._isProc = true;
3
+ Proc_prototype._isProc = true;
4
4
  }
5
5
 
6
6
  def self.new(&block)
@@ -2,11 +2,10 @@ class Range
2
2
  include Enumerable
3
3
 
4
4
  %x{
5
- var range_class = this;
6
- def._isRange = true;
5
+ Range.prototype._isRange = true;
7
6
 
8
7
  Opal.range = function(beg, end, exc) {
9
- var range = new range_class._alloc();
8
+ var range = new Range;
10
9
  range.begin = beg;
11
10
  range.end = end;
12
11
  range.exclude = exc;
@@ -94,4 +93,4 @@ class Range
94
93
  def inspect
95
94
  `this.begin + (this.exclude ? '...' : '..') + this.end`
96
95
  end
97
- end
96
+ end