aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--project.clj3
-rw-r--r--src/lang/asm.clj48
-rw-r--r--src/lang/interpreter.clj56
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)))))
)