From 1f5c19c07443d2535ede4ff71d23b40c195d617f Mon Sep 17 00:00:00 2001
From: Chas Emerick <chas@cemerick.com>
Date: Fri, 1 Feb 2013 13:28:01 -0500
Subject: [PATCH] CLJ-1153: default *read-eval* to false

---
 src/jvm/clojure/lang/Compiler.java       | 85 ++++++++++++++++++++++----------
 src/jvm/clojure/lang/RT.java             |  2 +-
 test/clojure/test_clojure/evaluation.clj |  4 +-
 3 files changed, 62 insertions(+), 29 deletions(-)

diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index 263a1b8..e4e7e92 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -21,6 +21,8 @@ import clojure.asm.commons.Method;
 import java.io.*;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Modifier;
+import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.util.*;
 import java.util.regex.Pattern;
 
@@ -4432,6 +4434,36 @@ static public class ObjExpr implements Expr{
 				gen.push(((Character) value).charValue());
 				gen.invokeStatic(Type.getType(Character.class), Method.getMethod("Character valueOf(char)"));
 				}
+		else if(value instanceof BigInteger)
+            {
+		    gen.newInstance(Type.getType(BigInteger.class));
+            gen.dup();
+            gen.push(((BigInteger)value).toString());
+            gen.invokeConstructor(Type.getType(BigInteger.class),
+                                  Method.getMethod("void <init>(String)"));         
+            }
+        else if(value instanceof BigDecimal)
+            {
+            gen.newInstance(Type.getType(BigDecimal.class));
+            gen.dup();
+            gen.push(((BigDecimal)value).toString());
+            gen.invokeConstructor(Type.getType(BigDecimal.class),
+                                  Method.getMethod("void <init>(String)"));         
+            }
+		else if(value instanceof BigInt)
+    		{
+    		emitValue(((BigInt)value).toBigInteger(), gen);
+    		gen.invokeStatic(Type.getType(BigInt.class), Method.getMethod("clojure.lang.BigInt fromBigInteger(java.math.BigInteger)"));    		
+    		}
+        else if(value instanceof Ratio)
+            {
+            gen.newInstance(Type.getType(Ratio.class));
+            gen.dup();
+            emitValue(((Ratio)value).numerator, gen);
+            emitValue(((Ratio)value).denominator, gen);
+            gen.invokeConstructor(Type.getType(Ratio.class),
+                                  Method.getMethod("void <init>(java.math.BigInteger, java.math.BigInteger)"));
+            }
 		else if(value instanceof Class)
 			{
 			Class cc = (Class)value;
@@ -4558,6 +4590,23 @@ static public class ObjExpr implements Expr{
 			gen.invokeStatic(Type.getType(Pattern.class),
 							 Method.getMethod("java.util.regex.Pattern compile(String)"));
 			}
+		else if(value instanceof Namespace)
+    		{
+		    gen.push(((Namespace)value).name.ns);
+            gen.push(((Namespace)value).name.name);
+            gen.invokeStatic(Type.getType(Symbol.class),
+                             Method.getMethod("clojure.lang.Symbol intern(String,String)"));
+    		gen.invokeStatic(Type.getType(Namespace.class),
+    		                 Method.getMethod("clojure.lang.Namespace find(clojure.lang.Symbol)"));
+    		}
+		else if(value instanceof clojure.lang.Fn)
+    		{
+		    // e.g. (eval (list + 1 2 3))
+		    gen.newInstance(Type.getType(value.getClass()));
+		    gen.dup();
+		    gen.invokeConstructor(Type.getType(value.getClass()),
+		                    new Method("<init>", Type.getConstructorDescriptor(value.getClass().getConstructors()[0])));
+    		}
 		else
 			{
 			String cs = null;
@@ -4569,7 +4618,7 @@ static public class ObjExpr implements Expr{
 			catch(Exception e)
 				{
 				throw Util.runtimeException(
-						"Can't embed object in code, maybe print-dup not defined: " +
+						"Can't embed object in code, maybe print-method not defined: " +
 						value);
 				}
 			if(cs.length() == 0)
@@ -4601,20 +4650,11 @@ static public class ObjExpr implements Expr{
 
 
 	void emitConstants(GeneratorAdapter clinitgen){
-		try
-			{
-			Var.pushThreadBindings(RT.map(RT.PRINT_DUP, RT.T));
-
-			for(int i = 0; i < constants.count(); i++)
-				{
-				emitValue(constants.nth(i), clinitgen);
-				clinitgen.checkCast(constantType(i));
-				clinitgen.putStatic(objtype, constantName(i), constantType(i));
-				}
-			}
-		finally
+		for(int i = 0; i < constants.count(); i++)
 			{
-			Var.popThreadBindings();
+			emitValue(constants.nth(i), clinitgen);
+			clinitgen.checkCast(constantType(i));
+			clinitgen.putStatic(objtype, constantName(i), constantType(i));
 			}
 	}
 
@@ -7240,20 +7280,11 @@ public static Object compile(Reader rdr, String sourcePath, String sourceName) t
 			                                                  null,
 			                                                  cv);
 			clinitgen.visitCode();
-			try
+			for(int i = n*INITS_PER; i < objx.constants.count() && i < (n+1)*INITS_PER; i++)
 				{
-				Var.pushThreadBindings(RT.map(RT.PRINT_DUP, RT.T));
-
-				for(int i = n*INITS_PER; i < objx.constants.count() && i < (n+1)*INITS_PER; i++)
-					{
-					objx.emitValue(objx.constants.nth(i), clinitgen);
-					clinitgen.checkCast(objx.constantType(i));
-					clinitgen.putStatic(objx.objtype, objx.constantName(i), objx.constantType(i));
-					}
-				}
-			finally
-				{
-				Var.popThreadBindings();
+				objx.emitValue(objx.constants.nth(i), clinitgen);
+				clinitgen.checkCast(objx.constantType(i));
+				clinitgen.putStatic(objx.objtype, objx.constantName(i), objx.constantType(i));
 				}
 			clinitgen.returnValue();
 			clinitgen.endMethod();
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java
index cea1bb5..fafa075 100644
--- a/src/jvm/clojure/lang/RT.java
+++ b/src/jvm/clojure/lang/RT.java
@@ -181,7 +181,7 @@ final static public Var ERR =
 final static Keyword TAG_KEY = Keyword.intern(null, "tag");
 final static Keyword CONST_KEY = Keyword.intern(null, "const");
 final static public Var AGENT = Var.intern(CLOJURE_NS, Symbol.intern("*agent*"), null).setDynamic();
-final static public Var READEVAL = Var.intern(CLOJURE_NS, Symbol.intern("*read-eval*"), T).setDynamic();
+final static public Var READEVAL = Var.intern(CLOJURE_NS, Symbol.intern("*read-eval*"), F).setDynamic();
 final static public Var DATA_READERS = Var.intern(CLOJURE_NS, Symbol.intern("*data-readers*"), RT.map()).setDynamic();
 final static public Var DEFAULT_DATA_READER_FN = Var.intern(CLOJURE_NS, Symbol.intern("*default-data-reader-fn*"), RT.map()).setDynamic();
 final static public Var DEFAULT_DATA_READERS = Var.intern(CLOJURE_NS, Symbol.intern("default-data-readers"), RT.map());
diff --git a/test/clojure/test_clojure/evaluation.clj b/test/clojure/test_clojure/evaluation.clj
index 62609ee..fb73aed 100644
--- a/test/clojure/test_clojure/evaluation.clj
+++ b/test/clojure/test_clojure/evaluation.clj
@@ -40,7 +40,9 @@
   (is (= (eval '(list + 1 2 3)) (list clojure.core/+ 1 2 3)))
   (test-that "Non-closure fns are supported as code"
              (is (= (eval (eval '(list + 1 2 3))) 6)))
-  (is (= (eval (list '+ 1 2 3)) 6)))
+  (is (= (eval (list '+ 1 2 3)) 6))
+  (test-that "boxed numerics are supported as code"
+    (is (= 4.5M (eval (list + 1N 2.0M 3/2))))))
 
 ; not using Clojure's RT/classForName since a bug in it could hide a bug in
 ; eval's resolution
-- 
1.8.0.1

