opal 0.3.6 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. data/README.md +69 -97
  2. data/bin/opal +2 -2
  3. data/{lib/core → corelib}/array.rb +85 -56
  4. data/corelib/boolean.rb +20 -0
  5. data/corelib/class.rb +58 -0
  6. data/{lib → corelib}/core.rb +2 -50
  7. data/corelib/dir.rb +22 -0
  8. data/{lib/core → corelib}/enumerable.rb +0 -0
  9. data/corelib/error.rb +19 -0
  10. data/{lib/core → corelib}/file.rb +7 -9
  11. data/{lib/core → corelib}/hash.rb +104 -144
  12. data/{lib/core → corelib}/kernel.rb +38 -44
  13. data/corelib/load_order +21 -0
  14. data/{lib/core → corelib}/match_data.rb +0 -0
  15. data/{lib/core → corelib}/module.rb +12 -8
  16. data/{lib/core → corelib}/nil_class.rb +2 -2
  17. data/{lib/core → corelib}/numeric.rb +37 -100
  18. data/corelib/object.rb +37 -0
  19. data/{lib/core → corelib}/proc.rb +3 -3
  20. data/corelib/range.rb +27 -0
  21. data/{lib/core → corelib}/regexp.rb +1 -1
  22. data/{lib/core → corelib}/string.rb +16 -107
  23. data/{lib/core → corelib}/top_self.rb +0 -0
  24. data/lib/opal.rb +7 -0
  25. data/lib/opal/browserify.rb +34 -0
  26. data/{opal_lib → lib}/opal/builder.rb +70 -24
  27. data/lib/opal/command.rb +52 -0
  28. data/lib/opal/context.rb +197 -0
  29. data/{opal_lib/opal/ruby/parser.rb → lib/opal/lexer.rb} +20 -4
  30. data/{opal_lib/opal/ruby → lib/opal}/nodes.rb +238 -127
  31. data/lib/opal/parser.rb +4894 -0
  32. data/{opal_lib/opal/ruby/ruby_parser.y → lib/opal/parser.y} +38 -18
  33. data/lib/rbp.rb +2 -0
  34. data/lib/rbp/package.rb +49 -0
  35. data/runtime/class.js +216 -189
  36. data/runtime/fs.js +2 -2
  37. data/runtime/init.js +242 -244
  38. data/runtime/loader.js +78 -99
  39. data/runtime/module.js +34 -40
  40. data/runtime/post.js +2 -2
  41. data/runtime/pre.js +1 -1
  42. data/runtime/runtime.js +129 -135
  43. data/{lib → stdlib}/dev.rb +10 -10
  44. data/{lib → stdlib}/racc/parser.rb +0 -6
  45. data/{lib → stdlib}/strscan.rb +4 -4
  46. metadata +57 -105
  47. data/lib/core/basic_object.rb +0 -51
  48. data/lib/core/class.rb +0 -38
  49. data/lib/core/dir.rb +0 -26
  50. data/lib/core/error.rb +0 -75
  51. data/lib/core/false_class.rb +0 -81
  52. data/lib/core/object.rb +0 -6
  53. data/lib/core/range.rb +0 -27
  54. data/lib/core/symbol.rb +0 -42
  55. data/lib/core/true_class.rb +0 -41
  56. data/lib/ospec.rb +0 -7
  57. data/lib/ospec/autorun.rb +0 -8
  58. data/lib/ospec/dsl.rb +0 -15
  59. data/lib/ospec/example.rb +0 -11
  60. data/lib/ospec/example/before_and_after_hooks.rb +0 -56
  61. data/lib/ospec/example/errors.rb +0 -17
  62. data/lib/ospec/example/example_group.rb +0 -12
  63. data/lib/ospec/example/example_group_factory.rb +0 -18
  64. data/lib/ospec/example/example_group_hierarchy.rb +0 -21
  65. data/lib/ospec/example/example_group_methods.rb +0 -100
  66. data/lib/ospec/example/example_group_proxy.rb +0 -15
  67. data/lib/ospec/example/example_methods.rb +0 -46
  68. data/lib/ospec/example/example_proxy.rb +0 -18
  69. data/lib/ospec/expectations.rb +0 -19
  70. data/lib/ospec/expectations/errors.rb +0 -8
  71. data/lib/ospec/expectations/fail_with.rb +0 -9
  72. data/lib/ospec/expectations/handler.rb +0 -33
  73. data/lib/ospec/helpers/scratch.rb +0 -18
  74. data/lib/ospec/matchers.rb +0 -24
  75. data/lib/ospec/matchers/be.rb +0 -1
  76. data/lib/ospec/matchers/generated_descriptions.rb +0 -20
  77. data/lib/ospec/matchers/operator_matcher.rb +0 -54
  78. data/lib/ospec/matchers/raise_error.rb +0 -38
  79. data/lib/ospec/runner.rb +0 -90
  80. data/lib/ospec/runner/example_group_runner.rb +0 -41
  81. data/lib/ospec/runner/formatter/html_formatter.rb +0 -139
  82. data/lib/ospec/runner/formatter/terminal_formatter.rb +0 -48
  83. data/lib/ospec/runner/options.rb +0 -34
  84. data/lib/ospec/runner/reporter.rb +0 -82
  85. data/opal_lib/opal.rb +0 -16
  86. data/opal_lib/opal/build_methods.rb +0 -51
  87. data/opal_lib/opal/bundle.rb +0 -70
  88. data/opal_lib/opal/command.rb +0 -68
  89. data/opal_lib/opal/context.rb +0 -81
  90. data/opal_lib/opal/context/console.rb +0 -10
  91. data/opal_lib/opal/context/file_system.rb +0 -34
  92. data/opal_lib/opal/context/loader.rb +0 -135
  93. data/opal_lib/opal/gem.rb +0 -84
  94. data/opal_lib/opal/rake/builder_task.rb +0 -44
  95. data/opal_lib/opal/rake/spec_task.rb +0 -32
  96. data/opal_lib/opal/ruby/ruby_parser.rb +0 -4862
  97. data/opal_lib/opal/version.rb +0 -4
  98. data/runtime/debug.js +0 -84
