Skip to content

Commit 87d1c3a

Browse files
committedSep 27, 2014
Merge pull request #585 from opal/operators
Operators 📈
2 parents 2f9235a + c1c88a9 commit 87d1c3a

File tree

7 files changed

+63
-6
lines changed

7 files changed

+63
-6
lines changed
 

‎benchmarks/operators.rb

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
t1 = Time.now
1+
require "benchmark"
22

3-
a = 0
4-
100000.times do
5-
a = a + 1
3+
time = Benchmark.measure do
4+
a = 0
5+
100000.times do
6+
a = a + 1
7+
end
8+
puts a
69
end
7-
puts a
810

9-
puts Time.now - t1
11+
puts time

‎lib/opal/cli.rb

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ def processor_option_names
133133
dynamic_require_severity
134134
source_map_enabled
135135
irb_enabled
136+
inline_operators
136137
]
137138
end
138139

‎lib/opal/cli_options.rb

+4
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ def initialize
103103
options[:arity_check] = true
104104
end
105105

106+
on('-V', 'Enable inline Operators') do
107+
options[:inline_operators] = true
108+
end
109+
106110
dynamic_require_levels = %w[error warning ignore]
107111
on('-D', '--dynamic-require LEVEL', dynamic_require_levels,
108112
'Set level of dynamic require severity.',

‎lib/opal/compiler.rb

+8
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ def self.compiler_option(name, default_value, options = {})
4545
# Prepare the code for future requires
4646
compiler_option :requirable, false, :as => :requirable?
4747

48+
# are operators compiled inline
49+
compiler_option :inline_operators, false, :as => :inline_operators?
50+
4851
attr_reader :result, :fragments
4952

5053
# Current scope
@@ -84,6 +87,11 @@ def helpers
8487
@helpers ||= Set.new([:breaker, :slice])
8588
end
8689

90+
# Operator helpers
91+
def operator_helpers
92+
@operator_helpers ||= Set.new
93+
end
94+
8795
# Method calls made in this file
8896
def method_calls
8997
@method_calls ||= Set.new

‎lib/opal/nodes/call.rb

+21
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ class CallNode < Base
1111

1212
SPECIALS = {}
1313

14+
# Operators that get optimized by compiler
15+
OPERATORS = { :+ => :plus, :- => :minus, :* => :times, :/ => :divide,
16+
:< => :lt, :<= => :le, :> => :gt, :>= => :ge }
17+
1418
def self.add_special(name, options = {}, &handler)
1519
SPECIALS[name] = options
1620
define_method("handle_#{name}", &handler)
@@ -139,6 +143,23 @@ def compile_default?
139143
@compile_default
140144
end
141145

146+
OPERATORS.each do |operator, name|
147+
add_special(operator.to_sym) do
148+
if compiler.inline_operators?
149+
compiler.operator_helpers << operator.to_sym
150+
lhs, rhs = expr(recvr), expr(arglist[1])
151+
152+
push fragment("$rb_#{name}(")
153+
push lhs
154+
push fragment(", ")
155+
push rhs
156+
push fragment(")")
157+
else
158+
compile_default!
159+
end
160+
end
161+
end
162+
142163
add_special :require do
143164
compile_default!
144165
str = DependencyResolver.new(compiler, arglist[1]).resolve

‎lib/opal/nodes/top.rb

+11
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def compile
2323
add_temp 'nil = $opal.nil'
2424

2525
add_used_helpers
26+
add_used_operators
2627
line scope.to_vars
2728

2829
compile_method_stubs
@@ -66,6 +67,16 @@ def add_used_helpers
6667
helpers.to_a.each { |h| add_temp "$#{h} = $opal.#{h}" }
6768
end
6869

70+
def add_used_operators
71+
operators = compiler.operator_helpers.to_a
72+
operators.each do |op|
73+
name = Nodes::CallNode::OPERATORS[op]
74+
line "function $rb_#{name}(lhs, rhs) {"
75+
line " return (typeof(lhs) === 'number' && typeof(rhs) === 'number') ? lhs #{op} rhs : lhs['$#{op}'](rhs);"
76+
line "}"
77+
end
78+
end
79+
6980
def compile_method_stubs
7081
if compiler.method_missing?
7182
calls = compiler.method_calls

‎stdlib/benchmark.rb

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module Benchmark
2+
3+
def measure(&block)
4+
start = Time.now
5+
yield
6+
Time.now - start
7+
end
8+
9+
module_function :measure
10+
end

0 commit comments

Comments
 (0)
Please sign in to comment.