Permalink
Browse files

Add map and vector support

  • Loading branch information...
1 parent 3225441 commit ba5a36c0a97424acb8527fd75c0caf6f65d820e9 @remleduff committed Mar 1, 2012
Showing with 30 additions and 2 deletions.
  1. +26 −2 src/clojure/java/compiler.clj
  2. +4 −0 test/test/clojure/java/compiler.clj
@@ -194,7 +194,7 @@
(.push *gen* (name v))
(.invokeStatic *gen* rt-type (Method/getMethod "clojure.lang.Keyword keyword(String,String)")))
-(defn- emit-list-as-array [list]
+(defn- emit-vals-as-array [list]
(.push *gen* (int (count list)))
(.newArray *gen* object-type)
(dorun
@@ -207,9 +207,13 @@
list)))
(defmethod emit-value clojure.lang.IPersistentMap [t v]
- (emit-list-as-array (reduce into [] v))
+ (emit-vals-as-array (reduce into [] v))
(.invokeStatic *gen* rt-type (Method/getMethod "clojure.lang.IPersistentMap map(Object[])")))
+(defmethod emit-value clojure.lang.IPersistentVector [t v]
+ (emit-vals-as-array v)
+ (.invokeStatic *gen* rt-type (Method/getMethod "clojure.lang.IPersistentVector vector(Object[])")))
+
(defmethod emit-value :default [t v]
(notsup "Don't know how to emit value: " [t v]))
@@ -606,4 +610,24 @@
(.dup *gen*)
(.invokeConstructor *gen* type constructor-method)))
+(defn- emit-as-array [list]
+ (.push *gen* (int (count list)))
+ (.newArray *gen* object-type)
+ (dorun
+ (map-indexed
+ (fn [i item]
+ (.dup *gen*)
+ (.push *gen* (int i))
+ (emit item)
+ (.arrayStore *gen* object-type))
+ list)))
+
+(defmethod emit-boxed :vector [args]
+ (emit-as-array (:children args))
+ (.invokeStatic *gen* rt-type (Method/getMethod "clojure.lang.IPersistentVector vector(Object[])")))
+
+(defmethod emit-boxed :map [{:keys [keys vals]}]
+ (emit-as-array (interleave keys vals))
+ (.invokeStatic *gen* rt-type (Method/getMethod "clojure.lang.IPersistentMap map(Object[])")))
+
(defmethod emit-boxed :default [args] (throw (Util/runtimeException (str "Unknown operator: " (:op args) "\nForm: " args))))
@@ -27,6 +27,10 @@
(deftest test-eval
(is (= 1 (c/eval '1)))
(is (= 3 (c/eval '(+ 1 2))))
+ (testing "vector"
+ (is (= [1 2] (c/eval '[1 2]))))
+ (testing "map"
+ (is (= {:x 1 :y 2} (c/eval '{:x 1 :y 2}))))
(testing "if"
(is (= :true (c/eval '(if :true :true :false))))
(is (= :false (c/eval '(if nil :true :false)))))

0 comments on commit ba5a36c

Please sign in to comment.