opal 0.3.43 → 0.3.44

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. data/CHANGELOG.md +19 -0
  2. data/README.md +1 -0
  3. data/Rakefile +29 -19
  4. data/examples/native/Gemfile +3 -0
  5. data/examples/native/README.md +17 -0
  6. data/examples/native/app/app.rb +38 -0
  7. data/examples/native/config.ru +8 -0
  8. data/examples/native/index.html.erb +12 -0
  9. data/lib/opal/lexer.rb +5 -1
  10. data/lib/opal/parser.rb +36 -10
  11. data/lib/opal/processor.rb +10 -9
  12. data/lib/opal/server.rb +17 -7
  13. data/lib/opal/target_scope.rb +2 -2
  14. data/lib/opal/version.rb +1 -1
  15. data/opal/opal-browser/script_loader.rb +8 -13
  16. data/opal/opal.rb +23 -5
  17. data/opal/opal/array.rb +128 -14
  18. data/opal/opal/boolean.rb +1 -1
  19. data/opal/opal/class.rb +92 -18
  20. data/opal/opal/enumerable.rb +90 -0
  21. data/opal/opal/error.rb +1 -1
  22. data/opal/opal/hash.rb +2 -2
  23. data/opal/opal/kernel.rb +3 -3
  24. data/opal/opal/numeric.rb +1 -1
  25. data/opal/opal/proc.rb +1 -1
  26. data/opal/opal/regexp.rb +31 -31
  27. data/opal/opal/runtime.js +181 -69
  28. data/opal/opal/string.rb +561 -40
  29. data/opal/opal/time.rb +1 -1
  30. data/opal/rbconfig.rb +17 -3
  31. data/opal/strscan.rb +41 -5
  32. data/spec/opal/class/new_spec.rb +27 -0
  33. data/spec/opal/native_spec.rb +127 -0
  34. data/spec/ospec/runner.rb +0 -2
  35. data/spec/parser/strscan/get_byte_spec.rb +29 -0
  36. data/spec/parser/strscan/skip_spec.rb +40 -0
  37. data/spec/rubyspec/core/array/each_spec.rb +1 -1
  38. data/spec/rubyspec/core/array/intersection_spec.rb +5 -0
  39. data/spec/rubyspec/core/array/max_spec.rb +32 -0
  40. data/spec/rubyspec/core/array/min_spec.rb +32 -0
  41. data/spec/rubyspec/core/array/minus_spec.rb +7 -5
  42. data/spec/rubyspec/core/array/multiply_spec.rb +1 -1
  43. data/spec/rubyspec/core/array/plus_spec.rb +1 -1
  44. data/spec/rubyspec/core/array/pop_spec.rb +1 -1
  45. data/spec/rubyspec/core/array/push_spec.rb +1 -1
  46. data/spec/rubyspec/core/array/rassoc_spec.rb +1 -1
  47. data/spec/rubyspec/core/array/reject_spec.rb +2 -2
  48. data/spec/rubyspec/core/array/reverse_each_spec.rb +2 -2
  49. data/spec/rubyspec/core/array/rindex_spec.rb +2 -2
  50. data/spec/rubyspec/core/array/select_spec.rb +1 -1
  51. data/spec/rubyspec/core/array/shift_spec.rb +1 -1
  52. data/spec/rubyspec/core/array/slice_spec.rb +1 -1
  53. data/spec/rubyspec/core/array/sort_spec.rb +15 -15
  54. data/spec/rubyspec/core/array/to_a_spec.rb +1 -1
  55. data/spec/rubyspec/core/array/to_ary_spec.rb +1 -1
  56. data/spec/rubyspec/core/array/uniq_spec.rb +1 -1
  57. data/spec/rubyspec/core/array/unshift_spec.rb +1 -1
  58. data/spec/rubyspec/core/array/zip_spec.rb +1 -1
  59. data/spec/rubyspec/core/enumerable/select_spec.rb +4 -1
  60. data/spec/rubyspec/core/module/const_defined_spec.rb +86 -0
  61. data/spec/rubyspec/core/module/const_get_spec.rb +55 -3
  62. data/spec/rubyspec/core/module/const_set_spec.rb +2 -2
  63. data/spec/rubyspec/core/module/constants_spec.rb +49 -0
  64. data/spec/rubyspec/core/regexp/match_spec.rb +66 -1
  65. data/spec/rubyspec/core/string/center_spec.rb +71 -0
  66. data/spec/rubyspec/core/string/chomp_spec.rb +6 -1
  67. data/spec/rubyspec/core/string/clone_spec.rb +8 -0
  68. data/spec/rubyspec/core/string/dup_spec.rb +8 -0
  69. data/spec/rubyspec/core/string/end_with_spec.rb +5 -1
  70. data/spec/rubyspec/core/string/gsub_spec.rb +15 -1
  71. data/spec/rubyspec/core/string/lines_spec.rb +9 -0
  72. data/spec/rubyspec/core/string/ljust_spec.rb +17 -0
  73. data/spec/rubyspec/core/string/match_spec.rb +25 -3
  74. data/spec/rubyspec/core/string/rindex_spec.rb +50 -0
  75. data/spec/rubyspec/core/string/rjust_spec.rb +17 -0
  76. data/spec/rubyspec/core/string/scan_spec.rb +66 -0
  77. data/spec/rubyspec/core/string/sub_spec.rb +17 -1
  78. data/spec/rubyspec/core/string/tr_s_spec.rb +31 -0
  79. data/spec/rubyspec/core/string/tr_spec.rb +31 -0
  80. data/spec/rubyspec/fixtures/constants.rb +6 -0
  81. data/spec/rubyspec/language/class_spec.rb +4 -8
  82. data/spec/rubyspec/language/numbers_spec.rb +10 -4
  83. data/spec/rubyspec/language/predefined_spec.rb +69 -2
  84. data/spec/rubyspec/library/rbconfig/config_spec.rb +47 -0
  85. data/spec/rubyspec/spec_helper.rb +6 -0
  86. metadata +46 -25
  87. data/opal/opal-eventable.rb +0 -26
  88. data/opal/opal/native.rb +0 -115
  89. data/spec/opal/eventable_spec.rb +0 -75
  90. data/spec/opal/native/element_reference_spec.rb +0 -40
  91. data/spec/opal/native/equal_spec.rb +0 -17
  92. data/spec/opal/native/fixtures/classes.rb +0 -27
  93. data/spec/opal/native/global_spec.rb +0 -12
  94. data/spec/opal/native/initialize_spec.rb +0 -8
  95. data/spec/opal/native/method_missing_spec.rb +0 -53
  96. data/spec/opal/native/to_native_spec.rb +0 -8
  97. data/spec/rubyspec/core/string/demodulize_spec.rb +0 -10
  98. data/spec/rubyspec/core/string/underscore_spec.rb +0 -17
