diff options
-rw-r--r-- | src/boot.clj | 30 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ProxyHandler.java | 56 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 11 |
4 files changed, 97 insertions, 2 deletions
diff --git a/src/boot.clj b/src/boot.clj index cdb58644..1633127e 100644 --- a/src/boot.clj +++ b/src/boot.clj @@ -521,6 +521,34 @@ (defn unintern [varsym] (. clojure.lang.Var (unintern varsym))) +(defn into-array [aseq] + (. clojure.lang.RT (seqToTypedArray (seq aseq)))) + +(defn array [& items] + (into-array items)) + +(defn make-proxy [classes method-map] + (. java.lang.reflect.Proxy + (newProxyInstance (. java.lang.ClassLoader (getSystemClassLoader)) + (into-array classes) + (new clojure.lang.ProxyHandler method-map)))) + +(defn print + ([x] (thisfn x *out*)) + ([x writer] (. clojure.lang.RT (print x writer)))) + +(defn newline + ([] (thisfn *out*)) + ([#^java.io.Writer writer] + (. writer (append \newline)) + nil)) + +(defn prn + ([x] (thisfn x *out*)) + ([x writer] + (print x writer) + (newline))) + (def *exports* '(clojure load-file eql-ref? @@ -545,5 +573,7 @@ cycle split-at split-with repeat replicate iterate dolist eval import unimport refer unrefer in-namespace unintern + into-array array + make-proxy prn print newline *out* *current-namespace* )) diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 7dbf4191..eb25c785 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -2691,7 +2691,7 @@ public static void main(String[] args){ //repl LineNumberingPushbackReader rdr = new LineNumberingPushbackReader(new InputStreamReader(System.in)); - OutputStreamWriter w = new OutputStreamWriter(System.out); + OutputStreamWriter w = (OutputStreamWriter) RT.OUT.get();//new OutputStreamWriter(System.out); Object EOF = new Object(); try diff --git a/src/jvm/clojure/lang/ProxyHandler.java b/src/jvm/clojure/lang/ProxyHandler.java new file mode 100644 index 00000000..883b19a9 --- /dev/null +++ b/src/jvm/clojure/lang/ProxyHandler.java @@ -0,0 +1,56 @@ +/** + * Copyright (c) Rich Hickey. All rights reserved. + * The use and distribution terms for this software are covered by the + * Common Public License 1.0 (http://opensource.org/licenses/cpl.php) + * which can be found in the file CPL.TXT at the root of this distribution. + * By using this software in any fashion, you are agreeing to be bound by + * the terms of this license. + * You must not remove this notice, or any other, from this software. + **/ + +/* rich Oct 4, 2007 */ + +package clojure.lang; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +public class ProxyHandler implements InvocationHandler{ +//method-name-string->fn +final IPersistentMap fns; + + +public ProxyHandler(IPersistentMap fns){ + this.fns = fns; +} + +public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{ + IFn fn = (IFn) fns.valAt(method.getName()); + if(fn == null) + throw new UnsupportedOperationException(); + Object ret = fn.applyTo(ArraySeq.create(args)); + Class rt = method.getReturnType(); + if(rt == Void.TYPE) + return null; + else if(rt.isPrimitive()) + { + if(rt == Character.TYPE) + return ret; + else if(rt == Integer.TYPE) + return ((Number)ret).intValue(); + else if(rt == Long.TYPE) + return ((Number)ret).longValue(); + else if(rt == Float.TYPE) + return ((Number)ret).floatValue(); + else if(rt == Double.TYPE) + return ((Number)ret).doubleValue(); + else if(rt == Boolean.TYPE) + return ret == null?Boolean.FALSE:Boolean.TRUE; + else if(rt == Byte.TYPE) + return (byte)((Number)ret).intValue(); + else if(rt == Short.TYPE) + return (short)((Number)ret).intValue(); + } + return ret; +} +} diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index 8c421e44..a555ef0c 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -15,12 +15,13 @@ package clojure.lang; import java.util.Iterator; import java.util.concurrent.atomic.AtomicInteger; import java.io.*; +import java.lang.reflect.Array; public class RT{ static public Symbol T = Symbol.create(null, "t"); final static public Var OUT = - Var.intern(Symbol.create("clojure", "out"), new OutputStreamWriter(System.out)); + Var.intern(Symbol.create("clojure", "*out*"), new OutputStreamWriter(System.out)); final static Keyword TAG_KEY = Keyword.intern("clojure", "tag"); //final static public Var CURRENT_MODULE = Var.intern(Symbol.create("clojure", "current-module"), @@ -564,6 +565,14 @@ static public Object[] seqToArray(ISeq seq) throws Exception{ return ret; } +static public Object seqToTypedArray(ISeq seq) throws Exception{ + int len = length(seq); + Object ret = Array.newInstance(len > 0 ? seq.first().getClass() : Object.class, len); + for(int i = 0; seq != null; ++i, seq = seq.rest()) + Array.set(ret,i,seq.first()); + return ret; +} + static public int length(ISeq list) throws Exception{ int i = 0; for(ISeq c = list; c != null; c = c.rest()) |