Skip to content

Commit

Permalink
Implement everything left for mandelbrot.
Browse files Browse the repository at this point in the history
* RTime for Time; only #-, #to_s, .new() work for now
* Return logic plus statement tweaks for non-expression nodes
* While logic
* Body-aware improvements to If logic
* Slightly modified bench_fractal.rb to use Time.new instead of .now
* to_java method added to RKernel
  • Loading branch information
headius committed Dec 11, 2012
1 parent 5687245 commit 0114990
Show file tree
Hide file tree
Showing 11 changed files with 168 additions and 57 deletions.
4 changes: 4 additions & 0 deletions src/main/java/RFixnum.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ public RObject to_s() {
public RObject to_i() {
return this;
}

public Object to_java() {
return fix;
}

public RObject $plus(RObject other) {
if (other instanceof RFloat) {
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/RFloat.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ public RObject to_int() {
public RObject to_f() {
return this;
}

public Object to_java() {
return flo;
}

public RObject $plus(RObject other) {
if (other instanceof RFixnum) {
Expand Down Expand Up @@ -104,6 +108,4 @@ public RObject to_f() {
return flo <= ((RFloat)other.to_f()).flo ? RTrue : RFalse;
}
}


}
14 changes: 12 additions & 2 deletions src/main/java/RKernel.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@ public class RKernel {
public static final RObject RFalse = new RBoolean(false);

public RObject puts(RObject... objects) {
for (RObject object : objects) System.out.println(object);
if (objects.length == 0) {
System.out.println();
} else {
for (RObject object : objects) {
System.out.println(object.to_s());
}
}
return RNil;
}

public RObject print(RObject object) {
System.out.print(object);
System.out.print(object.to_s());
return RNil;
}

Expand All @@ -32,6 +38,10 @@ public RObject to_f() {
public RObject to_s() {
return new RString("#<" + getClass().getName() + ">");
}

public Object to_java() {
return this;
}

public String toString() {
return to_s().toString();
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/RString.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,17 @@ public int length() {
public CharSequence subSequence(int start, int end) {
return str.subSequence(start, end);
}

public RObject to_s() {
return this;
}

public Object to_java() {
return str;
}

public RObject $percent(RObject arg) {
return new RString(String.format(str, arg.to_java()));
}

}
39 changes: 39 additions & 0 deletions src/main/java/RTime.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

import java.util.Calendar;
import java.util.GregorianCalendar;

public class RTime extends RObject {
public final Calendar cal;

public RTime() {
this(new GregorianCalendar());
}

public RTime(Calendar cal) {
this.cal = cal;
}

public RObject to_s() {
return new RString(cal.toString());
}

public RObject to_int() {
return new RFixnum(cal.getTimeInMillis());
}

public RObject to_f() {
return new RFloat(cal.getTimeInMillis() / 1000.0);
}

public Object to_java() {
return cal;
}

public RObject $minus(RObject other) {
if (other instanceof RTime) {
return new RFloat(cal.getTimeInMillis() / 1000.0 - ((RTime)other).cal.getTimeInMillis() / 1000.0);
}

throw new RuntimeException(other.getClass().getName() + " is not a Time object");
}
}
3 changes: 2 additions & 1 deletion src/main/ruby/fast_ruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
require 'fast_ruby/expression_compiler'

module FastRuby
BUILTINS = %w[puts]
BUILTINS = %w[puts print]

Char = java.lang.Character
java_import org.eclipse.jdt.core.dom.AST
Expand All @@ -30,6 +30,7 @@ module FastRuby
RString.java
RFloat.java
RArray.java
RTime.java
]
end

Expand Down
4 changes: 2 additions & 2 deletions src/main/ruby/fast_ruby/body_compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ def start
body.statements << last_var_assign
end

children = defined?(node.child_nodes) ? node.child_nodes : node
children && children.each do |child_node|
children = org.jruby.ast.BlockNode == node ? node.child_nodes : [node]
children.each do |child_node|
statement = StatementCompiler.new(ast, self, child_node).start

body.statements << statement if statement
Expand Down
1 change: 1 addition & 0 deletions src/main/ruby/fast_ruby/compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def build_robject
methods.each do |name, arity|
next if BUILTINS.include? name
method_decl = ast.new_method_declaration

method_decl.name = ast.new_simple_name name
method_decl.modifiers << ast.new_modifier(ModifierKeyword::PUBLIC_KEYWORD)
method_decl.return_type2 = ast.new_simple_type(ast.new_simple_name("RObject"))
Expand Down
50 changes: 42 additions & 8 deletions src/main/ruby/fast_ruby/expression_compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,20 @@ def visitClassNode(node)
end

def visitCallNode(node)
class_compiler.compiler.methods[safe_name(node.name)] = node.args_node ? node.args_node.child_nodes.size : 0

method_invocation = case node.name
when "new"
ast.new_class_instance_creation.tap do |construct|
construct.type = ast.new_simple_type(ast.new_simple_name(node.receiver_node.name))
construct.type = ast.new_simple_type(ast.new_simple_name(proper_class(node.receiver_node.name)))
end
else
ast.new_method_invocation.tap do |method_invocation|
method_invocation.name = ast.new_simple_name(safe_name(node.name))
method_invocation.expression = ExpressionCompiler.new(ast, body_compiler, node.receiver_node).start
if org.jruby.ast.ConstNode === node.receiver_node
method_invocation.expression = ast.new_name(proper_class(node.receiver_node.name))
else
class_compiler.compiler.methods[safe_name(node.name)] = node.args_node ? node.args_node.child_nodes.size : 0
method_invocation.expression = ExpressionCompiler.new(ast, body_compiler, node.receiver_node).start
end
end
end

Expand Down Expand Up @@ -166,13 +169,17 @@ def visitIfNode(node)
conditional.expression = java_boolean

if node.then_body
then_stmt = StatementCompiler.new(ast, body_compiler, node.then_body).start
conditional.then_statement = then_stmt
then_body_compiler = BodyCompiler.new(ast, method_compiler, node.then_body, false, false)
then_body_compiler.declared_vars = body_compiler.declared_vars
then_body_compiler.start
conditional.then_statement = then_body_compiler.body
end

if node.else_body
else_stmt = StatementCompiler.new(ast, body_compiler, node.else_body).start
conditional.else_statement = else_stmt
else_body_compiler = BodyCompiler.new(ast, method_compiler, node.else_body, false, false)
else_body_compiler.declared_vars = body_compiler.declared_vars
else_body_compiler.start
conditional.else_statement = else_body_compiler.body
end

body_compiler.body.statements << conditional
Expand Down Expand Up @@ -237,6 +244,12 @@ def visitWhileNode(node)
nil_expression
end

def visitReturnNode(node)
return_expr = ExpressionCompiler.new(ast, body_compiler, node.value_node).start

[:return, return_expr]
end

def safe_name(name)
new_name = ''

Expand All @@ -263,5 +276,26 @@ def safe_name(name)

new_name
end

def proper_class(name)
case name
when 'String'
'RString'
when 'Array'
'RArray'
when 'Fixnum'
'RFixnum'
when 'Boolean'
'RBoolean'
when 'Float'
'RFloat'
when 'Time'
'RTime'
when 'Object'
'RObject'
else
name
end
end
end
end
14 changes: 13 additions & 1 deletion src/main/ruby/fast_ruby/statement_compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,23 @@ def start
expression = ExpressionCompiler.new(ast, body_compiler, node).start

if expression
if Array === expression
type, expression = expression
end

last_assignment = ast.new_assignment
last_assignment.left_hand_side = ast.new_simple_name("$last")
last_assignment.right_hand_side = expression

ast.new_expression_statement(last_assignment)
case type
when :return
body_compiler.body.statements << ast.new_expression_statement(last_assignment)
ast.new_return_statement.tap do |return_stmt|
return_stmt.expression = ast.new_name('$last')
end
else
ast.new_expression_statement(last_assignment)
end
else
ast.new_empty_statement
end
Expand Down
78 changes: 37 additions & 41 deletions src/test/ruby/bench_fractal.rb
Original file line number Diff line number Diff line change
@@ -1,55 +1,51 @@
#!/usr/local/bin/ruby

class Mandelbrot
BAILOUT = 16
MAX_ITERATIONS = 1000
BAILOUT = 16
MAX_ITERATIONS = 1000

def initialize
def fractal
puts "Rendering"
y = -39
while y <= 39
puts
x = -39
while x <= 39
i = iterate(x/40.0,y/40.0)
if (i == 0)
print "*"
else
print " "
end
x+=1
y = -39
while y <= 39
puts
x = -39
while x <= 39
i = iterate(x/40.0,y/40.0)
if (i == 0)
print "*"
else
print " "
end
y+=1
end
end
x+=1
end
y+=1
end
end

def iterate(x,y)
cr = y-0.5
ci = x
zi = 0.0
zr = 0.0
i = 0
def iterate(x,y)
cr = y-0.5
ci = x
zi = 0.0
zr = 0.0
i = 0

while(1)
i += 1
temp = zr * zi
zr2 = zr * zr
zi2 = zi * zi
zr = zr2 - zi2 + cr
zi = temp + temp + ci
return i if (zi2 + zr2 > BAILOUT)
return 0 if (i > MAX_ITERATIONS)
end

end

while(1)
i += 1
temp = zr * zi
zr2 = zr * zr
zi2 = zi * zi
zr = zr2 - zi2 + cr
zi = temp + temp + ci
return i if (zi2 + zr2 > BAILOUT)
return 0 if (i > MAX_ITERATIONS)
end
end

i = 0
while i < 10
time = Time.now
Mandelbrot.new
time = Time.new
fractal
puts
puts "Ruby Elapsed %f" % (Time.now - time)
puts "Ruby Elapsed %f" % (Time.new - time)
i+=1
end

0 comments on commit 0114990

Please sign in to comment.