diff options
Diffstat (limited to '')
-rw-r--r-- | src/lang/compiler.clj | 102 |
1 files changed, 60 insertions, 42 deletions
diff --git a/src/lang/compiler.clj b/src/lang/compiler.clj index 52195d2f2..3e63fc801 100644 --- a/src/lang/compiler.clj +++ b/src/lang/compiler.clj @@ -13,13 +13,19 @@ ;; [Utils/General] (defmacro ^:private defcompiler [name match body] - `(defn ~name [~'*writer* ~'*form*] - (match ~'*form* - ~match - (do ~body - true) - _# - false))) + `(defn ~name [~'*state*] + (let [~'*name* (:name ~'*state*) + ~'*writer* (:writer ~'*state*) + ~'*form* (:form ~'*state*)] + (match ~'*form* + ~match + (do ~body + true) + _# + false)))) + +(defn compile-form* [writer form] + (compile-form {:writer writer, :form form})) (defn ^:private unwrap-ident [ident] (match ident @@ -61,9 +67,9 @@ (defcompiler ^:private compile-fn-call [::&parser/fn-call [::&parser/ident ?fn] ?args] (do (doseq [arg ?args] - (compile-form *writer* arg)) + (compile-form (assoc *state* :form arg))) (doto *writer* - (.visitMethodInsn Opcodes/INVOKESTATIC "output" ?fn "(Ljava/lang/Object;)Ljava/lang/Object;")))) + (.visitMethodInsn Opcodes/INVOKESTATIC *name* ?fn "(Ljava/lang/Object;)Ljava/lang/Object;")))) (defcompiler ^:private compile-static-access [::&parser/static-access ?class ?member] @@ -72,11 +78,11 @@ (defcompiler ^:private compile-dynamic-access [::&parser/dynamic-access ?object ?access] - (let [=object (compile-form *writer* ?object) + (let [=object (compile-form (assoc *state* :form ?object)) method (match ?access [::&parser/fn-call [::&parser/ident ?method] ?args] (do (doseq [arg ?args] - (compile-form *writer* arg)) + (compile-form (assoc *state* :form arg))) ?method))] (doto *writer* (.visitMethodInsn Opcodes/INVOKEVIRTUAL (->class "java.io.PrintStream") method "(Ljava/lang/Object;)V")))) @@ -89,13 +95,13 @@ [::&parser/if ?test ?then ?else] (let [else-label (new Label) end-label (new Label)] - (compile-form *writer* ?test) + (compile-form (assoc *state* :form ?test)) (.visitJumpInsn *writer* Opcodes/IFEQ else-label) - (compile-form *writer* ?then) + (compile-form (assoc *state* :form ?then)) (doto *writer* (.visitJumpInsn Opcodes/GOTO end-label) (.visitLabel else-label)) - (compile-form *writer* ?else) + (compile-form (assoc *state* :form ?else)) (.visitLabel *writer* end-label))) (defcompiler ^:private compile-def @@ -103,20 +109,27 @@ (match ?form [::&parser/fn-call [::&parser/ident ?name] ?args] (if (= "main" ?name) - (doto (.visitMethod *writer* (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) ?name "([Ljava/lang/String;)V" nil nil) - (.visitCode) - (compile-form ?body) - (.visitInsn Opcodes/RETURN) - (.visitMaxs 0 0) - (.visitEnd)) - (doto (.visitMethod *writer* (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) ?name "(Ljava/lang/Object;)Ljava/lang/Object;" nil nil) - (.visitCode) - (compile-form ?body) - (.visitInsn Opcodes/ARETURN) - (.visitMaxs 0 0) - (.visitEnd))) + (let [=method (doto (.visitMethod *writer* (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) ?name "([Ljava/lang/String;)V" nil nil) + (.visitCode))] + (compile-form (assoc *state* :writer =method :form ?body)) + (doto =method + (.visitInsn Opcodes/RETURN) + (.visitMaxs 0 0) + (.visitEnd))) + (let [=method (doto (.visitMethod *writer* (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) ?name "(Ljava/lang/Object;)Ljava/lang/Object;" nil nil) + (.visitCode))] + (compile-form (assoc *state* :writer =method :form ?body)) + (doto =method + (.visitInsn Opcodes/ARETURN) + (.visitMaxs 0 0) + (.visitEnd)))) )) +(defcompiler ^:private compile-module + [::&parser/module] + (.visit *writer* Opcodes/V1_5 (+ Opcodes/ACC_PUBLIC Opcodes/ACC_SUPER) + *name* nil "java/lang/Object" nil)) + (let [+compilers+ [compile-boolean compile-string compile-ident @@ -125,24 +138,29 @@ compile-dynamic-access compile-ann-class compile-if - compile-def]] - (defn ^:private compile-form [writer form] - (prn 'compile-form/form form) - (some #(% writer form) +compilers+))) + compile-def + compile-module]] + (defn ^:private compile-form [state] + (prn 'compile-form/state state) + (some #(% state) +compilers+))) ;; [Interface] -(defn compile [inputs] +(defn compile [class-name inputs] (prn 'inputs inputs) - (let [=class (doto (new ClassWriter ClassWriter/COMPUTE_MAXS) - (.visit Opcodes/V1_5 (+ Opcodes/ACC_PUBLIC Opcodes/ACC_SUPER) - "output" nil "java/lang/Object" nil))] - (doto (.visitMethod =class 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)) - (doall (map (partial compile-form =class) inputs)) + (let [=class (new ClassWriter ClassWriter/COMPUTE_MAXS) + ;; (doto (new ClassWriter ClassWriter/COMPUTE_MAXS) + ;; (.visit Opcodes/V1_5 (+ Opcodes/ACC_PUBLIC Opcodes/ACC_SUPER) + ;; "output" nil "java/lang/Object" nil)) + state {:name class-name + :writer =class + :form nil}] + ;; (doto (.visitMethod =class 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)) + (doall (map #(compile-form (assoc state :form %)) inputs)) (.visitEnd =class) (.toByteArray =class))) |