opal 0.3.33 → 0.3.34
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.
- data/.travis.yml +1 -1
- data/Gemfile +6 -1
- data/README.md +7 -7
- data/Rakefile +29 -31
- data/bin/opal +1 -1
- data/{core/parser/browser.js → lib/assets/javascripts/opal-parser.js.erb} +9 -1
- data/lib/assets/javascripts/opal.js.erb +321 -0
- data/{core → lib/assets/javascripts/opal}/alpha.rb +0 -0
- data/{core → lib/assets/javascripts/opal}/array.rb +14 -1
- data/{core → lib/assets/javascripts/opal}/basic_object.rb +0 -0
- data/{core → lib/assets/javascripts/opal}/boolean.rb +0 -0
- data/{core → lib/assets/javascripts/opal}/class.rb +3 -3
- data/{core → lib/assets/javascripts/opal}/comparable.rb +0 -0
- data/lib/assets/javascripts/opal/core.js +18 -0
- data/lib/assets/javascripts/opal/date.rb +156 -0
- data/{core → lib/assets/javascripts/opal}/enumerable.rb +0 -0
- data/{core → lib/assets/javascripts/opal}/error.rb +0 -0
- data/{core → lib/assets/javascripts/opal}/hash.rb +0 -0
- data/{core → lib/assets/javascripts/opal}/json.rb +1 -1
- data/{core → lib/assets/javascripts/opal}/kernel.rb +2 -2
- data/{core → lib/assets/javascripts/opal}/nil_class.rb +0 -0
- data/{core → lib/assets/javascripts/opal}/numeric.rb +0 -0
- data/{core → lib/assets/javascripts/opal}/proc.rb +0 -0
- data/{core/parser → lib/assets/javascripts/opal}/racc.rb +0 -0
- data/{core → lib/assets/javascripts/opal}/range.rb +0 -0
- data/{core → lib/assets/javascripts/opal}/regexp.rb +0 -0
- data/{core → lib/assets/javascripts/opal}/string.rb +0 -0
- data/{core/parser → lib/assets/javascripts/opal}/strscan.rb +0 -0
- data/{core → lib/assets/javascripts/opal}/time.rb +0 -0
- data/lib/opal.rb +25 -58
- data/lib/opal/lexer.rb +1 -1
- data/lib/opal/parser.rb +1 -1
- data/lib/opal/processor.rb +26 -0
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +1 -1
- data/spec/core/array/shuffle_spec.rb +11 -0
- data/spec/index.html +4 -6
- data/spec/spec_helper.rb +3 -1
- metadata +29 -35
- data/core/date.rb +0 -34
- data/core/erb.rb +0 -20
- data/core/load_order +0 -20
- data/core/runtime.js +0 -305
- data/core/test_runner/runner.js +0 -37
- data/lib/opal/builder.rb +0 -88
- data/lib/opal/erb.rb +0 -14
- data/lib/opal/rake_task.rb +0 -80
- data/spec/parser/erb_spec.rb +0 -32
- data/spec/test_case.html +0 -13
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -3,6 +3,11 @@ gemspec
|
|
3
3
|
|
4
4
|
gem "rake"
|
5
5
|
|
6
|
+
# for building opal.js
|
7
|
+
group :building do
|
8
|
+
gem "sprockets"
|
9
|
+
end
|
10
|
+
|
6
11
|
# for rebuilding grammar.rb from grammar.y
|
7
12
|
group :grammar do
|
8
13
|
gem "racc"
|
@@ -11,4 +16,4 @@ end
|
|
11
16
|
# running tests on command line
|
12
17
|
group :testing do
|
13
18
|
gem 'opal-spec'
|
14
|
-
end
|
19
|
+
end
|
data/README.md
CHANGED
@@ -27,23 +27,23 @@ web browser.
|
|
27
27
|
|
28
28
|
## Code Overview
|
29
29
|
|
30
|
-
### core
|
31
|
-
|
32
|
-
The `core` directory holds the opal runtime and corelib implemented in
|
33
|
-
ruby and javascript. These are built using `rake opal`, as above.
|
34
|
-
|
35
30
|
### lib
|
36
31
|
|
37
32
|
The `lib` directory holds the opal parser/compiler used to compile ruby
|
38
33
|
into javascript. It is also built ready for the browser into `opal-parser.js`
|
39
34
|
to allow compilation in any javascript environment.
|
40
35
|
|
36
|
+
### lib/assets/javascripts
|
37
|
+
|
38
|
+
This directory holds the opal runtime and corelib implemented in ruby and
|
39
|
+
javascript. These are built using `rake opal`, as above.
|
40
|
+
|
41
41
|
### spec
|
42
42
|
|
43
43
|
* **core** contains rubyspecs that apply to opal.
|
44
44
|
* **language** applicable specs from rubyspec for testing language semantics
|
45
45
|
* **opal** tests for extra methods/features in opal not found in standard ruby
|
46
|
-
* **lib** specs for opal lib (parser,
|
46
|
+
* **lib** specs for opal lib (parser, lexer, grammar etc)
|
47
47
|
|
48
48
|
## License
|
49
49
|
|
@@ -65,4 +65,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
65
65
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
66
66
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
67
67
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
68
|
-
THE SOFTWARE.
|
68
|
+
THE SOFTWARE.
|
data/Rakefile
CHANGED
@@ -1,14 +1,36 @@
|
|
1
1
|
require 'bundler/setup'
|
2
|
-
require 'opal
|
2
|
+
require 'opal-spec'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
t.parser = true # we want to also build opal-parser.js (used in specs)
|
4
|
+
desc "Build opal.js into ./build"
|
5
|
+
task :opal => [:dir] do
|
6
|
+
File.open('build/opal.js', 'w+') { |o| o.puts Opal.runtime }
|
8
7
|
end
|
9
8
|
|
10
|
-
|
11
|
-
task :
|
9
|
+
desc "Build opal-parser.js into ./build"
|
10
|
+
task :parser => [:dir] do
|
11
|
+
File.open('build/opal-parser.js', 'w+') { |o| o.puts Opal.parser_code }
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Build specs ready to run"
|
15
|
+
task :build_specs => [:dir] do
|
16
|
+
Opal.append_path File.join(File.dirname(__FILE__), 'spec')
|
17
|
+
|
18
|
+
File.open('build/specs.js', 'w+') do |out|
|
19
|
+
out.puts Opal.process('spec_helper')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
task :default => [:build_specs, :parser, :test]
|
24
|
+
|
25
|
+
desc "Run opal specs through phantomjs"
|
26
|
+
task :test do
|
27
|
+
OpalSpec.runner
|
28
|
+
end
|
29
|
+
|
30
|
+
task :dir do
|
31
|
+
require 'fileutils'
|
32
|
+
FileUtils.mkdir_p 'build'
|
33
|
+
end
|
12
34
|
|
13
35
|
desc "opal.min.js and opal-parser.min.js"
|
14
36
|
task :min do
|
@@ -52,27 +74,3 @@ def gzip(str)
|
|
52
74
|
return i.read
|
53
75
|
end
|
54
76
|
end
|
55
|
-
|
56
|
-
# For testing just specific sections of opal
|
57
|
-
desc "Build each test case into build/"
|
58
|
-
task :test_cases do
|
59
|
-
FileUtils.mkdir_p 'build/test_cases'
|
60
|
-
|
61
|
-
sources = Dir['spec/core/*', 'spec/language', 'spec/parser', 'spec/grammar']
|
62
|
-
|
63
|
-
sources.each do |c|
|
64
|
-
dest = "build/test_cases/#{File.basename c}"
|
65
|
-
FileUtils.mkdir_p dest
|
66
|
-
File.open("#{dest}/specs.js", "w+") do |out|
|
67
|
-
out.puts Opal.build_files(c)
|
68
|
-
end
|
69
|
-
|
70
|
-
File.open("#{dest}/index.html", "w+") do |out|
|
71
|
-
out.puts File.read("spec/test_case.html")
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
File.open("build/test_cases/runner.js", "w+") do |out|
|
76
|
-
out.puts Opal.parse(File.read("spec/spec_helper.rb"))
|
77
|
-
end
|
78
|
-
end
|
data/bin/opal
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
//= require opal/racc
|
2
|
+
//= require opal/strscan
|
3
|
+
|
4
|
+
// We need (some) of the libs from our real ruby parser (not in sprockets load path)
|
5
|
+
<% ['/grammar', '/lexer', '/parser', '/scope', ''].each do |f| %>
|
6
|
+
<%= Opal.parse File.read(File.join Opal.lib_dir, "opal#{f}.rb") %>
|
7
|
+
<% end %>
|
8
|
+
|
1
9
|
(function() {
|
2
10
|
// quick exit if not insde browser
|
3
11
|
if (typeof(window) === 'undefined' || typeof(document) === 'undefined') {
|
@@ -54,4 +62,4 @@
|
|
54
62
|
else {
|
55
63
|
window.attachEvent('onload', findRubyScripts);
|
56
64
|
}
|
57
|
-
})();
|
65
|
+
})();
|
@@ -0,0 +1,321 @@
|
|
1
|
+
// Opal v<%= Opal::VERSION %>
|
2
|
+
// http://opalrb.org
|
3
|
+
// Copyright 2013, Adam Beynon
|
4
|
+
// Released under the MIT Licence
|
5
|
+
//= require_self
|
6
|
+
//= require opal/core
|
7
|
+
(function(undefined) {
|
8
|
+
// The Opal object that is exposed globally
|
9
|
+
var Opal = this.Opal = {};
|
10
|
+
|
11
|
+
// Opal version
|
12
|
+
Opal.version = <%= Opal::VERSION.inspect %>;
|
13
|
+
|
14
|
+
// Very root class
|
15
|
+
function BasicObject(){}
|
16
|
+
|
17
|
+
// Core Object class
|
18
|
+
function Object(){}
|
19
|
+
|
20
|
+
// Class' class
|
21
|
+
function Class(){}
|
22
|
+
|
23
|
+
// the class of nil
|
24
|
+
function NilClass(){}
|
25
|
+
|
26
|
+
// TopScope is used for inheriting constants from the top scope
|
27
|
+
var TopScope = function(){};
|
28
|
+
|
29
|
+
// Opal just acts as the top scope
|
30
|
+
TopScope.prototype = Opal;
|
31
|
+
|
32
|
+
// To inherit scopes
|
33
|
+
Opal.alloc = TopScope;
|
34
|
+
|
35
|
+
// This is a useful reference to global object inside ruby files
|
36
|
+
Opal.global = this;
|
37
|
+
|
38
|
+
// Minify common function calls
|
39
|
+
var __hasOwn = Opal.hasOwnProperty;
|
40
|
+
var __slice = Opal.slice = Array.prototype.slice;
|
41
|
+
|
42
|
+
// Generates unique id for every ruby object
|
43
|
+
var unique_id = 0;
|
44
|
+
|
45
|
+
// Return next unique id
|
46
|
+
Opal.uid = function() {
|
47
|
+
return unique_id++;
|
48
|
+
};
|
49
|
+
|
50
|
+
// Table holds all class variables
|
51
|
+
Opal.cvars = {};
|
52
|
+
|
53
|
+
// Globals table
|
54
|
+
Opal.gvars = {};
|
55
|
+
|
56
|
+
Opal.klass = function(base, superklass, id, constructor) {
|
57
|
+
var klass;
|
58
|
+
if (base._isObject) {
|
59
|
+
base = base._klass;
|
60
|
+
}
|
61
|
+
|
62
|
+
if (superklass === null) {
|
63
|
+
superklass = Object;
|
64
|
+
}
|
65
|
+
|
66
|
+
if (__hasOwn.call(base._scope, id)) {
|
67
|
+
klass = base._scope[id];
|
68
|
+
}
|
69
|
+
else {
|
70
|
+
if (!superklass._methods) {
|
71
|
+
var bridged = superklass;
|
72
|
+
superklass = Object;
|
73
|
+
klass = bridge_class(bridged);
|
74
|
+
}
|
75
|
+
else {
|
76
|
+
klass = boot_class(superklass, constructor);
|
77
|
+
}
|
78
|
+
|
79
|
+
klass._name = (base === Object ? id : base._name + '::' + id);
|
80
|
+
|
81
|
+
var const_alloc = function() {};
|
82
|
+
var const_scope = const_alloc.prototype = new base._scope.alloc();
|
83
|
+
klass._scope = const_scope;
|
84
|
+
const_scope.alloc = const_alloc;
|
85
|
+
|
86
|
+
base[id] = base._scope[id] = klass;
|
87
|
+
|
88
|
+
if (superklass.$inherited) {
|
89
|
+
superklass.$inherited(klass);
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
return klass;
|
94
|
+
};
|
95
|
+
|
96
|
+
// Define new module (or return existing module)
|
97
|
+
Opal.module = function(base, id, constructor) {
|
98
|
+
var klass;
|
99
|
+
if (base._isObject) {
|
100
|
+
base = base._klass;
|
101
|
+
}
|
102
|
+
|
103
|
+
if (__hasOwn.call(base._scope, id)) {
|
104
|
+
klass = base._scope[id];
|
105
|
+
}
|
106
|
+
else {
|
107
|
+
klass = boot_class(Class, constructor);
|
108
|
+
klass._name = (base === Object ? id : base._name + '::' + id);
|
109
|
+
|
110
|
+
klass.$included_in = [];
|
111
|
+
|
112
|
+
var const_alloc = function() {};
|
113
|
+
var const_scope = const_alloc.prototype = new base._scope.alloc();
|
114
|
+
klass._scope = const_scope;
|
115
|
+
const_scope.alloc = const_alloc;
|
116
|
+
|
117
|
+
base[id] = base._scope[id] = klass;
|
118
|
+
}
|
119
|
+
|
120
|
+
return klass;
|
121
|
+
}
|
122
|
+
|
123
|
+
// Utility function to raise a "no block given" error
|
124
|
+
var no_block_given = function() {
|
125
|
+
throw new Error('no block given');
|
126
|
+
};
|
127
|
+
|
128
|
+
// Boot a base class (makes instances).
|
129
|
+
var boot_defclass = function(id, constructor, superklass) {
|
130
|
+
if (superklass) {
|
131
|
+
var ctor = function() {};
|
132
|
+
ctor.prototype = superklass.prototype;
|
133
|
+
|
134
|
+
constructor.prototype = new ctor();
|
135
|
+
}
|
136
|
+
|
137
|
+
var prototype = constructor.prototype;
|
138
|
+
|
139
|
+
prototype.constructor = constructor;
|
140
|
+
prototype._isObject = true;
|
141
|
+
prototype._klass = constructor;
|
142
|
+
|
143
|
+
constructor._included_in = [];
|
144
|
+
constructor._isClass = true;
|
145
|
+
constructor._name = id;
|
146
|
+
constructor._super = superklass;
|
147
|
+
constructor._methods = [];
|
148
|
+
constructor._smethods = [];
|
149
|
+
constructor._isObject = false;
|
150
|
+
|
151
|
+
constructor._donate = __donate;
|
152
|
+
constructor._sdonate = __sdonate;
|
153
|
+
|
154
|
+
Opal[id] = constructor;
|
155
|
+
|
156
|
+
return constructor;
|
157
|
+
};
|
158
|
+
|
159
|
+
// Create generic class with given superclass.
|
160
|
+
var boot_class = Opal.boot = function(superklass, constructor) {
|
161
|
+
var ctor = function() {};
|
162
|
+
ctor.prototype = superklass.prototype;
|
163
|
+
|
164
|
+
constructor.prototype = new ctor();
|
165
|
+
var prototype = constructor.prototype;
|
166
|
+
|
167
|
+
prototype._klass = constructor;
|
168
|
+
prototype.constructor = constructor;
|
169
|
+
|
170
|
+
constructor._included_in = [];
|
171
|
+
constructor._isClass = true;
|
172
|
+
constructor._super = superklass;
|
173
|
+
constructor._methods = [];
|
174
|
+
constructor._isObject = false;
|
175
|
+
constructor._klass = Class;
|
176
|
+
constructor._donate = __donate
|
177
|
+
constructor._sdonate = __sdonate;
|
178
|
+
|
179
|
+
constructor['$==='] = module_eqq;
|
180
|
+
constructor.$to_s = module_to_s;
|
181
|
+
|
182
|
+
var smethods;
|
183
|
+
|
184
|
+
smethods = superklass._smethods.slice();
|
185
|
+
|
186
|
+
constructor._smethods = smethods;
|
187
|
+
for (var i = 0, length = smethods.length; i < length; i++) {
|
188
|
+
var m = smethods[i];
|
189
|
+
constructor[m] = superklass[m];
|
190
|
+
}
|
191
|
+
|
192
|
+
return constructor;
|
193
|
+
};
|
194
|
+
|
195
|
+
var bridge_class = function(constructor) {
|
196
|
+
constructor.prototype._klass = constructor;
|
197
|
+
|
198
|
+
constructor._included_in = [];
|
199
|
+
constructor._isClass = true;
|
200
|
+
constructor._super = Object;
|
201
|
+
constructor._klass = Class;
|
202
|
+
constructor._methods = [];
|
203
|
+
constructor._smethods = [];
|
204
|
+
constructor._isObject = false;
|
205
|
+
|
206
|
+
constructor._donate = function(){};
|
207
|
+
constructor._sdonate = __sdonate;
|
208
|
+
|
209
|
+
constructor['$==='] = module_eqq;
|
210
|
+
constructor.$to_s = module_to_s;
|
211
|
+
|
212
|
+
var smethods = constructor._smethods = Class._methods.slice();
|
213
|
+
for (var i = 0, length = smethods.length; i < length; i++) {
|
214
|
+
var m = smethods[i];
|
215
|
+
constructor[m] = Object[m];
|
216
|
+
}
|
217
|
+
|
218
|
+
bridged_classes.push(constructor);
|
219
|
+
|
220
|
+
var table = Object.prototype, methods = Object._methods;
|
221
|
+
|
222
|
+
for (var i = 0, length = methods.length; i < length; i++) {
|
223
|
+
var m = methods[i];
|
224
|
+
constructor.prototype[m] = table[m];
|
225
|
+
}
|
226
|
+
|
227
|
+
constructor._smethods.push('$allocate');
|
228
|
+
|
229
|
+
return constructor;
|
230
|
+
};
|
231
|
+
|
232
|
+
Opal.puts = function(a) { console.log(a); };
|
233
|
+
|
234
|
+
// Initialization
|
235
|
+
// --------------
|
236
|
+
|
237
|
+
boot_defclass('BasicObject', BasicObject)
|
238
|
+
boot_defclass('Object', Object, BasicObject);
|
239
|
+
boot_defclass('Class', Class, Object);
|
240
|
+
|
241
|
+
Class.prototype = Function.prototype;
|
242
|
+
|
243
|
+
BasicObject._klass = Object._klass = Class._klass = Class;
|
244
|
+
|
245
|
+
// Implementation of Class#===
|
246
|
+
function module_eqq(object) {
|
247
|
+
if (object == null) {
|
248
|
+
return false;
|
249
|
+
}
|
250
|
+
|
251
|
+
var search = object._klass;
|
252
|
+
|
253
|
+
while (search) {
|
254
|
+
if (search === this) {
|
255
|
+
return true;
|
256
|
+
}
|
257
|
+
|
258
|
+
search = search._super;
|
259
|
+
}
|
260
|
+
|
261
|
+
return false;
|
262
|
+
}
|
263
|
+
|
264
|
+
// Implementation of Class#to_s
|
265
|
+
function module_to_s() {
|
266
|
+
return this._name;
|
267
|
+
}
|
268
|
+
|
269
|
+
// Donator for all 'normal' classes and modules
|
270
|
+
function __donate(defined, indirect) {
|
271
|
+
var methods = this._methods, included_in = this.$included_in;
|
272
|
+
|
273
|
+
// if (!indirect) {
|
274
|
+
this._methods = methods.concat(defined);
|
275
|
+
// }
|
276
|
+
|
277
|
+
if (included_in) {
|
278
|
+
for (var i = 0, length = included_in.length; i < length; i++) {
|
279
|
+
var includee = included_in[i];
|
280
|
+
var dest = includee.prototype;
|
281
|
+
|
282
|
+
for (var j = 0, jj = defined.length; j < jj; j++) {
|
283
|
+
var method = defined[j];
|
284
|
+
dest[method] = this.prototype[method];
|
285
|
+
}
|
286
|
+
|
287
|
+
if (includee.$included_in) {
|
288
|
+
includee._donate(defined, true);
|
289
|
+
}
|
290
|
+
}
|
291
|
+
|
292
|
+
}
|
293
|
+
}
|
294
|
+
|
295
|
+
// Donator for singleton (class) methods
|
296
|
+
function __sdonate(defined) {
|
297
|
+
this._smethods = this._smethods.concat(defined);
|
298
|
+
}
|
299
|
+
|
300
|
+
var bridged_classes = Object.$included_in = [];
|
301
|
+
|
302
|
+
BasicObject._scope = Object._scope = Opal;
|
303
|
+
Opal.Module = Opal.Class;
|
304
|
+
Opal.Kernel = Object;
|
305
|
+
|
306
|
+
var class_const_alloc = function(){};
|
307
|
+
var class_const_scope = new TopScope();
|
308
|
+
class_const_scope.alloc = class_const_alloc;
|
309
|
+
Class._scope = class_const_scope;
|
310
|
+
|
311
|
+
Object.prototype.toString = function() {
|
312
|
+
return this.$to_s();
|
313
|
+
};
|
314
|
+
|
315
|
+
Opal.top = new Object;
|
316
|
+
|
317
|
+
Opal.klass(Object, Object, 'NilClass', NilClass)
|
318
|
+
Opal.nil = new NilClass;
|
319
|
+
|
320
|
+
Opal.breaker = new Error('unexpected break');
|
321
|
+
}).call(this);
|