opal 0.3.10 → 0.3.11
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.
- data/README.md +47 -46
- data/lib/opal.rb +11 -3
- data/lib/opal/builder.rb +4 -46
- data/lib/opal/bundle.rb +11 -25
- data/lib/opal/command.rb +101 -22
- data/lib/opal/context.rb +16 -50
- data/lib/opal/lexer.rb +21 -2
- data/lib/opal/nodes.rb +134 -20
- data/lib/opal/parser.rb +7 -7
- data/lib/opal/parser.y +7 -7
- data/lib/opal/rake/bundle_task.rb +24 -23
- data/lib/opal/version.rb +3 -0
- data/opal-parser.js +8343 -0
- data/opal.js +5685 -0
- data/stdlib/dev.rb +6 -4
- data/templates/init/Rakefile +7 -0
- data/templates/init/index.html +17 -0
- data/templates/init/lib/__NAME__.rb +2 -0
- metadata +9 -32
- data/corelib/array.rb +0 -1424
- data/corelib/boolean.rb +0 -20
- data/corelib/class.rb +0 -58
- data/corelib/core.rb +0 -66
- data/corelib/dir.rb +0 -22
- data/corelib/enumerable.rb +0 -33
- data/corelib/error.rb +0 -19
- data/corelib/file.rb +0 -60
- data/corelib/hash.rb +0 -729
- data/corelib/kernel.rb +0 -251
- data/corelib/load_order +0 -21
- data/corelib/match_data.rb +0 -33
- data/corelib/module.rb +0 -101
- data/corelib/nil_class.rb +0 -54
- data/corelib/numeric.rb +0 -352
- data/corelib/object.rb +0 -37
- data/corelib/proc.rb +0 -55
- data/corelib/range.rb +0 -27
- data/corelib/regexp.rb +0 -69
- data/corelib/string.rb +0 -300
- data/corelib/top_self.rb +0 -8
- data/runtime/class.js +0 -386
- data/runtime/fs.js +0 -199
- data/runtime/init.js +0 -556
- data/runtime/loader.js +0 -330
- data/runtime/module.js +0 -103
- data/runtime/post.js +0 -10
- data/runtime/pre.js +0 -7
- data/runtime/runtime.js +0 -345
data/README.md
CHANGED
@@ -17,16 +17,10 @@ Opal does not aim to be 100% comaptible with other ruby implementations,
|
|
17
17
|
but does so where the generated code can be efficient on all modern web
|
18
18
|
browsers - including older versions of IE and mobile devices.
|
19
19
|
|
20
|
-
|
20
|
+
Installing opal
|
21
21
|
----------
|
22
22
|
|
23
|
-
|
24
|
-
directly in the web browser or with rbp - a new package manager designed
|
25
|
-
for opal but usable for any ruby project.
|
26
|
-
|
27
|
-
### Using the gem
|
28
|
-
|
29
|
-
Install via ruby gems:
|
23
|
+
Install the gem:
|
30
24
|
|
31
25
|
```
|
32
26
|
$ gem install opal
|
@@ -38,66 +32,73 @@ The `opal` command should then be available. To run the simple repl use:
|
|
38
32
|
opal irb
|
39
33
|
```
|
40
34
|
|
41
|
-
|
42
|
-
|
35
|
+
Usage
|
36
|
+
-----
|
37
|
+
|
38
|
+
The quickest way to get opal running is to use the project generator.
|
39
|
+
Simply run the command:
|
43
40
|
|
44
41
|
```
|
45
|
-
|
46
|
-
$ cd opal
|
47
|
-
$ bin/opal
|
42
|
+
opal init my_project
|
48
43
|
```
|
49
44
|
|
50
|
-
|
45
|
+
replacing "my_project" with any name. This will make a "my_project"
|
46
|
+
directory with a Rakefile, html document and libs needed for running
|
47
|
+
opal in the browser.
|
51
48
|
|
52
|
-
|
53
|
-
package.yml file to add the following dependency:
|
49
|
+
### Using opal in the browser
|
54
50
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
51
|
+
Opal runs directly in the browser, and is distributed as two files,
|
52
|
+
`opal.js` and `opal-parser.js`. To just run precompiled code, just the
|
53
|
+
`opal.js` runtime is required which includes the runtime and opals
|
54
|
+
implementation of the ruby core library (pre compiled).
|
55
|
+
|
56
|
+
To evaluate ruby code directly in the browser, `opal-parser.js` is also
|
57
|
+
required which will also load any ruby code found in script tags.
|
60
58
|
|
61
|
-
|
59
|
+
### Bundle
|
60
|
+
|
61
|
+
The Rakefile has a task to build your ruby project, so just run:
|
62
62
|
|
63
63
|
```
|
64
|
-
|
64
|
+
rake bundle
|
65
65
|
```
|
66
66
|
|
67
|
-
|
68
|
-
|
69
|
-
directly on the commandline. If you are just compiling ruby then just
|
70
|
-
the opal package is sufficient.
|
67
|
+
Open `index.html` in a browser, and now it should run. Edit, build and
|
68
|
+
run to suit.
|
71
69
|
|
72
|
-
|
73
|
-
|
70
|
+
Project structure
|
71
|
+
-----------------
|
74
72
|
|
75
|
-
|
76
|
-
|
77
|
-
|
73
|
+
This repo contains the code for the opal gem as well as the opal core
|
74
|
+
library and runtime. Files inside `bin/` and `lib/` are the files that
|
75
|
+
are used as part of the gem and run directly on your ruby environment.
|
78
76
|
|
79
|
-
|
80
|
-
|
81
|
-
|
77
|
+
`corelib/` contains opal's core library implementation and is not used
|
78
|
+
directly by the gem. These files are precompiled during development
|
79
|
+
ready to be used in the gem or in a browser.
|
82
80
|
|
83
|
-
|
84
|
-
|
81
|
+
`runtime/` contains opal's runtime written in javascript. It is not used
|
82
|
+
directly by the gem, but is built ready to use in the js contexts that
|
83
|
+
opal runs.
|
85
84
|
|
86
|
-
|
87
|
-
|
88
|
-
|
85
|
+
`stdlib/` contains the stdlib files that opal comes packaged with. The
|
86
|
+
gem does use these, but only as required. Opal does not include the full
|
87
|
+
opal stdlib, and some parts are actually written in javascript for
|
88
|
+
optimal performance. These can be `require()` at runtime.
|
89
89
|
|
90
|
-
|
90
|
+
`opal.js` and `opal-parser.js` are included in the gem, but not the
|
91
|
+
source repo. They are the latest built versions of opal and its parser
|
92
|
+
which are built before the gem is published.
|
91
93
|
|
92
94
|
Differences from ruby
|
93
95
|
---------------------
|
94
96
|
|
95
|
-
###
|
97
|
+
### Optional method\_missing
|
96
98
|
|
97
|
-
To optimize method dispatch, `method_missing` is
|
98
|
-
|
99
|
-
|
100
|
-
production code.
|
99
|
+
To optimize method dispatch, `method_missing` is, by default, turned off
|
100
|
+
in opal. It can easily be enabled by passing `:method_missing => true`
|
101
|
+
in the parser options.
|
101
102
|
|
102
103
|
### Immutable strings and removed symbols
|
103
104
|
|
data/lib/opal.rb
CHANGED
@@ -1,12 +1,20 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "opal/parser"
|
2
|
+
require "opal/builder"
|
3
|
+
require "opal/context"
|
4
|
+
require "opal/version"
|
4
5
|
|
5
6
|
# Opal is a set of build tools and runtime utilies for compiling ruby
|
6
7
|
# source code into javascript. Opal can use therubyracer to provide a
|
7
8
|
# ruby context for evaluating the generated javascript against the
|
8
9
|
# provided runtime.
|
9
10
|
module Opal
|
11
|
+
# Root opal directory (root of gem)
|
10
12
|
OPAL_DIR = File.expand_path('../..', __FILE__)
|
13
|
+
|
14
|
+
# Full path to our opal.js runtime file
|
15
|
+
OPAL_JS_PATH = File.join OPAL_DIR, "opal.js"
|
16
|
+
|
17
|
+
# Full path to our opal-parser.js parser file
|
18
|
+
OPAL_PARSER_JS_PATH = File.join OPAL_DIR, "opal-parser.js"
|
11
19
|
end
|
12
20
|
|
data/lib/opal/builder.rb
CHANGED
@@ -1,21 +1,17 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
require 'opal/parser'
|
3
|
+
require 'opal/version'
|
3
4
|
|
4
5
|
module Opal
|
5
|
-
|
6
6
|
# The Builder class is used for building single ruby sources, or
|
7
7
|
# building the core library ready for the browser/v8 context. It
|
8
|
-
# is not used directly for building
|
8
|
+
# is not used directly for building gem.
|
9
9
|
class Builder
|
10
10
|
|
11
11
|
OPAL_PATH = File.expand_path(File.join('..', '..', '..'), __FILE__)
|
12
12
|
|
13
13
|
STDLIB_PATH = File.join OPAL_PATH, 'stdlib'
|
14
14
|
|
15
|
-
RUNTIME_PATH = File.join OPAL_PATH, 'runtime'
|
16
|
-
|
17
|
-
CORE_PATH = File.join OPAL_PATH, 'corelib'
|
18
|
-
|
19
15
|
def initialize
|
20
16
|
@parser = Parser.new
|
21
17
|
end
|
@@ -43,7 +39,7 @@ module Opal
|
|
43
39
|
# relative_path = relative_path.sub(/\.rb/, '.js') if ext == '.rb'
|
44
40
|
content = compile_source full_path
|
45
41
|
|
46
|
-
"opal.lib('#{relative_path}
|
42
|
+
"opal.lib('#{relative_path}', #{content});\n"
|
47
43
|
end
|
48
44
|
|
49
45
|
# Simply compile the given source code at the given path. This is
|
@@ -61,51 +57,13 @@ module Opal
|
|
61
57
|
"function($rb, self, __FILE__) { #{src} }"
|
62
58
|
|
63
59
|
when '.rb'
|
64
|
-
|
65
|
-
"function($rb, self, __FILE__) { #{src} }"
|
60
|
+
return parse src
|
66
61
|
|
67
62
|
else
|
68
63
|
raise "Bad file type for wrapping. Must be ruby or javascript"
|
69
64
|
end
|
70
65
|
end
|
71
66
|
|
72
|
-
# Builds core opal runtime + core libs, and returns as a string.
|
73
|
-
# This can then just be used directly by any compiled code. The
|
74
|
-
# core lib is then auto loaded so it is ready for running.
|
75
|
-
def build_core
|
76
|
-
code = ''
|
77
|
-
|
78
|
-
%w[pre runtime init class module fs loader].each do |f|
|
79
|
-
code += File.read(File.join RUNTIME_PATH, f + '.js')
|
80
|
-
end
|
81
|
-
|
82
|
-
order = File.read(File.join(CORE_PATH, 'load_order')).strip.split
|
83
|
-
|
84
|
-
core = order.map do |o|
|
85
|
-
File.read File.join(CORE_PATH, o + '.rb')
|
86
|
-
end
|
87
|
-
|
88
|
-
code += "var core_lib = #{parse core.join};"
|
89
|
-
|
90
|
-
code + File.read(File.join RUNTIME_PATH, 'post.js')
|
91
|
-
end
|
92
|
-
|
93
|
-
# Builds the opal parser and dev.rb file, and returns as a string.
|
94
|
-
def build_parser
|
95
|
-
code = ''
|
96
|
-
|
97
|
-
%w[opal/nodes opal/lexer opal/parser].each do |src|
|
98
|
-
full = File.join OPAL_PATH, 'lib', src + '.rb'
|
99
|
-
compiled = compile_source full
|
100
|
-
code += "opal.lib('#{src}.rb', #{compiled});"
|
101
|
-
end
|
102
|
-
|
103
|
-
code += build_stdlib 'racc/parser', 'strscan', 'dev'
|
104
|
-
code += "opal.require('dev');"
|
105
|
-
|
106
|
-
code
|
107
|
-
end
|
108
|
-
|
109
67
|
# Build the given sources from the standard library. These can be
|
110
68
|
# globs. Returns a string of all content.
|
111
69
|
def build_stdlib(*files)
|
data/lib/opal/bundle.rb
CHANGED
@@ -1,41 +1,27 @@
|
|
1
1
|
require 'opal/builder'
|
2
2
|
|
3
|
-
begin
|
4
|
-
require 'rbp/package'
|
5
|
-
rescue LoadError
|
6
|
-
abort "You need to install rbp. `gem install rbp`."
|
7
|
-
end
|
8
|
-
|
9
3
|
module Opal
|
10
|
-
# Takes a package and builds it ready for the browser
|
11
4
|
class Bundle
|
12
|
-
|
13
|
-
|
14
|
-
|
5
|
+
attr_accessor :name
|
6
|
+
attr_accessor :version
|
15
7
|
attr_accessor :options
|
16
8
|
|
17
|
-
def initialize
|
18
|
-
@
|
19
|
-
@builder = Builder.new
|
9
|
+
def initialize
|
10
|
+
@builder = Builder.new
|
20
11
|
@options = {}
|
21
12
|
end
|
22
13
|
|
23
|
-
# Simple build - returns a string which can be written to a file
|
24
|
-
# FIXME: hardcoded lib directory to './lib'
|
25
14
|
def build
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
path
|
30
|
-
code = @builder.parse File.read(path), options
|
31
|
-
|
32
|
-
"\"#{lib}\": #{code}"
|
15
|
+
lib_files = Dir["{lib}/**/*.rb"].map do |lib|
|
16
|
+
code = @builder.parse File.read(lib), options
|
17
|
+
path = lib[4, lib.length - 7]
|
18
|
+
"\"#{path}\": #{code}"
|
33
19
|
end
|
34
20
|
|
35
21
|
bundle = []
|
36
|
-
bundle << %[opal.
|
37
|
-
bundle << %[ name: "#{@
|
38
|
-
bundle << %[ version: "#{@
|
22
|
+
bundle << %[opal.gem({\n]
|
23
|
+
bundle << %[ name: "#{@name}",\n]
|
24
|
+
bundle << %[ version: "#{@version}",\n]
|
39
25
|
bundle << %[ libs: {\n]
|
40
26
|
bundle << %[ #{lib_files.join ",\n "}\n]
|
41
27
|
bundle << %[ }\n]
|
data/lib/opal/command.rb
CHANGED
@@ -1,15 +1,20 @@
|
|
1
|
-
|
1
|
+
require 'optparse'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'opal/builder'
|
2
4
|
|
5
|
+
module Opal
|
6
|
+
# Command runner. When using the `opal` bin file, this class is used to
|
7
|
+
# delegate commands based on the options passed from the command line.
|
3
8
|
class Command
|
4
9
|
|
5
10
|
# Valid command line arguments
|
6
|
-
COMMANDS = [:help, :irb, :compile, :bundle, :exec, :eval, :install]
|
11
|
+
COMMANDS = [:help, :irb, :compile, :bundle, :exec, :eval, :install, :init]
|
7
12
|
|
8
13
|
def initialize(args)
|
9
14
|
command = args.shift
|
10
15
|
|
11
16
|
if command and COMMANDS.include?(command.to_sym)
|
12
|
-
__send__ command.to_sym
|
17
|
+
__send__ command.to_sym
|
13
18
|
elsif command and File.exists? command
|
14
19
|
eval command
|
15
20
|
else
|
@@ -17,36 +22,113 @@ module Opal
|
|
17
22
|
end
|
18
23
|
end
|
19
24
|
|
25
|
+
# Initialize a project either in current directory, or directory
|
26
|
+
# specified in ARGV.
|
27
|
+
def init
|
28
|
+
path = File.expand_path(ARGV.first || Dir.getwd)
|
29
|
+
base = File.basename(path)
|
30
|
+
template = File.join(OPAL_DIR, "templates", "init")
|
31
|
+
|
32
|
+
Dir.chdir(template) do
|
33
|
+
Dir["**/*"].each do |f|
|
34
|
+
next if File.directory? f
|
35
|
+
|
36
|
+
full = File.expand_path f, template
|
37
|
+
dest = File.join path, f.sub(/__NAME__/, base)
|
38
|
+
|
39
|
+
if File.exists? dest
|
40
|
+
puts "Skipping #{f}"
|
41
|
+
next
|
42
|
+
end
|
43
|
+
|
44
|
+
FileUtils.mkdir_p File.dirname(dest)
|
45
|
+
|
46
|
+
File.open(dest, 'w+') do |o|
|
47
|
+
o.write File.read(full).gsub(/__NAME__/, base)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
FileUtils.mkdir_p File.join(path, "js")
|
53
|
+
|
54
|
+
%w[opal.js opal-parser.js].each do |src|
|
55
|
+
File.open(File.join(path, "js", src), "w+") do |o|
|
56
|
+
o.write File.read(File.join(OPAL_DIR, src))
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
20
61
|
def help
|
21
62
|
puts "need to print help"
|
22
63
|
end
|
23
64
|
|
24
|
-
#
|
25
|
-
|
26
|
-
|
65
|
+
# Starts an irb session using an inline v8 context. Commands can be
|
66
|
+
# entered just like IRB. Use Ctrl-C or type `exit` to quit.
|
67
|
+
def irb(*)
|
68
|
+
ctx = Context.new :method_missing => true,
|
69
|
+
:overload_arithmetic => true,
|
70
|
+
:overload_comparison => true,
|
71
|
+
:overload_bitwise => true
|
27
72
|
ctx.start_repl
|
28
73
|
end
|
29
74
|
|
30
|
-
|
31
|
-
|
75
|
+
# If the given arg exists as a file, then the source code is compiled
|
76
|
+
# and then run through a javascript context and the result printed out.
|
77
|
+
#
|
78
|
+
# If the arg isn't a file, then it is assumed to be raw ruby code and it
|
79
|
+
# is compiled and run directly with the result being printed out.
|
80
|
+
#
|
81
|
+
# Usage:
|
82
|
+
#
|
83
|
+
# opal eval path/to/some/file.rb
|
84
|
+
# # => "some result"
|
85
|
+
#
|
86
|
+
# opal eval "1.class"
|
87
|
+
# # => Numeric
|
88
|
+
#
|
89
|
+
# @param [String] code path or ruby code to eval
|
90
|
+
def eval(code = nil, *)
|
91
|
+
abort "Usage: opal eval [Ruby code or file path]" unless code
|
92
|
+
|
93
|
+
if File.exists? code
|
94
|
+
code = Parser.new.parse File.read(code)
|
95
|
+
end
|
32
96
|
|
33
|
-
|
97
|
+
context = Context.new :method_missing => true,
|
98
|
+
:overload_arithmetic => true,
|
99
|
+
:overload_comparison => true,
|
100
|
+
:overload_bitwise => true
|
34
101
|
|
35
|
-
|
36
|
-
ctx.require_file File.expand_path(path)
|
102
|
+
puts context.eval code
|
37
103
|
end
|
38
104
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
105
|
+
# If the given path exists, then compiles the source code of that
|
106
|
+
# file and spits out the generated javascript.
|
107
|
+
#
|
108
|
+
# If this file does not exist, then assumes the input is ruby code
|
109
|
+
# to compile and return.
|
110
|
+
#
|
111
|
+
# Usage:
|
112
|
+
#
|
113
|
+
# opal compile path/to/ruby.rb
|
114
|
+
# # => "generated code"
|
115
|
+
#
|
116
|
+
# opal compile "some ruby code"
|
117
|
+
# # => generated code
|
118
|
+
#
|
119
|
+
# @param [String] path file path or ruby code
|
120
|
+
def compile(path = nil, *)
|
121
|
+
abort "Usage: opal compile [Ruby code or file path]" unless path
|
122
|
+
|
123
|
+
if File.exists? path
|
124
|
+
puts Parser.new.parse File.read(path)
|
125
|
+
else
|
126
|
+
puts Parser.new.parse path
|
127
|
+
end
|
46
128
|
end
|
47
129
|
|
48
130
|
# Bundle the gem (browserify) ready for the browser
|
49
|
-
def bundle
|
131
|
+
def bundle(*)
|
50
132
|
# lazy load incase user does not have rbp installed
|
51
133
|
require 'opal/bundle'
|
52
134
|
|
@@ -54,9 +136,6 @@ module Opal
|
|
54
136
|
package = Rbp::Package.load_path path
|
55
137
|
bundle = Bundle.new package
|
56
138
|
|
57
|
-
puts bundle
|
58
|
-
puts bundle.package
|
59
|
-
|
60
139
|
puts bundle.build
|
61
140
|
end
|
62
141
|
end
|