diff options
-rw-r--r-- | project.clj | 3 | ||||
-rw-r--r-- | src/lang/asm.clj | 48 | ||||
-rw-r--r-- | src/lang/interpreter.clj | 56 |
3 files changed, 100 insertions, 7 deletions
diff --git a/project.clj b/project.clj index 6f07b5b15..408dc63ab 100644 --- a/project.clj +++ b/project.clj @@ -4,4 +4,5 @@ :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :dependencies [[org.clojure/clojure "1.6.0"] - [org.clojure/core.match "0.2.1"]]) + [org.clojure/core.match "0.2.1"] + [org.ow2.asm/asm-all "5.0.3"]]) diff --git a/src/lang/asm.clj b/src/lang/asm.clj new file mode 100644 index 000000000..9f8e542c4 --- /dev/null +++ b/src/lang/asm.clj @@ -0,0 +1,48 @@ +(ns lang.asm + (:import (org.objectweb.asm Opcodes + ClassWriter + MethodVisitor))) + +(defn write-file [file data] + (with-open [stream (java.io.BufferedOutputStream. (java.io.FileOutputStream. file))] + (.write stream data))) + +(comment + (let [class-data (let [cw (doto (new ClassWriter ClassWriter/COMPUTE_MAXS) + (.visit Opcodes/V1_5 (+ Opcodes/ACC_PUBLIC Opcodes/ACC_SUPER) + "hello_world" nil "java/lang/Object" nil))] + (doto (.visitMethod cw Opcodes/ACC_PUBLIC "<init>" "()V" nil nil) + (.visitCode) + (.visitVarInsn Opcodes/ALOAD 0) + (.visitMethodInsn Opcodes/INVOKESPECIAL "java/lang/Object" "<init>" "()V") + (.visitInsn Opcodes/RETURN) + (.visitMaxs 0 0) + (.visitEnd)) + (doto (.visitMethod cw (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "main" "([Ljava/lang/String;)V" nil nil) + (.visitCode) + (.visitFieldInsn Opcodes/GETSTATIC "java/lang/System" "out" "Ljava/io/PrintStream;") + (.visitLdcInsn "Hello, World!") + (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/io/PrintStream" "println" "(Ljava/lang/String;)V") + (.visitInsn Opcodes/RETURN) + (.visitMaxs 0 0) + (.visitEnd)) + (.visitEnd cw) + (.toByteArray cw))] + (write-file "hello_world.class" class-data)) + + + ) + +;; package asm; +;; public class HelloWorld { +;; public static void main(String[] args) { +;; System.out.println("Hello, World!"); +;; } +;; } + + + + + + + diff --git a/src/lang/interpreter.clj b/src/lang/interpreter.clj index 85be602da..2c3f5af35 100644 --- a/src/lang/interpreter.clj +++ b/src/lang/interpreter.clj @@ -16,17 +16,46 @@ ;; (do (alter-var-root #'clojure.core/prn ;; (constantly #(.println System/out (apply pr-str %&)))))) -(def <=' (fn [x] (fn [y] (<= x y)))) -(def -' (fn [x] (fn [y] (- x y)))) -(def +' (fn [x] (fn [y] (+ x y)))) -(def *' (fn [x] (fn [y] (* x y)))) +(defprotocol Function + (apply [f x])) + +(defrecord Tagged [tag data]) + +;; (def <=' (fn [x] (fn [y] (<= x y)))) +;; (def -' (fn [x] (fn [y] (- x y)))) +;; (def +' (fn [x] (fn [y] (+ x y)))) +;; (def *' (fn [x] (fn [y] (* x y)))) ;; [Utils] (def ^:private +state+ - {:globals {"*" (fn [x] (fn [y] (* x y)))} + {:globals {"*" (reify Function + (apply [f x] + (reify Function + (apply [f y] + (* x y))))) + "-" (reify Function + (apply [f x] + (reify Function + (apply [f y] + (- x y))))) + "+" (reify Function + (apply [f x] + (reify Function + (apply [f y] + (+ x y))))) + "<=" (reify Function + (apply [f x] + (reify Function + (apply [f y] + (<= x y)))))} :stack {} :forms '()}) +;; (def ^:private +state+ +;; {:globals {"*" (fn [x] (fn [y] (* x y)))} +;; :stack {} +;; :forms '()}) + (defn wrap [x] (update-in +state+ [:forms] conj x)) @@ -131,7 +160,9 @@ ?args) ;; :let [_ (prn '=args =args)] ] - (fn-call =fn =args))) + (return (reduce #(%1 %2) =fn =args)) + ;; (fn-call =fn =args) + )) (def eval-form (try-all-m [eval-int @@ -163,6 +194,9 @@ ] (eval (update-in +state+ [:forms] concat syntax))) + ;; TODO: Add meta-data to top-level vars/fns. + ;; TODO: + ;; TODO: ;; (defdata (List x) ;; (#Nil []) @@ -177,4 +211,14 @@ ;; (set@ {#z 30} bar) (set@ {#z 30 #w "YOLO"} bar) ;; (remove@ [#x #y] bar) ;; (get@ [#x #y] bar) + + ;; (class (BiFunctor bf) + ;; (: bimap (All [a b c d] + ;; (-> [(-> [a] b) (-> [c] d) (bf a c)] (bf b d))))) + + ;; (instance (BiFunctor Either) + ;; (def (bimap f1 f2 either) + ;; (case either + ;; (#Left l) (#Left (f1 l)) + ;; (#Right r) (#Right (f2 r))))) ) |