@@ -442,6 +442,96 @@ module Enumerable
442
442
 
443
443
  alias map collect
444
444
 
445
+ def max(&block)
446
+ %x{
447
+ var proc, result;
448
+ var arg_error = false;
449
+ if (block !== nil) {
450
+ proc = function(obj) {
451
+ if (result == undefined) {
452
+ result = obj;
453
+ }
454
+ else if ((value = block(obj, result)) === __breaker) {
455
+ result = __breaker.$v;
456
+ return __breaker;
457
+ }
458
+ else {
459
+ if (value > 0) {
460
+ result = obj;
461
+ }
462
+ __breaker.$v = nil;
463
+ }
464
+ }
465
+ }
466
+ else {
467
+ proc = function(obj) {
468
+ var modules = obj.$class().$included_modules;
469
+ if (modules == undefined || modules.length == 0 || modules.indexOf(Opal.Comparable) == -1) {
470
+ arg_error = true;
471
+ return __breaker;
472
+ }
473
+ if (result == undefined || obj > result) {
474
+ result = obj;
475
+ }
476
+ }
477
+ }
478
+
479
+ #{self}.$each._p = proc;
480
+ #{self}.$each();
481
+
482
+ if (arg_error) {
483
+ #{raise ArgumentError, "Array#max"};
484
+ }
485
+
486
+ return (result == undefined ? nil : result);
487
+ }
488
+ end
489
+
490
+ def min(&block)
491
+ %x{
492
+ var proc, result;
493
+ var arg_error = false;
494
+ if (block !== nil) {
495
+ proc = function(obj) {
496
+ if (result == undefined) {
497
+ result = obj;
498
+ }
499
+ else if ((value = block(obj, result)) === __breaker) {
500
+ result = __breaker.$v;
501
+ return __breaker;
502
+ }
503
+ else {
504
+ if (value < 0) {
505
+ result = obj;
506
+ }
507
+ __breaker.$v = nil;
508
+ }
509
+ }
510
+ }
511
+ else {
512
+ proc = function(obj) {
513
+ var modules = obj.$class().$included_modules;
514
+ if (modules == undefined || modules.length == 0 || modules.indexOf(Opal.Comparable) == -1) {
515
+ arg_error = true;
516
+ return __breaker;
517
+ }
518
+ if (result == undefined || obj < result) {
519
+ result = obj;
520
+ }
521
+ }
522
+ }
523
+
524
+ #{self}.$each._p = proc;
525
+ #{self}.$each();
526
+
527
+ if (arg_error) {
528
+ #{raise ArgumentError, "Array#min"};
529
+ }
530
+
531
+ return (result == undefined ? nil : result);
532
+ }
533
+ end
534
+
445
535
  alias select find_all