data/corelib/object.rb ADDED
@@ -0,0 +1,37 @@
1
+ # Core object in hierarchy. Most of the implementation of this core
2
+ # object are implemented in {Kernel}.
3
+ class Object
4
+
5
+ def initialize(*a)
6
+ # ...
7
+ end
8
+
9
+ def ==(other)
10
+ `return self === other;`
11
+ end
12
+
13
+ def equal?(other)
14
+ self == other
15
+ end
16
+
17
+ def __send__(method_id, *args, &block)
18
+ `var method = self['m$' + method_id];
19
+
20
+ if ($B.f == arguments.callee) {
21
+ $B.f = method;
22
+ }
23
+
24
+ return method.apply(self, args);`
25
+ end
26
+
27
+ def instance_eval(&block)
28
+ raise ArgumentError, "block not supplied" unless block_given?
29
+ `block.call(self);`
30
+ self
31
+ end
32
+
33
+ def method_missing(sym, *args)
34
+ raise NoMethodError, "undefined method `#{sym}` for #{self.inspect}"
35
+ end
36
+ end
37
+
@@ -41,15 +41,15 @@ class Proc
41
41
  end
42
42
 
43
43
  def call(*args)
44
- `args.unshift(self.$proc[0]); return self.apply(null, args);`
44
+ `return self.apply(self.o$s,args);`
45
45
  end
46
46
 
47
47
  def to_s
48
- `return "#<Proc:0x" + (self.$hash() * 400487).toString(16) + (self.$lambda ? ' (lambda)' : '') + ">";`
48
+ `return "#<Proc:0x" + (self.$h() * 400487).toString(16) + (self.$lambda ? ' (lambda)' : '') + ">";`
49
49
  end
