Skip to content

Commit

Permalink
Use Opal::Compiler as main compiler class
Browse files Browse the repository at this point in the history
  • Loading branch information
adambeynon committed Oct 23, 2013
1 parent 05ed472 commit 74e004a
Show file tree
Hide file tree
Showing 19 changed files with 79 additions and 96 deletions.
2 changes: 2 additions & 0 deletions Gemfile
@@ -1,6 +1,8 @@
source 'https://rubygems.org'
gemspec

gem 'opal-sprockets', :path => '../opal-sprockets'

# Stick with older racc until
# https://github.com/tenderlove/racc/issues/32
# is solved.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -15,11 +15,11 @@ See the website, [http://opalrb.org](http://opalrb.org).

### Compiling ruby code

`Opal.parse` is a simple interface to just compile a string of ruby into a
`Opal.compile` is a simple interface to just compile a string of ruby into a
string of javascript code.

```ruby
Opal.parse("puts 'wow'") # => "(function() { ... })()"
Opal.compile("puts 'wow'") # => "(function() { ... })()"
```

Running this by itself is not enough, you need the opal runtime/corelib.
Expand Down
2 changes: 1 addition & 1 deletion Rakefile
Expand Up @@ -29,7 +29,7 @@ require 'opal-sprockets'
# We can't do this at runtime, so we hijack the method (and make sure we only
# do this at the top level). We figure out which file we are including, and
# add it to our require list
class ::Opal::Parser
class Opal::Compiler
alias_method :mspec_handle_call, :handle_call

def handle_call(sexp)
Expand Down
14 changes: 4 additions & 10 deletions lib/opal.rb
@@ -1,21 +1,15 @@
require 'opal/parser'
require 'opal/require_parser'
require 'opal/compiler'
require 'opal/dependency_compiler'
require 'opal/builder'
require 'opal/erb'
require 'opal/version'

# Opal is a ruby to javascript compiler, with a runtime for running
# in any javascript environment.
#
# Opal::Parser is the core class used for parsing ruby and generating
# javascript from its syntax tree. Opal::Processor is the main system used
# for compiling larger programs. Opal::Processor uses sprockets to maintain
# an environment of load paths, which can be used to require other ruby or
# javascript sources.
module Opal

def self.parse(source, options = {})
Parser.new.parse(source, options)
def self.compile(source, options = {})
Compiler.new.compile(source, options)
end

def self.gem_dir
Expand Down
8 changes: 4 additions & 4 deletions lib/opal/builder.rb
@@ -1,4 +1,4 @@
require 'opal/require_parser'
require 'opal/dependency_compiler'
require 'erb'

module Opal
Expand Down Expand Up @@ -70,10 +70,10 @@ def build_asset(path)
end

def compile_ruby(str, options={})
parser = RequireParser.new
result = parser.parse str, options
compiler = DependencyCompiler.new
result = compiler.compile str, options

parser.requires.each do |r|
compiler.requires.each do |r|
require_asset r
end

Expand Down
29 changes: 9 additions & 20 deletions lib/opal/cli.rb
Expand Up @@ -108,9 +108,9 @@ def show_compiled_source
if sprockets[filename]
puts sprockets[filename].to_a.last
elsif File.exist?(filename)
puts Opal.parse File.read(filename), options
puts Opal.compile File.read(filename), options
else
puts Opal.parse(filename, options)
puts Opal.compile(filename, options)
end
end

Expand All @@ -132,9 +132,9 @@ def set_processor_options
end

def map
parser = Opal::Parser.new
parser.parse(filename, options)
parser.source_map
compiler = Opal::Compiler.new
compiler.compile(filename, options)
compiler.source_map
end

def source
Expand All @@ -153,9 +153,7 @@ def processor_options
]
end




##
# SPROCKETS

def sprockets
Expand Down Expand Up @@ -184,18 +182,14 @@ def require_opal_sprockets
end
end




##
# OUTPUT

def puts *args
output.puts *args
end




##
# EVALS

def evals_source
Expand All @@ -215,16 +209,11 @@ def prepare_eval_code
end
end




##
# SOURCE

