opal 0.4.2 → 0.4.3

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