opal 0.4.2 → 0.4.3

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 (93) hide show
  1. data/.travis.yml +5 -0
  2. data/README.md +42 -2
  3. data/Rakefile +7 -6
  4. data/bin/opal +2 -2
  5. data/{opal → corelib}/opal.rb +21 -21
  6. data/{opal → corelib}/opal/array.rb +37 -24
  7. data/{opal → corelib}/opal/basic_object.rb +0 -0
  8. data/{opal → corelib}/opal/boolean.rb +0 -0
  9. data/{opal → corelib}/opal/class.rb +45 -22
  10. data/{opal → corelib}/opal/comparable.rb +0 -0
  11. data/{opal → corelib}/opal/enumerable.rb +0 -0
  12. data/{opal → corelib}/opal/enumerator.rb +0 -0
  13. data/{opal → corelib}/opal/error.rb +16 -12
  14. data/{opal → corelib}/opal/hash.rb +2 -2
  15. data/{opal → corelib}/opal/kernel.rb +16 -14
  16. data/{opal → corelib}/opal/native.rb +0 -0
  17. data/{opal → corelib}/opal/nil_class.rb +1 -1
  18. data/{opal → corelib}/opal/numeric.rb +0 -0
  19. data/{opal → corelib}/opal/proc.rb +0 -0
  20. data/{opal → corelib}/opal/range.rb +2 -2
  21. data/{opal → corelib}/opal/regexp.rb +0 -0
  22. data/{opal → corelib}/opal/runtime.js +92 -126
  23. data/{opal → corelib}/opal/string.rb +14 -13
  24. data/{opal → corelib}/opal/time.rb +0 -0
  25. data/lib/opal.rb +9 -8
  26. data/lib/opal/builder.rb +81 -0
  27. data/lib/opal/erb.rb +17 -0
  28. data/lib/opal/grammar.rb +33 -30
  29. data/lib/opal/grammar.y +18 -15
  30. data/lib/opal/grammar_helpers.rb +5 -5
  31. data/lib/opal/lexer.rb +3 -2
  32. data/lib/opal/parser.rb +58 -41
  33. data/lib/opal/require_parser.rb +77 -0
  34. data/lib/opal/version.rb +1 -1
  35. data/opal.gemspec +1 -1
  36. data/{config.ru → spec/config.ru} +0 -0
  37. data/spec/opal/array/to_json_spec.rb +3 -1
  38. data/spec/opal/boolean/to_json_spec.rb +3 -1
  39. data/spec/opal/erb/erb_spec.rb +25 -0
  40. data/spec/opal/erb/quoted.opalerb +1 -0
  41. data/spec/opal/erb/simple.opalerb +1 -0
  42. data/spec/opal/json/parse_spec.rb +3 -1
  43. data/spec/opal/kernel/to_json_spec.rb +3 -1
  44. data/spec/opal/nil/to_json_spec.rb +3 -1
  45. data/spec/opal/string/to_json_spec.rb +3 -1
  46. data/spec/parser/int_spec.rb +13 -0
  47. data/spec/parser/regexp_spec.rb +16 -0
  48. data/spec/parser/str_spec.rb +11 -0
  49. data/spec/rubyspec/core/array/plus_spec.rb +7 -2
  50. data/spec/rubyspec/core/hash/to_json_spec.rb +3 -1
  51. data/spec/rubyspec/core/numeric/to_json_spec.rb +3 -1
  52. data/spec/rubyspec/language/defined_spec.rb +9 -0
  53. data/spec/rubyspec/library/stringscanner/pos_spec.rb +20 -0
  54. data/{opal → stdlib}/date.rb +0 -0
  55. data/stdlib/erb.rb +26 -0
  56. data/{opal → stdlib}/fileutils.rb +0 -0
  57. data/{opal → stdlib}/iconv.rb +0 -0
  58. data/{opal/opal → stdlib}/json.rb +0 -0
  59. data/{opal → stdlib}/observer.rb +0 -0
  60. data/{opal → stdlib}/opal-browser/local_storage.rb +0 -0
  61. data/{opal → stdlib}/opal-browser/script_loader.rb +1 -1
  62. data/{opal → stdlib}/opal-parser.js.erb +1 -1
  63. data/{opal → stdlib}/opal-source-maps.js.erb +0 -0
  64. data/{opal → stdlib}/pp.rb +0 -0
  65. data/{opal → stdlib}/racc.rb +0 -0
  66. data/{opal → stdlib}/rbconfig.rb +0 -0
  67. data/{opal → stdlib}/source_map.rb +1 -1
  68. data/{opal → stdlib}/source_map/generator.rb +0 -0
  69. data/{opal → stdlib}/source_map/parser.rb +0 -0
  70. data/{opal → stdlib}/source_map/vlq.rb +0 -0
  71. data/{opal → stdlib}/strscan.rb +15 -0
  72. data/{opal → stdlib}/yaml.rb +0 -0
  73. metadata +87 -77
  74. checksums.yaml +0 -7
  75. data/CHANGELOG.md +0 -176
  76. data/examples/native/Gemfile +0 -3
  77. data/examples/native/README.md +0 -17
  78. data/examples/native/app/app.rb +0 -57
  79. data/examples/native/config.ru +0 -8
  80. data/examples/native/index.html.erb +0 -12
  81. data/examples/rack/Gemfile +0 -3
  82. data/examples/rack/README.md +0 -22
  83. data/examples/rack/app/app.rb +0 -5
  84. data/examples/rack/config.ru +0 -20
  85. data/examples/rack/index.html +0 -12
  86. data/examples/server/Gemfile +0 -3
  87. data/examples/server/README.md +0 -22
  88. data/examples/server/app/app.rb +0 -18
  89. data/examples/server/config.ru +0 -10
  90. data/examples/server/index.html.erb +0 -10
  91. data/opal/opal-template.rb +0 -33
  92. data/spec/opal/class/_inherited_spec.rb +0 -32
  93. data/spec/opal/class/new_spec.rb +0 -27