def sexp
Opal::Grammar.new.parse(source)
end



end
end
6 changes: 3 additions & 3 deletions lib/opal/parser.rb → lib/opal/compiler.rb
Expand Up @@ -7,7 +7,7 @@
require 'set'

module Opal
class Parser
class Compiler
# Generated code gets indented with two spaces on each scope
INDENT = ' '

Expand Down Expand Up @@ -38,8 +38,8 @@ def initialize
@helpers = Set.new([:breaker, :slice])
end

# Parse some ruby code to a string.
def parse(source, options = {})
# Compile some ruby code to a string.
def compile(source, options = {})
@source = source
setup_options options

Expand Down
10 changes: 5 additions & 5 deletions lib/opal/require_parser.rb → lib/opal/dependency_compiler.rb
@@ -1,17 +1,17 @@
require 'opal/parser'
require 'opal/compiler'

module Opal
# A parser which collects all require() statments for dependency building
class RequireParser < Parser
def self.parse source, options = {}
self.new.parse source, options
class DependencyCompiler < Compiler
def self.compile source, options = {}
self.new.compile source, options
end

# Holds an array of paths which this file 'requires'.
# @return Array<String>
attr_reader :requires

def parse source, options = {}
def compile(source, options = {})
@requires = []
@dynamic_require_severity = (options[:dynamic_require_severity] || :error)
super source, options
Expand Down
6 changes: 3 additions & 3 deletions lib/opal/erb.rb
@@ -1,8 +1,8 @@
require 'opal/parser'
require 'opal/compiler'

module Opal
module ERB
def self.parse(source, file_name = '(erb)')
def self.compile(source, file_name = '(erb)')
Compiler.new.compile source, file_name
end

Expand All @@ -15,7 +15,7 @@ def compile(source, file_name = '(erb)')
self.find_code
self.wrap_compiled

Opal.parse @result
Opal.compile @result
end

def fix_quotes
Expand Down
52 changes: 25 additions & 27 deletions lib/opal/fragment.rb
@@ -1,36 +1,34 @@
module Opal
class Parser
# A fragment holds a string of generated javascript that will be written
# to the destination. It also keeps hold of the original sexp from which
# it was generated. Using this sexp, when writing fragments in order, a
# mapping can be created of the original location => target location,
# aka, source-maps!
class Fragment
# String of javascript this fragment holds
attr_reader :code
# A fragment holds a string of generated javascript that will be written
# to the destination. It also keeps hold of the original sexp from which
# it was generated. Using this sexp, when writing fragments in order, a
# mapping can be created of the original location => target location,
# aka, source-maps!
class Fragment
# String of javascript this fragment holds
attr_reader :code

def initialize(code, sexp = nil)
@code = code.to_s
@sexp = sexp
end
def initialize(code, sexp = nil)
@code = code.to_s
@sexp = sexp
end

# In debug mode we may wish to include the original line as a comment
def to_code
if @sexp
"/*:#{@sexp.line}*/#{@code}"
else
@code
end
# In debug mode we may wish to include the original line as a comment
def to_code
if @sexp
"/*:#{@sexp.line}*/#{@code}"
else
@code
end
end

# inspect the contents of this fragment, f("fooo")
def inspect
"f(#{@code.inspect})"
end
# inspect the contents of this fragment, f("fooo")
def inspect
"f(#{@code.inspect})"
end

def line
@sexp.line if @sexp
end
def line
@sexp.line if @sexp
end
end
end
2 changes: 1 addition & 1 deletion lib/opal/nodes/base.rb
Expand Up @@ -71,7 +71,7 @@ def wrap(pre, post)
end

def fragment(str)
Opal::Parser::Fragment.new str, @sexp
Opal::Fragment.new str, @sexp
end

def error(msg)
Expand Down
4 changes: 2 additions & 2 deletions lib/opal/nodes/helpers.rb
Expand Up @@ -27,7 +27,7 @@ def variable(name)
# are valid in javascript. A $ suffix is added to non-valid names.
# varibales
def lvar_to_js(var)
var = "#{var}$" if Parser::Helpers::RESERVED.include? var.to_s
var = "#{var}$" if RESERVED.include? var.to_s
var.to_sym
end

