aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lux/analyser.clj44
-rw-r--r--src/lux/analyser/host.clj172
-rw-r--r--src/lux/analyser/lux.clj10
-rw-r--r--src/lux/base.clj4
-rw-r--r--src/lux/compiler.clj29
-rw-r--r--src/lux/compiler/host.clj84
-rw-r--r--src/lux/compiler/lux.clj10
-rw-r--r--src/lux/host.clj3
8 files changed, 254 insertions, 102 deletions
diff --git a/src/lux/analyser.clj b/src/lux/analyser.clj
index ba0fe4e66..01a562bfe 100644
--- a/src/lux/analyser.clj
+++ b/src/lux/analyser.clj
@@ -412,42 +412,44 @@
(matchv ::M/objects [token]
;; Arrays
[["lux;Meta" [meta ["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ "_jvm_new-array"]]]]
- ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ ?class]]]]
- ["lux;Cons" [["lux;Meta" [_ ["lux;IntS" ?length]]]
- ["lux;Nil" _]]]]]]]]]]]
+ ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ ?class]]]]
+ ["lux;Cons" [["lux;Meta" [_ ["lux;IntS" ?length]]]
+ ["lux;Nil" _]]]]]]]]]]]
(&&host/analyse-jvm-new-array analyse ?class ?length)
[["lux;Meta" [meta ["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ "_jvm_aastore"]]]]
- ["lux;Cons" [?array
- ["lux;Cons" [["lux;Meta" [_ ["lux;IntS" ?idx]]]
- ["lux;Cons" [?elem
- ["lux;Nil" _]]]]]]]]]]]]]
+ ["lux;Cons" [?array
+ ["lux;Cons" [["lux;Meta" [_ ["lux;IntS" ?idx]]]
+ ["lux;Cons" [?elem
+ ["lux;Nil" _]]]]]]]]]]]]]
(&&host/analyse-jvm-aastore analyse ?array ?idx ?elem)
[["lux;Meta" [meta ["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ "_jvm_aaload"]]]]
- ["lux;Cons" [?array
- ["lux;Cons" [["lux;Meta" [_ ["lux;IntS" ?idx]]]
- ["lux;Nil" _]]]]]]]]]]]
+ ["lux;Cons" [?array
+ ["lux;Cons" [["lux;Meta" [_ ["lux;IntS" ?idx]]]
+ ["lux;Nil" _]]]]]]]]]]]
(&&host/analyse-jvm-aaload analyse ?array ?idx)
;; Classes & interfaces
[["lux;Meta" [meta ["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ "_jvm_class"]]]]
- ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ ?name]]]]
- ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ ?super-class]]]]
- ["lux;Cons" [["lux;Meta" [_ ["lux;TupleS" ?fields]]]
- ["lux;Nil" _]]]]]]]]]]]]]
- (&&host/analyse-jvm-class analyse ?name ?super-class ?fields)
+ ["lux;Cons" [["lux;Meta" [_ ["lux;TextS" ?name]]]
+ ["lux;Cons" [["lux;Meta" [_ ["lux;TextS" ?super-class]]]
+ ["lux;Cons" [["lux;Meta" [_ ["lux;TupleS" ?interfaces]]]
+ ["lux;Cons" [["lux;Meta" [_ ["lux;TupleS" ?fields]]]
+ ?methods]]]]]]]]]]]]]]
+ (&&host/analyse-jvm-class analyse ?name ?super-class ?interfaces ?fields ?methods)
[["lux;Meta" [meta ["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ "_jvm_interface"]]]]
- ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ ?name]]]]
- ?members]]]]]]]]
- (&&host/analyse-jvm-interface analyse ?name ?members)
+ ["lux;Cons" [["lux;Meta" [_ ["lux;TextS" ?name]]]
+ ["lux;Cons" [["lux;Meta" [_ ["lux;TupleS" ?supers]]]
+ ?methods]]]]]]]]]]
+ (&&host/analyse-jvm-interface analyse ?name ?supers ?methods)
;; Programs
[["lux;Meta" [meta ["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ "_jvm_program"]]]]
- ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ ?args]]]]
- ["lux;Cons" [?body
- ["lux;Nil" _]]]]]]]]]]]
+ ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ ?args]]]]
+ ["lux;Cons" [?body
+ ["lux;Nil" _]]]]]]]]]]]
(&&host/analyse-jvm-program analyse ?args ?body)
[_]
diff --git a/src/lux/analyser/host.clj b/src/lux/analyser/host.clj
index 182eb9ebb..1aa683ea6 100644
--- a/src/lux/analyser/host.clj
+++ b/src/lux/analyser/host.clj
@@ -18,6 +18,14 @@
[_]
(fail "[Analyser Error] Can't extract Symbol.")))
+(defn ^:private extract-text [text]
+ (matchv ::M/objects [text]
+ [["lux;Meta" [_ ["lux;TextS" ?text]]]]
+ (return ?text)
+
+ [_]
+ (fail "[Analyser Error] Can't extract Text.")))
+
(defn ^:private analyse-1+ [analyse ?token]
(&type/with-var
(fn [$var]
@@ -112,9 +120,19 @@
analyse-jvm-invokevirtual "jvm-invokevirtual"
analyse-jvm-invokeinterface "jvm-invokeinterface"
- analyse-jvm-invokespecial "jvm-invokespecial"
)
+(defn analyse-jvm-invokespecial [analyse ?class ?method ?classes ?object ?args]
+ (|do [=classes (&/map% &host/extract-jvm-param ?classes)
+ =return (if (= "<init>" ?method)
+ (return &type/$Void)
+ (&host/lookup-virtual-method ?class ?method =classes))
+ =object (&&/analyse-1 analyse (&/V "lux;DataT" ?class) ?object)
+ =args (&/map2% (fn [?c ?o]
+ (&&/analyse-1 analyse (&/V "lux;DataT" ?c) ?o))
+ =classes ?args)]
+ (return (&/|list (&/T (&/V "jvm-invokespecial" (&/T ?class ?method =classes =object =args)) =return)))))
+
(defn analyse-jvm-null? [analyse ?object]
(|do [=object (&&/analyse-1 analyse ?object)]
(return (&/|list (&/T (&/V "jvm-null?" =object) (&/V "lux;DataT" "java.lang.Boolean"))))))
@@ -139,44 +157,134 @@
=array-type (&&/expr-type =array)]
(return (&/|list (&/T (&/V "jvm-aaload" (&/T =array ?idx)) =array-type)))))
-(defn analyse-jvm-class [analyse ?name ?super-class ?fields]
- (|do [?fields (&/map% (fn [?field]
+(defn ^:private analyse-modifiers [modifiers]
+ (&/fold% (fn [so-far modif]
+ (matchv ::M/objects [modif]
+ [["lux;Meta" [_ ["lux;TextS" "public"]]]]
+ (return (assoc so-far :visibility "public"))
+
+ [["lux;Meta" [_ ["lux;TextS" "private"]]]]
+ (return (assoc so-far :visibility "private"))
+
+ [["lux;Meta" [_ ["lux;TextS" "protected"]]]]
+ (return (assoc so-far :visibility "protected"))
+
+ [["lux;Meta" [_ ["lux;TextS" "static"]]]]
+ (return (assoc so-far :static? true))
+
+ [["lux;Meta" [_ ["lux;TextS" "final"]]]]
+ (return (assoc so-far :final? true))
+
+ [["lux;Meta" [_ ["lux;TextS" "abstract"]]]]
+ (return (assoc so-far :abstract? true))
+
+ [["lux;Meta" [_ ["lux;TextS" "synchronized"]]]]
+ (return (assoc so-far :concurrency "synchronized"))
+
+ [["lux;Meta" [_ ["lux;TextS" "volatile"]]]]
+ (return (assoc so-far :concurrency "volatile"))
+
+ [_]
+ (fail (str "[Analyser Error] Unknown modifier: " (&/show-ast modif)))))
+ {:visibility "default"
+ :static? false
+ :final? false
+ :abstract? false
+ :concurrency nil}
+ modifiers))
+
+(defn ^:private as-otype [tname]
+ (case tname
+ "boolean" "java.lang.Boolean"
+ "byte" "java.lang.Byte"
+ "short" "java.lang.Short"
+ "int" "java.lang.Integer"
+ "long" "java.lang.Long"
+ "float" "java.lang.Float"
+ "double" "java.lang.Double"
+ "char" "java.lang.Character"
+ ;; else
+ tname
+ ))
+
+(defn analyse-jvm-class [analyse ?name ?super-class ?interfaces ?fields ?methods]
+ (|do [=interfaces (&/map% extract-text ?interfaces)
+ =fields (&/map% (fn [?field]
(matchv ::M/objects [?field]
- [["lux;Meta" [_ ["lux;TupleS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" ?class]]]
- ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" ?field-name]]]
- ["lux;Nil" _]]]]]]]]]
- (return [?class ?field-name])
+ [["lux;Meta" [_ ["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ ?field-name]]]]
+ ["lux;Cons" [["lux;Meta" [_ ["lux;TextS" ?field-type]]]
+ ["lux;Cons" [["lux;Meta" [_ ["lux;TupleS" ?field-modifiers]]]
+ ["lux;Nil" _]]]]]]]]]]]
+ (|do [=field-modifiers (analyse-modifiers ?field-modifiers)]
+ (return {:name ?field-name
+ :modifiers =field-modifiers
+ :type ?field-type}))
[_]
- (fail "[Analyser Error] Fields must be Tuple2 of [Symbol, Symbol]")))
+ (fail "[Analyser Error] Wrong syntax for field.")))
?fields)
- :let [=fields (into {} (for [[class field] ?fields]
- [field {:access :public
- :type class}]))]
- $module &/get-module-name]
- (return (&/|list (&/V "jvm-class" (&/T $module ?name ?super-class =fields {}))))))
-
-(defn analyse-jvm-interface [analyse ?name ?members]
- (|do [=members (&/map% (fn [member]
- (matchv ::M/objects [member]
- [["lux;Meta" [_ ["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" ["" ":"]]]]
- ["lux;Cons" [["lux;Meta" [_ ["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ "->"]]]]
- ["lux;Cons" [["lux;Meta" [_ ["lux;TupleS" ?inputs]]]
- ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ ?output]]]]
- ["lux;Nil" _]]]]]]]]]]
- ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ ?member-name]]]]
- ["lux;Nil" _]]]]]]]]]]]
- (|do [inputs* (&/map% extract-ident ?inputs)]
- (return [?member-name [inputs* ?output]]))
+ =methods (&/map% (fn [?method]
+ (matchv ::M/objects [?method]
+ [[?idx ["lux;Meta" [_ ["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ ?method-name]]]]
+ ["lux;Cons" [["lux;Meta" [_ ["lux;TupleS" ?method-inputs]]]
+ ["lux;Cons" [["lux;Meta" [_ ["lux;TextS" ?method-output]]]
+ ["lux;Cons" [["lux;Meta" [_ ["lux;TupleS" ?method-modifiers]]]
+ ["lux;Cons" [?method-body
+ ["lux;Nil" _]]]]]]]]]]]]]]]]
+ (|do [=method-inputs (&/map% (fn [minput]
+ (matchv ::M/objects [minput]
+ [["lux;Meta" [_ ["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" ?input-name]]]
+ ["lux;Cons" [["lux;Meta" [_ ["lux;TextS" ?input-type]]]
+ ["lux;Nil" _]]]]]]]]]
+ (return (&/T (&/ident->text ?input-name) ?input-type))
+
+ [_]
+ (fail "[Analyser Error] Wrong syntax for method.")))
+ ?method-inputs)
+ =method-modifiers (analyse-modifiers ?method-modifiers)
+ =method-body (&/with-scope (str ?name "_" ?idx)
+ (&/fold (fn [body* input*]
+ (|let [[iname itype] input*]
+ (&&env/with-local iname (&/V "lux;DataT" (as-otype itype))
+ body*)))
+ (if (= "void" ?method-output)
+ (analyse-1+ analyse ?method-body)
+ (&&/analyse-1 analyse (&/V "lux;DataT" (as-otype ?method-output)) ?method-body))
+ (&/|reverse (if (:static? =method-modifiers)
+ =method-inputs
+ (&/|cons (&/T ";this" ?super-class)
+ =method-inputs)))))]
+ (return {:name ?method-name
+ :modifiers =method-modifiers
+ :inputs (&/|map &/|second =method-inputs)
+ :output ?method-output
+ :body =method-body}))
+
+ [_]
+ (fail "[Analyser Error] Wrong syntax for method.")))
+ (&/enumerate ?methods))]
+ (return (&/|list (&/V "jvm-class" (&/T ?name ?super-class =interfaces =fields =methods))))))
+
+(defn analyse-jvm-interface [analyse ?name ?supers ?methods]
+ (|do [=supers (&/map% extract-text ?supers)
+ =methods (&/map% (fn [method]
+ (matchv ::M/objects [method]
+ [["lux;Meta" [_ ["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ ?method-name]]]]
+ ["lux;Cons" [["lux;Meta" [_ ["lux;TupleS" ?inputs]]]
+ ["lux;Cons" [["lux;Meta" [_ ["lux;TextS" ?output]]]
+ ["lux;Cons" [["lux;Meta" [_ ["lux;TupleS" ?modifiers]]]
+ ["lux;Nil" _]]]]]]]]]]]]]
+ (|do [=inputs (&/map% extract-text ?inputs)
+ =modifiers (analyse-modifiers ?modifiers)]
+ (return {:name ?method-name
+ :modifiers =modifiers
+ :inputs =inputs
+ :output ?output}))
[_]
(fail "[Analyser Error] Invalid method signature!")))
- ?members)
- :let [=methods (into {} (for [[method [inputs output]] (&/->seq =members)]
- [method {:access :public
- :type [inputs output]}]))]
- $module &/get-module-name]
- (return (&/|list (&/V "jvm-interface" (&/T $module ?name =methods))))))
+ ?methods)]
+ (return (&/|list (&/V "jvm-interface" (&/T ?name =supers =methods))))))
(defn analyse-jvm-try [analyse ?body [?catches ?finally]]
(|do [=body (&&/analyse-1 analyse ?body)
diff --git a/src/lux/analyser/lux.clj b/src/lux/analyser/lux.clj
index dff936fbe..cdecd234f 100644
--- a/src/lux/analyser/lux.clj
+++ b/src/lux/analyser/lux.clj
@@ -329,14 +329,12 @@
==type (eval! =type)
_ (&type/check exo-type ==type)
=value (&&/analyse-1 analyse ==type ?value)]
- (matchv ::M/objects [=value]
- [[?expr ?expr-type]]
- (return (&/|list (&/T ?expr ==type))))))
+ (return (&/|list (&/T (&/V "ann" (&/T =value =type))
+ ==type)))))
(defn analyse-coerce [analyse eval! exo-type ?type ?value]
(|do [=type (&&/analyse-1 analyse &type/Type ?type)
==type (eval! =type)
=value (&&/analyse-1 analyse ==type ?value)]
- (matchv ::M/objects [=value]
- [[?expr ?expr-type]]
- (return (&/|list (&/T ?expr ==type))))))
+ (return (&/|list (&/T (&/V "ann" (&/T =value =type))
+ ==type)))))
diff --git a/src/lux/base.clj b/src/lux/base.clj
index c4aab9ec6..57b25f47e 100644
--- a/src/lux/base.clj
+++ b/src/lux/base.clj
@@ -454,7 +454,7 @@
[]
(findClass [^String class-name]
;; (prn 'findClass class-name)
- (if-let [bytecode (get @store class-name)]
+ (if-let [^bytes bytecode (get @store class-name)]
(.invoke define-class this (to-array [class-name bytecode (int 0) (int (alength bytecode))]))
(throw (IllegalStateException. (str "[Class Loader] Unknown class: " class-name))))))))
@@ -652,7 +652,7 @@
[_ _]
false))
-(defn enumerate* [idx xs]
+(defn ^:private enumerate* [idx xs]
(matchv ::M/objects [xs]
[["lux;Cons" [x xs*]]]
(V "lux;Cons" (T (T idx x)
diff --git a/src/lux/compiler.clj b/src/lux/compiler.clj
index db2c92c42..a0425cdbe 100644
--- a/src/lux/compiler.clj
+++ b/src/lux/compiler.clj
@@ -25,6 +25,9 @@
ClassWriter
MethodVisitor)))
+;; [Constants]
+(def ^:private version "0.2")
+
;; [Utils/Compilers]
(defn ^:private compile-expression [syntax]
(matchv ::M/objects [syntax]
@@ -72,6 +75,9 @@
[["lambda" [?scope ?env ?body]]]
(&&lambda/compile-lambda compile-expression ?scope ?env ?body)
+ [["ann" [?value-ex ?type-ex]]]
+ (&&lux/compile-ann compile-expression ?type ?value-ex ?type-ex)
+
;; Integer arithmetic
[["jvm-iadd" [?x ?y]]]
(&&host/compile-jvm-iadd compile-expression ?type ?x ?y)
@@ -308,11 +314,11 @@
[["jvm-program" ?body]]
(&&host/compile-jvm-program compile-expression ?body)
- [["jvm-interface" [?package ?name ?methods]]]
- (&&host/compile-jvm-interface compile-expression ?package ?name ?methods)
+ [["jvm-interface" [?name ?supers ?methods]]]
+ (&&host/compile-jvm-interface compile-expression ?name ?supers ?methods)
- [["jvm-class" [?package ?name ?super-class ?fields ?methods]]]
- (&&host/compile-jvm-class compile-expression ?package ?name ?super-class ?fields ?methods)))
+ [["jvm-class" [?name ?super-class ?interfaces ?fields ?methods]]]
+ (&&host/compile-jvm-class compile-expression ?name ?super-class ?interfaces ?fields ?methods)))
(defn ^:private eval! [expr]
(|do [id &/gen-id
@@ -353,9 +359,18 @@
file-content (slurp file-name)
=class (doto (new ClassWriter ClassWriter/COMPUTE_MAXS)
(.visit Opcodes/V1_5 (+ Opcodes/ACC_PUBLIC Opcodes/ACC_SUPER)
- (&host/->class name) nil "java/lang/Object" nil))
- _ (doto (.visitField =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_FINAL Opcodes/ACC_STATIC) "_hash" "I" nil (hash file-content))
- .visitEnd)]
+ (&host/->class name) nil "java/lang/Object" nil)
+ (-> (.visitField (+ Opcodes/ACC_PUBLIC Opcodes/ACC_FINAL Opcodes/ACC_STATIC) "_hash" "I" nil (hash file-content))
+ .visitEnd)
+ (-> (.visitField (+ Opcodes/ACC_PUBLIC Opcodes/ACC_FINAL Opcodes/ACC_STATIC) "_compiler" "Ljava/lang/String;" nil version)
+ .visitEnd)
+ ;; (-> (.visitField (+ Opcodes/ACC_PUBLIC Opcodes/ACC_FINAL Opcodes/ACC_STATIC) "_imports" "Ljava/lang/String;" nil ...)
+ ;; .visitEnd)
+ ;; (-> (.visitField (+ Opcodes/ACC_PUBLIC Opcodes/ACC_FINAL Opcodes/ACC_STATIC) "_exports" "Ljava/lang/String;" nil ...)
+ ;; .visitEnd)
+ ;; (-> (.visitField (+ Opcodes/ACC_PUBLIC Opcodes/ACC_FINAL Opcodes/ACC_STATIC) "_macros" "Ljava/lang/String;" nil ...)
+ ;; .visitEnd)
+ )]
(matchv ::M/objects [((&/exhaust% compiler-step)
(->> state
(&/set$ &/$SOURCE (&reader/from file-name file-content))
diff --git a/src/lux/compiler/host.clj b/src/lux/compiler/host.clj
index 87753dce3..e825ca0ad 100644
--- a/src/lux/compiler/host.clj
+++ b/src/lux/compiler/host.clj
@@ -238,7 +238,7 @@
(defn compile-jvm-new [compile *type* ?class ?classes ?args]
(|do [^MethodVisitor *writer* &/get-writer
- :let [init-sig (str "(" (reduce str "" (map &host/->type-signature ?classes)) ")V")
+ :let [init-sig (str "(" (&/fold str "" (&/|map &host/->type-signature ?classes)) ")V")
class* (&host/->class ?class)
_ (doto *writer*
(.visitTypeInsn Opcodes/NEW class*)
@@ -247,7 +247,7 @@
(|do [ret (compile arg)
:let [_ (prepare-arg! *writer* class-name)]]
(return ret)))
- (map vector ?classes ?args))
+ (&/zip2 ?classes ?args))
:let [_ (doto *writer*
(.visitMethodInsn Opcodes/INVOKESPECIAL class* "<init>" init-sig))]]
(return nil)))
@@ -303,40 +303,62 @@
:let [_ (.visitFieldInsn *writer* Opcodes/PUTFIELD (&host/->class ?class) ?field (&host/->java-sig *type*))]]
(return nil)))
-(defn compile-jvm-class [compile ?package ?name ?super-class ?fields ?methods]
- (let [parent-dir (&host/->package ?package)
- full-name (str parent-dir "/" ?name)
+(defn ^:private modifiers->int [mods]
+ (+ (case (:visibility mods)
+ "default" 0
+ "public" Opcodes/ACC_PUBLIC
+ "private" Opcodes/ACC_PRIVATE
+ "protected" Opcodes/ACC_PROTECTED)
+ (if (:static? mods) Opcodes/ACC_STATIC 0)
+ (if (:final? mods) Opcodes/ACC_FINAL 0)
+ (if (:abstract? mods) Opcodes/ACC_ABSTRACT 0)
+ (case (:concurrency mods)
+ "synchronized" Opcodes/ACC_SYNCHRONIZED
+ "volatile" Opcodes/ACC_VOLATILE
+ ;; else
+ 0)))
+
+(defn compile-jvm-class [compile ?name ?super-class ?interfaces ?fields ?methods]
+ (let [name* (&host/->class ?name)
super-class* (&host/->class ?super-class)
=class (doto (new ClassWriter ClassWriter/COMPUTE_MAXS)
(.visit Opcodes/V1_5 (+ Opcodes/ACC_PUBLIC Opcodes/ACC_SUPER)
- full-name nil super-class* nil))
- _ (do (doseq [[field props] ?fields]
- (doto (.visitField =class Opcodes/ACC_PUBLIC field (&host/->type-signature (:type props)) nil nil)
- (.visitEnd)))
- (doto (.visitMethod =class Opcodes/ACC_PUBLIC "<init>" "()V" nil nil)
- (.visitCode)
- (.visitVarInsn Opcodes/ALOAD 0)
- (.visitMethodInsn Opcodes/INVOKESPECIAL super-class* "<init>" "()V")
- (.visitInsn Opcodes/RETURN)
- (.visitMaxs 0 0)
- (.visitEnd))
- (.visitEnd =class)
- (.mkdirs (java.io.File. (str "output/" parent-dir))))]
- (&&/save-class! full-name (.toByteArray =class))))
-
-(defn compile-jvm-interface [compile ?package ?name ?methods]
- (let [parent-dir (&host/->package ?package)
- full-name (str parent-dir "/" ?name)
+ name* nil super-class* (->> ?interfaces (&/|map &host/->class) &/->seq (into-array String))))
+ _ (&/|map (fn [field]
+ (doto (.visitField =class (modifiers->int (:modifiers field)) (:name field)
+ (&host/->type-signature (:type field)) nil nil)
+ (.visitEnd)))
+ ?fields)]
+ (|do [_ (&/map% (fn [method]
+ (|let [signature (str "(" (&/fold str "" (&/|map &host/->type-signature (:inputs method))) ")"
+ (&host/->type-signature (:output method)))]
+ (&/with-writer (.visitMethod =class (modifiers->int (:modifiers method))
+ (:name method)
+ signature nil nil)
+ (|do [^MethodVisitor =method &/get-writer
+ :let [_ (.visitCode =method)]
+ _ (compile (:body method))
+ :let [_ (doto =method
+ (.visitInsn (if (= "void" (:output method)) Opcodes/RETURN Opcodes/ARETURN))
+ (.visitMaxs 0 0)
+ (.visitEnd))]]
+ (return nil)))))
+ ?methods)]
+ (&&/save-class! name* (.toByteArray (doto =class .visitEnd))))))
+
+(defn compile-jvm-interface [compile ?name ?supers ?methods]
+ (prn 'compile-jvm-interface (->> ?supers &/->seq pr-str))
+ (let [name* (&host/->class ?name)
=interface (doto (new ClassWriter ClassWriter/COMPUTE_MAXS)
(.visit Opcodes/V1_5 (+ Opcodes/ACC_PUBLIC Opcodes/ACC_INTERFACE)
- full-name nil "java/lang/Object" nil))
- _ (do (doseq [[?method ?props] ?methods
- :let [[?args ?return] (:type ?props)
- signature (str "(" (&/fold str "" (&/|map &host/->type-signature ?args)) ")" (&host/->type-signature ?return))]]
- (.visitMethod =interface (+ Opcodes/ACC_PUBLIC Opcodes/ACC_ABSTRACT) ?method signature nil nil))
- (.visitEnd =interface)
- (.mkdirs (java.io.File. (str "output/" parent-dir))))]
- (&&/save-class! full-name (.toByteArray =interface))))
+ name* nil "java/lang/Object" (->> ?supers (&/|map &host/->class) &/->seq (into-array String))))
+ _ (do (&/|map (fn [method]
+ (|let [signature (str "(" (&/fold str "" (&/|map &host/->type-signature (:inputs method))) ")"
+ (&host/->type-signature (:output method)))]
+ (.visitMethod =interface (modifiers->int (:modifiers method)) (:name method) signature nil nil)))
+ ?methods)
+ (.visitEnd =interface))]
+ (&&/save-class! name* (.toByteArray =interface))))
(defn compile-jvm-try [compile *type* ?body ?catches ?finally]
(|do [^MethodVisitor *writer* &/get-writer
diff --git a/src/lux/compiler/lux.clj b/src/lux/compiler/lux.clj
index cf4a65f04..d0caff173 100644
--- a/src/lux/compiler/lux.clj
+++ b/src/lux/compiler/lux.clj
@@ -135,7 +135,12 @@
(.visit Opcodes/V1_5 (+ Opcodes/ACC_PUBLIC Opcodes/ACC_FINAL Opcodes/ACC_SUPER)
current-class nil "java/lang/Object" (into-array ["lux/Function"]))
(-> (.visitField (+ Opcodes/ACC_PUBLIC Opcodes/ACC_FINAL Opcodes/ACC_STATIC) "_datum" datum-sig nil nil)
- (doto (.visitEnd))))]
+ (doto (.visitEnd)))
+ ;; (-> (.visitField (+ Opcodes/ACC_PUBLIC Opcodes/ACC_FINAL Opcodes/ACC_STATIC) "_mode" datum-sig nil ...)
+ ;; (doto (.visitEnd)))
+ ;; (-> (.visitField (+ Opcodes/ACC_PUBLIC Opcodes/ACC_FINAL Opcodes/ACC_STATIC) "_type" datum-sig nil nil)
+ ;; (doto (.visitEnd)))
+ )]
_ (&/with-writer (.visitMethod =class Opcodes/ACC_PUBLIC "<clinit>" "()V" nil nil)
(|do [^MethodVisitor **writer** &/get-writer
:let [_ (.visitCode **writer**)]
@@ -150,6 +155,9 @@
_ (&&/save-class! current-class (.toByteArray =class))]
(return nil)))
+(defn compile-ann [compile *type* ?value-ex ?type-ex]
+ (compile ?value-ex))
+
(defn compile-declare-macro [compile module name]
(|do [_ (&a-module/declare-macro module name)]
(return nil)))
diff --git a/src/lux/host.clj b/src/lux/host.clj
index 8817ea338..e2efd92e9 100644
--- a/src/lux/host.clj
+++ b/src/lux/host.clj
@@ -25,8 +25,7 @@
)))
(defn ^:private method->type [^Method method]
- (|do [=return (class->type (.getReturnType method))]
- (return =return)))
+ (class->type (.getReturnType method)))
;; [Resources]
(defn ^String ->class [class]