File without changes
File without changes
File without changes
@@ -4,7 +4,7 @@ class Exception
4
4
  def self.new(message = '')
5
5
  %x{
6
6
  var err = new Error(message);
7
- err.constructor = #{self};
7
+ err._klass = #{self};
8
8
  err.name = #{self}._name;
9
9
  return err;
10
10
  }
@@ -33,15 +33,19 @@ class Exception
33
33
  end
34
34
 
35
35
  class StandardError < Exception; end
36
- class RuntimeError < Exception; end
37
- class LocalJumpError < Exception; end
38
- class TypeError < Exception; end
39
- class NameError < Exception; end
40
- class NoMethodError < Exception; end
41
- class ArgumentError < Exception; end
42
- class IndexError < Exception; end
43
- class KeyError < Exception; end
44
- class RangeError < Exception; end
45
- class StopIteration < Exception; end
46
- class SyntaxError < Exception; end
36
+ class NameError < StandardError; end
37
+ class NoMethodError < NameError; end
38
+ class RuntimeError < StandardError; end
39
+ class LocalJumpError < StandardError; end
40
+ class TypeError < StandardError; end
41
+ class ArgumentError < StandardError; end
42
+ class IndexError < StandardError; end
43
+ class StopIteration < IndexError; end
44
+ class KeyError < IndexError; end
45
+ class RangeError < StandardError; end
46
+
47
+ class ScriptError < Exception; end
48
+ class SyntaxError < ScriptError; end
49
+ class NotImplementedError < ScriptError; end
50
+
47
51
  class SystemExit < Exception; end
@@ -3,7 +3,7 @@ class Hash
3
3
 
