Skip to content

Commit

Permalink
Introduce metaclass/new/allocate/initialize to better match Ruby.
Browse files Browse the repository at this point in the history
  • Loading branch information
headius committed Mar 28, 2013
1 parent 9dac9e0 commit 236ffb5
Show file tree
Hide file tree
Showing 15 changed files with 393 additions and 80 deletions.
32 changes: 29 additions & 3 deletions src/main/java/RArray.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,36 @@

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class RArray extends RObject {
public final ArrayList<RObject> impl;

public static class ArrayMeta extends ObjectMeta {
public ArrayMeta(String name) {
super(name);
}

public ArrayMeta() {
super("Array");
}

@Override
public RObject $new(RObject... args) {
return new RArray(args);
}

@Override
public RObject $new() {
return new RArray();
}

@Override
public RObject $new(RObject arg) {
return new RArray(arg);
}
}

public RArray() {
impl = new ArrayList<RObject>();
}
Expand All @@ -21,6 +43,10 @@ public RArray(List<RObject> impl) {
this.impl = new ArrayList<RObject>(impl);
}

public RClass $class() {
return RArray;
}

public RObject $less$less(RObject what) {
impl.add(what);

Expand Down
11 changes: 11 additions & 0 deletions src/main/java/RBoolean.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
public class RBoolean extends RObject {
public final boolean bool;

public static class BooleanMeta extends ObjectMeta {
public BooleanMeta() {
super("Boolean");
}
}

public RBoolean(boolean bool) {
this.bool = bool;
}

public RClass $class() {
return RBoolean;
}

public RObject to_s() {
return new RString(Boolean.toString(bool));
Expand Down
41 changes: 41 additions & 0 deletions src/main/java/RClass.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
public abstract class RClass extends RObject {
protected final RString name;

public RClass(String name) {
this.name = new RString(name);
}

public String toString() {
return name.toString();
}

public RObject to_s() {
return name;
}

public RObject $new(RObject... args) {
RObject object = allocate();
object.initialize(args);
return object;
}

public RObject $new() {
RObject object = allocate();
object.initialize();
return object;
}

public RObject $new(RObject arg) {
RObject object = allocate();
object.initialize(arg);
return object;
}

public RObject allocate() {
throw new RuntimeException("not allocatable: " + name);
}

public RObject name() {
return new RString(name);
}
}
15 changes: 15 additions & 0 deletions src/main/java/RFixnum.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,24 @@

public class RFixnum extends RObject {
public final long fix;

public static final RFixnum ZERO = new RFixnum(0);
public static final RFixnum ONE = new RFixnum(1);
public static final RFixnum TWO = new RFixnum(2);

public static final class FixnumMeta extends ObjectMeta {
public FixnumMeta() {
super("Fixnum");
}
}

public RFixnum(long fix) {
this.fix = fix;
}

public RClass $class() {
return RFixnum;
}

public RObject to_s() {
return new RString(Long.toString(fix));
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/RFloat.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
public class RFloat extends RObject {
public final double flo;

public static class FloatMeta extends ObjectMeta {
public FloatMeta() {
super("Float");
}
}

public RFloat(double flo) {
this.flo = flo;
}

public RClass $class() {
return RFloat;
}

public RObject to_s() {
return new RString(Double.toString(flo));
}
Expand Down
42 changes: 40 additions & 2 deletions src/main/java/RKernel.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,31 @@
public class RKernel {
public static final RObject RNil = new RObject();
public static final RObject RNil = new RNil();
public static final RObject RTrue = new RBoolean(true);
public static final RObject RFalse = new RBoolean(false);
public static final RString.StringMeta RString = new RString.StringMeta();
public static final RArray.ArrayMeta RArray = new RArray.ArrayMeta();
public static final RTime.TimeMeta RTime = new RTime.TimeMeta();
public static final RBoolean.BooleanMeta RBoolean = new RBoolean.BooleanMeta();
public static final RFixnum.FixnumMeta RFixnum = new RFixnum.FixnumMeta();
public static final RFloat.FloatMeta RFloat = new RFloat.FloatMeta();
public static final RNil.NilMeta NilClass = new RNil.NilMeta();

public static final RObject[] NULL_ARRAY = new RObject[0];

public static class ObjectMeta extends RClass {
public ObjectMeta(String name) {
super(name);
}

public ObjectMeta() {
super("Object");
}

public RObject allocate() {
return new RObject();
}
}
public static final ObjectMeta RObject = new ObjectMeta();

public RObject puts(RObject... objects) {
if (objects.length == 0) {
Expand Down Expand Up @@ -36,7 +60,7 @@ public RObject to_f() {
}

public RObject to_s() {
return new RString("#<" + getClass().getName() + ">");
return new RString("#<" + $class().name() + ">");
}

public Object to_java() {
Expand All @@ -55,4 +79,18 @@ public boolean toBoolean() {
public RObject method_missing(RObject name, RObject args) {
throw new RuntimeException("Method '" + name + "' not defined on type " + getClass().getName());
}

public RClass $class() {
Thread.dumpStack();
System.out.println(getClass());
return RObject;
}

public RObject initialize() {
return RNil;
}

public RObject initialize(RObject... args) {
throw new RuntimeException("too many args for #initialize (" + args.length + " for 0)");
}
}
24 changes: 24 additions & 0 deletions src/main/java/RNil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
public class RNil extends RObject {
public static class NilMeta extends RClass {
public NilMeta(String name) {
super(name);
}

public NilMeta() {
super("NilClass");
}
}

public RClass $class() {
return NilClass;
}

@Override
public RString to_s() {
return new RString("nil");
}

public RFixnum to_i() {
return new RFixnum(0);
}
}
31 changes: 31 additions & 0 deletions src/main/java/RString.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,40 @@
public class RString extends RObject implements CharSequence {
private final String str;

public static class StringMeta extends ObjectMeta {
public StringMeta() {
super("String");
}

@Override
public RObject $new(RObject... args) {
return new RString(args);
}

@Override
public RObject $new(RObject arg) {
return new RString(arg);
}
}

public RString(String str) {
this.str = str;
}

public RString(RObject arg) {
this.str = arg.toString();
}

public RString(RObject... args) {
if (args.length > 1) {
throw new RuntimeException("too many arguments for String.new (" + args.length + " for 1)");
}
this.str = args[0].toString();
}

public RClass $class() {
return RString;
}

public String toString() {
return str;
Expand Down
28 changes: 28 additions & 0 deletions src/main/java/RTime.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,30 @@
public class RTime extends RObject {
public final Calendar cal;

public static class TimeMeta extends ObjectMeta {
public TimeMeta(String name) {
super(name);
}

public TimeMeta() {
super("Time");
}

@Override
public RObject $new() {
return new RTime();
}

@Override
public RObject $new(RObject arg) {
Object asJava = arg.to_java();
if (asJava instanceof Calendar) {
return new RTime((Calendar)asJava);
}
throw new RuntimeException("invalid argument type: " + arg.$class().name());
}
}

public RTime() {
this(new GregorianCalendar());
}
Expand All @@ -13,6 +37,10 @@ public RTime(Calendar cal) {
this.cal = cal;
}

public RClass $class() {
return RTime;
}

public RObject to_s() {
return new RString(cal.toString());
}
Expand Down
4 changes: 3 additions & 1 deletion src/main/ruby/ruby_flux.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
require 'ruby_flux/expression_compiler'

module RubyFlux
BUILTINS = %w[puts print]
BUILTINS = %w[puts print $class to_i to_int to_s to_f initialize $new $equal$equal]

Char = java.lang.Character
java_import org.eclipse.jdt.core.dom.AST
Expand All @@ -26,13 +26,15 @@ module RubyFlux
InfixOperator = InfixExpression::Operator

COPIED_SOURCES = %w[
RNil.java
RKernel.java
RFixnum.java
RBoolean.java
RString.java
RFloat.java
RArray.java
RTime.java
RClass.java
]
end

Expand Down
Loading

0 comments on commit 236ffb5

Please sign in to comment.