diff options
Diffstat (limited to '')
-rw-r--r-- | src/lux/analyser.clj | 595 |
1 files changed, 158 insertions, 437 deletions
diff --git a/src/lux/analyser.clj b/src/lux/analyser.clj index 3183c7166..de75b9f26 100644 --- a/src/lux/analyser.clj +++ b/src/lux/analyser.clj @@ -6,7 +6,7 @@ normalize-ident]] [parser :as &parser] [type :as &type] - [macros :as ¯os] + [macro :as ¯o] [host :as &host]))) ;; [Util] @@ -71,7 +71,7 @@ _ =return)))) -(defn ^:private with-let [name mode type body] +(defn ^:private with-local [name mode type body] (fn [state] (let [old-mappings (-> state ::&util/local-envs first (get-in [:locals :mappings])) =return (body (update-in state [::&util/local-envs] @@ -95,9 +95,9 @@ _ =return)))) -(defn ^:private with-lets [locals monad] +(defn ^:private with-locals [locals monad] (reduce (fn [inner [label elem]] - (with-let label :local elem inner)) + (with-local label :local elem inner)) monad (reverse locals))) @@ -106,22 +106,29 @@ [::&util/ok [state (-> state ::&util/local-envs first :closure :mappings)]])) (defn ^:private analyse-1 [elem] - (exec [output (analyse-ast elem) - _ (&util/assert! (= 1 (count output)) "[Analyser Error] Can't expand to other than 1 element.")] - (return (first output)))) + (exec [output (analyse-ast elem)] + (match output + ([x] :seq) + (return x) + + :else + (fail "[Analyser Error] Can't expand to other than 1 element.")))) (defn ^:private analyse-2 [el1 el2] - (exec [output (mapcat-m analyse-ast (list el1 el2)) - _ (&util/assert! (= 2 (count output)) - "[Analyser Error] Can't expand to other than 2 elements.")] - (return [(first output) (second output)]))) + (exec [output (mapcat-m analyse-ast (list el1 el2))] + (match output + ([x y] :seq) + (return [x y]) + + :else + (fail "[Analyser Error] Can't expand to other than 2 elements.")))) (defn ^:private with-lambda [self self-type arg arg-type body] (fn [state] (let [body* (with-env (-> state ::&util/local-envs first :inner-closures str) (exec [$scope &util/get-scope] - (with-let self :self self-type - (with-let arg :local arg-type + (with-local self :self self-type + (with-local arg :local arg-type (exec [=return body =captured captured-vars] (return [$scope =next =captured =return]))))))] @@ -133,9 +140,9 @@ (match register [::Expression _ register-type] (let [register* [::Expression [::captured scope (get-in frame [:closure :counter]) register] register-type]] - [register* (-> frame - (update-in [:closure :counter] inc) - (assoc-in [:closure :mappings ident] register*))]))) + [register* (update-in frame [:closure] #(-> % + (update-in [:counter] inc) + (assoc-in [:mappings ident] register*)))]))) (defn ^:private extract-ident [ident] (match ident @@ -162,8 +169,8 @@ (-> % :closure :mappings (contains? ident) not)) [inner outer] (split-with no-binding? stack*)] (if (empty? outer) - (if-let [global|import (get-in state [::&util/global-env ident])] - [::&util/ok [state (list global|import)]] + (if-let [global (get-in state [::&util/global-env ident])] + [::&util/ok [state (list global)]] [::&util/failure (str "[Analyser Error] Unresolved identifier: " ident)]) (let [[=local inner*] (reduce (fn [[register new-inner] frame] (let [[register* frame*] (close-over (:name frame) ident register frame)] @@ -186,18 +193,8 @@ [::global ?module ?name] (exec [macro? (macro? ?module ?name)] (if macro? - (let [macro-class (str ?module "$" (normalize-ident ?name)) - output (-> (.loadClass loader macro-class) - .getDeclaredConstructors - first - (.newInstance (to-array [(int 0) nil])) - (.apply (¯os/->lux+ loader ?args)) - (.apply nil)) - ;; _ (prn 'output (str ?module ":" ?name) output (.-_1 output) (.-tag (.-_1 output))) - macro-expansion (¯os/->clojure+ (.-_1 output)) - state* (.-_2 output) - ;; _ (prn 'macro-expansion (str ?module ":" ?name) state* macro-expansion) - ] + (let [macro-class (&host/location (list ?name ?module)) + [macro-expansion state*] (¯o/expand loader macro-class)] (mapcat-m analyse-ast macro-expansion)) (exec [=args (mapcat-m analyse-ast ?args) :let [[needs-num =return-type] (match =fn-type @@ -223,450 +220,174 @@ =exprs-types (map-m expr-type =exprs)] (return (list [::Expression [::do =exprs] (last =exprs-types)])))) -(do-template [<name> <tag>] - (defn <name> [tests ?token body-id] - (match (:struct tests) - [<tag> ?patterns ?defaults] - {:struct [<tag> (update-in ?patterns [?token] (fn [bodies] - (if bodies - (conj bodies body-id) - #{body-id}))) - ?defaults] - :branches (conj (:branches tests) body-id)} - - [::???Tests] - {:struct [<tag> {?token #{body-id}} (list)] - :branches (conj (:branches tests) body-id)} +(defn ^:private locals [member] + (match member + [::&parser/Ident ?name] + (list ?name) - :else - (assert false "Can't do match."))) + [::&parser/Tuple ?submembers] + (mapcat locals ?submembers) - ^:private bool-tests ::BoolTests - ^:private int-tests ::IntTests - ^:private real-tests ::RealTests - ^:private char-tests ::CharTests - ^:private text-tests ::TextTests - ) + [::&parser/Form ([[::&parser/Tag _] & ?submembers] :seq)] + (mapcat locals ?submembers) -(defn with-default [struct ?local $body] - (match (:struct tests) - [::BoolTests ?patterns ?defaults] - {:struct [::BoolTests ?patterns (conj ?defaults [::default ?local $body])] - :branches (conj (:branches tests) body-id)} + _ + (list))) - [::IntTests ?patterns ?defaults] - {:struct [::IntTests ?patterns (conj ?defaults [::default ?local $body])] - :branches (conj (:branches tests) body-id)} +(defn ^:private analyse-branch [max-registers [bindings body]] + (reduce (fn [body* name] + (with-local name :local +dont-care-type+ body*)) + (reduce (fn [body* _] + (with-local "#" :local +dont-care-type+ body*)) + (analyse-1 body) + (range (- max-registers (count bindings)))) + bindings)) - [::RealTests ?patterns ?defaults] - {:struct [::RealTests ?patterns (conj ?defaults [::default ?local $body])] - :branches (conj (:branches tests) body-id)} +(defn ^:private analyse-case [analyse-ast ?variant ?branches] + (exec [=variant (analyse-1 ?variant) + _ (assert! (and (> (count ?branches) 0) (even? (count ?branches))) + "Unbalanced branches in \"case'\" expression.") + :let [branches (partition 2 ?branches) + locals-per-branch (map locals (map first branches)) + max-locals (reduce max 0 (map count locals-per-branch))] + base-register next-local-idx + =bodies (map-m (partial analyse-branch max-locals) + (map vector locals-per-branch (map second branches))) + =body-types (map-m expr-type =bodies) + =case-type (reduce-m &type/merge [::&type/Nothing] =body-types) + :let [=branches (map vector (map first branches) =bodies)]] + (return (list [::Expression [::case =variant base-register max-locals =branches] =case-type])))) - [::CharTests ?patterns ?defaults] - {:struct [::CharTests ?patterns (conj ?defaults [::default ?local $body])] - :branches (conj (:branches tests) body-id)} +(defn ^:private raise-expr [arg syntax] + (match syntax + [::Expression ?form ?type] + (match ?form + [::bool ?value] + syntax - [::TextTests ?patterns ?defaults] - {:struct [::TextTests ?patterns (conj ?defaults [::default ?local $body])] - :branches (conj (:branches tests) body-id)} - )) + [::int ?value] + syntax -(def ^:private product-match [<type> ?tag ?members body-id] - (condp = (:type struct) - <type> (update-in struct [:patterns] - (fn [branches] - (if-let [{:keys [arity cases]} (get branches ?tag)] - (if (= arity (count ?members)) - (-> branches - (update-in [?tag :cases] conj {:case ?members - :body body-id}) - (update-in [?tag :branches] conj body-id)) - (assert false (str "Arity doesn't match. " (count ?members) "=/=" arity))) - (assoc branches ?tag {:arity (count ?members) - :cases [{:case ?members - :body body-id}] - :branches #{body-id}})))) - nil (-> struct - (assoc :type <type>) - (assoc-in [:patterns ?tag] {:arity (count ?members) - :cases [{:case ?members - :body body-id}] - :branches #{body-id}})) - ;; else - (assert false "Can't do match.") - )) + [::real ?value] + syntax -(def ^:private gen-product-branches [generate-branches <type> branches] - (do (assert (<= (count (:defaults branches)) 1)) - {:type <type> - :patterns (into {} (for [[?tag ?struct] (:patterns branches)] - [?tag {:parts (let [grouped-parts (apply map list (for [{:keys [case body]} (:cases ?struct)] - (map #(vector % body) case)))] - (map generate-branches grouped-parts)) - :branches (:branches ?struct)}])) - :default (-> branches :defaults first) - :branches (:branches branches)})) - -(let [fold-branch (fn [struct [pattern $body]] - (match pattern - [::BoolPM ?value] - (bool-tests struct $body) - - [::IntPM ?value] - (int-tests struct $body) - - [::RealPM ?value] - (real-tests struct $body) - - [::CharPM ?token] - (char-tests struct $body) - - [::TextPM ?text] - (text-tests struct $body) - - [::TuplePM ?members] - (product-match struct ::tuple-tests nil ?members $body) - - [::VariantPM ?tag ?members] - (product-match struct ::variant-tests ?tag ?members $body) - - [::LocalPM ?local] - (with-default struct ?local $body) - )) - base-struct [::???Tests] - generate-branches (fn generate-branches [data] - (let [branches* (reduce fold-branch base-struct data)] - (match branches* - [::BoolTests _] branches* - [::IntTests _] branches* - [::RealTests _] branches* - [::CharTests _] branches* - [::TextTests _] branches* - ::TupleTests (gen-product-branches generate-branches ::tuple-tests branches*) - ::VariantTests (gen-product-branches generate-branches ::variant-tests branches*) - nil {:type ::defaults, - :stores (reduce (fn [total [_ ?store ?body]] - (update-in total [?store] (fn [mapping] - (if mapping - (conj mapping ?body) - #{?body})))) - {} - (:defaults branches*)) - :branches (:branches branches*)}))) - get-vars (fn get-vars [pattern] - (match pattern - [::&parser/Bool ?value] - (list) - - [::&parser/Int ?value] - (list) - - [::&parser/Real ?value] - (list) - - [::&parser/Char ?token] - (list) - - [::&parser/Text ?text] - (list) - - [::&parser/Tag _] - (list) - - [::&parser/Ident ?name] - (list ?name) - - [::&parser/Tuple ?members] - (mapcat get-vars ?members) - - [::&parser/Form ([[::&parser/Tag _] & ?members] :seq)] - (mapcat get-vars ?members) - )) - ->instructions (fn ->instructions [locals pattern] - (clojure.core.match/match pattern - [::&parser/Bool ?value] - [::BoolPM ?value] - - [::&parser/Int ?value] - [::IntPM ?value] - - [::&parser/Real ?value] - [::RealPM ?value] - - [::&parser/Char ?value] - [::CharPM ?value] - - [::&parser/Text ?value] - [::TextPM ?value] - - [::&parser/Tag ?tag] - [::VariantPM ?tag (list)] - - [::&parser/Ident ?name] - [::LocalPM (get locals ?name)] - - [::&parser/Tuple ?members] - [::TuplePM (map (partial ->instructions locals) ?members)] - - [::&parser/Form ([[::&parser/Tag ?tag] & ?members] :seq)] - [::VariantPM ?tag (map (partial ->instructions locals) ?members)] - ))] - (defn ^:private ->decision-tree [$base branches] - (let [vars (for [branch branches] - (clojure.core.match/match branch - [::case-branch ?pattern ?body] - (get-vars ?pattern))) - [_ branch-mappings branches*] (reduce (fn [[$link links branches*] branch] - (clojure.core.match/match branch - [::case-branch ?pattern ?body] - [(inc $link) (assoc links $link ?body) (conj branches* [::case-branch ?pattern $link])])) - [0 {} []] - branches) - branches** (for [[branch branch-vars] (map vector branches* vars) - :let [[_ locals] (reduce (fn [[$local =locals] $var] - [(inc $local) (assoc =locals $var [::local $local])]) - [$base {}] branch-vars)]] - (clojure.core.match/match branch - [::case-branch ?pattern ?body] - [(->instructions locals ?pattern) ?body])) - max-registers (reduce max 0 (map count vars))] - [max-registers branch-mappings (generate-branches branches**)]))) - -(defn ^:private locals-getter [?member] - (match ?member - [::&parser/Ident ?name] - (list [?name +dont-care-type+]) + [::char ?value] + syntax - [::&parser/Tuple ?submembers] - (mapcat locals-getter ?submembers) + [::text ?value] + syntax + + [::tuple ?members] + [::Expression [::tuple (map (partial raise-expr arg) ?members)] ?type] - [::&parser/Form ([[::&parser/Tag ?subtag] & ?submembers] :seq)] - (mapcat locals-getter ?submembers) + [::variant ?tag ?members] + [::Expression [::variant ?tag (map (partial raise-expr arg) ?members)] ?type] + + [::local ?idx] + [::Expression [::local (inc ?idx)] ?type] + + [::captured _ _ ?source] + ?source - _ - (list) - )) + [::self ?curried] + [::Expression [::self (cons arg (map (partial raise-expr arg) ?curried))] ?type] -(defn ^:private analyse-case-branches [branches] - (map-m (fn [[?pattern ?body]] - (match ?pattern - [::&parser/Bool ?token] - (exec [=body (analyse-1 ?body)] - (return [::case-branch ?pattern =body])) - - [::&parser/Int ?token] - (exec [=body (analyse-1 ?body)] - (return [::case-branch ?pattern =body])) - - [::&parser/Real ?token] - (exec [=body (analyse-1 ?body)] - (return [::case-branch ?pattern =body])) - - [::&parser/Char ?token] - (exec [=body (analyse-1 ?body)] - (return [::case-branch ?pattern =body])) - - [::&parser/Text ?token] - (exec [=body (analyse-1 ?body)] - (return [::case-branch ?pattern =body])) - - [::&parser/Ident ?name] - (exec [=body (with-let ?name :local +dont-care-type+ - (analyse-1 ?body))] - (return [::case-branch ?pattern =body])) - - [::&parser/Tag ?tag] - (exec [=body (analyse-1 ?body)] - (return [::case-branch ?pattern =body])) - - [::&parser/Tuple ?members] - (exec [=body (with-lets (mapcat locals-getter ?members) - (analyse-1 ?body))] - (return [::case-branch ?pattern =body])) - - [::&parser/Form ([[::&parser/Tag ?tag] & ?members] :seq)] - (exec [=body (with-lets (mapcat locals-getter ?members) - (analyse-1 ?body))] - (return [::case-branch ?pattern =body])) - )) - branches)) + [::global _ _] + syntax -(defn ^:private analyse-case [analyse-ast ?variant ?branches] - (exec [=variant (analyse-1 ?variant) - _ (assert! (and (> (count ?branches) 0) (even? (count ?branches))) - "Imbalanced branches in \"case'\" expression.") - $base next-local-idx - [num-registers mappings tree] (exec [=branches (analyse-case-branches (partition 2 ?branches))] - (return (->decision-tree $base =branches)))] - (return (list [::Expression [::case $base =variant num-registers mappings tree] +dont-care-type+])))) - -(defn ^:private raise-tree-bindings [raise-expr arg ?tree] - (let [tree-partial-f (partial raise-tree-bindings raise-expr arg)] - (case (:type ?tree) - (::tuple ::variant) - (-> ?tree - (update-in [:patterns] - #(into {} (for [[?tag ?unapply] %] - [?tag (update-in ?unapply [:parts] (partial map tree-partial-f))]))) - (update-in [:default] - (fn [[tag local $branch :as total]] - (if total - (match (raise-expr arg [::Expression local [::&type/Nothing]]) - [::Expression local* [::&type/Nothing]] - [tag local* $branch]))))) - - ::defaults - (update-in ?tree [:stores] - #(into {} (for [[?store ?branches] %] - (match (raise-expr arg [::Expression ?store [::&type/Nothing]]) - [::Expression =store [::&type/Nothing]] - [=store ?branches])))) - ;; else - (assert false (pr-str ?tree)) - ))) + [::case ?variant ?base ?num-bindings ?pm-struct] + ... -(defn ^:private raise-expr [arg syntax] - ;; (prn 'raise-bindings body) - (let [partial-f (partial raise-expr arg) - tree-partial-f (partial raise-tree-bindings raise-expr arg)] - (match syntax - [::Expression ?form ?type] - (match ?form - [::bool ?value] - syntax - - [::int ?value] - syntax - - [::real ?value] - syntax - - [::char ?value] - syntax - - [::text ?value] - syntax - - [::tuple ?members] - [::Expression [::tuple (map partial-f ?members)] ?type] + [::lambda ?scope ?captured ?args ?value] + [::Expression [::lambda (pop ?scope) + (into {} (for [[?name ?sub-syntax] ?captured] + [?name (raise-expr arg ?sub-syntax)])) + ?args + ?value] + ?type] - [::variant ?tag ?members] - [::Expression [::variant ?tag (map partial-f ?members)] ?type] - - [::local ?idx] - [::Expression [::local (inc ?idx)] ?type] - - [::captured _ _ ?source] - ?source - - [::self ?curried] - [::Expression [::self (cons arg (map partial-f ?curried))] ?type] - - [::global _ _] - syntax - - [::let ?idx ?value ?body] - [::Expression [::let (inc ?idx) (partial-f ?value) - (partial-f ?body)] - ?type] - - [::case ?base ?variant ?registers ?mappings ?tree] - (let [=variant (partial-f ?variant) - =mappings (into {} (for [[idx syntax] ?mappings] - [idx (partial-f syntax)])) - =tree (tree-partial-f ?tree)] - [::Expression [::case (inc ?base) =variant ?registers =mappings =tree] ?type]) - - [::lambda ?scope ?captured ?args ?value] - [::Expression [::lambda (pop ?scope) - (into {} (for [[?name ?sub-syntax] ?captured] - [?name (partial-f ?sub-syntax)])) - ?args - ?value] - ?type] - - [::call ?func ?args] - [::Expression [::call (partial-f ?func) (map partial-f ?args)] ?type] - - [::do ?asts] - [::Expression [::do (map partial-f ?asts)] ?type] - - [::jvm-getstatic _ _] - syntax - - [::jvm-invokevirtual ?class ?method ?arg-classes ?obj ?args] - [::Expression [::jvm-invokevirtual ?class ?method ?arg-classes - (partial-f ?obj) - (map partial-f ?args)] - ?type] + [::call ?func ?args] + [::Expression [::call (raise-expr arg ?func) (map (partial raise-expr arg) ?args)] ?type] - ;; Integer arithmetic - [::jvm-iadd ?x ?y] - [::Expression [::jvm-iadd (partial-f ?x) (partial-f ?y)] ?type] + [::do ?asts] + [::Expression [::do (map (partial raise-expr arg) ?asts)] ?type] - [::jvm-isub ?x ?y] - [::Expression [::jvm-isub (partial-f ?x) (partial-f ?y)] ?type] + [::jvm-getstatic _ _] + syntax + + [::jvm-invokevirtual ?class ?method ?arg-classes ?obj ?args] + [::Expression [::jvm-invokevirtual ?class ?method ?arg-classes + (raise-expr arg ?obj) + (map (partial raise-expr arg) ?args)] + ?type] - [::jvm-imul ?x ?y] - [::Expression [::jvm-imul (partial-f ?x) (partial-f ?y)] ?type] + ;; Integer arithmetic + [::jvm-iadd ?x ?y] + [::Expression [::jvm-iadd (raise-expr arg ?x) (raise-expr arg ?y)] ?type] - [::jvm-idiv ?x ?y] - [::Expression [::jvm-idiv (partial-f ?x) (partial-f ?y)] ?type] + [::jvm-isub ?x ?y] + [::Expression [::jvm-isub (raise-expr arg ?x) (raise-expr arg ?y)] ?type] - [::jvm-irem ?x ?y] - [::Expression [::jvm-irem (partial-f ?x) (partial-f ?y)] ?type] + [::jvm-imul ?x ?y] + [::Expression [::jvm-imul (raise-expr arg ?x) (raise-expr arg ?y)] ?type] - ;; Long arithmetic - [::jvm-ladd ?x ?y] - [::Expression [::jvm-ladd (partial-f ?x) (partial-f ?y)] ?type] + [::jvm-idiv ?x ?y] + [::Expression [::jvm-idiv (raise-expr arg ?x) (raise-expr arg ?y)] ?type] - [::jvm-lsub ?x ?y] - [::Expression [::jvm-lsub (partial-f ?x) (partial-f ?y)] ?type] + [::jvm-irem ?x ?y] + [::Expression [::jvm-irem (raise-expr arg ?x) (raise-expr arg ?y)] ?type] - [::jvm-lmul ?x ?y] - [::Expression [::jvm-lmul (partial-f ?x) (partial-f ?y)] ?type] + ;; Long arithmetic + [::jvm-ladd ?x ?y] + [::Expression [::jvm-ladd (raise-expr arg ?x) (raise-expr arg ?y)] ?type] - [::jvm-ldiv ?x ?y] - [::Expression [::jvm-ldiv (partial-f ?x) (partial-f ?y)] ?type] + [::jvm-lsub ?x ?y] + [::Expression [::jvm-lsub (raise-expr arg ?x) (raise-expr arg ?y)] ?type] - [::jvm-lrem ?x ?y] - [::Expression [::jvm-lrem (partial-f ?x) (partial-f ?y)] ?type] + [::jvm-lmul ?x ?y] + [::Expression [::jvm-lmul (raise-expr arg ?x) (raise-expr arg ?y)] ?type] - ;; Float arithmetic - [::jvm-fadd ?x ?y] - [::Expression [::jvm-fadd (partial-f ?x) (partial-f ?y)] ?type] + [::jvm-ldiv ?x ?y] + [::Expression [::jvm-ldiv (raise-expr arg ?x) (raise-expr arg ?y)] ?type] - [::jvm-fsub ?x ?y] - [::Expression [::jvm-fsub (partial-f ?x) (partial-f ?y)] ?type] + [::jvm-lrem ?x ?y] + [::Expression [::jvm-lrem (raise-expr arg ?x) (raise-expr arg ?y)] ?type] - [::jvm-fmul ?x ?y] - [::Expression [::jvm-fmul (partial-f ?x) (partial-f ?y)] ?type] + ;; Float arithmetic + [::jvm-fadd ?x ?y] + [::Expression [::jvm-fadd (raise-expr arg ?x) (raise-expr arg ?y)] ?type] - [::jvm-fdiv ?x ?y] - [::Expression [::jvm-fdiv (partial-f ?x) (partial-f ?y)] ?type] + [::jvm-fsub ?x ?y] + [::Expression [::jvm-fsub (raise-expr arg ?x) (raise-expr arg ?y)] ?type] - [::jvm-frem ?x ?y] - [::Expression [::jvm-frem (partial-f ?x) (partial-f ?y)] ?type] + [::jvm-fmul ?x ?y] + [::Expression [::jvm-fmul (raise-expr arg ?x) (raise-expr arg ?y)] ?type] - ;; Double arithmetic - [::jvm-dadd ?x ?y] - [::Expression [::jvm-dadd (partial-f ?x) (partial-f ?y)] ?type] + [::jvm-fdiv ?x ?y] + [::Expression [::jvm-fdiv (raise-expr arg ?x) (raise-expr arg ?y)] ?type] - [::jvm-dsub ?x ?y] - [::Expression [::jvm-dsub (partial-f ?x) (partial-f ?y)] ?type] + [::jvm-frem ?x ?y] + [::Expression [::jvm-frem (raise-expr arg ?x) (raise-expr arg ?y)] ?type] - [::jvm-dmul ?x ?y] - [::Expression [::jvm-dmul (partial-f ?x) (partial-f ?y)] ?type] + ;; Double arithmetic + [::jvm-dadd ?x ?y] + [::Expression [::jvm-dadd (raise-expr arg ?x) (raise-expr arg ?y)] ?type] - [::jvm-ddiv ?x ?y] - [::Expression [::jvm-ddiv (partial-f ?x) (partial-f ?y)] ?type] + [::jvm-dsub ?x ?y] + [::Expression [::jvm-dsub (raise-expr arg ?x) (raise-expr arg ?y)] ?type] - [::jvm-drem ?x ?y] - [::Expression [::jvm-drem (partial-f ?x) (partial-f ?y)] ?type] + [::jvm-dmul ?x ?y] + [::Expression [::jvm-dmul (raise-expr arg ?x) (raise-expr arg ?y)] ?type] - _ - (assert false syntax) - )))) + [::jvm-ddiv ?x ?y] + [::Expression [::jvm-ddiv (raise-expr arg ?x) (raise-expr arg ?y)] ?type] + + [::jvm-drem ?x ?y] + [::Expression [::jvm-drem (raise-expr arg ?x) (raise-expr arg ?y)] ?type] + + _ + (assert false syntax) + ))) (defn ^:private analyse-lambda [analyse-ast ?self ?arg ?body] (exec [[_ =arg =return :as =function] &type/fresh-function |