opal 0.3.2 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (203) hide show
  1. data/README.md +85 -127
  2. data/bin/opal +3 -3
  3. data/lib/core.rb +114 -0
  4. data/{gems/core/lib → lib}/core/array.rb +68 -187
  5. data/{gems/core/lib → lib}/core/basic_object.rb +22 -5
  6. data/lib/core/class.rb +38 -0
  7. data/{gems/core/lib → lib}/core/dir.rb +1 -1
  8. data/lib/core/enumerable.rb +33 -0
  9. data/{gems/core/lib → lib}/core/error.rb +1 -4
  10. data/{gems/core/lib → lib}/core/false_class.rb +0 -0
  11. data/{gems/core/lib → lib}/core/file.rb +11 -3
  12. data/{gems/core/lib → lib}/core/hash.rb +12 -0
  13. data/{gems/core/lib → lib}/core/kernel.rb +114 -86
  14. data/lib/core/match_data.rb +33 -0
  15. data/lib/core/module.rb +97 -0
  16. data/{gems/core/lib → lib}/core/nil_class.rb +0 -0
  17. data/{gems/core/lib → lib}/core/numeric.rb +5 -0
  18. data/{gems/core/lib → lib}/core/object.rb +0 -0
  19. data/{gems/core/lib → lib}/core/proc.rb +13 -3
  20. data/{gems/core/lib → lib}/core/range.rb +10 -0
  21. data/{gems/core/lib → lib}/core/regexp.rb +33 -1
  22. data/{gems/core/lib → lib}/core/string.rb +25 -10
  23. data/{gems/core/lib → lib}/core/symbol.rb +3 -3
  24. data/{gems/core/lib → lib}/core/top_self.rb +0 -0
  25. data/{gems/core/lib → lib}/core/true_class.rb +0 -0
  26. data/lib/dev.rb +169 -0
  27. data/{gems/ospec/lib → lib}/ospec.rb +1 -0
  28. data/lib/ospec/autorun.rb +8 -0
  29. data/{gems/ospec/lib → lib}/ospec/dsl.rb +2 -2
  30. data/{gems/ospec/lib → lib}/ospec/example.rb +0 -0
  31. data/{gems/ospec/lib → lib}/ospec/example/before_and_after_hooks.rb +0 -0
  32. data/{gems/ospec/lib → lib}/ospec/example/errors.rb +0 -0
  33. data/{gems/ospec/lib → lib}/ospec/example/example_group.rb +0 -0
  34. data/{gems/ospec/lib → lib}/ospec/example/example_group_factory.rb +0 -3
  35. data/{gems/ospec/lib → lib}/ospec/example/example_group_hierarchy.rb +4 -3
  36. data/{gems/ospec/lib → lib}/ospec/example/example_group_methods.rb +1 -1
  37. data/{gems/ospec/lib → lib}/ospec/example/example_group_proxy.rb +3 -2
  38. data/{gems/ospec/lib → lib}/ospec/example/example_methods.rb +1 -1
  39. data/{gems/ospec/lib → lib}/ospec/example/example_proxy.rb +7 -7
  40. data/{gems/ospec/lib → lib}/ospec/expectations.rb +0 -0
  41. data/{gems/ospec/lib → lib}/ospec/expectations/errors.rb +0 -0
  42. data/{gems/ospec/lib → lib}/ospec/expectations/fail_with.rb +4 -3
  43. data/{gems/ospec/lib → lib}/ospec/expectations/handler.rb +6 -0
  44. data/lib/ospec/helpers/scratch.rb +18 -0
  45. data/{gems/ospec/lib → lib}/ospec/matchers.rb +2 -2
  46. data/{gems/ospec/lib → lib}/ospec/matchers/be.rb +0 -0
  47. data/{gems/ospec/lib → lib}/ospec/matchers/generated_descriptions.rb +0 -0
  48. data/{gems/ospec/lib → lib}/ospec/matchers/operator_matcher.rb +2 -0
  49. data/lib/ospec/matchers/raise_error.rb +38 -0
  50. data/lib/ospec/runner.rb +90 -0
  51. data/{gems/ospec/lib → lib}/ospec/runner/example_group_runner.rb +10 -13
  52. data/lib/ospec/runner/formatter/html_formatter.rb +139 -0
  53. data/{gems/ospec/lib → lib}/ospec/runner/formatter/terminal_formatter.rb +0 -0
  54. data/{gems/ospec/lib → lib}/ospec/runner/options.rb +1 -3
  55. data/{gems/ospec/lib → lib}/ospec/runner/reporter.rb +0 -9
  56. data/lib/racc/parser.rb +165 -0
  57. data/lib/strscan.rb +52 -0
  58. data/{lib → opal_lib}/opal.rb +2 -0
  59. data/opal_lib/opal/build_methods.rb +51 -0
  60. data/opal_lib/opal/builder.rb +164 -0
  61. data/opal_lib/opal/bundle.rb +70 -0
  62. data/opal_lib/opal/command.rb +68 -0
  63. data/{lib → opal_lib}/opal/context.rb +21 -9
  64. data/{lib → opal_lib}/opal/context/console.rb +0 -2
  65. data/opal_lib/opal/context/file_system.rb +34 -0
  66. data/{lib → opal_lib}/opal/context/loader.rb +26 -8
  67. data/opal_lib/opal/gem.rb +84 -0
  68. data/{lib → opal_lib}/opal/rake/builder_task.rb +2 -2
  69. data/opal_lib/opal/rake/spec_task.rb +32 -0
  70. data/{lib → opal_lib}/opal/ruby/nodes.rb +730 -109
  71. data/{lib → opal_lib}/opal/ruby/parser.rb +90 -23
  72. data/opal_lib/opal/ruby/ruby_parser.rb +4862 -0
  73. data/opal_lib/opal/ruby/ruby_parser.y +1454 -0
  74. data/opal_lib/opal/version.rb +4 -0
  75. data/runtime/class.js +359 -0
  76. data/runtime/debug.js +84 -0
  77. data/runtime/fs.js +199 -0
  78. data/runtime/init.js +558 -0
  79. data/runtime/loader.js +351 -0
  80. data/runtime/module.js +109 -0
  81. data/runtime/post.js +10 -0
  82. data/runtime/pre.js +7 -0
  83. data/runtime/runtime.js +351 -0
  84. metadata +88 -175
  85. data/.gitignore +0 -7
  86. data/Changelog +0 -31
  87. data/LICENSE +0 -75
  88. data/Rakefile +0 -86
  89. data/gems/core/README.md +0 -14
  90. data/gems/core/Rakefile +0 -8
  91. data/gems/core/core.gemspec +0 -13
  92. data/gems/core/lib/core.rb +0 -34
  93. data/gems/core/lib/core/class.rb +0 -31
  94. data/gems/core/lib/core/module.rb +0 -100
  95. data/gems/core/lib/core/vm.rb +0 -16
  96. data/gems/core/spec/core/array/append_spec.rb +0 -30
  97. data/gems/core/spec/core/array/assoc_spec.rb +0 -29
  98. data/gems/core/spec/core/array/at_spec.rb +0 -37
  99. data/gems/core/spec/core/array/clear_spec.rb +0 -22
  100. data/gems/core/spec/core/array/collect_bang_spec.rb +0 -27
  101. data/gems/core/spec/core/array/collect_spec.rb +0 -27
  102. data/gems/core/spec/core/array/compact_spec.rb +0 -41
  103. data/gems/core/spec/core/array/concat_spec.rb +0 -15
  104. data/gems/core/spec/core/array/constructor_spec.rb +0 -14
  105. data/gems/core/spec/core/array/each_spec.rb +0 -9
  106. data/gems/core/spec/core/array/element_reference_spec.rb +0 -4
  107. data/gems/core/spec/core/array/first_spec.rb +0 -35
  108. data/gems/core/spec/core/array/include_spec.rb +0 -9
  109. data/gems/core/spec/core/array/join_spec.rb +0 -6
  110. data/gems/core/spec/core/array/last_spec.rb +0 -51
  111. data/gems/core/spec/core/array/length_spec.rb +0 -6
  112. data/gems/core/spec/core/array/map_spec.rb +0 -33
  113. data/gems/core/spec/core/array/reverse_spec.rb +0 -6
  114. data/gems/core/spec/core/builtin_constants/builtin_constants_spec.rb +0 -7
  115. data/gems/core/spec/core/false/and_spec.rb +0 -10
  116. data/gems/core/spec/core/false/inspect_spec.rb +0 -6
  117. data/gems/core/spec/core/false/or_spec.rb +0 -10
  118. data/gems/core/spec/core/false/to_s_spec.rb +0 -6
  119. data/gems/core/spec/core/false/xor_spec.rb +0 -10
  120. data/gems/core/spec/core/file/join_spec.rb +0 -19
  121. data/gems/core/spec/core/hash/assoc_spec.rb +0 -32
  122. data/gems/core/spec/core/kernel/instance_eval_spec.rb +0 -0
  123. data/gems/core/spec/core/kernel/loop_spec.rb +0 -24
  124. data/gems/core/spec/core/kernel/raise_spec.rb +0 -0
  125. data/gems/core/spec/core/module/attr_accessor_spec.rb +0 -28
  126. data/gems/core/spec/core/number/lt_spec.rb +0 -12
  127. data/gems/core/spec/core/string/sub_spec.rb +0 -24
  128. data/gems/core/spec/core/true/and_spec.rb +0 -10
  129. data/gems/core/spec/core/true/inspect_spec.rb +0 -6
  130. data/gems/core/spec/core/true/or_spec.rb +0 -10
  131. data/gems/core/spec/core/true/to_s_spec.rb +0 -6
  132. data/gems/core/spec/core/true/xor_spec.rb +0 -10
  133. data/gems/core/spec/language/and_spec.rb +0 -61
  134. data/gems/core/spec/language/array_spec.rb +0 -68
  135. data/gems/core/spec/language/block_spec.rb +0 -38
  136. data/gems/core/spec/language/break_spec.rb +0 -36
  137. data/gems/core/spec/language/case_spec.rb +0 -103
  138. data/gems/core/spec/language/def_spec.rb +0 -21
  139. data/gems/core/spec/language/eigenclass_spec.rb +0 -60
  140. data/gems/core/spec/language/file_spec.rb +0 -13
  141. data/gems/core/spec/language/fixtures/block.rb +0 -21
  142. data/gems/core/spec/language/fixtures/super.rb +0 -293
  143. data/gems/core/spec/language/hash_spec.rb +0 -29
  144. data/gems/core/spec/language/if_spec.rb +0 -54
  145. data/gems/core/spec/language/loop_spec.rb +0 -11
  146. data/gems/core/spec/language/metaclass_spec.rb +0 -21
  147. data/gems/core/spec/language/method_spec.rb +0 -124
  148. data/gems/core/spec/language/next_spec.rb +0 -25
  149. data/gems/core/spec/language/or_spec.rb +0 -34
  150. data/gems/core/spec/language/redo_spec.rb +0 -24
  151. data/gems/core/spec/language/regexp_spec.rb +0 -26
  152. data/gems/core/spec/language/rescue_spec.rb +0 -20
  153. data/gems/core/spec/language/return_spec.rb +0 -47
  154. data/gems/core/spec/language/string_spec.rb +0 -25
  155. data/gems/core/spec/language/super_spec.rb +0 -32
  156. data/gems/core/spec/language/until_spec.rb +0 -157
  157. data/gems/core/spec/language/variables_spec.rb +0 -155
  158. data/gems/core/spec/language/while_spec.rb +0 -163
  159. data/gems/core/spec/spec_helper.rb +0 -5
  160. data/gems/core_fs/README.md +0 -19
  161. data/gems/dev/Rakefile +0 -5
  162. data/gems/dev/lib/dev.js +0 -99
  163. data/gems/dev/lib/dev/generator.js +0 -1264
  164. data/gems/dev/lib/dev/parser.js +0 -979
  165. data/gems/dev/lib/dev/ruby_parser.js +0 -1088
  166. data/gems/dev/lib/dev/ruby_parser.y +0 -1267
  167. data/gems/dev/lib/dev/string_scanner.js +0 -38
  168. data/gems/dev/tools/racc2js/README.md +0 -39
  169. data/gems/dev/tools/racc2js/math_parser.js +0 -222
  170. data/gems/dev/tools/racc2js/math_parser.rb +0 -133
  171. data/gems/dev/tools/racc2js/math_parser.y +0 -28
  172. data/gems/dev/tools/racc2js/parser.js +0 -218
  173. data/gems/dev/tools/racc2js/racc2js.rb +0 -153
  174. data/gems/json/README.md +0 -4
  175. data/gems/json/json.gemspec +0 -14
  176. data/gems/json/lib/json.rb +0 -64
  177. data/gems/json/lib/json/ext.rb +0 -51
  178. data/gems/json/lib/json/json2.js +0 -481
  179. data/gems/ospec/README.md +0 -0
  180. data/gems/ospec/lib/ospec/autorun.rb +0 -3
  181. data/gems/ospec/lib/ospec/runner.rb +0 -40
  182. data/gems/ospec/lib/ospec/runner/formatter/html_formatter.rb +0 -91
  183. data/gems/ospec/ospec.gemspec +0 -0
  184. data/gems/rquery/README.md +0 -9
  185. data/gems/rquery/lib/rquery.rb +0 -10
  186. data/gems/rquery/lib/rquery/ajax.rb +0 -4
  187. data/gems/rquery/lib/rquery/css.rb +0 -96
  188. data/gems/rquery/lib/rquery/document.rb +0 -25
  189. data/gems/rquery/lib/rquery/element.rb +0 -292
  190. data/gems/rquery/lib/rquery/event.rb +0 -108
  191. data/gems/rquery/lib/rquery/jquery.js +0 -8177
  192. data/gems/rquery/lib/rquery/request.rb +0 -138
  193. data/gems/rquery/lib/rquery/response.rb +0 -49
  194. data/gems/rquery/rquery.gemspec +0 -16
  195. data/lib/opal.js +0 -1597
  196. data/lib/opal/builder.rb +0 -117
  197. data/lib/opal/bundle.rb +0 -131
  198. data/lib/opal/command.rb +0 -11
  199. data/lib/opal/context/file_system.rb +0 -19
  200. data/lib/opal/gem.rb +0 -153
  201. data/lib/opal/ruby/ruby_parser.rb +0 -5170
  202. data/lib/opal/ruby/ruby_parser.y +0 -1298
  203. data/opal.gemspec +0 -15