446
536
 
447
537
  alias take first
data/opal/opal/error.rb CHANGED
@@ -1,4 +1,4 @@
1
- class Exception < `Error`
1
+ class Exception
2
2
  attr_reader :message
3
3
 
4
4
  def self.new(message = '')
data/opal/opal/hash.rb CHANGED
@@ -2,7 +2,7 @@ class Hash
2
2
  include Enumerable
3
3
 
4
4
  %x{
5
- __hash = Opal.hash = function() {
5
+ var __hash = Opal.hash = function() {
6
6
  var hash = new Hash,
7
7
  args = __slice.call(arguments),
8
8
  keys = [],
@@ -30,7 +30,7 @@ class Hash
30
30
  # compile time, so they are just added here by the constructor
31
31
  # function
32
32
  %x{
33
- __hash2 = Opal.hash2 = function(keys, map) {
33
+ var __hash2 = Opal.hash2 = function(keys, map) {
34
34
  var hash = new Hash;
35
35
  hash.keys = keys;
36
36
  hash.map = map;
data/opal/opal/kernel.rb CHANGED
@@ -386,7 +386,7 @@ module Kernel
386
386
 
387
387
  def singleton_class
388
388
  %x{
389
- if (#{self}._isClass) {
389
+ if (typeof(#{self}) === 'function') {
390
390
  if (#{self}._singleton) {
391
391
  return #{self}._singleton;
392
392
  }
@@ -400,7 +400,7 @@ module Kernel
400
400
  return meta;
401
401
  }
402
402
 
403
- if (!#{self}._isObject) {
403
+ if (typeof(#{self}) === 'function') {
404
404
  return #{self}._klass;
405
405
  }
406
406
 
@@ -412,7 +412,7 @@ module Kernel
412
412
  var orig_class = #{self}._klass,
413
413
  class_id = "#<Class:#<" + orig_class._name + ":" + orig_class._id + ">>";
414
414
 
415
- function Singleton() {};
415
+ var Singleton = function () {};
416
416
  var meta = Opal.boot(orig_class, Singleton);
417
417
  meta._name = class_id;
418
418
 
data/opal/opal/numeric.rb CHANGED
@@ -1,4 +1,4 @@
1
- class Numeric < `Number`
1
+ class Numeric
2
2
  include Comparable
3
3
 
4
4
  `def._isNumber = true`
data/opal/opal/proc.rb CHANGED
@@ -1,4 +1,4 @@
1
- class Proc < `Function`
1
+ class Proc
2
2
  `def._isProc = true`
3
3
  `def.is_lambda = true`
4
4
 
data/opal/opal/regexp.rb CHANGED
@@ -1,10 +1,10 @@
1
- class Regexp < `RegExp`
1
+ class Regexp
2
2
  def self.escape(string)
3
3
  `string.replace(/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\^\\$\\|]/g, '\\\\$&')`
4
4
  end
5
5
 
6
- def self.new(string, options = undefined)
7
- `new RegExp(string, options)`
6
+ def self.new(regexp, options = undefined)
7
+ `new RegExp(regexp, options)`
8
8
  end
9
9
 
10
10
  def ==(other)
@@ -15,17 +15,23 @@ class Regexp < `RegExp`
15
15
 
16
16
  def =~(string)
17
17
  %x{
18
- var result = #{self}.exec(string);
18
+ var re = #{self};
19
+ if (re.global) {
20
+ // should we clear it afterwards too?
21
+ re.lastIndex = 0;
22
+ }
23
+ else {
24
+ // rewrite regular expression to add the global flag to capture pre/post match
25
+ re = new RegExp(re.source, 'g' + (re.multiline ? 'm' : '') + (re.ignoreCase ? 'i' : ''));
26
+ }
19
27
 
20
- if (result) {
21
- result.$to_s = match_to_s;
22
- result.$inspect = match_inspect;
23
- result._klass = #{MatchData};
28
+ var result = re.exec(string);
24
29
 
25
- #{$~ = `result`};
30
+ if (result) {
31
+ #{$~ = MatchData.new(`re`, `result`)};
26
32
  }
27
33
  else {
28
- #{$~ = nil};
34
+ #{$~ = $` = $' = nil};
29
35
  }
30
36
 
31
37
  return result ? result.index : nil;
@@ -36,37 +42,31 @@ class Regexp < `RegExp`
36
42
 
37
43
  alias_native :inspect, :toString
38
44
 
39
- def match(pattern, pos = undefined)
45
+ def match(string, pos = undefined)
40
46
  %x{
41
- var result = #{self}.exec(pattern);
47
+ var re = #{self};
48
+ if (re.global) {
49
+ // should we clear it afterwards too?
50
+ re.lastIndex = 0;
51
+ }
52
+ else {
53
+ re = new RegExp(re.source, 'g' + (#{self}.multiline ? 'm' : '') + (#{self}.ignoreCase ? 'i' : ''));
54
+ }
42
55
 
43
- if (result) {
44
- result.$to_s = match_to_s;
45
- result.$inspect = match_inspect;
46
- result._klass = #{MatchData};
56
+ var result = re.exec(string);
47
57
 
48
- return #{$~ = `result`};
58
+ if (result) {
59
+ return #{$~ = MatchData.new(`re`, `result`)};
49
60
  }
50
61
  else {
51
- return #{$~ = nil};
62
+ return #{$~ = $` = $' = nil};
52
63
  }
53
64
  }
54
65
  end
55
66
 
56
- def to_s
67
+ def source
57
68
  `#{self}.source`
58
69
  end
59
70
 
60
- %x{
61
- function match_to_s() {
62
- return this[0];
63
- }
64
-
65
- function match_inspect() {
66
- return "<#MatchData " + this[0].$inspect() + ">";
67
- }
68
- }
69
- end
70
-
71
- class MatchData
71
+ alias to_s source
72
72
  end
data/opal/opal/runtime.js CHANGED
@@ -21,7 +21,7 @@
21
21
  TopScope.prototype = Opal;
22
22
 
23
23
  // To inherit scopes
24
- Opal.alloc = TopScope;
24
+ Opal.constructor = TopScope;
25
25
 
26
26
  // This is a useful reference to global object inside ruby files
27
27
  Opal.global = this;
@@ -44,9 +44,40 @@
44
44
  // Globals table
45
45
  Opal.gvars = {};
46
46
 
47
+ /*
48
+ * Create a new constants scope for the given class with the given
49
+ * base. Constants are looked up through their parents, so the base
50
+ * scope will be the outer scope of the new klass.
51
+ */
52
+ function create_scope(base, klass, id) {
53
+ var const_alloc = function() {};
54
+ var const_scope = const_alloc.prototype = new base.constructor();
55
+ klass._scope = const_scope;
56
+ const_scope.base = klass;
57
+ const_scope.constructor = const_alloc;
58
+
59
+ if (id) {
60
+ base[id] = base.constructor[id] = klass;
61
+ }
62
+ }
63
+
64
+ /*
65
+ Define a bridged class. Bridged classes will always be in the top level
66
+ scope, and will always be a subclass of Object.
67
+ */
68
+ Opal.bridge = function(name, constructor) {
69
+ var klass = bridge_class(constructor);
70
+
71
+ klass._name = name;
72
+
73
+ create_scope(Opal, klass, name);
74
+
75
+ return klass;
76
+ };
77
+
47
78
  Opal.klass = function(base, superklass, id, constructor) {
48
79
  var klass;
49
- if (base._isObject) {
80
+ if (typeof(base) !== 'function') {
50
81
  base = base._klass;
51
82
  }
52
83
 
@@ -69,11 +100,7 @@
69
100
 
70
101
  klass._name = (base === Object ? id : base._name + '::' + id);
71
102
 
72
- var const_alloc = function() {};
73
- var const_scope = const_alloc.prototype = new base._scope.alloc();
74
- klass._scope = const_scope;
75
- const_scope.base = klass;
76
- const_scope.alloc = const_alloc;
103
+ create_scope(base._scope, klass);
77
104
 
78
105
  base[id] = base._scope[id] = klass;
79
106
 
@@ -88,7 +115,7 @@
88
115
  // Define new module (or return existing module)
89
116
  Opal.module = function(base, id, constructor) {
90
117
  var klass;
91
- if (base._isObject) {
118
+ if (typeof(base) !== 'function') {
92
119
  base = base._klass;
93
120
  }
94
121
 
@@ -101,12 +128,7 @@
101
128
 
102
129
  klass.$included_in = [];
103
130
 
104
- var const_alloc = function() {};
105
- var const_scope = const_alloc.prototype = new base._scope.alloc();
106
- klass._scope = const_scope;
107
- const_scope.alloc = const_alloc;
108
-
109
- base[id] = base._scope[id] = klass;
131
+ create_scope(base._scope, klass, id);
110
132
  }
111
133
 
112
134
  return klass;
@@ -129,20 +151,14 @@
129
151
  var prototype = constructor.prototype;
130
152
 
131
153
  prototype.constructor = constructor;
132
- prototype._isObject = true;
133
154
  prototype._klass = constructor;
134
155
 
135
156
  constructor._inherited = [];
136
157
  constructor._included_in = [];
137
- constructor._isClass = true;
138
158
  constructor._name = id;
139
159
  constructor._super = superklass;
140
160
  constructor._methods = [];
141
161
  constructor._smethods = [];
142
- constructor._isObject = false;
143
-
144
- constructor._donate = __donate;
145
- constructor._defs = __defs;
146
162
 
147
163
  constructor['$==='] = module_eqq;
148
164
  constructor.$to_s = module_to_s;
@@ -166,13 +182,9 @@
166
182
 
167
183
  constructor._inherited = [];
168
184
  constructor._included_in = [];
169
- constructor._isClass = true;
170
185
  constructor._super = superklass;
171
186
  constructor._methods = [];
172
- constructor._isObject = false;
173
187
  constructor._klass = Class;
174
- constructor._donate = __donate
175
- constructor._defs = __defs;
176
188
 
177
189
  constructor['$==='] = module_eqq;
178
190
  constructor.$to_s = module_to_s;
@@ -201,15 +213,10 @@
201
213
 
202
214
  constructor._inherited = [];
203
215
  constructor._included_in = [];
204
- constructor._isClass = true;
205
216
  constructor._super = Object;
206
217
  constructor._klass = Class;
207
218
  constructor._methods = [];
208
219
  constructor._smethods = [];
209
- constructor._isObject = false;
210
-
211
- constructor._donate = function(){};
212
- constructor._defs = __defs;
213
220
 
214
221
  constructor['$==='] = module_eqq;
215
222
  constructor.$to_s = module_to_s;
@@ -237,17 +244,106 @@
237
244
 
238
245
  Opal.puts = function(a) { console.log(a); };
239
246
 
240
- var mm_mid = '';
247
+ // Method missing dispatcher
248
+ Opal.mm = function(mid) {
249
+ var dispatcher = function() {
250
+ var args = __slice.call(arguments);
241
251
 
242
- var method_missing_dispatcher = function() {
243
- this.$method_missing._p = method_missing_dispatcher._p;
244
- return this.$method_missing.apply(this, [mm_mid].concat(__slice.call(arguments)));
252
+ if (this.$method_missing) {
253
+ this.$method_missing._p = dispatcher._p;
254
+ return this.$method_missing.apply(this, [mid].concat(args));
255
+ }
256
+ else {
257
+ return native_send(this, mid, args);
258
+ }
259
+ };
260
+
261
+ return dispatcher;
245
262
  };
246
263
 
247
- // Method missing dispatcher
248
- Opal.mm = function(mid) {
249
- mm_mid = mid;
250
- return method_missing_dispatcher;
264
+ // send a method to a native object
265
+ var native_send = function(obj, mid, args) {
266
+ var prop, block = native_send._p;
267
+ native_send._p = null;
268
+
269
+ if (prop = native_methods[mid]) {
270
+ return prop(obj, args, block);
271
+ }
272
+
273
+ prop = obj[mid];
274
+
275
+ if (typeof(prop) === "function") {
276
+ prop = prop.apply(obj, args.$to_native());
277
+ }
278
+ else if (mid.charAt(mid.length - 1) === "=") {
279
+ prop = mid.slice(0, mid.length - 1);
280
+ return obj[prop] = args[0];
281
+ }
282
+
283
+ if (prop != null) {
284
+ return prop;
285
+ }
286
+
287
+ return nil;
288
+ };
289
+
290
+ var native_methods = {
291
+ "==": function(obj, args) {
292
+ return obj === args[0];
293
+ },
294
+
295
+ "[]": function(obj, args) {
296
+ var prop = obj[args[0]];
297
+
298
+ if (prop != null) {
299
+ return prop;
300
+ }
301
+
302
+ return nil;
303
+ },
304
+
305
+ "respond_to?": function(obj, args) {
306
+ return obj[args[0]] != null;
307
+ },
308
+
309
+ "each": function(obj, args, block) {
310
+ var prop;
311
+
312
+ if (obj.length === +obj.length) {
313
+ for (var i = 0, len = obj.length; i < len; i++) {
314
+ prop = obj[i];
315
+
316
+ if (prop == null) {
317
+ prop = nil;
318
+ }
319
+
320
+ block(prop);
321
+ }
322
+ }
323
+ else {
324
+ for (var key in obj) {
325
+ prop = obj[key];
326
+
327
+ if (prop == null) {
328
+ prop = nil;
329
+ }
330
+
331
+ block(key, prop);
332
+ }
333
+ }
334
+
335
+ return obj;
336
+ },
337
+
338
+ "to_a": function(obj, args) {
339
+ var result = [];
340
+
341
+ for (var i = 0, length = obj.length; i < length; i++) {
342
+ result.push(obj[i]);
343
+ }
344
+
345
+ return result;
346
+ }
251
347
  };
252
348
 
253
349
  // Const missing dispatcher
@@ -257,7 +353,7 @@
257
353
 
258
354
  // Arity count error dispatcher
259
355
  Opal.ac = function(actual, expected, object, meth) {
260
- var inspect = (object._isObject ? object._klass._name + '#' : object._name + '.') + meth;
356
+ var inspect = ((typeof(object) !== 'function') ? object._klass._name + '#' : object._name + '.') + meth;
261
357
  var msg = '[' + inspect + '] wrong number of arguments(' + actual + ' for ' + expected + ')'
262
358
  throw Opal.ArgumentError.$new(msg);
263
359
  };
@@ -288,17 +384,6 @@
288
384
  return recv.$method_missing.apply(recv, [mid].concat(args));
289
385
  };
290
386
 
291
- // Initialization
292
- // --------------
293
-
294
- boot_defclass('BasicObject', BasicObject)
295
- boot_defclass('Object', Object, BasicObject);
296
- boot_defclass('Class', Class, Object);
297
-
298
- Class.prototype = Function.prototype;
299
-
300
- BasicObject._klass = Object._klass = Class._klass = Class;
301
-
302
387
  // Implementation of Class#===
303
388
  function module_eqq(object) {
304
389
  if (object == null) {
@@ -323,12 +408,14 @@
323
408
  return this._name;
324
409
  }
325
410
 
326
- // Donator for all 'normal' classes and modules
327
- function __donate(defined, indirect) {
328
- var methods = this._methods, included_in = this.$included_in;
411
+ /**
412
+ * Donate methods for a class/module
413
+ */
414
+ Opal.donate = function(klass, defined, indirect) {
415
+ var methods = klass._methods, included_in = klass.$included_in;
329
416
 
330
417
  // if (!indirect) {
331
- this._methods = methods.concat(defined);
418
+ klass._methods = methods.concat(defined);
332
419
  // }
333
420
 
334
421
  if (included_in) {
@@ -338,39 +425,58 @@
338
425
 
339
426
  for (var j = 0, jj = defined.length; j < jj; j++) {
340
427
  var method = defined[j];
341
- dest[method] = this.prototype[method];
428
+ dest[method] = klass.prototype[method];
342
429
  }
343
430
 
344
431
  if (includee.$included_in) {
345
- includee._donate(defined, true);
432
+ Opal.donate(includee, defined, true);
346
433
  }
347
434
  }
348
-
349
435
  }
350
- }
436
+ };
351
437
 
352
- // Define a singleton method on a class
353
- function __defs(mid, body) {
354
- this._smethods.push(mid);
355
- this[mid] = body;
438
+ /*
439
+ Define a singleton method on the given klass
440
+
441
+ Opal.defs(Array, '$foo', function() {})
356
442
 
357
- var inherited = this._inherited;
443
+ @param [Function] klass
444
+ @param [String] mid the method_id
445
+ @param [Function] body function body
446
+ */
447
+ Opal.defs = function(klass, mid, body) {
448
+ klass._smethods.push(mid);
449
+ klass[mid] = body;
450
+
451
+ var inherited = klass._inherited;
358
452
  if (inherited.length) {
359
453
  for (var i = 0, length = inherited.length, subclass; i < length; i++) {
360
454
  subclass = inherited[i];
361
455
  if (!subclass[mid]) {
362
- subclass._defs(mid, body);
456
+ Opal.defs(subclass, mid, body);
363
457
  }
364
458
  }
365
459
  }
366
- }
460
+ };
367
461
 
368
462
  // Defines methods onto Object (which are then donated to bridged classes)
369
463
  Object._defn = function (mid, body) {
370
464
  this.prototype[mid] = body;
371
- this._donate([mid]);
465
+ Opal.donate(this, [mid]);
372
466
  };
373
467
 
468
+ // Initialization
469
+ // --------------
470
+
471
+ boot_defclass('BasicObject', BasicObject)
472
+ boot_defclass('Object', Object, BasicObject);
473
+ boot_defclass('Class', Class, Object);
474
+
475
+ Class.prototype = Function.prototype;
476
+
477
+ BasicObject._klass = Object._klass = Class._klass = Class;
478
+
479
+
374
480
  var bridged_classes = Object.$included_in = [];
375
481
 
376
482
  Opal.base = Object;
@@ -378,10 +484,7 @@
378
484
  Opal.Module = Opal.Class;
379
485
  Opal.Kernel = Object;
380
486
 
381
- var class_const_alloc = function(){};
382
- var class_const_scope = new TopScope();
383
- class_const_scope.alloc = class_const_alloc;
384
- Class._scope = class_const_scope;
487
+ create_scope(Opal, Class);
385
488
 
386
489
  Object.prototype.toString = function() {
387
490
  return this.$to_s();
@@ -394,4 +497,13 @@
394
497
  nil.call = nil.apply = function() { throw Opal.LocalJumpError.$new('no block given'); };
395
498
 
396
499
  Opal.breaker = new Error('unexpected break');
500
+
501
+ Opal.bridge('Array', Array);
502
+ Opal.bridge('Boolean', Boolean);
503
+ Opal.bridge('Numeric', Number);
504
+ Opal.bridge('String', String);
505
+ Opal.bridge('Proc', Function);
506
+ Opal.bridge('Exception', Error);
507
+ Opal.bridge('Regexp', RegExp);
508
+ Opal.bridge('Time', Date);
397
509
  }).call(this);