opal 0.3.6 → 0.3.9

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 (98) hide show
  1. data/README.md +69 -97
  2. data/bin/opal +2 -2
  3. data/{lib/core → corelib}/array.rb +85 -56
  4. data/corelib/boolean.rb +20 -0
  5. data/corelib/class.rb +58 -0
  6. data/{lib → corelib}/core.rb +2 -50
  7. data/corelib/dir.rb +22 -0
  8. data/{lib/core → corelib}/enumerable.rb +0 -0
  9. data/corelib/error.rb +19 -0
  10. data/{lib/core → corelib}/file.rb +7 -9
  11. data/{lib/core → corelib}/hash.rb +104 -144
  12. data/{lib/core → corelib}/kernel.rb +38 -44
  13. data/corelib/load_order +21 -0
  14. data/{lib/core → corelib}/match_data.rb +0 -0
  15. data/{lib/core → corelib}/module.rb +12 -8
  16. data/{lib/core → corelib}/nil_class.rb +2 -2
  17. data/{lib/core → corelib}/numeric.rb +37 -100
  18. data/corelib/object.rb +37 -0
  19. data/{lib/core → corelib}/proc.rb +3 -3
  20. data/corelib/range.rb +27 -0
  21. data/{lib/core → corelib}/regexp.rb +1 -1
  22. data/{lib/core → corelib}/string.rb +16 -107
  23. data/{lib/core → corelib}/top_self.rb +0 -0
  24. data/lib/opal.rb +7 -0
  25. data/lib/opal/browserify.rb +34 -0
  26. data/{opal_lib → lib}/opal/builder.rb +70 -24
  27. data/lib/opal/command.rb +52 -0
  28. data/lib/opal/context.rb +197 -0
  29. data/{opal_lib/opal/ruby/parser.rb → lib/opal/lexer.rb} +20 -4
  30. data/{opal_lib/opal/ruby → lib/opal}/nodes.rb +238 -127
  31. data/lib/opal/parser.rb +4894 -0
  32. data/{opal_lib/opal/ruby/ruby_parser.y → lib/opal/parser.y} +38 -18
  33. data/lib/rbp.rb +2 -0
  34. data/lib/rbp/package.rb +49 -0
  35. data/runtime/class.js +216 -189
  36. data/runtime/fs.js +2 -2
  37. data/runtime/init.js +242 -244
  38. data/runtime/loader.js +78 -99
  39. data/runtime/module.js +34 -40
  40. data/runtime/post.js +2 -2
  41. data/runtime/pre.js +1 -1
  42. data/runtime/runtime.js +129 -135
  43. data/{lib → stdlib}/dev.rb +10 -10
  44. data/{lib → stdlib}/racc/parser.rb +0 -6
  45. data/{lib → stdlib}/strscan.rb +4 -4
  46. metadata +57 -105
  47. data/lib/core/basic_object.rb +0 -51
  48. data/lib/core/class.rb +0 -38
  49. data/lib/core/dir.rb +0 -26
  50. data/lib/core/error.rb +0 -75
  51. data/lib/core/false_class.rb +0 -81
  52. data/lib/core/object.rb +0 -6
  53. data/lib/core/range.rb +0 -27
  54. data/lib/core/symbol.rb +0 -42
  55. data/lib/core/true_class.rb +0 -41
  56. data/lib/ospec.rb +0 -7
  57. data/lib/ospec/autorun.rb +0 -8
  58. data/lib/ospec/dsl.rb +0 -15
  59. data/lib/ospec/example.rb +0 -11
  60. data/lib/ospec/example/before_and_after_hooks.rb +0 -56
  61. data/lib/ospec/example/errors.rb +0 -17
  62. data/lib/ospec/example/example_group.rb +0 -12
  63. data/lib/ospec/example/example_group_factory.rb +0 -18
  64. data/lib/ospec/example/example_group_hierarchy.rb +0 -21
  65. data/lib/ospec/example/example_group_methods.rb +0 -100
  66. data/lib/ospec/example/example_group_proxy.rb +0 -15
  67. data/lib/ospec/example/example_methods.rb +0 -46
  68. data/lib/ospec/example/example_proxy.rb +0 -18
  69. data/lib/ospec/expectations.rb +0 -19
  70. data/lib/ospec/expectations/errors.rb +0 -8
  71. data/lib/ospec/expectations/fail_with.rb +0 -9
  72. data/lib/ospec/expectations/handler.rb +0 -33
  73. data/lib/ospec/helpers/scratch.rb +0 -18
  74. data/lib/ospec/matchers.rb +0 -24
  75. data/lib/ospec/matchers/be.rb +0 -1
  76. data/lib/ospec/matchers/generated_descriptions.rb +0 -20
  77. data/lib/ospec/matchers/operator_matcher.rb +0 -54
  78. data/lib/ospec/matchers/raise_error.rb +0 -38
  79. data/lib/ospec/runner.rb +0 -90
  80. data/lib/ospec/runner/example_group_runner.rb +0 -41
  81. data/lib/ospec/runner/formatter/html_formatter.rb +0 -139
  82. data/lib/ospec/runner/formatter/terminal_formatter.rb +0 -48
  83. data/lib/ospec/runner/options.rb +0 -34
  84. data/lib/ospec/runner/reporter.rb +0 -82
  85. data/opal_lib/opal.rb +0 -16
  86. data/opal_lib/opal/build_methods.rb +0 -51
  87. data/opal_lib/opal/bundle.rb +0 -70
  88. data/opal_lib/opal/command.rb +0 -68
  89. data/opal_lib/opal/context.rb +0 -81
  90. data/opal_lib/opal/context/console.rb +0 -10
  91. data/opal_lib/opal/context/file_system.rb +0 -34
  92. data/opal_lib/opal/context/loader.rb +0 -135
  93. data/opal_lib/opal/gem.rb +0 -84
  94. data/opal_lib/opal/rake/builder_task.rb +0 -44
  95. data/opal_lib/opal/rake/spec_task.rb +0 -32
  96. data/opal_lib/opal/ruby/ruby_parser.rb +0 -4862
  97. data/opal_lib/opal/version.rb +0 -4
  98. data/runtime/debug.js +0 -84
