diff options
author | Rich Hickey <richhickey@gmail.com> | 2008-01-06 17:13:59 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2008-01-06 17:13:59 +0000 |
commit | ebe40313d671a1cbc9930e58b550a68d1da3c075 (patch) | |
tree | 17b15c201f8b3bf2be00e8cf02c812a44a5b0b76 /src/jvm/clojure | |
parent | 433fc199d68217c4d048eaeac81d7ff9f6928c7e (diff) |
first cut of true/false support
Diffstat (limited to 'src/jvm/clojure')
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 96 | ||||
-rw-r--r-- | src/jvm/clojure/lang/LispReader.java | 9 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Num.java | 10 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 24 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Reflector.java | 12 |
5 files changed, 113 insertions, 38 deletions
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 7b825b76..dd3fe7e1 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -117,6 +117,7 @@ private static final Type RT_TYPE = Type.getType(RT.class); final static Type CLASS_TYPE = Type.getType(Class.class); final static Type REFLECTOR_TYPE = Type.getType(Reflector.class); final static Type THROWABLE_TYPE = Type.getType(Throwable.class); +final static Type BOOLEAN_OBJECT_TYPE = Type.getType(Boolean.class); private static final Type[][] ARG_TYPES; private static final Type[] EXCEPTION_TYPES = {Type.getType(Exception.class)}; @@ -561,10 +562,11 @@ static abstract class HostExpr implements Expr{ Label falseLabel = gen.newLabel(); Label endLabel = gen.newLabel(); gen.ifZCmp(GeneratorAdapter.EQ, falseLabel); - gen.getStatic(RT_TYPE, "T", KEYWORD_TYPE); + gen.getStatic(BOOLEAN_OBJECT_TYPE, "TRUE", BOOLEAN_OBJECT_TYPE); gen.goTo(endLabel); gen.mark(falseLabel); - NIL_EXPR.emit(C.EXPRESSION, fn, gen); + gen.getStatic(BOOLEAN_OBJECT_TYPE, "FALSE", BOOLEAN_OBJECT_TYPE); +// NIL_EXPR.emit(C.EXPRESSION, fn, gen); gen.mark(endLabel); } else if(returnType == void.class) @@ -1134,8 +1136,41 @@ static class NilExpr extends LiteralExpr{ } } -static NilExpr NIL_EXPR = new NilExpr(); +final static NilExpr NIL_EXPR = new NilExpr(); + +static class BooleanExpr extends LiteralExpr{ + final boolean val; + + + public BooleanExpr(boolean val){ + this.val = val; + } + + Object val(){ + return val ? RT.T : RT.F; + } + + public void emit(C context, FnExpr fn, GeneratorAdapter gen){ + if(context != C.STATEMENT) + { + if(val) + gen.getStatic(BOOLEAN_OBJECT_TYPE, "TRUE", BOOLEAN_OBJECT_TYPE); + else + gen.getStatic(BOOLEAN_OBJECT_TYPE, "FALSE", BOOLEAN_OBJECT_TYPE); + } + } + + public boolean hasJavaClass(){ + return true; + } + + public Class getJavaClass() throws Exception{ + return Boolean.class; + } +} +final static BooleanExpr TRUE_EXPR = new BooleanExpr(true); +final static BooleanExpr FALSE_EXPR = new BooleanExpr(false); static class NumExpr extends LiteralExpr{ final Num num; @@ -1711,7 +1746,7 @@ static class NewExpr implements Expr{ } -static class IdenticalExpr extends UntypedExpr{ +static class IdenticalExpr implements Expr{ final Expr expr1; final Expr expr2; @@ -1721,9 +1756,17 @@ static class IdenticalExpr extends UntypedExpr{ this.expr2 = expr2; } + public boolean hasJavaClass(){ + return true; + } + + public Class getJavaClass(){ + return Boolean.class; + } + public Object eval() throws Exception{ return expr1.eval() == expr2.eval() ? - RT.T : null; + RT.T : RT.F; } public void emit(C context, FnExpr fn, GeneratorAdapter gen){ @@ -1734,10 +1777,12 @@ static class IdenticalExpr extends UntypedExpr{ expr1.emit(C.EXPRESSION, fn, gen); expr2.emit(C.EXPRESSION, fn, gen); gen.visitJumpInsn(IF_ACMPNE, not); - gen.getStatic(RT_TYPE, "T", KEYWORD_TYPE); + gen.getStatic(BOOLEAN_OBJECT_TYPE, "TRUE", BOOLEAN_OBJECT_TYPE); +// gen.getStatic(RT_TYPE, "T", KEYWORD_TYPE); gen.goTo(end); gen.mark(not); - NIL_EXPR.emit(C.EXPRESSION, fn, gen); + gen.getStatic(BOOLEAN_OBJECT_TYPE, "FALSE", BOOLEAN_OBJECT_TYPE); +// NIL_EXPR.emit(C.EXPRESSION, fn, gen); gen.mark(end); } } @@ -1753,7 +1798,7 @@ static class IdenticalExpr extends UntypedExpr{ } } -static class InstanceExpr extends UntypedExpr{ +static class InstanceExpr implements Expr{ final Expr expr; final String className; @@ -1765,7 +1810,15 @@ static class InstanceExpr extends UntypedExpr{ public Object eval() throws Exception{ return Class.forName(className).isInstance(expr.eval()) ? - RT.T : null; + RT.T : RT.F; + } + + public boolean hasJavaClass(){ + return true; + } + + public Class getJavaClass(){ + return Boolean.class; } public void emit(C context, FnExpr fn, GeneratorAdapter gen){ @@ -1776,10 +1829,12 @@ static class InstanceExpr extends UntypedExpr{ expr.emit(C.EXPRESSION, fn, gen); gen.instanceOf(Type.getObjectType(className.replace('.', '/'))); gen.ifZCmp(GeneratorAdapter.EQ, not); - gen.getStatic(RT_TYPE, "T", KEYWORD_TYPE); + gen.getStatic(BOOLEAN_OBJECT_TYPE, "TRUE", BOOLEAN_OBJECT_TYPE); +// gen.getStatic(RT_TYPE, "T", KEYWORD_TYPE); gen.goTo(end); gen.mark(not); - NIL_EXPR.emit(C.EXPRESSION, fn, gen); + gen.getStatic(BOOLEAN_OBJECT_TYPE, "FALSE", BOOLEAN_OBJECT_TYPE); +// NIL_EXPR.emit(C.EXPRESSION, fn, gen); gen.mark(end); } } @@ -1850,22 +1905,29 @@ static class IfExpr implements Expr{ } public Object eval() throws Exception{ - if(testExpr.eval() != null) + Object t = testExpr.eval(); + if(t != null && t != Boolean.FALSE) return thenExpr.eval(); return elseExpr.eval(); } public void emit(C context, FnExpr fn, GeneratorAdapter gen){ - Label elseLabel = gen.newLabel(); + Label nullLabel = gen.newLabel(); + Label falseLabel = gen.newLabel(); Label endLabel = gen.newLabel(); gen.visitLineNumber(line, gen.mark()); testExpr.emit(C.EXPRESSION, fn, gen); - gen.ifNull(elseLabel); + gen.dup(); + gen.ifNull(nullLabel); + gen.getStatic(BOOLEAN_OBJECT_TYPE, "FALSE", BOOLEAN_OBJECT_TYPE); + gen.visitJumpInsn(IF_ACMPEQ, falseLabel); thenExpr.emit(context, fn, gen); gen.goTo(endLabel); - gen.mark(elseLabel); + gen.mark(nullLabel); + gen.pop(); + gen.mark(falseLabel); elseExpr.emit(context, fn, gen); gen.mark(endLabel); } @@ -2910,6 +2972,10 @@ private static Expr analyze(C context, Object form, String name) throws Exceptio //todo symbol macro expansion? if(form == null) return NIL_EXPR; + else if(form == Boolean.TRUE) + return TRUE_EXPR; + else if(form == Boolean.FALSE) + return FALSE_EXPR; Class fclass = form.getClass(); if(fclass == Symbol.class) return analyzeSymbol((Symbol) form); diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java index c41ff6fb..52db79c6 100644 --- a/src/jvm/clojure/lang/LispReader.java +++ b/src/jvm/clojure/lang/LispReader.java @@ -190,7 +190,14 @@ static private Object interpretToken(String s) throws Exception{ {
return null;
}
-
+ else if(s.equals("true"))
+ {
+ return RT.T;
+ }
+ else if(s.equals("false"))
+ {
+ return RT.F;
+ }
else if(s.equals("/"))
{
return SLASH;
diff --git a/src/jvm/clojure/lang/Num.java b/src/jvm/clojure/lang/Num.java index 3aa5f3b1..5d8df4f5 100644 --- a/src/jvm/clojure/lang/Num.java +++ b/src/jvm/clojure/lang/Num.java @@ -111,11 +111,11 @@ static public Object[] truncate(Object num, Object div){ } static public Object quotient(Object num, Object div){ - return truncate(num,div)[0]; + return truncate(num, div)[0]; } static public Object remainder(Object num, Object div){ - return truncate(num,div)[1]; + return truncate(num, div)[1]; } abstract public Object[] truncateDivide(Num rhs); @@ -188,15 +188,15 @@ static public Num negate(Object x){ } static public Object negPred(Object x){ - return Num.from(x).minusp() ? RT.T : null; + return Num.from(x).minusp() ? RT.T : RT.F; } static public Object posPred(Object x){ - return Num.from(x).plusp() ? RT.T : null; + return Num.from(x).plusp() ? RT.T : RT.F; } static public Object zeroPred(Object x){ - return Num.from(x).zerop() ? RT.T : null; + return Num.from(x).zerop() ? RT.T : RT.F; } static public Num dec(Object x){ diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index 05c1557b..3586aab0 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -19,7 +19,8 @@ import java.lang.reflect.Array; public class RT{ -static public Keyword T = Keyword.intern(Symbol.create(null, "t")); +static final public Boolean T = Boolean.TRUE;//Keyword.intern(Symbol.create(null, "t")); +static final public Boolean F = Boolean.FALSE;//Keyword.intern(Symbol.create(null, "t")); final static public Var OUT = Var.intern(Symbol.create("clojure", "*out*"), new OutputStreamWriter(System.out)); final static public Var IN = @@ -115,7 +116,7 @@ Symbol.create("Exception"), "java.lang.Exception" ); -final static Var PRINT_META = Var.intern(Symbol.create("clojure", "*print-meta*"), null); +final static Var PRINT_META = Var.intern(Symbol.create("clojure", "*print-meta*"), F); final static Var PRINT_READABLY = Var.intern(Symbol.create("clojure", "*print-readably*"), T); final static Var IMPORTS = Var.intern(Symbol.create("clojure", "*imports*"), DEFAULT_IMPORTS); @@ -151,7 +152,7 @@ final static Var REFERS = new AFn(){ public Object invoke(Object arg1, Object arg2) throws Exception{ - return arg1 == arg2 ? RT.T : null; + return arg1 == arg2 ? RT.T : RT.F; } }) )); @@ -162,9 +163,10 @@ static public final Object[] EMPTY_ARRAY = new Object[]{}; //static public final Character[] chars; static AtomicInteger id = new AtomicInteger(1); -static{ -OUT.setTag(Symbol.create("java.io.OutputStreamWriter")); -} +static + { + OUT.setTag(Symbol.create("java.io.OutputStreamWriter")); + } //static // { // chars = new Character[256]; @@ -339,7 +341,7 @@ static public Associative assoc(Object coll, Object key, Object val){ static public Object contains(Object coll, Object key){ if(coll == null) return false; - return ((Associative) coll).containsKey(key) ? T : null; + return ((Associative) coll).containsKey(key) ? T : F; } static public Object find(Object coll, Object key){ @@ -444,11 +446,11 @@ static public Character box(char x){ } static public Object box(boolean x){ - return x ? T : null; + return x ? T : F; } static public Object box(Boolean x){ - return x ? T : null; + return x;// ? T : null; } static public Num box(byte x){ @@ -681,11 +683,11 @@ static public boolean suppressRead(){ static public void print(Object x, Writer w) throws Exception{ //todo - make extensible - boolean readably = PRINT_READABLY.get() != null; + boolean readably = booleanCast(PRINT_READABLY.get()); if(x instanceof Obj) { Obj o = (Obj) x; - if(RT.count(o.meta()) > 0 && readably && PRINT_META.get() != null) + if(RT.count(o.meta()) > 0 && readably && booleanCast(PRINT_META.get())) { IPersistentMap meta = o.meta(); w.write("#^"); diff --git a/src/jvm/clojure/lang/Reflector.java b/src/jvm/clojure/lang/Reflector.java index 2192ce1f..867f3590 100644 --- a/src/jvm/clojure/lang/Reflector.java +++ b/src/jvm/clojure/lang/Reflector.java @@ -65,7 +65,7 @@ static Object invokeMatchingMethod(String methodName, List methods, Object targe } if(m == null) throw new IllegalArgumentException("No matching method found: " + methodName); - return prepRet(m.getReturnType(),m.invoke(target, boxedArgs)); + return prepRet(m.getReturnType(), m.invoke(target, boxedArgs)); } public static Method getAsMethodOfPublicBase(Class c, Method m){ @@ -149,7 +149,7 @@ public static Object getStaticField(String className, String fieldName) throws E Field f = getField(c, fieldName, true); if(f != null) { - return prepRet(f.getType(),f.get(null)); + return prepRet(f.getType(), f.get(null)); } throw new IllegalArgumentException("No matching field found"); } @@ -170,7 +170,7 @@ public static Object getInstanceField(Object target, String fieldName) throws Ex Field f = getField(c, fieldName, false); if(f != null) { - return prepRet(f.getType(),f.get(target)); + return prepRet(f.getType(), f.get(target)); } throw new IllegalArgumentException("No matching field found"); } @@ -192,7 +192,7 @@ public static Object invokeInstanceMember(Object target, String name) throws Exc Field f = getField(c, name, false); if(f != null) //field get { - return prepRet(f.getType(),f.get(target)); + return prepRet(f.getType(), f.get(target)); } return invokeInstanceMethod(target, name, RT.EMPTY_ARRAY); } @@ -323,8 +323,8 @@ static boolean isCongruent(Class[] params, Object[] args){ } static Object prepRet(Class c, Object x){ - if(c == boolean.class) - return ((Boolean) x).booleanValue() ? RT.T : null; +// if(c == boolean.class) +// return ((Boolean) x).booleanValue() ? RT.T : null; return x; } } |