4
4
  %x{
5
5
  var __hash = Opal.hash = function() {
6
- var hash = new Hash,
6
+ var hash = new Hash._alloc,
7
7
  args = __slice.call(arguments),
8
8
  keys = [],
9
9
  assocs = {};
@@ -31,7 +31,7 @@ class Hash
31
31
  # function
32
32
  %x{
33
33
  var __hash2 = Opal.hash2 = function(keys, map) {
34
- var hash = new Hash;
34
+ var hash = new Hash._alloc;
35
35
  hash.keys = keys;
36
36
  hash.map = map;
37
37
  return hash;
@@ -36,7 +36,7 @@ module Kernel
36
36
  #{ raise NameError };
37
37
  }
38
38
 
39
- func.constructor = #{Method};
39
+ func._klass = #{Method};
40
40
  return func;
41
41
  }
42
42
  end
@@ -75,7 +75,7 @@ module Kernel
75
75
  end
76
76
 
77
77
  def class
78
- `#{self}.constructor`
78
+ `#{self}._klass`
79
79
  end
80
80
 
81
81
  def define_singleton_method(name, &body)
@@ -255,7 +255,7 @@ module Kernel
255
255
  end
256
256
 
257
257
  def instance_of?(klass)
258
- `#{self}.constructor === klass`
258
+ `#{self}._klass === klass`
259
259
  end
260
260
 
261
261
  def instance_variable_defined?(name)
@@ -290,7 +290,7 @@ module Kernel
290
290
 
291
291
  def is_a?(klass)
292
292
  %x{
293
- var search = #{self}.constructor;
293
+ var search = #{self}._klass;
294
294
 
295
295
  while (search) {
296
296
  if (search === klass) {
@@ -401,22 +401,24 @@ module Kernel
401
401
 
402
402
  def singleton_class
403
403
  %x{
404
- if (typeof(#{self}) === 'function') {
404
+ if (#{self}._isClass) {
405
405
  if (#{self}._singleton) {
406
406
  return #{self}._singleton;
407
407
  }
408
408
 
409
- var meta = new __opal.Class;
410
- meta.constructor = __opal.Class;
409
+ var meta = new __opal.Class._alloc;
410
+ meta._klass = __opal.Class;
411
411
  #{self}._singleton = meta;
412
- meta.prototype = #{self};
412
+ // FIXME - is this right? (probably - methods defined on
413
+ // class' singleton should also go to subclasses?)
414
+ meta._proto = #{self}.constructor.prototype;
413
415
  meta._isSingleton = true;
414
416
 
415
417
  return meta;
416
418
  }
417
419
 
418
- if (typeof(#{self}) === 'function') {
419
- return #{self}.constructor;
420
+ if (#{self}._isClass) {
421
+ return #{self}._klass;
420
422
  }
421
423
 
422
424
  if (#{self}._singleton) {
@@ -424,16 +426,16 @@ module Kernel
424
426
  }
425
427
 
426
428
  else {
427
- var orig_class = #{self}.constructor,
429
+ var orig_class = #{self}._klass,
428
430
  class_id = "#<Class:#<" + orig_class._name + ":" + orig_class._id + ">>";
429
431
 
430
432
  var Singleton = function () {};
431
433
  var meta = Opal.boot(orig_class, Singleton);
432
434
  meta._name = class_id;
433
435
 
434
- meta.prototype = #{self};
436
+ meta._proto = #{self};
435
437
  #{self}._singleton = meta;
436
- meta.constructor = orig_class.constructor;
438
+ meta._klass = orig_class._klass;
437
439
 
438
440
  return meta;
439
441
  }
@@ -460,7 +462,7 @@ module Kernel
460
462
  end
461
463
 
462
464
  def to_s
463
- `return "#<" + #{self}.constructor._name + ":" + #{self}._id + ">";`
465
+ `return "#<" + #{self}._klass._name + ":" + #{self}._id + ">";`
464
466
  end
465
467
 
466
468
  alias to_str to_s
File without changes
@@ -54,7 +54,7 @@ class NilClass
54
54
  end
55
55
 
56
56
  def to_n
57
- `nil`
57
+ `null`
58
58
  end
59
59
 
60
60
  def to_s
File without changes
File without changes
@@ -2,10 +2,10 @@ class Range
2
2
  include Enumerable
3
3
 
4
4
  %x{
5
- Range.prototype._isRange = true;
5
+ Range._proto._isRange = true;
6
6
 
7
7
  Opal.range = function(beg, end, exc) {
8
- var range = new Range;
8
+ var range = new Range._alloc;
9
9
  range.begin = beg;
10
10
  range.end = end;
11
11
  range.exclude = exc;
File without changes
@@ -77,29 +77,30 @@
77
77
 
78
78
  Opal.klass = function(base, superklass, id, constructor) {
79
79
  var klass;
80
- if (typeof(base) !== 'function') {
81
- base = base.constructor;
80
+
81
+ if (!base._isClass) {
82
+ base = base._klass;
82
83
  }
83
84
 
84
85
  if (superklass === null) {
85
- superklass = Object;
86
+ superklass = ObjectClass;
86
87
  }
87
88
 
88
89
  if (__hasOwn.call(base._scope, id)) {
89
90
  klass = base._scope[id];
90
91
 
91
- if (typeof klass !== 'function') {
92
+ if (!klass._isClass) {
92
93
  throw Opal.TypeError.$new(id + " is not a class");
93
94
  }
94
95
 
95
- if (superklass !== klass._super && superklass !== Object) {
96
+ if (superklass !== klass._super && superklass !== ObjectClass) {
96
97
  throw Opal.TypeError.$new("superclass mismatch for class " + id);
97
98
  }
98
99
  }
99
100
  else {
100
101
  klass = boot_class(superklass, constructor);
101
102
 
102
- klass._name = (base === Object ? id : base._name + '::' + id);
103
+ klass._name = (base === ObjectClass ? id : base._name + '::' + id);
103
104
 
104
105
  create_scope(base._scope, klass);
105
106
 
@@ -116,20 +117,21 @@
116
117
  // Define new module (or return existing module)
117
118
  Opal.module = function(base, id, constructor) {
118
119
  var klass;
119
- if (typeof(base) !== 'function') {
120
- base = base.constructor;
120
+
121
+ if (!base._isClass) {
122
+ base = base._klass;
121
123
  }
122
124
 
123
125
  if (__hasOwn.call(base._scope, id)) {
124
126
  klass = base._scope[id];
125
127
 
126
- if (!klass._mod$ && klass !== Object) {
128
+ if (!klass._mod$ && klass !== ObjectClass) {
127
129
  throw Opal.TypeError.$new(id + " is not a module")
128
130
  }
129
131
  }
130
132
  else {
131
- klass = boot_class(Class, constructor);
132
- klass._name = (base === Object ? id : base._name + '::' + id);
133
+ klass = boot_class(ClassClass, constructor);
134
+ klass._name = (base === ObjectClass ? id : base._name + '::' + id);
133
135
  klass._mod$ = true;
134
136
 
135
137
  klass._included_in = [];
@@ -157,65 +159,79 @@
157
159
  var prototype = constructor.prototype;
158
160
 
159
161
  prototype.constructor = constructor;
160
- prototype.constructor = constructor;
161
162
 
162
- constructor._name = id;
163
- constructor._super = superklass;
164
- constructor._methods = [];
165
- constructor._smethods = [];
163
+ return constructor;
164
+ };
166
165
 
167
- constructor['$==='] = module_eqq;
168
- constructor.$to_s = module_to_s;
169
- constructor.toString = module_to_s;
166
+ // Boot the actual (meta?) classes of core classes
167
+ var boot_makemeta = function(id, klass, superklass) {
168
+ function RubyClass() {
169
+ this._id = unique_id++;
170
+ };
170
171
 
171
- Opal[id] = constructor;
172
+ var ctor = function() {};
173
+ ctor.prototype = superklass.prototype;
172
174
 
173
- return constructor;
175
+ RubyClass.prototype = new ctor();
176
+
177
+ var prototype = RubyClass.prototype;
178
+ prototype._isBoot = true;
179
+ prototype._alloc = klass;
180
+ prototype._isClass = true;
181
+ prototype._name = id;
182
+ prototype._super = superklass;
183
+ prototype.constructor = RubyClass;
184
+ prototype._methods = [];
185
+
186
+ var result = new RubyClass();
187
+ klass.prototype._klass = result;
188
+ result._proto = klass.prototype;
189
+
190
+ Opal[id] = result;
191
+
192
+ return result;
174
193
  };
175
194
 
176
195
  // Create generic class with given superclass.
177
196
  var boot_class = Opal.boot = function(superklass, constructor) {
197
+ // instances
178
198
  var ctor = function() {};
179
- ctor.prototype = superklass.prototype;
199
+ ctor.prototype = superklass._proto;
180
200
 
181
201
  constructor.prototype = new ctor();
182
202
  var prototype = constructor.prototype;
183
203
 
184
204
  prototype.constructor = constructor;
185
205
 
186
- constructor._super = superklass;
187
- constructor._methods = [];
188
- constructor.constructor = Class;
189
-
190
- constructor['$==='] = module_eqq;
191
- constructor.$to_s = module_to_s;
192
- constructor.toString = module_to_s;
206
+ // class itself
207
+ function OpalClass() {
208
+ this._id = unique_id++;
209
+ };
193
210
 
194
- constructor['$[]'] = undefined;
195
- constructor.$call = undefined;
211
+ var mtor = function() {};
212
+ mtor.prototype = superklass.constructor.prototype;
196
213
 
197
- var smethods;
214
+ OpalClass.prototype = new mtor();
198
215
 
199
- smethods = superklass._smethods.slice();
216
+ prototype = OpalClass.prototype;
217
+ prototype._alloc = constructor;
218
+ prototype._isClass = true;
219
+ prototype.constructor = OpalClass;
220
+ prototype._super = superklass;
221
+ prototype._methods = [];
200
222
 
201
- constructor._smethods = smethods;
202
- for (var i = 0, length = smethods.length; i < length; i++) {
203
- var m = smethods[i];
204
- constructor[m] = superklass[m];
205
- }
223
+ var result = new OpalClass();
224
+ constructor.prototype._klass = result;
206
225
 
207
- var inherited = superklass._inherited;
226
+ result._proto = constructor.prototype;
208
227
 
209
- if (!inherited) {
210
- inherited = superklass._inherited = [];
211
- }
212
-
213
- inherited.push(constructor);
228
+ return result;
214
229
 
215
230
  return constructor;
216
231
  };
217
232
 
218
233
  var bridge_class = function(constructor) {
234
+ var klass = boot_class(ObjectClass, constructor);
219
235
  var i, length, m;
220
236
 
221
237
  constructor.prototype.constructor = constructor;
@@ -223,30 +239,17 @@
223
239
  constructor._super = Object;
224
240
  constructor.constructor = Class;
225
241
  constructor._methods = [];
226
- constructor._smethods = [];
227
-
228
- constructor['$==='] = module_eqq;
229
- constructor.$to_s = module_to_s;
230
- constructor.toString = module_to_s;
231
242
 
232
- var smethods = constructor._smethods = Class._methods.slice();
233
- for (i = 0, length = smethods.length; i < length; i++) {
234
- m = smethods[i];
235
- constructor[m] = Object[m];
236
- }
243
+ bridged_classes.push(klass);
237
244
 
238
- bridged_classes.push(constructor);
239
-
240
- var table = Object.prototype, methods = Object._methods;
245
+ var table = ObjectClass._proto, methods = ObjectClass._methods;
241
246
 
242
247
  for (i = 0, length = methods.length; i < length; i++) {
243
248
  m = methods[i];
244
249
  constructor.prototype[m] = table[m];
245
250
  }
246
251
 
247
- constructor._smethods.push('$allocate');
248
-
249
- return constructor;
252
+ return klass;
250
253
  };
251
254
 
252
255
  Opal.puts = function(a) { console.log(a); };
@@ -464,30 +467,6 @@
464
467
  return recv.$method_missing.apply(recv, [mid].concat(args));
465
468
  };
466
469
 
467
- // Implementation of Class#===
468
- function module_eqq(object) {
469
- if (object == null) {
470
- return false;
471
- }
472
-
473
- var search = object.constructor;
474
-
475
- while (search) {
476
- if (search === this) {
477
- return true;
478
- }
479
-
480
- search = search._super;
481
- }
482
-
483
- return false;
484
- }
485
-
486
- // Implementation of Class#to_s
487
- function module_to_s() {
488
- return this._name;
489
- }
490
-
491
470
  /**
492
471
  * Donate methods for a class/module
493
472
  */
@@ -501,11 +480,11 @@
501
480
  if (included_in) {
502
481
  for (var i = 0, length = included_in.length; i < length; i++) {
503
482
  var includee = included_in[i];
504
- var dest = includee.prototype;
483
+ var dest = includee._proto;
505
484
 
506
485
  for (var j = 0, jj = defined.length; j < jj; j++) {
507
486
  var method = defined[j];
508
- dest[method] = klass.prototype[method];
487
+ dest[method] = klass._proto[method];
509
488
  }
510
489
 
511
490
  if (includee._included_in) {
@@ -515,64 +494,51 @@
515
494
  }
516
495
  };
517
496
 
518
- /*
519
- Define a singleton method on the given klass
520
-
521
- Opal.defs(Array, '$foo', function() {})
522
-
523
- @param [Function] klass
524
- @param [String] mid the method_id
525
- @param [Function] body function body
526
- */
527
- Opal.defs = function(klass, mid, body) {
528
- klass._smethods.push(mid);
529
- klass[mid] = body;
530
-
531
- var inherited = klass._inherited;
532
- if (inherited && inherited.length) {
533
- for (var i = 0, length = inherited.length, subclass; i < length; i++) {
534
- subclass = inherited[i];
535
- if (!subclass[mid]) {
536
- Opal.defs(subclass, mid, body);
537
- }
538
- }
539
- }
540
- };
541
-
542
- // Defines methods onto Object (which are then donated to bridged classes)
543
- Object._defn = function (mid, body) {
544
- this.prototype[mid] = body;
545
- Opal.donate(this, [mid]);
546
- };
547
-
548
497
  // Initialization
549
498
  // --------------
550
499
 
500
+ // Constructors for *instances* of core objects
551
501
  boot_defclass('BasicObject', BasicObject);
552
502
  boot_defclass('Object', Object, BasicObject);
553
503
  boot_defclass('Class', Class, Object);
554
504
 
555
- Class.prototype = Function.prototype;
505
+ // Constructors for *classes* of core objects
506
+ var BasicObjectClass = boot_makemeta('BasicObject', BasicObject, Class);
507
+ var ObjectClass = boot_makemeta('Object', Object, BasicObjectClass.constructor);
508
+ var ClassClass = boot_makemeta('Class', Class, ObjectClass.constructor);
509
+
510
+ // Fix booted classes to use their metaclass
511
+ BasicObjectClass._klass = ClassClass;
512
+ ObjectClass._klass = ClassClass;
513
+ ClassClass._klass = ClassClass;
556
514
 
557
- BasicObject.constructor = Object.constructor = Class.constructor = Class;
515
+ // Fix superclasses of booted classes
516
+ BasicObjectClass._super = null;
517
+ ObjectClass._super = BasicObjectClass;
518
+ ClassClass._super = ObjectClass;
558
519
 
520
+ // Defines methods onto Object (which are then donated to bridged classes)
521
+ ObjectClass._defn = function (mid, body) {
522
+ this._proto[mid] = body;
523
+ Opal.donate(this, [mid]);
524
+ };
559
525
 
560
- var bridged_classes = Object._included_in = [];
526
+ var bridged_classes = ObjectClass._included_in = [];
561
527
 
562
- Opal.base = Object;
563
- BasicObject._scope = Object._scope = Opal;
528
+ Opal.base = ObjectClass;
529
+ BasicObjectClass._scope = ObjectClass._scope = Opal;
564
530
  Opal.Module = Opal.Class;
565
- Opal.Kernel = Object;
531
+ Opal.Kernel = ObjectClass;
566
532
 
567
- create_scope(Opal, Class);
533
+ create_scope(Opal, ClassClass);
568
534
 
569
- Object.prototype.toString = function() {
535
+ ObjectClass._proto.toString = function() {
570
536
  return this.$to_s();
571
537
  };
572
538
 
573
- Opal.top = new Object;
539
+ Opal.top = new ObjectClass._alloc();
574
540
 
575
- Opal.klass(Object, Object, 'NilClass', NilClass);
541
+ Opal.klass(ObjectClass, ObjectClass, 'NilClass', NilClass);
576
542
 
577
543
  var nil = Opal.nil = new NilClass;
578
544
  nil.call = nil.apply = function() { throw Opal.LocalJumpError.$new('no block given'); };