opal 0.3.6 → 0.3.9

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