50
50
 
51
51
  def lambda?
52
- `return self.$fn.$lambda ? Qtrue : Qfalse;`
52
+ `return self.$lambda;`
53
53
  end
54
54
  end
55
55
 
data/corelib/range.rb ADDED
@@ -0,0 +1,27 @@
1
+ class Range
2
+
3
+ def begin
4
+ `return self.beg;`
5
+ end
6
+
7
+ alias_method :first, :begin
8
+
9
+ def end
10
+ `return self.end;`
11
+ end
12
+
13
+ def to_s
14
+ `var str = #{`self.beg`.to_s};
15
+ var str2 = #{`self.end`.to_s};
16
+ var join = self.exc ? '...' : '..';
17
+ return str + join + str2;`
18
+ end
19
+
20
+ def inspect
21
+ `var str = #{`self.beg`.inspect};
22
+ var str2 = #{`self.end`.inspect};
23
+ var join = self.exc ? '...' : '..';
24
+ return str + join + str2;`
25
+ end
26
+ end
27
+
@@ -36,7 +36,7 @@ class Regexp
36
36
  end
37
37
 
38
38
  def ==(other)
39
- `return self.toString() === other.toString() ? Qtrue : Qfalse;`
39
+ `return self.toString() === other.toString();`
40
40
  end
41
41
 
42
42
  def eql?(other)
@@ -1,99 +1,13 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
- # String objects holds a sequence of bytes, typically representing
4
- # characters. Strings may be constructed by using methods like
5
- # {String.new} or literals, like the following:
6
- #
7
- # String.new("foo") # => "foo"
8
- # "bar" # => "bar"
9
- #
10
- # Strings in Opal are immutable; which means that their contents cannot
11
- # be changed. This means that a lot of methods like `strip!` are not
12
- # present, and will yield a `NoMethodError`. Thier immutable
13
- # counterparts are still available, which typically just return a new
14
- # string.
15
- #
16
- # Implementation details
17
- # ----------------------
18
- #
19
- # Ruby strings are toll-free bridged to native javascript strings,
20
- # meaning that anywhere that a ruby string is required, a normal
21
- # javascript string may be passed. This dramatically improves the
22
- # performance of Opal due to a lower overhead in allocating strings as
23
- # well as the ability to used functions of the String prototype to
24
- # perform many of the core ruby methods.
25
- #
26
- # It is due to this limitation that strings are immutable. Javascript
27
- # strings are immutable too, which limits what can be done with them in
28
- # regards to Ruby methods.
29
- #
30
- # Ruby compatibility
31
- # ------------------
32
- #
33
- # As discussed, {String} instances are immutable so they do not
34
- # implement any of the self mutable methods found in the ruby core
35
- # library. Most of these methods have their relative immutable
36
- # implementations, or alternative methods to take their place.
37
- #
38
- # Custom subclasses of {String} can be used, and are constructed in the
39
- # {.new} method. To due opals internals, a regular string is constructed
40
- # using `new String(string_content)`, and its class and method table
41
- # simply pointed at the custom subclass. As these custom subclasses are
42
- # simply javascript strings as well, they are also limited to being
43
- # immutable. This is because they share the same internal structre as
44
- # regular {String} instances.
45
- #
46
- # String instances will never actually have their {.allocate} methods
47
- # called. Due to the way opal bridges strings to javascript, when a new
48
- # string is constructed, its value must be know. This is not possible in
49
- # `allocate` as the value is not passed. Therefore the creation of
50
- # strings (including subclasses) is done in {.new} where the string
51
- # value is passed as an argument.
52
- #
53
- # Finally, strings do not currently include the `Comparable` module, as
54
- # it is not yet implemented. The main methods used by {String} from this
55
- # module are implemented directly as String methods. When `Comparable`
56
- # is implemented, these methods will be moved back to the module.
57
3
  class String
58
4
 
