aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEduardo Julian2015-05-06 19:10:55 -0400
committerEduardo Julian2015-05-06 19:10:55 -0400
commitc0bd1c6af6d1691ddc2627710e352a1bbe3eb1c7 (patch)
tree3ad74f9036572c1e31dc908ee87874599acf1275 /src
parent94891d38a25ae4e4cec4471d04eace38b47357c6 (diff)
- Made some small optimizations in the compiler.
Diffstat (limited to 'src')
-rw-r--r--src/lux/analyser/case.clj37
-rw-r--r--src/lux/analyser/host.clj7
-rw-r--r--src/lux/analyser/lux.clj24
-rw-r--r--src/lux/base.clj26
-rw-r--r--src/lux/compiler/case.clj13
-rw-r--r--src/lux/compiler/host.clj11
-rw-r--r--src/lux/compiler/lux.clj35
-rw-r--r--src/lux/host.clj43
-rw-r--r--src/lux/reader.clj7
9 files changed, 108 insertions, 95 deletions
diff --git a/src/lux/analyser/case.clj b/src/lux/analyser/case.clj
index cdcf40e0f..f18dc7836 100644
--- a/src/lux/analyser/case.clj
+++ b/src/lux/analyser/case.clj
@@ -169,10 +169,9 @@
[["TupleTotal" [total? ?values]] ["TupleTestAC" ?tests]]
(if (= (&/|length ?values) (&/|length ?tests))
- (|do [structs (&/map% (fn [vt]
- (|let [[v t] vt]
- (merge-total v (&/T t ?body))))
- (&/zip2 ?values ?tests))]
+ (|do [structs (&/map2% (fn [v t]
+ (merge-total v (&/T t ?body)))
+ ?values ?tests)]
(return (&/V "TupleTotal" (&/T total? structs))))
(fail "[Pattern-matching error] Inconsistent tuple-size."))
@@ -189,17 +188,18 @@
[["RecordTotal" [total? ?values]] ["RecordTestAC" ?tests]]
(if (= (&/|length ?values) (&/|length ?tests))
- (|do [structs (&/map% (fn [lr]
- (|let [[[lslot sub-struct] [rslot value]] lr]
- (if (= lslot rslot)
- (|do [sub-struct* (merge-total sub-struct (&/T value ?body))]
- (return (&/T lslot sub-struct*)))
- (fail "[Pattern-matching error] Record slots mismatch."))))
- (&/zip2 ?values
- (->> ?tests
- &/->seq
- (sort compare-kv)
- &/->list)))]
+ (|do [structs (&/map2% (fn [left right]
+ (|let [[lslot sub-struct] left
+ [rslot value]right]
+ (if (= lslot rslot)
+ (|do [sub-struct* (merge-total sub-struct (&/T value ?body))]
+ (return (&/T lslot sub-struct*)))
+ (fail "[Pattern-matching error] Record slots mismatch."))))
+ ?values
+ (->> ?tests
+ &/->seq
+ (sort compare-kv)
+ &/->list))]
(return (&/V "RecordTotal" (&/T total? structs))))
(fail "[Pattern-matching error] Inconsistent record-size."))
@@ -238,10 +238,9 @@
(return true)
(matchv ::M/objects [value-type]
[["lux;TupleT" ?members]]
- (|do [totals (&/map% (fn [sv]
- (|let [[sub-struct ?member] sv]
- (check-totality ?member sub-struct)))
- (&/zip2 ?structs ?members))]
+ (|do [totals (&/map2% (fn [sub-struct ?member]
+ (check-totality ?member sub-struct))
+ ?structs ?members)]
(return (&/fold #(and %1 %2) true totals)))
[_]
diff --git a/src/lux/analyser/host.clj b/src/lux/analyser/host.clj
index d57493439..0d9fb1333 100644
--- a/src/lux/analyser/host.clj
+++ b/src/lux/analyser/host.clj
@@ -111,10 +111,9 @@
=classes (&/map% &host/extract-jvm-param ?classes)
=return (&host/lookup-virtual-method =class ?method =classes)
=object (&&/analyse-1 analyse (&/V "lux;DataT" ?class) ?object)
- =args (&/map% (fn [c+o]
- (|let [[?c ?o] c+o]
- (&&/analyse-1 analyse (&/V "lux;DataT" ?c) ?o)))
- (&/zip2 =classes ?args))]
+ =args (&/map2% (fn [?c ?o]
+ (&&/analyse-1 analyse (&/V "lux;DataT" ?c) ?o))
+ =classes ?args)]
(return (&/|list (&/T (&/V <tag> (&/T =class ?method =classes =object =args)) =return)))))
analyse-jvm-invokevirtual "jvm-invokevirtual"
diff --git a/src/lux/analyser/lux.clj b/src/lux/analyser/lux.clj
index d461d5b6b..26376ad60 100644
--- a/src/lux/analyser/lux.clj
+++ b/src/lux/analyser/lux.clj
@@ -27,10 +27,9 @@
(|do [exo-type* (&type/actual-type exo-type)]
(matchv ::M/objects [exo-type*]
[["lux;TupleT" ?members]]
- (|do [=elems (&/map% (fn [ve]
- (|let [[elem-t elem] ve]
- (&&/analyse-1 analyse elem-t elem)))
- (&/zip2 ?members ?elems))]
+ (|do [=elems (&/map2% (fn [elem-t elem]
+ (&&/analyse-1 analyse elem-t elem))
+ ?members ?elems)]
(return (&/|list (&/T (&/V "tuple" =elems)
exo-type))))
@@ -160,15 +159,14 @@
(|let [scopes (&/|tail (&/folds #(&/|cons (&/get$ &/$NAME %2) %1)
(&/|map #(&/get$ &/$NAME %) outer)
(&/|reverse inner)))
- [=local inner*] (&/fold (fn [register+new-inner frame+in-scope]
- (|let [[register new-inner] register+new-inner
- [frame in-scope] frame+in-scope
- [register* frame*] (&&lambda/close-over (&/|cons module-name (&/|reverse in-scope)) ident register frame)]
- (&/T register* (&/|cons frame* new-inner))))
- (&/T (or (->> top-outer (&/get$ &/$LOCALS) (&/get$ &/$MAPPINGS) (&/|get local-ident))
- (->> top-outer (&/get$ &/$CLOSURE) (&/get$ &/$MAPPINGS) (&/|get local-ident)))
- (&/|list))
- (&/zip2 (&/|reverse inner) scopes))]
+ [=local inner*] (&/fold2 (fn [register+new-inner frame in-scope]
+ (|let [[register new-inner] register+new-inner
+ [register* frame*] (&&lambda/close-over (&/|cons module-name (&/|reverse in-scope)) ident register frame)]
+ (&/T register* (&/|cons frame* new-inner))))
+ (&/T (or (->> top-outer (&/get$ &/$LOCALS) (&/get$ &/$MAPPINGS) (&/|get local-ident))
+ (->> top-outer (&/get$ &/$CLOSURE) (&/get$ &/$MAPPINGS) (&/|get local-ident)))
+ (&/|list))
+ (&/|reverse inner) scopes)]
(&/run-state (|do [btype (&&/expr-type =local)
_ (&type/check exo-type btype)]
(return (&/|list =local)))
diff --git a/src/lux/base.clj b/src/lux/base.clj
index d834915de..5292faffa 100644
--- a/src/lux/base.clj
+++ b/src/lux/base.clj
@@ -612,6 +612,19 @@
[_ _]
(fail "Lists don't match in size.")))
+(defn map2% [f xs ys]
+ (matchv ::M/objects [xs ys]
+ [["lux;Cons" [x xs*]] ["lux;Cons" [y ys*]]]
+ (|do [z (f x y)
+ zs (map2% f xs* ys*)]
+ (return (|cons z zs)))
+
+ [["lux;Nil" _] ["lux;Nil" _]]
+ (return (V "lux;Nil" nil))
+
+ [_ _]
+ (fail "Lists don't match in size.")))
+
(defn fold2 [f init xs ys]
(matchv ::M/objects [xs ys]
[["lux;Cons" [x xs*]] ["lux;Cons" [y ys*]]]
@@ -623,3 +636,16 @@
[_ _]
false))
+
+(defn enumerate* [idx xs]
+ (matchv ::M/objects [xs]
+ [["lux;Cons" [x xs*]]]
+ (V "lux;Cons" (T (T idx x)
+ (enumerate* (inc idx) xs*)))
+
+ [["lux;Nil" _]]
+ xs
+ ))
+
+(defn enumerate [xs]
+ (enumerate* 0 xs))
diff --git a/src/lux/compiler/case.clj b/src/lux/compiler/case.clj
index 2720e31f7..37847f553 100644
--- a/src/lux/compiler/case.clj
+++ b/src/lux/compiler/case.clj
@@ -92,7 +92,7 @@
(->> (|let [[idx test] idx+member
$next (new Label)
$sub-else (new Label)])
- (doseq [idx+member (&/->seq (&/zip2 (&/|range (&/|length ?members)) ?members))])))
+ (doseq [idx+member (->> ?members &/enumerate &/->seq)])))
(.visitInsn Opcodes/POP)
(.visitJumpInsn Opcodes/GOTO $target))
@@ -110,11 +110,12 @@
(->> (|let [[idx [_ test]] idx+member
$next (new Label)
$sub-else (new Label)])
- (doseq [idx+member (&/->seq (&/zip2 (&/|range (&/|length ?slots))
- (->> ?slots
- &/->seq
- (sort compare-kv)
- &/->list)))])))
+ (doseq [idx+member (->> ?slots
+ &/->seq
+ (sort compare-kv)
+ &/->list
+ &/enumerate
+ &/->seq)])))
(.visitInsn Opcodes/POP)
(.visitJumpInsn Opcodes/GOTO $target))
diff --git a/src/lux/compiler/host.clj b/src/lux/compiler/host.clj
index 429424240..8782acfa5 100644
--- a/src/lux/compiler/host.clj
+++ b/src/lux/compiler/host.clj
@@ -202,12 +202,11 @@
:let [method-sig (str "(" (&/fold str "" (&/|map &host/->type-signature ?classes)) ")" (&host/->java-sig *type*))]
_ (compile ?object)
:let [_ (.visitTypeInsn *writer* Opcodes/CHECKCAST (&host/->class ?class))]
- _ (&/map% (fn [class-name+arg]
- (|let [[class-name arg] class-name+arg]
- (|do [ret (compile arg)
- :let [_ (prepare-arg! *writer* class-name)]]
- (return ret))))
- (&/zip2 ?classes ?args))
+ _ (&/map2% (fn [class-name arg]
+ (|do [ret (compile arg)
+ :let [_ (prepare-arg! *writer* class-name)]]
+ (return ret)))
+ ?classes ?args)
:let [_ (doto *writer*
(.visitMethodInsn <op> (&host/->class ?class) ?method method-sig)
(prepare-return! *type*))]]
diff --git a/src/lux/compiler/lux.clj b/src/lux/compiler/lux.clj
index 4e3e4add1..491cf62fb 100644
--- a/src/lux/compiler/lux.clj
+++ b/src/lux/compiler/lux.clj
@@ -54,15 +54,14 @@
_ (doto *writer*
(.visitLdcInsn (int num-elems))
(.visitTypeInsn Opcodes/ANEWARRAY (&host/->class "java.lang.Object")))]
- _ (&/map% (fn [idx+elem]
- (|let [[idx elem] idx+elem]
- (|do [:let [_ (doto *writer*
- (.visitInsn Opcodes/DUP)
- (.visitLdcInsn (int idx)))]
- ret (compile elem)
- :let [_ (.visitInsn *writer* Opcodes/AASTORE)]]
- (return ret))))
- (&/zip2 (&/|range num-elems) ?elems))]
+ _ (&/map2% (fn [idx elem]
+ (|do [:let [_ (doto *writer*
+ (.visitInsn Opcodes/DUP)
+ (.visitLdcInsn (int idx)))]
+ ret (compile elem)
+ :let [_ (.visitInsn *writer* Opcodes/AASTORE)]]
+ (return ret)))
+ (&/|range num-elems) ?elems)]
(return nil)))
(defn compile-record [compile *type* ?elems]
@@ -75,15 +74,15 @@
_ (doto *writer*
(.visitLdcInsn (int num-elems))
(.visitTypeInsn Opcodes/ANEWARRAY (&host/->class "java.lang.Object")))]
- _ (&/map% (fn [idx+kv]
- (|let [[idx [k v]] idx+kv]
- (|do [:let [_ (doto *writer*
- (.visitInsn Opcodes/DUP)
- (.visitLdcInsn (int idx)))]
- ret (compile v)
- :let [_ (.visitInsn *writer* Opcodes/AASTORE)]]
- (return ret))))
- (&/zip2 (&/|range num-elems) elems*))]
+ _ (&/map2% (fn [idx kv]
+ (|let [[k v] kv]
+ (|do [:let [_ (doto *writer*
+ (.visitInsn Opcodes/DUP)
+ (.visitLdcInsn (int idx)))]
+ ret (compile v)
+ :let [_ (.visitInsn *writer* Opcodes/AASTORE)]]
+ (return ret))))
+ (&/|range num-elems) elems*)]
(return nil)))
(defn compile-variant [compile *type* ?tag ?value]
diff --git a/src/lux/host.clj b/src/lux/host.clj
index 783b61298..55a772fcc 100644
--- a/src/lux/host.clj
+++ b/src/lux/host.clj
@@ -54,7 +54,7 @@
(def ->package ->class)
(defn ->type-signature [class]
- (assert (string? class))
+ ;; (assert (string? class))
(case class
"void" "V"
"boolean" "Z"
@@ -96,15 +96,13 @@
(do-template [<name> <static?>]
(defn <name> [target field]
- (let [target (Class/forName target)]
- (if-let [type* (first (for [^Field =field (.getFields target)
- :when (and (= target (.getDeclaringClass =field))
- (= field (.getName =field))
- (= <static?> (Modifier/isStatic (.getModifiers =field))))]
- (.getType =field)))]
- (|do [=type (class->type type*)]
- (return =type))
- (fail (str "[Analyser Error] Field does not exist: " target field)))))
+ (if-let [type* (first (for [^Field =field (.getDeclaredFields (Class/forName target))
+ :when (and (= field (.getName =field))
+ (= <static?> (Modifier/isStatic (.getModifiers =field))))]
+ (.getType =field)))]
+ (|do [=type (class->type type*)]
+ (return =type))
+ (fail (str "[Analyser Error] Field does not exist: " target "." field))))
lookup-static-field true
lookup-field false
@@ -112,21 +110,16 @@
(do-template [<name> <static?>]
(defn <name> [target method-name args]
- (let [target (Class/forName target)]
- (if-let [method (first (for [^Method =method (.getMethods target)
- :when (and (= target (.getDeclaringClass =method))
- (= method-name (.getName =method))
- (= <static?> (Modifier/isStatic (.getModifiers =method)))
- (&/fold #(and %1 %2)
- true
- (&/|map (fn [xy]
- (|let [[x y] xy]
- (= x y)))
- (&/zip2 args
- (&/|map #(.getName ^Class %) (&/->list (seq (.getParameterTypes =method))))))))]
- =method))]
- (method->type method)
- (fail (str "[Analyser Error] Method does not exist: " target method-name)))))
+ (if-let [method (first (for [^Method =method (.getDeclaredMethods (Class/forName target))
+ :when (and (= method-name (.getName =method))
+ (= <static?> (Modifier/isStatic (.getModifiers =method)))
+ (&/fold2 #(and %1 (= %2 %3))
+ true
+ args
+ (&/|map #(.getName ^Class %) (&/->list (seq (.getParameterTypes =method))))))]
+ =method))]
+ (method->type method)
+ (fail (str "[Analyser Error] Method does not exist: " target "." method-name))))
lookup-static-method true
lookup-virtual-method false
diff --git a/src/lux/reader.clj b/src/lux/reader.clj
index 38ff4d5e6..3c5f0066d 100644
--- a/src/lux/reader.clj
+++ b/src/lux/reader.clj
@@ -69,14 +69,13 @@
(defn from [file-name]
(let [lines (&/->list (string/split-lines (slurp file-name)))]
(&/|map (fn [line+line-num]
- (|let [[line line-num] line+line-num]
+ (|let [[line-num line] line+line-num]
(&/V "lux;Meta" (&/T (&/T file-name line-num 0)
line))))
(&/|filter (fn [line+line-num]
- (|let [[line line-num] line+line-num]
+ (|let [[line-num line] line+line-num]
(not (empty? line))))
- (&/zip2 lines
- (&/|range (&/|length lines)))))))
+ (&/enumerate lines)))))
(def current-line
(fn [state]