@@ -1,138 +0,0 @@
1
- # The Request class wraps the native XMLHttpRequest object in the
2
- # browser and makes use of jQuery's ajax facilities to make requests.
3
- class Request
4
-
5
- # Default options used by all Requests. Unless an option here is
6
- # overrideen, then these defaults will be used on each request. This
7
- # is not a full list of all options that can be used; these are just
8
- # the bare essentials and useful defaults.
9
- DEFAULT_OPTIONS = {
10
- :url => '',
11
- :type => 'GET'
12
- }
13
-
14
- # Creates a new Request object. The passed options are merged with
15
- # DEFAULT_OPTIONS and will be used as the base options for each
16
- # request. Request specific options may be passed to {#send}, and
17
- # these will be used in preference to the options passed here.
18
- #
19
- # Most of the options that can be set also have their own designated
20
- # getters and setters as instance methods on this class. This allows
21
- # for options to be set in a more independant manner instead of
22
- # collecting all options into the initialization hash.
23
- #
24
- # @param [Hash] options request options
25
- # @return [Request] returns new request instance
26
- def initialize(options = {})
27
- @options = DEFAULT_OPTIONS.merge options
28
- @complete_action = nil
29
- @failure_action = nil
30
- @success_action = nil
31
- end
32
-
33
- # Creates attribute reader and writers for the given options that will
34
- # set/retrieve the values from the options hash belonging to this
35
- # instance. Each of these options may also be overriden by the final
36
- # values sent to {#send}, or one of its aliases: {#get}, {#post},
37
- # {#put} or {#delete}.
38
- #
39
- # @param [String, Symbol] names option names to set
40
- def self.option_accessor(*names)
41
- names.each do |name|
42
- # define option getter
43
- define_method(name) { @options[name] }
44
- # define option setter
45
- define_method("#{name}=") { |value| @options[name] = value }
46
- end
47
- end
48
-
49
- # By default all requests will be sent async, to avoid locking up the
50
- # browser. Set this to `false` to send requests in a sync fashion.
51
- # This defaults to `true` to send by async by default.
52
- option_accessor :async
53
-
54
- # Gets the type of the request, which is "GET" by default. This value
55
- # may be "GET" or "POST", as they are well supported by the browser,
56
- # but "PUT" and "DELETE" may also be used, but they are not supported
57
- # within the browser.
58
- option_accessor :type
59
-
60
- # Holds the string representing the URL to which the request is sent.
61
- # By default this is an empty string, so it needs to be set to get any
62
- # useful requests back.
63
- option_accessor :url
64
-
65
- # Sets the username to use when accessing the HTTP authentication
66
- # requests.
67
- option_accessor :username
68
-
69
- # Sets the relevant password used in the HTTP authentication requests.
70
- option_accessor :password
71
-
72
- # Sends the request with the specified options. These options are
73
- # merged with the options given to {#initialize}. There are also
74
- # aliases for this method for automatically setting the request
75
- # type; {#put}, {#post}, {#get} and {#delete} will automatically
76
- # set the correct request type to avoid the need to set it in the
77
- # options.
78
- #
79
- # @param [Hash] options the request options
80
- # @return [Request] returns the receiver
81
- def send(options = {})
82
- `options = #{@options.merge options};
83
-
84
- // native options object
85
- var opts = {};
86
-
87
- // we must have a url
88
- opts.url = #{options[:url]}
89
-
90
- // request type
91
- opts.type = #{options[:type]}
92
-
93
- // success callback
94
- if (#{@success_action} != nil) {
95
- opts.success = function(data, textStatus, jqXHR) {
96
- var response = #{Response.new `jqXHR`};
97
- #{@success_action.call `response`};
98
- };
99
- }
100
-
101
- $.ajax(opts);
102
-
103
- return self;`
104
- end
105
-
106
- def get(options = {})
107
- options[:type] = 'GET'
108
- send options
109
- end
110
-
111
- def post(options = {})
112
- options[:type] = 'POST'
113
- send options
114
- end
115
-
116
- def put(options = {})
117
- options[:type] = 'PUT'
118
- send options
119
- end
120
-
121
- def delete(options = {})
122
- options[:type] = 'DELETE'
123
- send options
124
- end
125
-
126
- # Register a block that will be called if the request succeeds.
127
- def success(&block)
128
- @success_action = block
129
- end
130
-
131
- # Register a block that will be called if the request fails
132
-
133
- def failure(&block)
134
- @failure_action = block
135
- end
136
- end
137
-
138
-
@@ -1,49 +0,0 @@
1
- # Instances of Response are automatically created by Request, so you do
2
- # not need to make them yourself. This is the object that will be passed
3
- # to each of the callbacks for a Request object. For this reason, this
4
- # object will be created if the request succeeds, or indeed fails.
5
- class Response
6
- # Private initializer. This handles a native jquery requets object, so
7
- # this should all probably be private.
8
- def initialize(request)
9
- `self.$xhr = request`
10
- end
11
-
12
- # Returns the numeric status code for the response.
13
- #
14
- # @return [Numeric]
15
- def status
16
- `return self.$xhr.status;`
17
- end
18
-
19
- # Returns the string status message for the response.
20
- #
21
- # @return [String]
22
- def status_text
23
- `return self.$xhr.statusText;`
24
- end
25
-
26
- # Returns the response text from the request.
27
- #
28
- # @return [String]
29
- def text
30
- `return self.$xhr.responseText;`
31
- end
32
-
33
- # Returns `true` if the response represents a successfull request,
34
- # `false` otherwise.
35
- #
36
- # @return [true, false]
37
- def success?
38
- `return (self.$xhr.status >= 200 && self.$xhr.status < 300) ? Qtrue : Qfalse;`
39
- end
40
-
41
- # Returns `false` if the response was the result of an unsuccessful
42
- # request, `true` otherwise.
43
- #
44
- # @return [true, false]
45
- def failure?
46
- !success?
47
- end
48
- end
49
-
@@ -1,16 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- Gem::Specification.new do |s|
4
- s.name = "rquery"
5
- s.version = "0.0.1"
6
- s.authors = ["Adam Beynon"]
7
- s.email = ["adam@adambeynon.com"]
8
- s.homepage = "http://github.com/adambeynon/opal"
9
- s.summary = "Rquery DOM library for ruby/opal"
10
-
11
- s.files = Dir.glob("{bin,lib}/**/*") + %w[README.md]
12
- s.require_path = "lib"
13
-
14
- s.add_dependency "json"
15
- end
16
-
data/lib/opal.js DELETED
@@ -1,1597 +0,0 @@
1
- /**
2
- Incase we are in browser, wrap body to avoid global vars. Just opal can become
3
- a top level var. We treat opal as our exports in nodejs, as we reassign them
4
- at the bottom of this file.
5
- */
6
- var opal = {};
7
-
8
- (function() {
9
-
10
- // So we can minimize
11
- var Op = opal;
12
-
13
- /**
14
- Core runtime classes, objects and literals.
15
- */
16
- var cBasicObject, cObject, cModule, cClass,
17
- mKernel, cNilClass, cTrueClass, cFalseClass,
18
- cFile, cProc, cNumeric, cArray,
19
- cHash, cString, cSymbol, cRange,
20
- cRegexp, cMatch, Qself, Qnil,
21
- Qfalse, Qtrue;
22
-
23
- /**
24
- Exception classes. Some of these are used by runtime so they are here for
25
- convenience.
26
- */
27
- var eException, eStandardError, eLocalJumpError, eNameError,
28
- eNoMethodError, eArgError, eScriptError, eLoadError,
29
- eRuntimeError, eTypeError, eIndexError, eKeyError,
30
- eRangeError;
31
-
32
- /**
33
- Standard jump exceptions to save re-creating them everytime they are needed
34
- */
35
- var rb_vm_return_instance,
36
- rb_vm_loop_return_instance,
37
- rb_vm_next_instance,
38
- rb_vm_break_instance;
39
-
40
- // ..........................................................
41
- // VIRTUAL MACHINE
42
- //
43
-
44
- /**
45
- This is the VM param that gets given to all files in opal. This contains
46
- just the VM methods for opal, to keep the global opal namespace cleaner as
47
- it is used just for external access.
48
- */
49
- Op.vm = {};
50
-
51
- // for minimizng
52
- var Vm = Op.vm;
53
- Vm.opal = Op;
54
-
55
- /**
56
- Core object type flags. Added as local variables, and onto Opal prototype.
57
- */
58
- var T_CLASS = Vm.T_CLASS = 1,
59
- T_MODULE = Vm.T_MODULE = 2,
60
- T_OBJECT = Vm.T_OBJECT = 4,
61
- T_BOOLEAN = Vm.T_BOOLEAN = 8,
62
- T_STRING = Vm.T_STRING = 16,
63
- T_ARRAY = Vm.T_ARRAY = 32,
64
- T_NUMBER = Vm.T_NUMBER = 64,
65
- T_PROC = Vm.T_PROC = 128,
66
- T_SYMBOL = Vm.T_SYMBOL = 256,
67
- T_HASH = Vm.T_HASH = 512,
68
- T_RANGE = Vm.T_RANGE = 1024,
69
- T_ICLASS = Vm.T_ICLASS = 2056,
70
- FL_SINGLETON = Vm.FL_SINGLETON = 4112;
71
-
72
- /**
73
- For setting up method_missing methods. Each ruby file that has been compiled
74
- with call this method with an array of all method_ids that it makes use of.
75
- These only need to be from method calls. This allows us to make sure this
76
- method exists on the base prototype, and is set to simply call method_missing
77
- for the receiver. This adds overhead to the beginning of each file being
78
- loaded, but is more more efficient than having to check for method_missing on
79
- every method call in the file for the entirety of its lifetime.
80
-
81
- @param {Array<String>} method_ids An array of method_ids to register
82
- */
83
- Vm.mm = function(method_ids) {
84
- var prototype = cBasicObject.$m_prototype_tbl;
85
-
86
- for (var i = 0, ii = method_ids.length; i < ii; i++) {
87
- var method_id = method_ids[i];
88
- // only add fake method if not already defined
89
- if (!prototype.hasOwnProperty(method_id)) {
90
- // our fake method implementation
91
- var imp = (function(method_id) {
92
- return function(self) {
93
- var args = [].slice.call(arguments, 1);
94
- args.unshift(Vm.Y(method_id));
95
- args.unshift(self);
96
- return self.$m.method_missing.apply(null, args);
97
- };
98
- })(method_id);
99
- // mark as a fake method to help respond_to? and send, etc.
100
- imp.$rbMM = true;
101
- prototype[method_id] = imp;
102
- }
103
- }
104
- };
105
-
106
- /**
107
- Define methods. Public method for defining a method on the given base.
108
-
109
- @param {RObject} base The base to define method on
110
- @param {String} method_id Ruby mid
111
- @param {Function} body The method implementation
112
- @param {Boolean} singleton Singleton or Normal method. true for singleton
113
- */
114
-
115
- Vm.dm = function(base, method_id, body, singleton) {
116
- if (singleton) {
117
- define_singleton_method(base, method_id, body);
118
- } else {
119
- // should this instead do a rb_singleton_method?? probably..
120
- if (base.$flags & T_OBJECT) {
121
- base = base.$klass;
122
- }
123
-
124
- define_method(base, method_id, body);
125
- }
126
-
127
- return Qnil;
128
- };
129
-
130
- /**
131
- Define classes. This is the public API for defining classes, shit classes
132
- and modules.
133
-
134
- @param {RObject} base
135
- @param {RClass} super_class
136
- @param {String} id
137
- @param {Function} body
138
- @param {Number} flag
139
- */
140
- Vm.dc = function(base, super_class, id, body, flag) {
141
- var klass;
142
-
143
- switch (flag) {
144
- case 0:
145
- if (base.$flags & T_OBJECT) {
146
- base = class_real(base.$klass);
147
- }
148
-
149
- if (super_class == Qnil) {
150
- super_class = cObject;
151
- }
152
-
153
- klass = define_class_under(base, id, super_class);
154
- break;
155
-
156
- case 1:
157
- klass = singleton_class(base);
158
- break;
159
-
160
- case 2:
161
- if (base.$flags & T_OBJECT) {
162
- base = class_real(base.$klass);
163
- }
164
- klass = define_module_under(base, id);
165
- break;
166
-
167
- default:
168
- raise(eException, "define_class got a unknown flag " + flag);
169
- }
170
-
171
- return body.call(klass);
172
- };
173
-
174
- /**
175
- Returns a new RHash instance constructed from the given arguments of
176
- alternate key, value pairs.
177
- */
178
- Vm.H = function() {
179
- return new RHash(Array.prototype.slice.call(arguments));
180
- };
181
-
182
- /**
183
- Returns a new ruby symbol with the given intern value. Symbols are made
184
- using the new String() constructor, and just have its klass and method
185
- table reassigned. This makes dealing with strings/symbols internally
186
- easier as both can be used as a string within opal.
187
-
188
- @param {String} intern Symbol value
189
- @return {RSymbol} symbol
190
- */
191
- Vm.Y = function(intern) {
192
- if (symbol_table.hasOwnProperty(intern)) {
193
- return symbol_table[intern];
194
- }
195
-
196
- var res = new String(intern);
197
- res.$klass = cSymbol;
198
- res.$m = cSymbol.$m_tbl;
199
- symbol_table[intern] = res;
200
- return res;
201
- };
202
-
203
- /**
204
- Returns a new ruby range. 'G' for range... yeah.
205
-
206
- @param {RObject} beg The start item for the range
207
- @param {RObject} end The finish item for the range
208
- @param {true, false} exclude_end Whether or not the range excludes the last item
209
- @return {RRange} Returns the new range instance
210
- */
211
- Vm.G = function(beg, end, exclude_end) {
212
- return new RRange(beg, end, exclude_end);
213
- };
214
-
215
- /**
216
- Ruby break statement with the given value. When no break value is needed, nil
217
- should be passed here. An undefined/null value is not valid and will cause an
218
- internal error.
219
-
220
- @param {RObject} value The break value.
221
- */
222
- Vm.B = function(value) {
223
- rb_vm_break_instance.$value = value;
224
- throw rb_vm_break_instance;
225
- };
226
-
227
- /**
228
- Ruby return, with the given value. The func is the reference function which
229
- represents the method that this statement must return from.
230
- */
231
- Vm.R = function(value, func) {
232
- rb_vm_return_instance.$value = value;
233
- rb_vm_return_instance.$func = func;
234
- throw rb_vm_return_instance;
235
- };
236
-
237
- /**
238
- Block passing. This holds the current block info for the runtime.
239
-
240
- f: function
241
- p: block
242
- y: yield error
243
-
244
- */
245
- Vm.P = {
246
- f: null,
247
- p: null,
248
- y: function() {
249
- throw new Error("LocalJumpError - opal.P.y - no block given");
250
- }
251
- };
252
-
253
- /**
254
- Define a toll free bridged class.
255
-
256
- @param {Object} prototype Native prototype to extend
257
- @param {Number} flags The flags for instances of class
258
- @param {String} id Class id
259
- @param {RClass} super_klass
260
- */
261
- Vm.bridged_class = function(prototype, flags, id, super_klass) {
262
- return bridge_class(prototype, flags || T_OBJECT, id, super_klass);
263
- };
264
-
265
- /**
266
- Sets the constant value `val` on the given `klass` as `id`.
267
-
268
- @param {RClass} klass
269
- @param {String} id
270
- @param {Object} val
271
- @return {Object} returns the set value
272
- */
273
- function const_set(klass, id, val) {
274
- klass.$c_prototype[id] = val;
275
- return val;
276
- }
277
-
278
- /**
279
- Lookup a constant named `id` on the `klass`. This will throw an error if
280
- the constant cannot be found.
281
-
282
- @param {RClass} klass
283
- @param {String} id
284
- */
285
- function const_get(klass, id) {
286
- if (klass.$c[id]) {
287
- return (klass.$c[id]);
288
- }
289
-
290
- var parent = klass.$parent;
291
-
292
- while (parent && parent != cObject) {
293
- if (parent.$c[id]) {
294
- return parent.$c[id];
295
- }
296
-
297
- parent = parent.$parent;
298
- }
299
-
300
- raise(eNameError, 'uninitialized constant ' + id);
301
- };
302
-
303
- /**
304
- Returns true or false depending whether a constant named `id` is defined
305
- on the receiver `klass`.
306
-
307
- @param {RClass} klass
308
- @param {String} id
309
- @return {true, false}
310
- */
311
- function const_defined(klass, id) {
312
- if (klass.$c[id]) {
313
- return true;
314
- }
315
-
316
- return false;
317
- };
318
-
319
- /**
320
- Set an instance variable on the receiver.
321
- */
322
- function ivar_set(obj, id, val) {
323
- obj[id] = val;
324
- return val;
325
- };
326
-
327
- /**
328
- Return an instance variable set on the receiver, or nil if one does not
329
- exist.
330
- */
331
- function ivar_get(obj, id) {
332
- return obj.hasOwnProperty(id) ? obj[id] : Qnil;
333
- };
334
-
335
- /**
336
- Determines whether and instance variable has been set on the receiver.
337
- */
338
- function ivar_defined(obj, id) {
339
- return obj.hasOwnProperty(id) ? true : false;
340
- };
341
-
342
- /**
343
- This table holds all the global variables accessible from ruby.
344
-
345
- Entries are mapped by their global id => an object that contains the
346
- given keys:
347
-
348
- - name
349
- - value
350
- - getter
351
- - setter
352
- */
353
- var global_tbl = {};
354
-
355
- /**
356
- Defines a hooked/global variable.
357
-
358
- @param {String} name The global name (e.g. '$:')
359
- @param {Function} getter The getter function to return the variable
360
- @param {Function} setter The setter function used for setting the var
361
- @return {null}
362
- */
363
- function define_hooked_variable(name, getter, setter) {
364
- var entry = {
365
- "name": name,
366
- "value": Qnil,
367
- "getter": getter,
368
- "setter": setter
369
- };
370
-
371
- global_tbl[name] = entry;
372
- };
373
-
374
- /**
375
- A default read only getter for a global variable. This will simply throw a
376
- name error with the given id. This can be used for variables that should
377
- not be altered.
378
- */
379
- function gvar_readonly_setter(id, value) {
380
- raise(eNameError, id + " is a read-only variable");
381
- };
382
-
383
- /**
384
- Retrieve a global variable. This will use the assigned getter.
385
- */
386
- function gvar_get(id) {
387
- var entry = global_tbl[id];
388
- if (!entry) { return Qnil; }
389
- return entry.getter(id);
390
- };
391
-
392
- /**
393
- Set a global. If not already set, then we assign basic getters and setters.
394
- */
395
- function gvar_set(id, value) {
396
- var entry = global_tbl[id];
397
- if (entry) { return entry.setter(id, value); }
398
-
399
- define_hooked_variable(id,
400
-
401
- function(id) {
402
- return global_tbl[id].value;
403
- },
404
-
405
- function(id, value) {
406
- return (global_tbl[id].value = value);
407
- }
408
- );
409
-
410
- return gvar_set(id, value);
411
- };
412
-
413
- /**
414
- Every object has a unique id. This count is used as the next id for the
415
- next created object. Therefore, first ruby object has id 0, next has 1 etc.
416
- */
417
- var hash_yield = 0;
418
-
419
- /**
420
- Yield the next object id, updating the count, and returning it.
421
- */
422
- function yield_hash() {
423
- return hash_yield++;
424
- };
425
-
426
- /**
427
- The root class. Every class in opal is an instance of RClass.
428
-
429
- @constructor
430
- @param {RClass} klass
431
- @param {RClass} super_klass
432
- */
433
- var RClass = Vm.RClass = function(klass, super_klass) {
434
- this.$id = yield_hash();
435
- this.$super = super_klass;
436
-
437
- if (super_klass) {
438
- var ctor = function() {};
439
- ctor.prototype = super_klass.$m_prototype_tbl;
440
-
441
- var m_ctor = function() {};
442
- m_ctor.prototype = new ctor();
443
-
444
- this.$m_tbl = new m_ctor();
445
- this.$m_prototype_tbl = m_ctor.prototype;
446
-
447
- var cctor = function() {};
448
- cctor.prototype = super_klass.$c_prototype;
449
-
450
- var c_ctor = function() {};
451
- c_ctor.prototype = new cctor();
452
-
453
- this.$c = new c_ctor();
454
- this.$c_prototype = c_ctor.prototype;
455
- }
456
- else {
457
- var m_ctor = function() {};
458
- this.$m_tbl = new m_ctor();
459
- this.$m_prototype_tbl = m_ctor.prototype;
460
-
461
- var c_ctor = function() {};
462
- this.$c = new c_ctor();
463
- this.$c_prototype = c_ctor.prototype;
464
- }
465
-
466
- this.$method_table = {};
467
- return this;
468
- };
469
-
470
- // RClass protoype for minimizing
471
- var Rp = RClass.prototype;
472
-
473
- /**
474
- Flags. Every RClass instance is simply a T_CLASS, so mark as so.
475
- */
476
- Rp.$flags = T_CLASS;
477
-
478
- /**
479
- RTest/truthiness - every RClass instance is true.
480
- */
481
- Rp.$r = true;
482
-
483
- /**
484
- The root object. Every object in opal (apart from toll free bridged classes
485
- like array, string etc) are an instance of RObject.
486
-
487
- @param {RClass} klass
488
- */
489
- var RObject = Vm.RObject = function(klass) {
490
- this.$id = yield_hash();
491
- this.$klass = klass;
492
- this.$m = klass.$m_tbl;
493
- return this;
494
- };
495
-
496
- // For minimizing
497
- var Bp = RObject.prototype;
498
-
499
- /**
500
- Flags - every RObject instance is simply a T_OBJECT
501
- */
502
- Bp.$flags = T_OBJECT;
503
-
504
- /**
505
- RTest - every RObject instance is true.
506
- */
507
- Bp.$r = true;
508
-
509
- /**
510
- The hash of a class or object in ruby is simply it's id, as all objects and
511
- classes have unique ids.
512
- */
513
- Bp.$hash = Rp.$hash = function() {
514
- return this.$id;
515
- };
516
-
517
- /**
518
- Internal method for defining a method.
519
-
520
- @param {RClass} klass The klass to define the method on
521
- @param {String} name The method id
522
- @param {Function} body Method implementation
523
- @return {Qnil}
524
- */
525
- function define_method(klass, name, body) {
526
- klass.$m_prototype_tbl[name] = body;
527
- klass.$method_table[name] = body;
528
-
529
- if (klass.$included_in) {
530
- for (var i = 0; i < klass.$included_in.length; i++) {
531
- klass.$included_in[i].$m_prototype_tbl[name] = body;
532
- klass.$included_in[i].$method_table[name] = body;
533
- }
534
- }
535
-
536
- if (!body.$rbName) {
537
- body.$rbName = name;
538
- }
539
-
540
- return Qnil;
541
- };
542
-
543
- Vm.define_method = define_method;
544
-
545
- function define_singleton_method(klass, name, body) {
546
- define_method(singleton_class(klass), name, body);
547
- };
548
-
549
- function define_alias(base, new_name, old_name) {
550
- define_method(base, new_name, base.$m_tbl[old_name]);
551
- return Qnil;
552
- };
553
-
554
- /**
555
- Implementation for Class#allocate
556
- */
557
- function obj_alloc(klass) {
558
- var result = new RObject(klass, T_OBJECT);
559
- return result;
560
- };
561
-
562
- /**
563
- Raise the exception class with the given string message.
564
- */
565
- function raise(exc, str) {
566
- if (str === undefined) {
567
- str = exc;
568
- exc = eException;
569
- }
570
- var exception = exc.$m.allocate(exc);
571
- exception.message = str;
572
- vm_raise(exception);
573
- };
574
-
575
- /**
576
- Raise an exception instance (DO NOT pass strings to this)
577
- */
578
- function vm_raise(exc) {
579
- throw exc;
580
- };
581
-
582
- Vm.raise = vm_raise;
583
-
584
- /**
585
- Throw an argument error when the wrong number of arguments were given to a
586
- method.
587
-
588
- @param {Number} given The number of arguments actually given
589
- @param {Number} expected The number of arguments we expected to have
590
- */
591
- function arg_error(given, expected) {
592
- raise(eArgError,
593
- "wrong number of arguments(" + given + " for " + expected + ")");
594
- };
595
-
596
- /**
597
- Call a super method.
598
-
599
- callee is the function that actually called super(). We use this to find
600
- the right place in the tree to find the method that actually called super.
601
- This is actually done in super_find.
602
- */
603
- Vm.S = function(callee, self, args) {
604
- var mid = callee.$rbName;
605
- var func = super_find(self.$klass, callee, callee.$rbName);
606
-
607
- if (!func) {
608
- raise(eNoMethodError, "super: no superclass method for " + mid);
609
- raise(eNoMethodError, "super: no super class method `" + mid + "`" +
610
- " for " + self.$m.inspect(self));
611
- }
612
-
613
- var args_to_send = [self, mid].concat(args);
614
- return func.apply(null, args_to_send);
615
- };
616
-
617
- /**
618
- Actually find super impl to call. Returns null if cannot find it.
619
- */
620
- function super_find(klass, callee, mid) {
621
- var cur_method;
622
-
623
- while (klass) {
624
- if (klass.$method_table[mid]) {
625
- if (klass.$method_table[mid] == callee) {
626
- break;
627
- }
628
- }
629
- klass = klass.$super;
630
- }
631
-
632
- if (!klass) { return null; }
633
-
634
- klass = klass.$super;
635
-
636
- while (klass) {
637
- if (klass.$method_table[mid]) {
638
- return klass.$method_table[mid];
639
- }
640
-
641
- klass = klass.$super;
642
- }
643
-
644
- return null;
645
- };
646
-
647
- /**
648
- VM method to get a contant from the given base.
649
-
650
- @global
651
- */
652
- rb_vm_cg = function(base, id) {
653
- if (base.$flags & T_OBJECT) {
654
- base = class_real(base.$klass);
655
- }
656
- return const_get(base, id);
657
- };
658
-
659
- /**
660
- VM method to set a contant in base.
661
-
662
- @global
663
- */
664
- rb_vm_cs = function(base, id, val) {
665
- if (base.$flags & T_OBJECT) {
666
- base = class_real(base.$klass);
667
- }
668
- return const_set(base, id, val);
669
- };
670
-
671
- /**
672
- Get global by id
673
- */
674
- Vm.gg = function(id) {
675
- return gvar_get(id);
676
- };
677
-
678
- /**
679
- Set global by id
680
- */
681
- Vm.gs = function(id, value) {
682
- return gvar_set(id, value);
683
- };
684
-
685
- /**
686
- Getter method for getting the load path for opal.
687
-
688
- @param {String} id The globals id being retrieved.
689
- @return {Array} Load paths
690
- */
691
- function load_path_getter(id) {
692
- return opal.loader.paths;
693
- };
694
-
695
- /**
696
- Getter method to get all loaded features.
697
-
698
- @param {String} id Feature global id
699
- @return {Array} Loaded features
700
- */
701
- function loaded_feature_getter(id) {
702
- return loaded_features;
703
- };
704
-
705
- /**
706
- Main init method. This is called once this file has fully loaded. It setups
707
- all the core objects and classes and required runtime features.
708
- */
709
- function init() {
710
-
711
- var metaclass;
712
-
713
- Vm.BasicObject = cBasicObject = boot_defrootclass('BasicObject');
714
- Vm.Object = cObject = boot_defclass('Object', cBasicObject);
715
- Vm.Module = cModule = boot_defclass('Module', cObject);
716
- Vm.Class = cClass = boot_defclass('Class', cModule);
717
-
718
- const_set(cObject, 'BasicObject', cBasicObject);
719
-
720
- metaclass = make_metaclass(cBasicObject, cClass);
721
- metaclass = make_metaclass(cObject, metaclass);
722
- metaclass = make_metaclass(cModule, metaclass);
723
- metaclass = make_metaclass(cClass, metaclass);
724
-
725
- boot_defmetametaclass(cModule, metaclass);
726
- boot_defmetametaclass(cObject, metaclass);
727
- boot_defmetametaclass(cBasicObject, metaclass);
728
-
729
- define_method(cBasicObject, "!", obj_not);
730
- define_method(cBasicObject, "!=", obj_not_equal);
731
-
732
- mKernel = define_module('Kernel');
733
-
734
- include_module(cObject, mKernel);
735
-
736
- define_method(cClass, "allocate", obj_alloc);
737
- define_method(cClass, "new", class_new_instance);
738
- define_method(cClass, "initialize", class_initialize);
739
- define_singleton_method(cClass, "new", class_s_new);
740
-
741
- define_method(mKernel, "puts", obj_puts);
742
-
743
- Qself = obj_alloc(cObject);
744
- Vm.top = Qself;
745
-
746
- cNilClass = define_class('NilClass', cObject);
747
- Vm.Qnil = Qnil = obj_alloc(cNilClass);
748
- Qnil.$r = false;
749
-
750
- cTrueClass = define_class('TrueClass', cObject);
751
- Vm.Qtrue = Qtrue = obj_alloc(cTrueClass);
752
-
753
- cFalseClass = define_class('FalseClass', cObject);
754
- Vm.Qfalse = Qfalse = obj_alloc(cFalseClass);
755
- Qfalse.$r = false;
756
-
757
- cArray = bridge_class(Array.prototype,
758
- T_OBJECT | T_ARRAY, 'Array', cObject);
759
-
760
- Array.prototype.$hash = function() {
761
- return (this.$id || (this.$id = yield_hash()));
762
- };
763
-
764
- cNumeric = bridge_class(Number.prototype,
765
- T_OBJECT | T_NUMBER, 'Numeric', cObject);
766
-
767
- cHash = bridge_class(RHash.prototype,
768
- T_OBJECT | T_HASH, 'Hash', cObject);
769
-
770
- RHash.prototype.$hash = function() {
771
- return (this.$id || (this.$id = yield_hash()));
772
- };
773
-
774
- define_singleton_method(cHash, '[]', hash_s_create);
775
-
776
- cRegexp = bridge_class(RegExp.prototype, T_OBJECT,
777
- 'Regexp', cObject);
778
-
779
- define_hooked_variable('$:', load_path_getter, gvar_readonly_setter);
780
- define_hooked_variable('$LOAD_PATH', load_path_getter, gvar_readonly_setter);
781
-
782
- const_set(cObject, 'ARGV', []);
783
-
784
- eException = bridge_class(Error.prototype, T_OBJECT, 'Exception', cObject);
785
-
786
- eStandardError = define_class("StandardError", eException);
787
- eRuntimeError = define_class("RuntimeError", eException);
788
- eLocalJumpError = define_class("LocalJumpError", eStandardError);
789
- eTypeError = define_class("TypeError", eStandardError);
790
- eNameError = define_class("NameError", eStandardError);
791
- eNoMethodError = define_class('NoMethodError', eNameError);
792
- eArgError = define_class('ArgumentError', eStandardError);
793
- eScriptError = define_class('ScriptError', eException);
794
- eLoadError = define_class('LoadError', eScriptError);
795
-
796
- eIndexError = define_class("IndexError", eStandardError);
797
- eKeyError = define_class("KeyError", eIndexError);
798
- eRangeError = define_class("RangeError", eStandardError);
799
-
800
- rb_vm_break_instance = new Error('unexpected break');
801
- rb_vm_break_instance.$klass = eLocalJumpError;
802
- rb_vm_break_instance.$keyword = 2;
803
-
804
- rb_vm_return_instance = new Error('unexpected return');
805
- rb_vm_return_instance.$klass = eLocalJumpError;
806
- rb_vm_return_instance.$keyword = 1;
807
-
808
- rb_vm_next_instance = new Error('unexpected next');
809
- rb_vm_next_instance.$klass = eLocalJumpError;
810
- rb_vm_next_instance.$keyword = 3;
811
-
812
- cString = bridge_class(String.prototype,
813
- T_OBJECT | T_STRING, 'String', cObject);
814
-
815
- cSymbol = define_class('Symbol', cObject);
816
-
817
- cProc = bridge_class(Function.prototype,
818
- T_OBJECT | T_PROC, 'Proc', cObject);
819
-
820
- Function.prototype.$hash = function() {
821
- return (this.$id || (this.$id = yield_hash()));
822
- };
823
-
824
- cRange = bridge_class(RRange.prototype, T_OBJECT | T_RANGE,
825
- 'Range', cObject);
826
-
827
- RRange.prototype.$hash = function() {
828
- return (this.$id || (this.$id = yield_hash()));
829
- };
830
-
831
- const_set(cObject, 'RUBY_PLATFORM', 'opal');
832
- };
833
-
834
- /**
835
- Define a top level module with the given id
836
- */
837
- function define_module(id) {
838
- return define_module_under(cObject, id);
839
- };
840
-
841
- function define_module_under(base, id) {
842
- var module;
843
-
844
- if (const_defined(base, id)) {
845
- module = const_get(base, id);
846
- if (module.$flags & T_MODULE) {
847
- return module;
848
- }
849
-
850
- throw id + " is not a module.";
851
- }
852
-
853
- module = define_module_id(id);
854
- const_set(base, id, module);
855
- module.$parent = base;
856
- return module;
857
- };
858
-
859
- function define_module_id(id) {
860
- var module = define_class_id(id, cModule);
861
- module.$flags = T_MODULE;
862
- name_class(module, id);
863
- return module;
864
- };
865
-
866
- function mod_create() {
867
- return class_boot(cModule);
868
- };
869
-
870
- function include_module(klass, module) {
871
-
872
- if (!klass.$included_modules) {
873
- klass.$included_modules = [];
874
- }
875
-
876
- if (klass.$included_modules.indexOf(module) != -1) {
877
- return;
878
- }
879
- klass.$included_modules.push(module);
880
-
881
- if (!module.$included_in) {
882
- module.$included_in = [];
883
- }
884
-
885
- module.$included_in.push(klass);
886
-
887
- for (var method in module.$method_table) {
888
- if (module.$method_table.hasOwnProperty(method)) {
889
- define_method(klass, method, module.$method_table[method]);
890
- }
891
- }
892
- };
893
-
894
- Vm.include_module = include_module;
895
-
896
- function extend_module(klass, module) {
897
- if (!klass.$extended_modules) {
898
- klass.$extended_modules = [];
899
- }
900
-
901
- if (klass.$extended_modules.indexOf(module) != -1) {
902
- return;
903
- }
904
- klass.$extended_modules.push(module);
905
-
906
- if (!module.$extended_in) {
907
- module.$extended_in = [];
908
- }
909
-
910
- module.$extended_in.push(klass);
911
-
912
- var meta = klass.$klass;
913
-
914
- for (var method in module.$method_table) {
915
- if (module.$method_table.hasOwnProperty(method)) {
916
- define_method(meta, method, module.$method_table[method]);
917
- }
918
- }
919
- };
920
-
921
- Vm.extend_module = extend_module;
922
-
923
- /**
924
- Boot a base class (only used for very core object classes)
925
- */
926
- function boot_defclass(id, super_klass) {
927
- var result = class_boot(super_klass);
928
- name_class(result, id);
929
- const_set((cObject || result), id, result);
930
- return result;
931
- };
932
-
933
- /**
934
- Like boot_defclass, but for root object only (i.e. basicobject)
935
- */
936
- function boot_defrootclass(id) {
937
- var result = new RClass(null, null);
938
- result.$flags = T_CLASS;
939
- name_class(result, id);
940
- const_set((cObject || result), id, result);
941
- return result;
942
- };
943
-
944
- function class_boot(super_class) {
945
- if (super_class) {
946
- var ctor = function() {};
947
- ctor.prototype = super_class.constructor.prototype;
948
-
949
- var result = function() {
950
- RClass.call(this, null, super_class);
951
- return this;
952
- };
953
- result.prototype = new ctor();
954
-
955
- var klass = new result();
956
- klass.$klass = cClass;
957
- return klass;
958
- }
959
- else {
960
- var result = new RClass(null, null);
961
- return result;
962
- }
963
- };
964
-
965
- /**
966
- @global
967
- */
968
- function class_real(klass) {
969
- while (klass.$flags & FL_SINGLETON) { klass = klass.$super; }
970
- return klass;
971
- };
972
-
973
- Vm.class_real = class_real;
974
-
975
- /**
976
- Name the class with the given id.
977
- */
978
- function name_class(klass, id) {
979
- klass.__classid__ = id;
980
- };
981
-
982
- /**
983
- Make metaclass for the given class
984
- */
985
- function make_metaclass(klass, super_class) {
986
- if ((klass.$flags & T_CLASS) && (klass.$flags & FL_SINGLETON)) {
987
- return make_metametaclass(klass);
988
- }
989
- else {
990
- var meta = class_boot(super_class);
991
- meta.$flags |= FL_SINGLETON;
992
- klass.$klass = meta;
993
- klass.$m = meta.$m_tbl;
994
- meta.$c = klass.$c;
995
- singleton_class_attached(meta, klass);
996
-
997
- return meta;
998
- }
999
- };
1000
-
1001
- function singleton_class_attached(klass, obj) {
1002
- if (klass.$flags & FL_SINGLETON) {
1003
- ivar_set(klass, '__attached__', obj);
1004
- }
1005
- };
1006
-
1007
- function make_metametaclass(metaclass) {
1008
- var metametaclass, super_of_metaclass;
1009
-
1010
- if (metaclass.$klass == metaclass) {
1011
- metametaclass = class_boot(null);
1012
- metametaclass.$klass = metametaclass;
1013
- }
1014
- else {
1015
- metametaclass = class_boot(null);
1016
- metametaclass.$klass = metaclass.$klass.$klass == metaclass.$klass
1017
- ? make_metametaclass(metaclass.$klass)
1018
- : metaclass.$klass.$klass;
1019
- }
1020
-
1021
- metametaclass.$flags |= FL_SINGLETON;
1022
-
1023
- singleton_class_attached(metametaclass, metaclass);
1024
- metaclass.$klass = metametaclass;
1025
- metaclass.$m = metametaclass.$m_tbl;
1026
- super_of_metaclass = metaclass.$super;
1027
-
1028
- metametaclass.$super = ivar_get(super_of_metaclass.$klass, '__attached__')
1029
- == super_of_metaclass
1030
- ? super_of_metaclass.$klass
1031
- : make_metametaclass(super_of_metaclass);
1032
-
1033
- return metametaclass;
1034
- };
1035
-
1036
- function boot_defmetametaclass(klass, metametaclass) {
1037
- klass.$klass.$klass = metametaclass;
1038
- };
1039
-
1040
- /**
1041
- Define toll free bridged class
1042
- */
1043
- function bridge_class(prototype, flags, id, super_class) {
1044
- var klass = define_class(id, super_class);
1045
-
1046
- prototype.$klass = klass;
1047
- prototype.$m = klass.$m_tbl;
1048
- prototype.$flags = flags;
1049
- prototype.$r = true;
1050
-
1051
- prototype.$hash = function() {
1052
- return flags + '_' + this;
1053
- };
1054
-
1055
- return klass;
1056
- };
1057
-
1058
- /**
1059
- Define a new class (normal way), with the given id and superclass. Will be
1060
- top level.
1061
- */
1062
- function define_class(id, super_klass) {
1063
- return define_class_under(cObject, id, super_klass);
1064
- };
1065
-
1066
- function define_class_under(base, id, super_klass) {
1067
- var klass;
1068
-
1069
- if (const_defined(base, id)) {
1070
- return const_get(base, id);
1071
- }
1072
-
1073
- klass = define_class_id(id, super_klass);
1074
-
1075
- name_class(klass, id);
1076
- const_set(base, id, klass);
1077
- klass.$parent = base;
1078
- return klass;
1079
- };
1080
-
1081
- /**
1082
- Actually create class
1083
- */
1084
- function define_class_id(id, super_klass) {
1085
- var klass;
1086
-
1087
- if (!super_klass) {
1088
- super_klass = cObject;
1089
- }
1090
- klass = class_create(super_klass);
1091
- name_class(klass, id);
1092
- make_metaclass(klass, super_klass.$klass);
1093
- return klass;
1094
- };
1095
-
1096
- function class_create(super_klass) {
1097
- return class_boot(super_klass);
1098
- };
1099
-
1100
- /**
1101
- Get singleton class of obj
1102
- */
1103
- function singleton_class(obj) {
1104
- var obj;
1105
-
1106
- if ((obj.$klass.$flags & FL_SINGLETON)&& ivar_get(obj.$klass, '__attached__') == obj) {
1107
- klass = obj.$klass;
1108
- }
1109
- else {
1110
- var class_id = obj.$klass.__classid__;
1111
- klass = make_metaclass(obj, obj.$klass);
1112
- }
1113
-
1114
- return klass;
1115
- };
1116
-
1117
- function RHash(args) {
1118
- var k, v;
1119
- this.$keys = [];
1120
- this.$assocs = {};
1121
- this.$default = Qnil;
1122
-
1123
- for (var i = 0; i < args.length; i++) {
1124
- k = args[i];
1125
- v = args[i+1];
1126
- i++;
1127
- this.$keys.push(k);
1128
- this.$assocs[k.$hash()] = v;
1129
- }
1130
- return this;
1131
- };
1132
-
1133
- /**
1134
- Symbol table. All symbols are stored here.
1135
- */
1136
- var symbol_table = { };
1137
-
1138
- /**
1139
- Range ruby object
1140
- */
1141
- function RRange(beg, end, exclude_end) {
1142
- this.$beg = beg;
1143
- this.$end = end;
1144
- this.$exc = exclude_end;
1145
- return this;
1146
- };
1147
-
1148
- /**
1149
- Creates a new hash populated with the given objects. Equivalent to the
1150
- literal `{ key => value, ... }`.
1151
-
1152
- @example
1153
- Hash["a", 100, "b", 200]
1154
- # => {"a" =>100, "b"=>200}
1155
-
1156
- @return [Hash]
1157
- */
1158
- function hash_s_create(obj, mid) {
1159
- return opalhash.apply(null, Array.prototype.slice.call(arguments, 2));
1160
- };
1161
-
1162
- function class_s_new(cls, sup) {
1163
- var klass = define_class_id("AnonClass", sup || cObject);
1164
- return klass;
1165
- };
1166
-
1167
- function class_new_instance(cls) {
1168
- var obj = cls.$m.allocate(cls);
1169
- var args = Array.prototype.slice.call(arguments, 1);
1170
- args.unshift(obj);
1171
-
1172
- if (Vm.P.f == arguments.callee) {
1173
- VM.P.f = obj.$m.initialize;
1174
- }
1175
-
1176
- obj.$m.initialize.apply(obj, args);
1177
- return obj;
1178
- };
1179
-
1180
- function class_initialize(cla, mid, sup) {
1181
- var klass = define_class_id('', sup || cObject);
1182
- return klass;
1183
- };
1184
-
1185
- /**
1186
- Prints each argument in turn to the browser console. Currently there is no
1187
- use of `$stdout`, so it is hardcoded into this method to write to the
1188
- console directly.
1189
-
1190
- @param {Object} args objects to print using `inspect`
1191
- @return {nil}
1192
- */
1193
- function obj_puts(obj) {
1194
- var args = Array.prototype.slice.call(arguments, 1);
1195
-
1196
- for (var i = 0; i < args.length; i++) {
1197
- console.log((args[i].$m.to_s(args[i])).toString());
1198
- }
1199
-
1200
- return Qnil;
1201
- };
1202
-
1203
- /**
1204
- @example
1205
- !obj # => true or false
1206
- */
1207
- function obj_not(obj, mid) {
1208
- return obj.$r ? Qfalse : Qtrue;
1209
- };
1210
-
1211
- /**
1212
- @example
1213
- obj != obj2 # => true or false
1214
- */
1215
- function obj_not_equal(obj1, mid, obj2) {
1216
- var res = obj1.$m['=='](obj1, obj2);
1217
- return res.$r ? Qfalse : Qtrue;
1218
- };
1219
-
1220
- // ..........................................................
1221
- // FILESYSTEM
1222
- //
1223
-
1224
- // added to main opal namespace, and Fs for minimizing here.
1225
- var Fs = Op.fs = {};
1226
-
1227
- /**
1228
- Regular expression used for splitting filenames into their dirname,
1229
- basename and extension. This is unix style only, as filenames inside
1230
- opal in the browser will only ever have this style of filename. The gem
1231
- fs support will depend on the platform being run.
1232
- **/
1233
- var PATH_RE = /^(.+\/(?!$)|\/)?((?:.+?)?(\.[^.]*)?)$/;
1234
-
1235
- /**
1236
- Holds the current working directory for the application. This is '/' by
1237
- default, but is usually set to the base directory of the main gem.
1238
-
1239
- @type {String}
1240
- */
1241
- Fs.cwd = '/';
1242
-
1243
- /**
1244
- Join the given args using the default seperator. The path returned is not
1245
- expanded.
1246
-
1247
- @param {arguments<String<} args The arguments to join
1248
- @return {String}
1249
- */
1250
- var file_join = Fs.join = function() {
1251
- var parts = [].slice.call(arguments, 0);
1252
- return parts.join('/');
1253
- };
1254
-
1255
- /**
1256
- Normalize the path by removing '..' and '.' parts, remove '//' etc to
1257
- return a nice normalized path.
1258
-
1259
- @param {String} path The path needing normalization
1260
- @param {String} base Optional base to normalize to
1261
- @return {String} Normalized path
1262
- */
1263
- var file_expand_path = Fs.expand_path = function(path, base) {
1264
- path = file_join(base || Fs.cwd, path);
1265
-
1266
- var parts = path.split('/'), result = [], part;
1267
-
1268
- // initial /
1269
- if (parts[0] === '') result.push('');
1270
-
1271
- for (var i = 0, ii = parts.length; i < ii; i++) {
1272
- part = parts[i];
1273
-
1274
- if (part == '..') {
1275
- result.pop();
1276
- }
1277
- else if (part == '.' || part == '') {
1278
-
1279
- }
1280
- else {
1281
- result.push(part);
1282
- }
1283
- }
1284
-
1285
- return result.join('/');
1286
- };
1287
-
1288
- /**
1289
- Returns all of the components of the given `file_name` except for the last
1290
- one.
1291
-
1292
- @param {String} file_name
1293
- @return {String}
1294
- */
1295
- var file_dirname = Fs.dirname = function(file_name) {
1296
- var dirname = PATH_RE.exec(file_name)[1];
1297
-
1298
- if (!dirname) return '.';
1299
- else if (dirname === '/') return dirname;
1300
- else return dirname.substring(0, dirname.length - 1);
1301
- };
1302
-
1303
- /**
1304
- Returns the file extension of the given `file_name`.
1305
-
1306
- @param {String} file_name
1307
- @return {String}
1308
- */
1309
- Fs.extname = function(file_name) {
1310
- var extname = PATH_RE.exec(file_name)[3];
1311
-
1312
- if (!extname || extname === '.') return '';
1313
- else return extname;
1314
- };
1315
-
1316
-
1317
- // ..........................................................
1318
- // LOADER
1319
- //
1320
-
1321
- /**
1322
- Require a module.
1323
-
1324
- @param {String} id The module id
1325
- @return {Object} returns the exports
1326
- */
1327
- Op.require = function(id, parent) {
1328
- var resolved = Op.loader.resolve_module(id, null);
1329
- var cached = Op.cache[resolved];
1330
-
1331
- if (cached) {
1332
- return true;
1333
- }
1334
-
1335
- Op.cache[resolved] = true;
1336
- // try/catch?
1337
- load_file(Op.loader, resolved);
1338
-
1339
- return true;
1340
- };
1341
-
1342
- // Virtual machine must also be able to require..
1343
- Vm.require = Op.require;
1344
-
1345
- /**
1346
- Register a package with the given package info.
1347
-
1348
- This will probably (definately??) always be done only in the browser.
1349
-
1350
- @param {String} name The package name
1351
- @param {Object} info The package info
1352
- */
1353
- Op.register = function(name, info) {
1354
-
1355
- // make sure we get a string name
1356
- if (typeof name !== 'string') {
1357
- throw new Error("Cannot register a package without a proper name");
1358
- }
1359
-
1360
- // registering a single module/file
1361
- if (typeof info === 'string' || typeof info === 'function') {
1362
- register_module(name, info);
1363
- }
1364
- // make sure info is a proper package
1365
- else if (typeof info === 'object') {
1366
- register_package(name, info);
1367
- }
1368
- // else, we have an error.. we can only register packages or modules
1369
- else {
1370
- throw new Error("Invalid package.json data for '" + name + "'");
1371
- }
1372
- };
1373
-
1374
- /**
1375
- Private method to actually register the package. This is private to
1376
- avoid external interferance. This will be called from {opal#register}.
1377
-
1378
- @param {String} name The package name
1379
- @param {Object} info The package information
1380
- */
1381
- var register_package = function(name, info) {
1382
- var factories = Op.loader.factories,
1383
- paths = Op.loader.paths;
1384
-
1385
- // register all files
1386
- var files = info.files || {};
1387
-
1388
- // root dir for package is /package_name
1389
- var root_dir = '/' + name;
1390
-
1391
- // assume './lib' dir for lib files (for now.. should be dynamic)
1392
- var lib_dir = './lib';
1393
-
1394
- // add lib dir to paths
1395
- paths.unshift(file_expand_path(file_join(root_dir, lib_dir)));
1396
-
1397
- for (var file in files) {
1398
- if (files.hasOwnProperty(file)) {
1399
- // full path to file; we use the root dir
1400
- var file_path = file_expand_path(file_join(root_dir, file));
1401
-
1402
- factories[file_path] = files[file];
1403
- }
1404
- }
1405
-
1406
- ////////////////////////////////////////
1407
- // Autobooting. Basically, autoload opal.
1408
- //
1409
- if (name === 'opal') {
1410
- Op.require(name);
1411
- }
1412
- };
1413
-
1414
- /**
1415
- Private method to register a single module. These modules are added to the
1416
- very top level dir: /module_name.js
1417
- */
1418
- var register_module = function(name, factory) {
1419
- // name gets preceeded with a '/' for root files
1420
- var factory_name = '/' + name;
1421
-
1422
- Op.loader.factories[factory_name] = factory;
1423
- };
1424
-
1425
-
1426
- // valid extensions for loading
1427
- var load_extensions = {};
1428
-
1429
- load_extensions['.js'] = function(loader, filename) {
1430
- var source = loader.module_contents(filename);
1431
- return execute_file(loader, source, filename);
1432
- };
1433
-
1434
- load_extensions['.rb'] = function(loader, filename) {
1435
- var source = loader.ruby_module_contents(filename);
1436
- return execute_file(loader, source, filename);
1437
- };
1438
-
1439
- /**
1440
- The loader is the core machinery used for loading and executing modules
1441
- within opal. An instance of opal will have a .loader property, which
1442
- is an instance of this Loader class. A Loader is responsible for finding,
1443
- opening and reading the contents of modules on disk. Within the browser,
1444
- which is the default environment, a loader will use XHR requests or cached
1445
- modules from JSON to load the required modules.
1446
-
1447
- Within the browser, the loader, currently, just looks at its opal
1448
- instance for registered files and packages and uses them as needed.
1449
- opal also has 'built in' packages from commonjs, like 'system' etc, so
1450
- all loaders must check opal first for registered packages.
1451
-
1452
- @param {opal} opal The opal instance for this loader
1453
- */
1454
- var Loader = function(opal) {
1455
- this.opal = opal;
1456
- this.paths = [''];
1457
-
1458
- this.factories = {};
1459
-
1460
-
1461
- return this;
1462
- };
1463
-
1464
- // Loader prototype
1465
- var Lp = Loader.prototype;
1466
-
1467
- /**
1468
- The paths property is an array of disk paths in which to search for
1469
- required modules. In the browser this functionality isn't really used.
1470
-
1471
- This array is created within the constructor method for uniqueness
1472
- between instances for correct sandboxing.
1473
- */
1474
- Lp.paths = null;
1475
-
1476
- /**
1477
- factories of registered packages, paths => function/string. This is
1478
- generic, but in reality only the browser uses this, and it is treated
1479
- as the mini filesystem. Not just factories can go here, anything can!
1480
- Images, text, json, whatever.
1481
- */
1482
- Lp.factories = {};
1483
-
1484
- /**
1485
- Valid factory format for use in require();
1486
- */
1487
- Lp.valid_extensions = ['.js', '.rb'];
1488
-
1489
- /**
1490
- Resolves the path to the module, which can then be used to load. This
1491
- method will throw an error if the module cannot be found. If this method
1492
- returns a successful filename, then subsequent methods like load_module
1493
- should be successful and should not throw errors.
1494
-
1495
- @param {String} id The id to look for
1496
- @param {Module} parent The module that has requested the id
1497
- */
1498
- Lp.resolve_module = function(id, parent) {
1499
- var resolved = this.find_module(id, this.paths);
1500
-
1501
- if (!resolved) {
1502
- throw new Error("Cannot find module '" + id + "'");
1503
- }
1504
-
1505
- return resolved;
1506
- };
1507
-
1508
- Lp.find_module = function(id, paths) {
1509
- var extensions = this.valid_extensions, factories = this.factories, candidate;
1510
-
1511
- for (var i = 0, ii = paths.length; i < ii; i++) {
1512
- for (var j = 0, jj = extensions.length; j < jj; j++) {
1513
- candidate = file_join(paths[i], id + extensions[j]);
1514
-
1515
- console.log(candidate);
1516
- if (factories[candidate]) {
1517
- return candidate;
1518
- }
1519
- }
1520
- }
1521
-
1522
- return null;
1523
- };
1524
-
1525
- /**
1526
- Module contents
1527
- */
1528
- Lp.module_contents = function(filename) {
1529
- return this.factories[filename];
1530
- };
1531
-
1532
- /**
1533
- Actually load the file with the given resolved filename. This filename has
1534
- been checked, and is known to exist.
1535
- */
1536
- function load_file(loader, filename) {
1537
- var extension = load_extensions[PATH_RE.exec(filename)[3] || '.js'];
1538
-
1539
- if (!extension) {
1540
- throw new Error("Loader.load - Bad extension for resolved path");
1541
- }
1542
-
1543
- extension(loader, filename);
1544
- };
1545
-
1546
- /**
1547
- Run content, which by now must be javascript. If the content is a string,
1548
- then it is simply evaluated. Within the browser it might be a function, so
1549
- we call it, passing our standard args.
1550
-
1551
- The arguments we pass are standardised as:
1552
-
1553
- VM - Our opal vm variable which exposes runtime methods
1554
- Qself - the top level ruby object, which is the 'self' for files
1555
- filename - the Filename to run the file as for __FILE__
1556
-
1557
- @param {String, Function} content The javascript content to be run.
1558
- @param {String} filename Filename to run content as.
1559
- */
1560
- function execute_file(loader, content, filename) {
1561
-
1562
- var args = [Vm, Qself, filename];
1563
-
1564
- if (typeof content === 'function') {
1565
- return content.apply(Op, args);
1566
-
1567
- } else if (typeof content === 'string') {
1568
- var func = loader.wrap(content, filename);
1569
- return func.apply(Op, args);
1570
-
1571
- } else {
1572
- throw new Error(
1573
- "Loader.execute - bad content sent for '" + filename + "'");
1574
- }
1575
- };
1576
-
1577
- // ..........................................................
1578
- // FINAL INITILIZATION
1579
- //
1580
-
1581
- // init ruby runtime
1582
- init();
1583
-
1584
- // browser based loader - overriden by v8 context
1585
- Op.loader = new Loader(Op);
1586
-
1587
- // cache of filenames already evaluated
1588
- Op.cache = {};
1589
-
1590
- })();
1591
-
1592
- // if in a commonjs system already (node etc), exports become our opal
1593
- // object. Otherwise, in the browser, we just get a top level opal var
1594
- if ((typeof require !== 'undefined') && (typeof module !== 'undefined')) {
1595
- module.exports = opal;
1596
- }
1597
-