59
5
  def self.new(str = "")
60
- `var result = new String(str);
61
- result.$klass = self;
62
- result.$m = self.$m_tbl;
63
- return result;`
6
+ str
64
7
  end
65
8
 
66
- # Copy - returns a new string containing `count` copies of the receiver.
67
- #
68
- # @example
69
- #
70
- # 'Ho! ' * 3
71
- # # => 'Ho! Ho! Ho! '
72
- #
73
- # @param [Numeric] count number of copies
74
- # @return [String]
75
- def *(count)
76
- `var result = [];
77
-
78
- for (var i = 0; i < count; i++) {
79
- result.push(self);
80
- }
81
-
82
- return result.join('');`
83
- end
84
-
85
- # Concatenation - Returns a new string containing `other` concatenated onto
86
- # `self`.
87
- #
88
- # @example
89
- #
90
- # 'Hello from ' + self.to_s
91
- # # => 'Hello from main'
92
- #
93
- # @param [String] other string to concatenate
94
- # @return [String]
95
- def +(other)
96
- `return self + other;`
9
+ def ==(other)
10
+ `return self.valueOf() === other.valueOf();`
97
11
  end
98
12
 
99
13
  # Returns a copy of `self` with the first character converted to uppercase and
@@ -226,7 +140,7 @@ class String
226
140
  `var r = pattern.toString();
227
141
  r = r.substr(1, r.lastIndexOf('/') - 1);
228
142
  r = new RegExp(r, 'g');
229
- return self.replace(pattern, function(str) {
143
+ return self.replace(r, function(str) {
230
144
  return replace;
231
145
  });`
232
146
  end
@@ -252,21 +166,12 @@ class String
252
166
  # @param [String] other string to compare
253
167
  # @return [-1, 0, 1, nil] result
254
168
  def <=>(other)
255
- `if (typeof other != 'string') return nil;
169
+ `if (!(other.o$f & T_STRING)) return nil;
256
170
  else if (self > other) return 1;
257
171
  else if (self < other) return -1;