data/runtime/loader.js CHANGED
@@ -20,7 +20,7 @@ load_extensions['.rb'] = function(loader, path) {
20
20
  @param {String} id lib path/name
21
21
  @return {Boolean}
22
22
  */
23
- var load_require = Op.require = Rt.require = function(lib) {
23
+ var rb_require = Op.require = function(lib) {
24
24
  var resolved = Op.loader.resolve_lib(lib);
25
25
  var cached = Op.cache[resolved];
26
26
 
@@ -61,91 +61,94 @@ Op.run = function(body) {
61
61
  var res = Qnil;
62
62
 
63
63
  if (typeof body != 'function') {
64
- throw new Error("Expected body to be a function");
64
+ rb_raise(rb_eException, "Expected body to be a function");
65
65
  }
66
66
 
67
- try {
68
- res = body(Rt, Rt.top, "(opal)");
69
- }
70
- catch (exc) {
71
- var exc, stack;
72
-
73
- if (exc && exc['@message']) {
74
- puts(exc.$klass.__classid__ + ': ' + exc['@message']);
75
- }
76
- else {
77
- puts('NativeError: ' + exc.message);
78
- }
79
-
80
- // first try (if in debug mode...)
81
- if (typeof OPAL_DEBUG != 'undefined') {
82
- puts(stack);
83
- Db.stack = [];
84
- }
85
- else if (stack = exc.stack) {
86
- puts(stack);
87
- }
88
- }
67
+ // try {
68
+ res = body(Rt, rb_top_self, "(opal)");
69
+ // }
70
+ // catch (err) {
71
+ // var stack;
72
+
73
+ // if (err.$message) {
74
+ // puts(err.$k.__classid__ + ': ' + err.$message);
75
+ // }
76
+ // else if (err.message) {
77
+ // puts(err.$k.__classid__ + ': ' + err.message);
78
+ // }
79
+ // else {
80
+ // puts('NativeError: ' + err.message);
81
+ // console.log(err);
82
+ // }
83
+ // }
89
84
  return res;
90
85
  };
91
86
 
92
87
  /**
93
- Register a lib or gem with the given info. If info is an object then
94
- a gem will be registered with the object represented a JSON version
95
- of the gemspec for the gem. If the info is simply a function (or
96
- string?) then a singular lib will be registerd with the function as
97
- its body.
88
+ Register a simple lib file. This file is simply just put into the lib
89
+ "directory" so it is ready to load"
98
90
 
99
91
  @param {String} name The lib/gem name
100
- @param {Object, Function} info
92
+ @param {String, Function} info
101
93
  */
102
- Op.register = function(name, info) {
103
- // make sure name is useful
94
+ Op.lib = function(name, info) {
95
+ // make sure name if useful
104
96
  if (typeof name !== 'string') {
105
- throw new Error("Cannot register a lib without a proper name");
97
+ rb_raise(rb_eException, "Cannot register a lib without a proper name");
106
98
  }
107
99
 
108
- // registering a lib/file?
100
+ // make sure info is useful
109
101
  if (typeof info === 'string' || typeof info === 'function') {
110
- load_register_lib(name, info);
102
+ return load_register_lib(name, info);
111
103
  }
112
- // registering a gem?
113
- else if (typeof info === 'object') {
114
- load_register_gem(name, info);
104
+
105
+ // something went wrong..
106
+ rb_raise(rb_eException, "Invalid lib data for: " + name);
107
+ };
108
+
109
+ /**
110
+ External api for defining a package. This takes an object that defines
111
+ all the package info and files.
112
+
113
+ @param {Object} info Package info
114
+ */
115
+ Op.package = function(info) {
116
+ if (typeof info === 'object') {
117
+ load_register_package(info);
115
118
  }
116
- // something has gone wrong..
117
119
  else {
118
- throw new Error("Invalid gem/lib data for '" + name + "'");
120
+ rb_raise(rb_eException, "Invalid package data");
119
121
  }
120
122
  };
121
123
 
122
124
  /**
123
- Actually register a predefined gem. This is for the browser context
124
- where gems can be serialized into JSON and defined before hand.
125
+ Actually register a predefined package. This is for the browser context
126
+ where package can be serialized into JSON and defined before hand.
125
127
 
126
- @param {String} name Gem name
127
128
  @param {Object} info Serialized gemspec
128
129
  */
129
- function load_register_gem(name, info) {
130
+ function load_register_package(info) {
130
131
  var factories = Op.loader.factories,
131
- paths = Op.loader.paths;
132
+ paths = Op.loader.paths,
133
+ name = info.name;
132
134
 
133
135
  // register all lib files
134
- var files = info.files || {};
136
+ var libs = info.libs || {};
135
137
 
136
138
  // root dir for gem is '/gem_name'
137
139
  var root_dir = '/' + name;
138
140
 
139
141
  // for now assume './lib' as dir for all libs (should be dynamic..)
140
- var lib_dir = './lib';
142
+ var lib_dir = '/' + name + '/lib/';
141
143
 
142
144
  // add lib dir to paths
143
145
  paths.unshift(fs_expand_path(fs_join(root_dir, lib_dir)));
144
146
 
145
- for (var file in files) {
146
- if (files.hasOwnProperty(file)) {
147
- var file_path = fs_expand_path(fs_join(root_dir, file));
148
- factories[file_path] = files[file];
147
+ for (var lib in libs) {
148
+ if (hasOwnProperty.call(libs, lib)) {
149
+ var file_path = lib_dir + lib;
150
+ Op.loader.factories[file_path] = libs[lib];
151
+ Op.loader.libs[lib] = file_path;
149
152
  }
150
153
  }
151
154
 
@@ -160,8 +163,9 @@ function load_register_gem(name, info) {
160
163
  @param {Function, String} factory
161
164
  */
162
165
  function load_register_lib(name, factory) {
163
- var path = '/' + name;
166
+ var path = '/lib/' + name;
164
167
  Op.loader.factories[path] = factory;
168
+ Op.loader.libs[name] = path;
165
169
  }
166
170
 
167
171
  /**
@@ -179,6 +183,7 @@ function Loader(opal) {
179
183
  this.opal = opal;
180
184
  this.paths = ['', '/lib'];
181
185
  this.factories = {};
186
+ this.libs = {};
182
187
  return this;
183
188
  }
184
189
 
@@ -215,52 +220,31 @@ Lp.resolve_lib = function(lib) {
215
220
  var resolved = this.find_lib(lib, this.paths);
216
221
 
217
222
  if (!resolved) {
218
- throw new Error("LoadError: no such file to load -- " + lib);
223
+ raise(eLoadError, "no such file to load -- " + lib);
219
224
  }
220
225
 
221
226
  return resolved;
222
227
  };
223
228
 
224
- /**
225
- Locates the lib/file using the given paths.
226
-
227
- @param {String} lib The lib path/file to look for
228
- @param {Array} paths Load paths to use
229
- @return {String} Located path
230
- */
231
- Lp.find_lib = function(id, paths) {
232
- var extensions = this.valid_extensions, factories = this.factories, candidate;
229
+ Lp.find_lib = function(id) {
230
+ var libs = this.libs;
231
+ var id_with_ext = id + '.rb';
233
232
 
234
- for (var i = 0, ii = extensions.length; i < ii; i++) {
235
- for (var j = 0, jj = paths.length; j < jj; j++) {
236
- candidate = fs_join(paths[j], id + extensions[i]);
237
-
238
- if (factories[candidate]) {
239
- return candidate;
240
- }
241
- }
233
+ // try to load a lib path first - i.e. something in our load path
234
+ if (libs[id_with_ext]) {
235
+ return libs[id_with_ext];
242
236
  }
243
237
 
244
- // try full path (we try to load absolute path!)
245
- if (factories[id]) {
246
- return id;
247
- }
238
+ // go through full paths..
248
239
 
249
- // try full path with each extension
250
- for (var i = 0; i < extensions.length; i++) {
251
- candidate = id + extensions[i];
252
- if (factories[candidate]) {
253
- return candidate;
254
- }
255
- }
256
-
257
- // try each path with no extension (if id already has extension)
258
- for (var i = 0; i < paths.length; i++) {
259
- candidate = fs_join(paths[j], id);
260
-
261
- if (factories[candidate]) {
262
- return candidate;
240
+ // next, incase our require() has a ruby extension..
241
+ if (id.lastIndexOf('.rb') == id.length - 3) {
242
+ // id = id.substr(0, id.length - 3);
243
+ if (libs[id]) {
244
+ return libs[id];
263
245
  }
246
+ // if not..
247
+ // return null;
264
248
  }
265
249
 
266
250
  return null;
@@ -292,7 +276,7 @@ function load_file(loader, path) {
292
276
  var ext = load_extensions[PATH_RE.exec(path)[3] || '.js'];
293
277
 
294
278
  if (!ext) {
295
- throw new Error("load_run_file - Bad extension for resolved path");
279
+ rb_raise(rb_eException, "load_run_file - Bad extension for resolved path");
296
280
  }
297
281
 
298
282
  ext(loader, path);
@@ -310,7 +294,7 @@ function load_file(loader, path) {
310
294
  @param {String} path
311
295
  */
312
296
  function load_execute_file(loader, content, path) {
313
- var args = [Rt, top_self, path];
297
+ var args = [Rt, rb_top_self, path];
314
298
 
315
299
  if (typeof content === 'function') {
316
300
  return content.apply(Op, args);
@@ -320,8 +304,7 @@ function load_execute_file(loader, content, path) {
320
304
  return func.apply(Op, args);
321
305
 
322
306
  } else {
323
- throw new Error(
324
- "Loader.execute - bad content sent for '" + path + "'");
307
+ rb_raise(rb_eException, "Loader.execute - bad content for: " + path);
325
308
  }
326
309
  }
327
310
 
@@ -331,8 +314,8 @@ function load_execute_file(loader, content, path) {
331
314
  @param {String} id The globals id being retrieved.
332
315
  @return {Array} Load paths
333
316
  */
334
- function load_path_getter(id) {
335
- return Rt.A(opal.loader.paths);
317
+ function rb_load_path_getter(id) {
318
+ return Op.loader.paths;
336
319
  }
337
320
 
338
321
  /**
@@ -341,11 +324,7 @@ function load_path_getter(id) {
341
324
  @param {String} id Feature global id
342
325
  @return {Array} Loaded features
343
326
  */
344
- function loaded_feature_getter(id) {
327
+ function rb_loaded_feature_getter(id) {
345
328
  return loaded_features;
346
329
  }
347
330
 
348
- function obj_require(obj, path) {
349
- return Rt.require(path) ? Qtrue : Qfalse;
350
- }
351
-
data/runtime/module.js CHANGED
@@ -2,49 +2,49 @@
2
2
  /**
3
3
  Define a top level module with the given id
4
4
  */
5
- function define_module(id) {
6
- return define_module_under(cObject, id);
5
+ function rb_define_module(id) {
6
+ return rb_define_module_under(rb_cObject, id);
7
7
  };
8
8
 
9
- function define_module_under(base, id) {
9
+ function rb_define_module_under(base, id) {
10
10
  var module;
11
11
 
12
- if (const_defined(base, id)) {
13
- module = const_get(base, id);
14
- if (module.$flags & T_MODULE) {
12
+ if (rb_const_defined(base, id)) {
13
+ module = rb_const_get(base, id);
14
+ if (module.$f & T_MODULE) {
15
15
  return module;
16
16
  }
17
17
 
18
- throw new Error(id + " is not a module.");
18
+ rb_raise(rb_eException, id + " is not a module");
19
19
  }
20
20
 
21
- module = define_module_id(id);
21
+ module = rb_define_module_id(id);
22
22
 
23
- if (base == cObject) {
24
- name_class(module, id);
23
+ if (base == rb_cObject) {
24
+ rb_name_class(module, id);
25
25
  } else {
26
- name_class(module, base.__classid__ + '::' + id);
26
+ rb_name_class(module, base.__classid__ + '::' + id);
27
27
  }
28
28
 
29
- const_set(base, id, module);
29
+ rb_const_set(base, id, module);
30
30
  module.$parent = base;
31
31
  return module;
32
32
  };
33
33
 
34
- function define_module_id(id) {
35
- var module = class_create(cModule);
36
- make_metaclass(module, cModule);
34
+ function rb_define_module_id(id) {
35
+ var module = rb_class_create(rb_cModule);
36
+ rb_make_metaclass(module, rb_cModule);
37
37
 
38
- module.$flags = T_MODULE;
38
+ module.$f = T_MODULE;
39
39
  module.$included_in = [];
40
40
  return module;
41
41
  };
42
42
 
43
- function mod_create() {
44
- return class_boot(cModule);
43
+ function rb_mod_create() {
44
+ return rb_class_boot(rb_cModule);
45
45
  };
46
46
 
47
- function include_module(klass, module) {
47
+ function rb_include_module(klass, module) {
48
48
 
49
49
  if (!klass.$included_modules) {
50
50
  klass.$included_modules = [];
@@ -61,24 +61,21 @@ function include_module(klass, module) {
61
61
 
62
62
  module.$included_in.push(klass);
63
63
 
64
- for (var method in module.$method_table) {
65
- if (module.$method_table.hasOwnProperty(method)) {
66
- define_raw_method(klass, method,
67
- module.$m_tbl[method],
68
- module.$m_tbl['$' + method]);
64
+ for (var method in module.$m) {
65
+ if (hasOwnProperty.call(module.$m, method)) {
66
+ rb_define_raw_method(klass, method,
67
+ module.$a.prototype[method]);
69
68
  }
70
69
  }
71
70
 
72
- for (var constant in module.$c) {
73
- if (module.$c.hasOwnProperty(constant)) {
74
- const_set(klass, constant, module.$c[constant]);
75
- }
76
- }
71
+ // for (var constant in module.$c) {
72
+ // if (hasOwnProperty.call(module.$c, constant)) {
73
+ // const_set(klass, constant, module.$c[constant]);
74
+ // }
75
+ // }
77
76
  };
78
77
 
79
- Rt.include_module = include_module;
80
-
81
- function extend_module(klass, module) {
78
+ function rb_extend_module(klass, module) {
82
79
  if (!klass.$extended_modules) {
83
80
  klass.$extended_modules = [];
84
81
  }
@@ -94,16 +91,13 @@ function extend_module(klass, module) {
94
91
 
95
92
  module.$extended_in.push(klass);
96
93
 
97
- var meta = klass.$klass;
94
+ var meta = klass.$k;
98
95
 
99
- for (var method in module.$method_table) {
100
- if (module.$method_table.hasOwnProperty(method)) {
101
- define_raw_method(meta, method,
102
- module.$m_tbl[method],
103
- module.$m_tbl['$' + method]);
96
+ for (var method in module.o$m) {
97
+ if (hasOwnProperty.call(module.o$m, method)) {
98
+ rb_define_raw_method(meta, method,
99
+ module.o$a.prototype[method]);
104
100
  }
105
101
  }
106
102
  };
107
103
 
108
- Rt.extend_module = extend_module;
109
-
data/runtime/post.js CHANGED
@@ -1,10 +1,10 @@
1
1
 
2
2
  init();
3
3
 
4
- })();
4
+ })(undefined);
5
5
 
6
6
  // if in a commonjs system already (node etc), exports become our opal
7
7
  // object. Otherwise, in the browser, we just get a top level opal var
8
8
  if ((typeof require !== 'undefined') && (typeof module !== 'undefined')) {
9
- module.exports = opal;
9
+ module.exports = opalscript;
10
10
  }
data/runtime/pre.js CHANGED
@@ -1,6 +1,6 @@
1
1
  opal = {};
2
2
 
3
- (function() {
3
+ (function(undefined) {
4
4
 
5
5
  // So we can minimize
6
6
  var Op = opal;
data/runtime/runtime.js CHANGED
@@ -2,56 +2,53 @@
2
2
  All methods and properties available to ruby/js sources at runtime. These
3
3
  are kept in their own namespace to keep the opal namespace clean.
4
4
  */
5
- Op.runtime = {};
5
+ var Rt = Op.runtime = {};
6
6
 
7
- // for minimizng
8
- var Rt = Op.runtime;
9
7
  Rt.opal = Op;
10
8
 
11
9
  /**
12
10
  Opal platform - this is overriden in gem context and nodejs context. These
13
11
  are the default values used in the browser, `opal-browser'.
14
12
  */
15
- Op.platform = {
16
- platform: "opal",
17
- engine: "opal-browser",
18
- version: "1.9.2",
19
- argv: []
20
- };
13
+ var PLATFORM_PLATFORM = "opal";
14
+ var PLATFORM_ENGINE = "opal-browser";
15
+ var PLATFORM_VERSION = "1.9.2";
16
+ var PLATFORM_ARGV = [];
17
+
18
+ // Minimize js types
19
+ var ArrayProto = Array.prototype,
20
+ ObjectProto = Object.prototype,
21
+
22
+ ArraySlice = ArrayProto.slice,
23
+
24
+ hasOwnProperty = ObjectProto.hasOwnProperty;
21
25
 
22
26
  /**
23
27
  Core runtime classes, objects and literals.
24
28
  */
25
- var cBasicObject, cObject, cModule, cClass,
26
- mKernel, cNilClass, cTrueClass, cFalseClass,
27
- cArray,
28
- cRegexp, cMatch, top_self, Qnil,
29
- Qfalse, Qtrue,
29
+ var rb_cBasirb_cObject, rb_cObject, rb_cModule, rb_cClass,
30
+ rb_mKernel, rb_cNilClass, rb_cBoolean,
31
+ rb_cArray, rb_cNumeric,
32
+ rb_cRegexp, rb_cMatch, rb_top_self, Qnil,
30
33
 
31
- cDir;
34
+ rb_cDir;
32
35
 
33
36
  /**
34
37
  Core object type flags. Added as local variables, and onto runtime.
35
38
  */
36
- var T_CLASS = Rt.T_CLASS = 1,
37
- T_MODULE = Rt.T_MODULE = 2,
38
- T_OBJECT = Rt.T_OBJECT = 4,
39
- T_BOOLEAN = Rt.T_BOOLEAN = 8,
40
- T_STRING = Rt.T_STRING = 16,
41
- T_ARRAY = Rt.T_ARRAY = 32,
42
- T_NUMBER = Rt.T_NUMBER = 64,
43
- T_PROC = Rt.T_PROC = 128,
44
- T_SYMBOL = Rt.T_SYMBOL = 256,
45
- T_HASH = Rt.T_HASH = 512,
46
- T_RANGE = Rt.T_RANGE = 1024,
47
- T_ICLASS = Rt.T_ICLASS = 2056,
48
- FL_SINGLETON = Rt.FL_SINGLETON = 4112;
49
-
50
- /**
51
- Method visibility modes
52
- */
53
- var FL_PUBLIC = 0,
54
- FL_PRIVATE = 1;
39
+ var T_CLASS = 1,
40
+ T_MODULE = 2,
41
+ T_OBJECT = 4,
42
+ T_BOOLEAN = 8,
43
+ T_STRING = 16,
44
+ T_ARRAY = 32,
45
+ T_NUMBER = 64,
46
+ T_PROC = 128,
47
+ T_SYMBOL = 256,
48
+ T_HASH = 512,
49
+ T_RANGE = 1024,
50
+ T_ICLASS = 2056,
51
+ FL_SINGLETON = 4112;
55
52
 
56
53
  /**
57
54
  Define classes. This is the public API for defining classes, shift classes
@@ -68,35 +65,32 @@ Rt.dc = function(base, super_class, id, body, flag) {
68
65
 
69
66
  switch (flag) {
70
67
  case 0:
71
- if (base.$flags & T_OBJECT) {
72
- base = class_real(base.$klass);
68
+ if (base.$f & T_OBJECT) {
69
+ base = rb_class_real(base.$k);
73
70
  }
74
71
 
75
72
  if (super_class == Qnil) {
76
- super_class = cObject;
73
+ super_class = rb_cObject;
77
74
  }
78
75
 
79
- klass = define_class_under(base, id, super_class);
76
+ klass = rb_define_class_under(base, id, super_class);
80
77
  break;
81
78
 
82
79
  case 1:
83
- klass = singleton_class(base);
80
+ klass = rb_singleton_class(base);
84
81
  break;
85
82
 
86
83
  case 2:
87
- if (base.$flags & T_OBJECT) {
88
- base = class_real(base.$klass);
84
+ if (base.$f & T_OBJECT) {
85
+ base = rb_class_real(base.$k);
89
86
  }
90
- klass = define_module_under(base, id);
87
+ klass = rb_define_module_under(base, id);
91
88
  break;
92
89
 
93
90
  default:
94
- raise(eException, "define_class got a unknown flag " + flag);
91
+ rb_raise(rb_eException, "define_class got a unknown flag " + flag);
95
92
  }
96
93
 
97
- // when reopening a class always set it back to public
98
- klass.$mode = FL_PUBLIC;
99
-
100
94
  var res = body(klass);
101
95
 
102
96
  return res;
@@ -117,79 +111,38 @@ Rt.um = function(kls) {
117
111
  for (var i = 0, ii = args.length; i < ii; i++) {
118
112
  (function(mid) {
119
113
  var func = function() {
120
- raise(eNoMethodError, "undefined method `" + mid + "' for " + this.m$inspect());
114
+ rb_raise(rb_eNoMethodError, "undefined method `" + mid + "' for " + this.m$inspect());
121
115
  };
122
116
 
123
- kls.allocator.prototype['m$' + mid] = func;
117
+ kls.o$a.prototype['m$' + mid] = func;
124
118
 
125
- if (kls.$bridge_prototype) {
126
- kls.$bridge_prototype['m$' + mid] = func;
127
- }
128
119
  })(args[i].m$to_s());
129
120
  }
130
121
 
131
122
  return Qnil;
132
123
  };
133
124
 
134
- /**
135
- Method missing support - used in debug mode (opt in).
136
- */
137
- Rt.mm = function(method_ids) {
138
- var prototype = cBasicObject.$m_tbl;
139
-
140
- for (var i = 0, ii = method_ids.length; i < ii; i++) {
141
- var mid = method_ids[i];
142
-
143
- if (!prototype[mid]) {
144
- var imp = (function(mid, method_id) {
145
- return function(self) {
146
- var args = [].slice.call(arguments, 0);
147
- args.unshift(intern(method_id));
148
- args.unshift(self);
149
- return self.$m.method_missing.apply(null, args);
150
- };
151
- })(mid, method_ids[i]);
152
-
153
- imp.$rbMM = true;
154
-
155
- prototype[mid] = prototype['$' + mid] = imp;
156
- }
157
- }
158
- };
159
-
160
125
  /**
161
126
  Define methods. Public method for defining a method on the given base.
162
127
 
163
128
  @param {Object} klass The base to define method on
164
129
  @param {String} name Ruby mid
165
- @param {Function} public_body The method implementation
130
+ @param {Function} body The method implementation
166
131
  @param {Number} arity Method arity
167
132
  @return {Qnil}
168
133
  */
169
- Rt.dm = function(klass, name, public_body, arity) {
170
- if (klass.$flags & T_OBJECT) {
171
- klass = klass.$klass;
134
+ Rt.dm = function(klass, name, body, arity) {
135
+ if (klass.$f & T_OBJECT) {
136
+ klass = klass.$k;
172
137
  }
173
138
 
174
- var mode = klass.$mode;
175
- var private_body = public_body;
176
-
177
- if (mode == FL_PRIVATE) {
178
- public_body = function() {
179
- raise(eNoMethodError, "private method `" + name +
180
- "' called for " + this.$m$inspect());
181
- };
182
- public_body.$arity = -1;
139
+ if (!body.$rbName) {
140
+ body.$rbName = name;
141
+ body.$arity = arity;
183
142
  }
184
143
 
185
- if (!private_body.$rbName) {
186
- private_body.$rbName = name;
187
- private_body.$rbArity = arity;
188
- }
189
-
190
- // FIXME: add to private/public methods
191
- // klass.$methods.push(intern(name));
192
- define_raw_method(klass, name, private_body, public_body);
144
+ rb_define_raw_method(klass, 'm$' + name, body);
145
+ klass.$methods.push(name);
193
146
 
194
147
  return Qnil;
195
148
  };
@@ -204,7 +157,7 @@ Rt.dm = function(klass, name, public_body, arity) {
204
157
  @return {Qnil}
205
158
  */
206
159
  Rt.ds = function(base, method_id, body, arity) {
207
- return Rt.dm(singleton_class(base), method_id, body);
160
+ return Rt.dm(rb_singleton_class(base), method_id, body);
208
161
  };
209
162
 
210
163
  /**
@@ -215,44 +168,45 @@ Rt.ds = function(base, method_id, body, arity) {
215
168
  This is actually done in super_find.
216
169
  */
217
170
  Rt.S = function(callee, self, args) {
218
- var mid = callee.$rbName;
219
- var func = super_find(self.$klass, callee, mid);
171
+ var mid = 'm$' + callee.$rbName;
172
+ var func = rb_super_find(self.$k, callee, mid);
220
173
 
221
174
  if (!func) {
222
- raise(eNoMethodError, "super: no super class method `" + mid + "`" +
175
+ rb_raise(rb_eNoMethodError, "super: no super class method `" + mid + "`" +
223
176
  " for " + self.m$inspect());
224
177
  }
225
178
 
226
- var args_to_send = [self].concat(args);
179
+ // var args_to_send = [self].concat(args);
180
+ var args_to_send = [].concat(args);
227
181
  return func.apply(self, args_to_send);
228
182
  };
229
183
 
230
184
  /**
231
185
  Actually find super impl to call. Returns null if cannot find it.
232
186
  */
233
- function super_find(klass, callee, mid) {
187
+ function rb_super_find(klass, callee, mid) {
234
188
  var cur_method;
235
189
 
236
190
  while (klass) {
237
- if (klass.$m_tbl[mid]) {
238
- if (klass.$m_tbl[mid] == callee) {
239
- cur_method = klass.$m_tbl[mid];
191
+ if (klass.$m[mid]) {
192
+ if (klass.$m[mid] == callee) {
193
+ cur_method = klass.$m[mid];
240
194
  break;
241
195
  }
242
196
  }
243
- klass = klass.$super;
197
+ klass = klass.$s;
244
198
  }
245
199
 
246
200
  if (!(klass && cur_method)) { return null; }
247
201
 
248
- klass = klass.$super;
202
+ klass = klass.$s;
249
203
 
250
204
  while (klass) {
251
- if (klass.$m_tbl[mid]) {
252
- return klass.$m_tbl[mid];
205
+ if (klass.$m[mid]) {
206
+ return klass.$m[mid];
253
207
  }
254
208
 
255
- klass = klass.$super;
209
+ klass = klass.$s;
256
210
  }
257
211
 
258
212
  return null;
@@ -262,19 +216,19 @@ function super_find(klass, callee, mid) {
262
216
  Exception classes. Some of these are used by runtime so they are here for
263
217
  convenience.
264
218
  */
265
- var eException, eStandardError, eLocalJumpError, eNameError,
266
- eNoMethodError, eArgError, eScriptError, eLoadError,
267
- eRuntimeError, eTypeError, eIndexError, eKeyError,
268
- eRangeError;
219
+ var rb_eException, rb_eStandardError, rb_eLocalJumpError, rb_eNameError,
220
+ rb_eNoMethodError, rb_eArgError, rb_eScriptError, rb_eLoadError,
221
+ rb_eRuntimeError, rb_eTypeError, rb_eIndexError, rb_eKeyError,
222
+ rb_eRangeError;
269
223
 
270
- var eExceptionInstance;
224
+ var rb_eExceptionInstance;
271
225
 
272
226
  /**
273
227
  Standard jump exceptions to save re-creating them everytime they are needed
274
228
  */
275
- var eReturnInstance,
276
- eBreakInstance,
277
- eNextInstance;
229
+ var rb_eReturnInstance,
230
+ rb_eBreakInstance,
231
+ rb_eNextInstance;
278
232
 
279
233
  /**
280
234
  Ruby break statement with the given value. When no break value is needed, nil
@@ -284,8 +238,8 @@ var eReturnInstance,
284
238
  @param {RubyObject} value The break value.
285
239
  */
286
240
  Rt.B = function(value) {
287
- eBreakInstance.$value = value;
288
- raise_exc(eBreakInstance);
241
+ rb_eBreakInstance.$value = value;
242
+ rb_raise_exc(rb_eBreakInstance);
289
243
  };
290
244
 
291
245
  /**
@@ -293,53 +247,70 @@ Rt.B = function(value) {
293
247
  represents the method that this statement must return from.
294
248
  */
295
249
  Rt.R = function(value, func) {
296
- eReturnInstance.$value = value;
297
- eReturnInstance.$func = func;
298
- throw eReturnInstance;
250
+ rb_eReturnInstance.$value = value;
251
+ rb_eReturnInstance.$func = func;
252
+ throw rb_eReturnInstance;
299
253
  };
300
254
 
301
255
  /**
302
256
  Get the given constant name from the given base
303
257
  */
304
258
  Rt.cg = function(base, id) {
305
- if (base.$flags & T_OBJECT) {
306
- base = class_real(base.$klass);
259
+ if (base.$f & T_OBJECT) {
260
+ base = rb_class_real(base.$k);
307
261
  }
308
- return const_get(base, id);
262
+ return rb_const_get(base, id);
309
263
  };
310
264
 
311
265
  /**
312
266
  Set constant from runtime
313
267
  */
314
268
  Rt.cs = function(base, id, val) {
315
- if (base.$flags & T_OBJECT) {
316
- base = class_real(base.$klass);
269
+ if (base.$f & T_OBJECT) {
270
+ base = rb_class_real(base.$k);
317
271
  }
318
- return const_set(base, id, val);
272
+ return rb_const_set(base, id, val);
319
273
  };
320
274
 
321
275
  /**
322
276
  Get global by id
323
277
  */
324
278
  Rt.gg = function(id) {
325
- return gvar_get(id);
279
+ return rb_gvar_get(id);
326
280
  };
327
281
 
328
282
  /**
329
283
  Set global by id
330
284
  */
331
285
  Rt.gs = function(id, value) {
332
- return gvar_set(id, value);
286
+ return rb_gvar_set(id, value);
287
+ };
288
+
289
+ /**
290
+ Class variables table
291
+ */
292
+ var rb_class_variables = {};
293
+
294
+ Rt.cvg = function(id) {
295
+ var v = rb_class_variables[id];
296
+
297
+ if (v) return v;
298
+
299
+ return Qnil;
300
+ };
301
+
302
+ Rt.cvs = function(id, val) {
303
+ return rb_class_variables[id] = val;
333
304
  };
334
305
 
335
- function regexp_match_getter(id) {
306
+ function rb_regexp_match_getter(id) {
336
307
  var matched = Rt.X;
337
308
 
338
309
  if (matched) {
339
310
  if (matched.$md) {
340
311
  return matched.$md;
341
312
  } else {
342
- var res = new cMatch.allocator();
313
+ var res = new cMatch.o$a();
343
314
  res.$data = matched;
344
315
  matched.$md = res;
345
316
  return res;
@@ -349,3 +320,26 @@ function regexp_match_getter(id) {
349
320
  }
350
321
  }
351
322
 
323
+ /**
324
+ An array of procs to call for at_exit()
325
+
326
+ @param {Function} proc implementation
327
+ */
328
+ var rb_end_procs = [];
329
+
330
+ /**
331
+ Called upon exit: we need to run all of our registered procs
332
+ in reverse order: i.e. call last ones first.
333
+
334
+ FIXME: do we need to try/catch this??
335
+ */
336
+ Rt.do_at_exit = function() {
337
+ var proc;
338
+
339
+ while (proc = rb_end_procs.pop()) {
340
+ proc.call(proc.$self);
341
+ }
342
+
343
+ return null;
344
+ };
345
+