aboutsummaryrefslogtreecommitdiff
path: root/src/lang/compiler.clj
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lang/compiler.clj102
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)))