258
172
  return 0;`
259
173
  end
260
174
 
261
- # Equality - if other is not a string, returns false. Otherwise, returns true
262
- # if self <=> other returns zero.
263
- #
264
- # @param [String] other string to compare
265
- # @return [true, false]
266
- def ==(other)
267
- `return self.valueOf() === other.valueOf() ? Qtrue : Qfalse;`
268
- end
269
-
270
175
  # Match - if obj is a Regexp, then uses it to match against self, returning
271
176
  # nil if there is no match, or the index of the match location otherwise. If
272
177
  # obj is not a regexp, then it calls =~ on it, using the receiver as an
@@ -277,8 +182,8 @@ class String
277
182
  # @param [Regexp, Objec] obj
278
183
  # @return [Numeric, nil]
279
184
  def =~(obj)
280
- `if (obj.$flags & $rb.T_STRING) {
281
- $rb.raise(VM.TypeError, "type mismatch: String given");
185
+ `if (obj.o$f & T_STRING) {
186
+ raise(eTypeError, "type mismatch: String given");
282
187
  }`
283
188
 
284
189
  obj =~ self
@@ -313,7 +218,7 @@ class String
313
218
  #
314
219
  # @return [true, false]
315
220
  def empty?
316
- `return self.length == 0 ? Qtrue : Qfalse;`
221
+ `return self.length == 0;`
317
222
  end
318
223
 
319
224
  # Returns true is self ends with the given suffix.
@@ -327,10 +232,10 @@ class String
327
232
  # @return [true, false]
328
233
  def end_with?(suffix)
329
234
  `if (self.lastIndexOf(suffix) == self.length - suffix.length) {
330
- return Qtrue;
235
+ return true;
331
236
  }
332
237
 
333
- return Qfalse;`
238
+ return false;`
334
239
  end
335
240
 
336
241
  # Two strings are equal if they have the same length and content.
@@ -338,7 +243,11 @@ class String
338
243
  # @param [String] other string to compare
339
244
  # @return [true, false]
340
245
  def eql?(other)
341
- `return self == other ? Qtrue : Qfalse;`
246
+ `return self == other;`
247
+ end
248
+
249
+ def +(other)
250
+ `return self + other;`
342
251
  end
343
252
 
344
253
  # Returns true if self contains the given string `other`.
@@ -351,7 +260,7 @@ class String
351
260
  # @param [String] other string to check for
352
261
  # @return [true, false]
353
262
  def include?(other)
354
- `return self.indexOf(other) == -1 ? Qfalse : Qtrue;`
263
+ `return self.indexOf(other) == -1 ? false : true;`
355
264
  end
356
265
 
357
266
  # Returns the index of the first occurance of the given `substr` or pattern in
File without changes
data/lib/opal.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'rbp'
2
+
3
+ require 'opal/parser'
4
+ require 'opal/builder'
5
+ require 'opal/context'
6
+ require 'opal/browserify'
7
+
@@ -0,0 +1,34 @@
1
+ module Opal
2
+
3
+ # Takes a package and builds it ready for the browser
4
+ class Browserify
5
+
6
+ def initialize(package)
7
+ @package = package
8
+ @builder = Builder.new
9
+ end
10
+
11
+ # Simple build - returns a string which can be written to a file
12
+ # FIXME: hardcoded lib directory to './lib'
13
+ def build
14
+ libs = @package.lib_files
15
+ libs.map! do |f|
16
+ path = File.join @package.root, './lib', f
17
+ src = @builder.compile_source path
18
+ "\"#{f}\": #{src}"
19
+ end
20
+
21
+ bundle = []
22
+ bundle << %[opal.package({\n]
23
+ bundle << %[ name: "#{@package.name}",\n]
24
+ bundle << %[ version: "#{@package.version}",\n]
25
+ bundle << %[ libs: {\n]
26
+ bundle << %[ #{libs.join ",\n "}\n]
27
+ bundle << %[ }\n]
28
+ bundle << %[});\n]
29
+
30
+ bundle.join ''
31
+ end
32
+ end
33
+ end
34
+
@@ -1,52 +1,97 @@
1
1
  require 'fileutils'
2
- require 'opal/build_methods'
3
2
 
4
3
  module Opal
5
- # Builder is used for compiling simple ruby files into javascript files
6
- # through the command line or a rake task. It is used for non bundle based
7
- # building systems, and is meant for building small scale pages rather than
8
- # applications.
4
+
5
+ # The Builder class is used for building single ruby sources, or
6
+ # building the core library ready for the browser/v8 context. It
7
+ # is not used directly for building packages.
9
8
  class Builder
10
- include BuildMethods
11
9
 
12
10
  OPAL_PATH = File.expand_path(File.join('..', '..', '..'), __FILE__)
13
11
 
14
- STDLIB_PATH = File.join OPAL_PATH, 'lib'
12
+ STDLIB_PATH = File.join OPAL_PATH, 'stdlib'
15
13
 
16
14
  RUNTIME_PATH = File.join OPAL_PATH, 'runtime'
17
15
 
18
- def build_runtime
19
- code = ''
16
+ CORE_PATH = File.join OPAL_PATH, 'corelib'
20
17
 
21
- %w[pre runtime init class module fs loader debug post].each do |f|
22
- code += File.read(File.join RUNTIME_PATH, f + '.js')
23
- end
18
+ # Returns the result of the compiled file ready for opal to load.
19
+ #
20
+ # `relative_path` is used for the name the built file should have.
21
+ # This is used for building a singular rb or js file into the
22
+ # compiled output, and will avoid the user's dir setup being exposed
23
+ # in production code. It will be of the form
24
+ # `lib/some_lib/some_lib.rb`
25
+ #
26
+ # @param [String] full_path The full pathname to the file to build
27
+ # @paeam [String] relative_path The pathname to be used in the build
28
+ # file.
29
+ #
30
+ # @return [String]
31
+ def wrap_source(full_path, relative_path = nil)
32
+ relative_path ||= full_path
33
+ ext = File.extname full_path
34
+ # relative_path = relative_path.sub(/\.rb/, '.js') if ext == '.rb'
35
+ content = compile_source full_path
36
+
37
+ "opal.lib('#{relative_path}.rb', #{content});\n"
38
+ end
24
39
 
25
- code
40
+ # Simply compile the given source code at the given path. This is
41
+ # for compiling ruby or javascript sources only. This can be used
42
+ # for any method that builds for the browser.
43
+ #
44
+ # @param [String] full_path location of the source to build
45
+ # @return [String] compiled source
46
+ def compile_source(full_path)
47
+ ext = File.extname full_path
48
+ src = File.read full_path
49
+
50
+ case ext
51
+ when '.js'
52
+ "function($rb, self, __FILE__) { #{src} }"
53
+
54
+ when '.rb'
55
+ src = Opal::Parser.new(src).parse!.generate_top
56
+ "function($rb, self, __FILE__) { #{src} }"
57
+
58
+ else
59
+ raise "Bad file type for wrapping. Must be ruby or javascript"
60
+ end
26
61
  end
27
62
 
28
63
  # Builds core opal runtime + core libs, and returns as a string.
29
64
  # This can then just be used directly by any compiled code. The
30
65
  # core lib is then auto loaded so it is ready for running.
31
66
  def build_core
32
- code = build_runtime
33
- code += build_stdlib('core.rb', 'core/*.rb')
34
- code += "opal.require('core');"
67
+ code = ''
35
68
 
36
- code
69
+ %w[pre runtime init class module fs loader].each do |f|
70
+ code += File.read(File.join RUNTIME_PATH, f + '.js')
71
+ end
72
+
73
+ order = File.read(File.join(CORE_PATH, 'load_order')).strip.split
74
+
75
+ core = order.map do |o|
76
+ File.read File.join(CORE_PATH, o + '.rb')
77
+ end
78
+
79
+ code += 'var core_lib = function($rb, self, __FILE__) { ' + Opal::Parser.new(core.join).parse!.generate_top + '};'
80
+
81
+ code + File.read(File.join RUNTIME_PATH, 'post.js')
37
82
  end
38
83
 
39
84
  # Builds the opal parser and dev.rb file, and returns as a string.
40
85
  def build_parser
41
86
  code = ''
42
87
 
43
- %w[opal/ruby/nodes opal/ruby/parser opal/ruby/ruby_parser].each do |src|
44
- full = File.join OPAL_PATH, 'opal_lib', src + '.rb'
88
+ %w[opal/nodes opal/lexer opal/parser].each do |src|
89
+ full = File.join OPAL_PATH, 'lib', src + '.rb'
45
90
  compiled = compile_source full
46
- code += "opal.register('#{src}.rb', #{compiled});"
91
+ code += "opal.lib('#{src}.rb', #{compiled});"
47
92
  end
48
93
 
49
- code += build_stdlib 'racc/parser.rb', 'strscan.rb', 'dev.rb'
94
+ code += build_stdlib 'racc/parser', 'strscan', 'dev'
50
95
  code += "opal.require('dev');"
51
96
 
52
97
  code
@@ -57,9 +102,10 @@ module Opal
57
102
  def build_stdlib(*files)
58
103
  code = []
59
104
  Dir.chdir(STDLIB_PATH) do
60
- Dir.[](*files).each do |lib|
61
- full_path = File.join STDLIB_PATH, lib
62
- code << wrap_source(full_path, lib)
105
+ files.each do |file|
106
+ lib = Dir[file + '.rb']
107
+ full_path = File.join STDLIB_PATH, lib.first
108
+ code << wrap_source(full_path, file)
63
109
  end
64
110
  end
65
111