Expand Down Expand Up @@ -91,7 +91,7 @@ def js_truthy_optimize(sexp)

if mid == :block_given?
expr(sexp)
elsif Parser::COMPARE.include? mid.to_s
elsif Compiler::COMPARE.include? mid.to_s
expr(sexp)
elsif mid == :"=="
expr(sexp)
Expand Down
2 changes: 1 addition & 1 deletion lib/opal/target_scope.rb
Expand Up @@ -35,7 +35,7 @@ class TargetScope
attr_accessor :catch_return

# @param [Symbol] type the scope type (:class, :module, :iter, :def, :top)
# @param [Opal::Parser] parser a parser instance used to create this scope
# @param [Opal::Compiler] parser a parser instance used to create this scope
def initialize(type, parser)
@parser = parser
@type = type
Expand Down
18 changes: 9 additions & 9 deletions spec/opal/parser/irb_spec.rb
@@ -1,43 +1,43 @@
require 'spec_helper'

describe Opal::Parser do
describe Opal::Compiler do
describe "irb parser option" do
before do
@parser = Opal::Parser.new
@compiler = Opal::Compiler.new
end

it "creates Opal.irb_vars if it does not exist" do
$global["Opal"].irb_vars = nil
eval_js(@parser.parse "nil", :irb => true)
eval_js(@compiler.compile "nil", :irb => true)

($global["Opal"].irb_vars == nil).should be_false
end

it "does not create Opal.irb_vars if :irb option not passed" do
$global["Opal"].irb_vars = nil
eval_js(@parser.parse "nil")
eval_js(@compiler.compile "nil")

($global["Opal"].irb_vars == nil).should be_true
end

it "sets each s(:lasgn) in the top level onto irb_vars" do
eval_js @parser.parse "foo = 42", :irb => true
eval_js @compiler.compile "foo = 42", :irb => true
$global["Opal"].irb_vars.foo.should == 42
end

it "gets each s(:lvar) in the top level from irb_vars" do
eval_js @parser.parse "foo = 3.142; bar = foo", :irb => true
eval_js @compiler.compile "foo = 3.142; bar = foo", :irb => true
$global["Opal"].irb_vars.bar.should == 3.142
end

it "persists local vars between parses" do
eval_js @parser.parse "foo = 'hello world'", :irb => true
eval_js @parser.parse "bar = foo.upcase", :irb => true
eval_js @compiler.compile "foo = 'hello world'", :irb => true
eval_js @compiler.compile "bar = foo.upcase", :irb => true
$global["Opal"].irb_vars.bar.should == "HELLO WORLD"
end

it "can still call top level methods" do
eval_js(@parser.parse("to_s", :irb => true)).should == "main"
eval_js(@compiler.compile("to_s", :irb => true)).should == "main"
end
end
end
2 changes: 1 addition & 1 deletion spec/opal/source_map_spec.rb
Expand Up @@ -4,7 +4,7 @@
describe Opal::SourceMap do
before do
pathname = 'foo.rb'
parser = Opal::Parser.new
parser = Opal::Compiler.new
@source = parser.parse("1 + 1", pathname)
@map = Opal::SourceMap.new(parser.fragments, pathname)
end
Expand Down
4 changes: 2 additions & 2 deletions spec/parser/parse_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'

describe Opal::Parser do
describe Opal::Compiler do
it "parses operators before \n in command calls" do
[:<<, :>>, :|, :^, :&, :<=>, :==, :===, :=~, :>, :>=, :<, :<=, :<<, :>>, :%, :**].each do |mid|
opal_parse("self #{mid}\nself").should == [:call, [:self], mid, [:arglist, [:self]]]
Expand Down Expand Up @@ -30,7 +30,7 @@
it "should parse constant lookups" do
eval("Object").should == Object
eval("Array").should == Array
eval("Opal::Parser").should == Opal::Parser
eval("Opal::Compiler").should == Opal::Compiler
end

it "should parse class and module definitions" do
Expand Down

0 comments on commit 74e004a

Please sign in to comment.