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/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