aboutsummaryrefslogtreecommitdiff
path: root/src/lang/type.clj
diff options
context:
space:
mode:
authorEduardo Julian2014-12-20 23:25:40 -0400
committerEduardo Julian2014-12-20 23:25:40 -0400
commit74d3233f7d7984ebcef0d4e6778f0596e867de6c (patch)
treeacb80d80ecf005fceff316b7ba4084407087c68c /src/lang/type.clj
parentef185e0ec91af1d22762ef55dc5586c240633e18 (diff)
* Java interop is almost finished.
% _. and _.. syntax has been replaced with ::
Diffstat (limited to 'src/lang/type.clj')
-rw-r--r--src/lang/type.clj64
1 files changed, 63 insertions, 1 deletions
diff --git a/src/lang/type.clj b/src/lang/type.clj
index 465f6e9fc..cfb404a21 100644
--- a/src/lang/type.clj
+++ b/src/lang/type.clj
@@ -3,7 +3,7 @@
(:require [clojure.core.match :refer [match]]
[lang.util :as &util :refer [exec return* return fail fail*
repeat-m try-m try-all-m map-m
- apply-m]]))
+ apply-m assert!]]))
;; [Util]
(def ^:private success (return nil))
@@ -39,6 +39,7 @@
(return [=function =args =return])))
(defn solve [expected actual]
+ ;; (prn 'solve expected actual)
(match [expected actual]
[::any _]
success
@@ -64,10 +65,35 @@
_ (update ?id =top actual)]
success)]))
+ [[::primitive ?prim] _]
+ (let [as-obj (case ?prim
+ "boolean" [:lang.type/object "java.lang.Boolean" []]
+ "int" [:lang.type/object "java.lang.Integer" []]
+ "long" [:lang.type/object "java.lang.Long" []]
+ "char" [:lang.type/object "java.lang.Character" []]
+ "float" [:lang.type/object "java.lang.Float" []]
+ "double" [:lang.type/object "java.lang.Double" []])]
+ (solve as-obj actual))
+
+ [[::object ?eclass []] [::object ?aclass []]]
+ (if (.isAssignableFrom (Class/forName ?eclass) (Class/forName ?aclass))
+ success
+ (fail (str "Can't solve types: " (pr-str expected actual))))
+
[_ _]
(fail (str "Can't solve types: " (pr-str expected actual)))
))
+(defn pick-matches [methods args]
+ (if (empty? methods)
+ (fail "No matches.")
+ (try-all-m [(match (-> methods first second)
+ [::function ?args ?return]
+ (exec [_ (assert! (= (count ?args) (count args)) "Args-size doesn't match.")
+ _ (map-m (fn [[e a]] (solve e a)) (map vector ?args args))]
+ (return (first methods))))
+ (pick-matches (rest methods) args)])))
+
(defn clean [type]
(match type
[::var ?id]
@@ -84,3 +110,39 @@
_
(return type)))
+
+;; Java Reflection
+(defn class->type [class]
+ (if-let [[_ base arr-level] (re-find #"^([^\[]+)(\[\])*$"
+ (str (if-let [pkg (.getPackage class)]
+ (str (.getName pkg) ".")
+ "")
+ (.getSimpleName class)))]
+ (if (= "void" base)
+ (return ::nothing)
+ (let [base* (case base
+ ("boolean" "byte" "short" "int" "long" "float" "double" "char")
+ [::primitive base]
+ ;; else
+ [::object base []])]
+ (if arr-level
+ (return (reduce (fn [inner _]
+ [::array inner])
+ base*
+ (range (/ (count arr-level) 2.0))))
+ (return base*)))
+
+ )))
+
+(defn method->type [method]
+ (exec [=args (map-m class->type (seq (.getParameterTypes method)))
+ =return (class->type (.getReturnType method))]
+ (return [::function (vec =args) =return])))
+
+(defn return-type [func]
+ (match func
+ [::function _ ?return]
+ (return ?return)
+
+ _
+ (fail (str "Type is not a function: " (pr-str func)))))