From ea0cff44a5f003f8956ffbce9ea5f6957fdf4c92 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Thu, 16 May 2019 21:18:23 -0400 Subject: Yet more fiddling with types for JVM interop. + Some progress on anonymous classes. + More elaborate handling of JVM arrays. --- .../source/luxc/lang/translation/jvm/function.lux | 85 ++-- .../luxc/lang/translation/jvm/procedure/host.lux | 239 +++++----- stdlib/source/lux/data/collection/array.lux | 2 +- stdlib/source/lux/data/text.lux | 2 +- stdlib/source/lux/host.jvm.lux | 132 ++++-- stdlib/source/lux/target/jvm/type.lux | 41 +- stdlib/source/lux/tool/compiler/phase.lux | 7 +- .../tool/compiler/phase/extension/analysis/jvm.lux | 486 ++++++++++++--------- 8 files changed, 562 insertions(+), 432 deletions(-) diff --git a/new-luxc/source/luxc/lang/translation/jvm/function.lux b/new-luxc/source/luxc/lang/translation/jvm/function.lux index ae876c3fc..d0764796f 100644 --- a/new-luxc/source/luxc/lang/translation/jvm/function.lux +++ b/new-luxc/source/luxc/lang/translation/jvm/function.lux @@ -9,13 +9,13 @@ ["." text format] [collection - ["." list ("#/." functor monoid)]]] + ["." list ("#@." functor monoid)]]] [target - [jvm - ["." type (#+ Type Method)]]] + ["." jvm #_ + ["#" type (#+ Type Method)]]] [tool [compiler - [analysis (#+ Arity)] + [analysis (#+ Arity Environment)] [synthesis (#+ Synthesis Abstraction Apply)] ["_." reference (#+ Register Variable)] ["." phase @@ -30,9 +30,8 @@ ["." runtime] ["." reference]]) - (def: arity-field Text "arity") -(def: $Object Type (type.class "java.lang.Object" (list))) +(def: $Object Type (jvm.class "java.lang.Object" (list))) (def: (poly-arg? arity) (-> Arity Bit) @@ -40,29 +39,29 @@ (def: (reset-method class) (-> Text Method) - (type.method (list) (#.Some (type.class class (list))) (list))) + (jvm.method (list) (#.Some (jvm.class class (list))) (list))) (def: (captured-args env) - (-> (List Variable) (List Type)) + (-> Environment (List Type)) (list.repeat (list.size env) $Object)) (def: (init-method env arity) - (-> (List Variable) Arity Method) + (-> Environment Arity Method) (if (poly-arg? arity) - (type.method (list.concat (list (captured-args env) - (list type.int) - (list.repeat (dec arity) $Object))) - #.None - (list)) - (type.method (captured-args env) #.None (list)))) + (jvm.method (list.concat (list (captured-args env) + (list jvm.int) + (list.repeat (dec arity) $Object))) + #.None + (list)) + (jvm.method (captured-args env) #.None (list)))) (def: (implementation-method arity) - (type.method (list.repeat arity $Object) (#.Some $Object) (list))) + (jvm.method (list.repeat arity $Object) (#.Some $Object) (list))) (def: get-amount-of-partialsI Inst (|>> (_.ALOAD 0) - (_.GETFIELD //.function-class runtime.partials-field type.int))) + (_.GETFIELD //.function-class runtime.partials-field jvm.int))) (def: (load-fieldI class field) (-> Text Text Inst) @@ -72,7 +71,7 @@ (def: (inputsI start amount) (-> Register Nat Inst) (|> (list.n/range start (n/+ start (dec amount))) - (list/map _.ALOAD) + (list@map _.ALOAD) _.fuse)) (def: (applysI start amount) @@ -97,24 +96,24 @@ (list.repeat amount) _.fuse)) -(def: (with-captured env) - (-> (List Variable) Def) - (|> (list.enumerate env) - (list/map (.function (_ [env-idx env-source]) - (def.field #$.Private $.finalF (reference.foreign-name env-idx) $Object))) - def.fuse)) +(def: #export with-environment + (-> Environment Def) + (|>> list.enumerate + (list@map (.function (_ [env-idx env-source]) + (def.field #$.Private $.finalF (reference.foreign-name env-idx) $Object))) + def.fuse)) (def: (with-partial arity) (-> Arity Def) (if (poly-arg? arity) (|> (list.n/range 0 (n/- 2 arity)) - (list/map (.function (_ idx) + (list@map (.function (_ idx) (def.field #$.Private $.finalF (reference.partial-name idx) $Object))) def.fuse) function.identity)) (def: (instance class arity env) - (-> Text Arity (List Variable) (Operation Inst)) + (-> Text Arity Environment (Operation Inst)) (do phase.monad [captureI+ (monad.map @ reference.variable env) #let [argsI (if (poly-arg? arity) @@ -129,14 +128,14 @@ (_.INVOKESPECIAL class "" (init-method env arity) #0))))) (def: (with-reset class arity env) - (-> Text Arity (List Variable) Def) + (-> Text Arity Environment Def) (def.method #$.Public $.noneM "reset" (reset-method class) (if (poly-arg? arity) (let [env-size (list.size env) captureI (|> (case env-size 0 (list) _ (list.n/range 0 (dec env-size))) - (list/map (.function (_ source) + (list@map (.function (_ source) (|>> (_.ALOAD 0) (_.GETFIELD class (reference.foreign-name source) $Object)))) _.fuse) @@ -161,7 +160,7 @@ (def: function-init-method Method - (type.method (list type.int) #.None (list))) + (jvm.method (list jvm.int) #.None (list))) (def: (function-init arity env-size) (-> Arity Nat Inst) @@ -172,21 +171,21 @@ (_.INVOKESPECIAL //.function-class "" function-init-method #0)))) (def: (with-init class env arity) - (-> Text (List Variable) Arity Def) + (-> Text Environment Arity Def) (let [env-size (list.size env) offset-partial (: (-> Nat Nat) (|>> inc (n/+ env-size))) store-capturedI (|> (case env-size 0 (list) _ (list.n/range 0 (dec env-size))) - (list/map (.function (_ register) + (list@map (.function (_ register) (|>> (_.ALOAD 0) (_.ALOAD (inc register)) (_.PUTFIELD class (reference.foreign-name register) $Object)))) _.fuse) store-partialI (if (poly-arg? arity) (|> (list.n/range 0 (n/- 2 arity)) - (list/map (.function (_ idx) + (list@map (.function (_ idx) (let [register (offset-partial idx)] (|>> (_.ALOAD 0) (_.ALOAD (inc register)) @@ -201,18 +200,18 @@ _.RETURN)))) (def: (with-apply class env function-arity @begin bodyI apply-arity) - (-> Text (List Variable) Arity Label Inst Arity + (-> Text Environment Arity Label Inst Arity Def) (let [num-partials (dec function-arity) @default ($.new-label []) - @labels (list/map $.new-label (list.repeat num-partials [])) + @labels (list@map $.new-label (list.repeat num-partials [])) arity-over-extent (|> (.int function-arity) (i/- (.int apply-arity))) - casesI (|> (list/compose @labels (list @default)) + casesI (|> (list@compose @labels (list @default)) (list.zip2 (list.n/range 0 num-partials)) - (list/map (.function (_ [stage @label]) + (list@map (.function (_ [stage @label]) (let [load-partialsI (if (n/> 0 stage) (|> (list.n/range 0 (dec stage)) - (list/map (|>> reference.partial-name (load-fieldI class))) + (list@map (|>> reference.partial-name (load-fieldI class))) _.fuse) function.identity)] (cond (i/= arity-over-extent (.int stage)) @@ -242,7 +241,7 @@ load-capturedI (|> (case env-size 0 (list) _ (list.n/range 0 (dec env-size))) - (list/map (|>> reference.foreign-name (load-fieldI class))) + (list@map (|>> reference.foreign-name (load-fieldI class))) _.fuse)] (|>> (_.label @label) (_.NEW class) @@ -262,20 +261,20 @@ (_.TABLESWITCH +0 (|> num-partials dec .int) @default @labels) casesI - (_.INVOKESTATIC //.runtime-class "apply_fail" (type.method (list) #.None (list)) #0) + (_.INVOKESTATIC //.runtime-class "apply_fail" (jvm.method (list) #.None (list)) #0) _.NULL _.ARETURN )))) (def: #export (with-function @begin class env arity bodyI) - (-> Label Text (List Variable) Arity Inst + (-> Label Text Environment Arity Inst (Operation [Def Inst])) (let [env-size (list.size env) applyD (: Def (if (poly-arg? arity) (|> (n/min arity runtime.num-apply-variants) (list.n/range 1) - (list/map (with-apply class env arity @begin bodyI)) + (list@map (with-apply class env arity @begin bodyI)) (list& (with-implementation arity @begin bodyI)) def.fuse) (def.method #$.Public $.strictM runtime.apply-method (runtime.apply-signature 1) @@ -284,7 +283,7 @@ _.ARETURN)))) functionD (: Def (|>> (def.int-field #$.Public ($_ $.++F $.staticF $.finalF) arity-field (.int arity)) - (with-captured env) + (with-environment env) (with-partial arity) (with-init class env arity) (with-reset class arity env) @@ -323,7 +322,7 @@ [functionI (translate functionS) argsI (monad.map @ translate argsS) #let [applyI (|> (segment runtime.num-apply-variants argsI) - (list/map (.function (_ chunkI+) + (list@map (.function (_ chunkI+) (|>> (_.CHECKCAST //.function-class) (_.fuse chunkI+) (_.INVOKEVIRTUAL //.function-class runtime.apply-method (runtime.apply-signature (list.size chunkI+)) #0)))) diff --git a/new-luxc/source/luxc/lang/translation/jvm/procedure/host.lux b/new-luxc/source/luxc/lang/translation/jvm/procedure/host.lux index 55798c806..be2a0bace 100644 --- a/new-luxc/source/luxc/lang/translation/jvm/procedure/host.lux +++ b/new-luxc/source/luxc/lang/translation/jvm/procedure/host.lux @@ -31,6 +31,8 @@ ["." generation [extension (#+ Nullary Unary Binary nullary unary binary)]] + [analysis + [".A" reference]] ["." extension ["." bundle] [analysis @@ -39,17 +41,27 @@ [luxc [lang [host - ["$" jvm (#+ Label Inst Handler Bundle Operation Phase) + ["$" jvm (#+ Label Inst Def Handler Bundle Operation Phase) ["_" inst] - ["_." def]]]]]) + ["_." def]]]]] + ["." /// #_ + ["#." reference] + ["#." function]]) -(template [] - [(exception: #export ( {message Text}) - message)] +(exception: #export invalid-syntax-for-argument-generation) - [invalid-syntax-for-jvm-type] - [invalid-syntax-for-argument-generation] - ) +(def: (custom [parser handler]) + (All [s] + (-> [(.Parser s) + (-> Text Phase s (Operation Inst))] + Handler)) + (function (_ extension-name phase input) + (case (.run input parser) + (#error.Success input') + (handler extension-name phase input') + + (#error.Failure error) + (phase.throw extension.invalid-syntax [extension-name %synthesis input])))) (template [ ] [(def: @@ -306,7 +318,17 @@ "char" jvm.char _ (jvm.class elem-class (list))))) -(def: (array::length extension-name generate inputs) +(def: (primitive-array-length-handler jvm-primitive) + (-> Type Handler) + (..custom [.any + (function (_ extension-name generate arrayS) + (do phase.monad + [arrayI (generate arrayS)] + (wrap (|>> arrayI + (_.CHECKCAST (jvm.descriptor (jvm.array 1 jvm-primitive))) + _.ARRAYLENGTH))))])) + +(def: (array::length::object extension-name generate inputs) Handler (case inputs (^ (list (synthesis.i64 nesting) @@ -427,7 +449,17 @@ Bundle (<| (bundle.prefix "array") (|> bundle.empty - (bundle.install "length" array::length) + (dictionary.merge (<| (bundle.prefix "length") + (|> bundle.empty + (bundle.install "boolean" (primitive-array-length-handler jvm.boolean)) + (bundle.install "byte" (primitive-array-length-handler jvm.byte)) + (bundle.install "short" (primitive-array-length-handler jvm.short)) + (bundle.install "int" (primitive-array-length-handler jvm.int)) + (bundle.install "long" (primitive-array-length-handler jvm.long)) + (bundle.install "float" (primitive-array-length-handler jvm.float)) + (bundle.install "double" (primitive-array-length-handler jvm.double)) + (bundle.install "char" (primitive-array-length-handler jvm.char)) + (bundle.install "object" array::length::object)))) (dictionary.merge (<| (bundle.prefix "new") (|> bundle.empty (bundle.install "boolean" (new-primitive-array-handler jvm.boolean)) @@ -671,62 +703,30 @@ _ (phase.throw extension.invalid-syntax [extension-name %synthesis inputs]))) -(def: base-type - (.Parser Type) - ($_ <>.either - (<>.after (.this "boolean") (<>@wrap jvm.boolean)) - (<>.after (.this "byte") (<>@wrap jvm.byte)) - (<>.after (.this "short") (<>@wrap jvm.short)) - (<>.after (.this "int") (<>@wrap jvm.int)) - (<>.after (.this "long") (<>@wrap jvm.long)) - (<>.after (.this "float") (<>@wrap jvm.float)) - (<>.after (.this "double") (<>@wrap jvm.double)) - (<>.after (.this "char") (<>@wrap jvm.char)) - (<>@map (function (_ name) - (jvm.class name (list))) - (.many (.none-of "["))) - )) - -(def: java-type - (.Parser Type) - (do <>.monad - [raw base-type - nesting (<>.some (.this "[]"))] - (wrap (jvm.array (list.size nesting) raw)))) - -(def: (generate-type argD) - (-> Text (Operation Type)) - (case (.run java-type argD) - (#error.Failure error) - (phase.throw invalid-syntax-for-jvm-type argD) - - (#error.Success type) - (phase@wrap type))) - (def: (generate-arg generate argS) (-> (-> Synthesis (Operation Inst)) Synthesis (Operation [Type Inst])) (case argS (^ (synthesis.tuple (list (synthesis.text argD) argS))) (do phase.monad - [argD (phase.lift (:: error.monad map - jvm.reflection-class - (jvm.parse-signature argD))) - argT (generate-type argD) + [argT (phase.lift (.run jvm.parse-signature argD)) argI (generate argS)] (wrap [argT argI])) _ - (phase.throw invalid-syntax-for-argument-generation ""))) + (phase.throw invalid-syntax-for-argument-generation []))) (def: (method-return-type description) (-> Text (Operation (Maybe Type))) (case description - "void" + (^ (static jvm.void-descriptor)) (phase@wrap #.None) _ - (phase@map (|>> #.Some) (generate-type description)))) + (|> description + (.run jvm.parse-signature) + phase.lift + (phase@map (|>> #.Some))))) (def: (prepare-argI [type argI]) (-> [Type Inst] Inst) @@ -738,46 +738,35 @@ #.None argI)) -(def: (invoke::static extension-name generate inputs) +(def: invoke::static Handler - (case inputs - (^ (list& (synthesis.text class) - (synthesis.text method) - (synthesis.text unboxed) - argsS)) - (do phase.monad - [argsTI (monad.map @ (generate-arg generate) argsS) - returnT (method-return-type unboxed)] - (wrap (|>> (_.fuse (list@map ..prepare-argI argsTI)) - (_.INVOKESTATIC class method - (jvm.method (list@map product.left argsTI) returnT (list)) - false)))) - - _ - (phase.throw extension.invalid-syntax [extension-name %synthesis inputs]))) + (..custom + [($_ <>.and .text .text .text (<>.some .any)) + (function (_ extension-name generate [class method unboxed argsS]) + (do phase.monad + [argsTI (monad.map @ (generate-arg generate) argsS) + returnT (method-return-type unboxed)] + (wrap (|>> (_.fuse (list@map ..prepare-argI argsTI)) + (_.INVOKESTATIC class method + (jvm.method (list@map product.left argsTI) returnT (list)) + false)))))])) (template [ ] - [(def: ( extension-name generate inputs) + [(def: Handler - (case inputs - (^ (list& (synthesis.text class) - (synthesis.text method) - (synthesis.text unboxed) - objectS - argsS)) - (do phase.monad - [objectI (generate objectS) - argsTI (monad.map @ (generate-arg generate) argsS) - returnT (method-return-type unboxed)] - (wrap (|>> objectI - (_.CHECKCAST class) - (_.fuse (list@map ..prepare-argI argsTI)) - ( class method - (jvm.method (list@map product.left argsTI) returnT (list)) - )))) - - _ - (phase.throw extension.invalid-syntax [extension-name %synthesis inputs])))] + (..custom + [($_ <>.and .text .text .text .any (<>.some .any)) + (function (_ extension-name generate [class method unboxed objectS argsS]) + (do phase.monad + [objectI (generate objectS) + argsTI (monad.map @ (generate-arg generate) argsS) + returnT (method-return-type unboxed)] + (wrap (|>> objectI + (_.CHECKCAST class) + (_.fuse (list@map ..prepare-argI argsTI)) + ( class method + (jvm.method (list@map product.left argsTI) returnT (list)) + )))))]))] [invoke::virtual _.INVOKEVIRTUAL false] [invoke::special _.INVOKESPECIAL false] @@ -821,19 +810,6 @@ (bundle.install "constructor" invoke::constructor)))) ))) -(def: (custom [parser handler]) - (All [s] - (-> [(.Parser s) - (-> Text Phase s (Operation Inst))] - Handler)) - (function (_ extension-name phase input) - (case (.run input parser) - (#error.Success input') - (handler extension-name phase input') - - (#error.Failure error) - (phase.throw extension.invalid-syntax [extension-name %synthesis input])))) - (def: var (.Parser Var) .text) @@ -902,7 +878,7 @@ (def: return (.Parser Return) - (<>.or (.constant! ["" "void"]) + (<>.or (.constant! ["" jvm.void-descriptor]) ..jvm-type)) (def: overriden-method-definition @@ -998,6 +974,39 @@ (#synthesis.Extension [name inputsS+]) (#synthesis.Extension [name (list@map recur inputsS+)])))) +(def: $Object (jvm.class jvm.object-class (list))) + +(def: (anonymous-init-method env) + (-> Environment Method) + (jvm.method (list.repeat (list.size env) $Object) + #.None + (list))) + +(def: (with-anonymous-init class env) + (-> Text Environment Def) + (let [store-capturedI (|> env + list.size + list.indices + (list@map (.function (_ register) + (|>> (_.ALOAD 0) + (_.ALOAD (inc register)) + (_.PUTFIELD class (///reference.foreign-name register) $Object)))) + _.fuse)] + (_def.method #$.Public $.noneM "" (anonymous-init-method env) + (|>> (_.ALOAD 0) + (_.INVOKESPECIAL jvm.object-class "" (jvm.method (list) #.None (list)) #0) + store-capturedI + _.RETURN)))) + +(def: (anonymous-instance class env) + (-> Text Environment (Operation Inst)) + (do phase.monad + [captureI+ (monad.map @ ///reference.variable env)] + (wrap (|>> (_.NEW class) + _.DUP + (_.fuse captureI+) + (_.INVOKESPECIAL class "" (anonymous-init-method env) #0))))) + (def: class::anonymous Handler (..custom @@ -1012,14 +1021,15 @@ constructor-args overriden-methods]) (do phase.monad - [#let [global-mapping (|> overriden-methods - ## Get all the environments. - (list@map product.left) - ## Combine them. - list@join - ## Remove duplicates. - (set.from-list reference.hash) - set.to-list + [#let [total-environment (|> overriden-methods + ## Get all the environments. + (list@map product.left) + ## Combine them. + list@join + ## Remove duplicates. + (set.from-list reference.hash) + set.to-list) + global-mapping (|> total-environment ## Give them names as "foreign" variables. list.enumerate (list@map (function (_ [id capture]) @@ -1043,14 +1053,13 @@ self-name arguments returnT exceptionsT (normalize-method-body local-mapping body)])) overriden-methods)] - ## _ (generation.save! true ["" function-class] - ## [function-class - ## (def.class #$.V1_6 #$.Public $.finalC - ## function-class (list) - ## ($.simple-class //.function-class) (list) - ## functionD)]) - _ (phase.throw extension.invalid-syntax ["YOLO-TRON" %synthesis (list)])] - (wrap _.DUP)))])) + _ (generation.save! true ["" class-name] + [class-name + (_def.class #$.V1_6 #$.Public $.finalC + class-name (list) + super-class super-interfaces + (|>> (///function.with-environment total-environment)))])] + (anonymous-instance class-name total-environment)))])) (def: bundle::class Bundle diff --git a/stdlib/source/lux/data/collection/array.lux b/stdlib/source/lux/data/collection/array.lux index b6f877d73..cac39d65f 100644 --- a/stdlib/source/lux/data/collection/array.lux +++ b/stdlib/source/lux/data/collection/array.lux @@ -50,7 +50,7 @@ (~~ (static @.jvm)) (|> array (:coerce ) - "jvm array length" + "jvm array length object" "jvm conversion int-to-long" "jvm object cast" (: ) diff --git a/stdlib/source/lux/data/text.lux b/stdlib/source/lux/data/text.lux index a9cec1526..ad5d49ae2 100644 --- a/stdlib/source/lux/data/text.lux +++ b/stdlib/source/lux/data/text.lux @@ -189,7 +189,7 @@ (def: (hash input) (`` (for {(~~ (static @.old)) (|> input - (: (primitive "java.lang.String" [])) + (: (primitive "java.lang.String")) "jvm invokevirtual:java.lang.String:hashCode:" "jvm convert int-to-long" (:coerce Nat)) diff --git a/stdlib/source/lux/host.jvm.lux b/stdlib/source/lux/host.jvm.lux index d93edbfe4..495d8a7ce 100644 --- a/stdlib/source/lux/host.jvm.lux +++ b/stdlib/source/lux/host.jvm.lux @@ -1811,27 +1811,27 @@ {type (..type^ imports (list))} size) {#.doc (doc "Create an array of the given type, with the given size." - (array Object 10))} - (case type - (^template [ ] - (^ (#jvm.Primitive )) - (wrap (list (` ( (~ size)))))) - ([#jvm.Boolean "jvm znewarray"] - [#jvm.Byte "jvm bnewarray"] - [#jvm.Short "jvm snewarray"] - [#jvm.Int "jvm inewarray"] - [#jvm.Long "jvm lnewarray"] - [#jvm.Float "jvm fnewarray"] - [#jvm.Double "jvm dnewarray"] - [#jvm.Char "jvm cnewarray"]) - - _ - (wrap (list (` ("jvm anewarray" (~ (type$ type)) (~ size))))))) + (array java/lang/Object 10))} + (let [g!size (` (|> (~ size) + (.: .Nat) + (.:coerce (.primitive "java.lang.Long")) + "jvm object cast" + "jvm conversion long-to-int"))] + (case type + (^template [ ] + (^ (#jvm.Primitive )) + (wrap (list (` ( (~ g!size)))))) + ([#jvm.Boolean "jvm array new boolean"] + [#jvm.Byte "jvm array new byte"] + [#jvm.Short "jvm array new short"] + [#jvm.Int "jvm array new int"] + [#jvm.Long "jvm array new long"] + [#jvm.Float "jvm array new float"] + [#jvm.Double "jvm array new double"] + [#jvm.Char "jvm array new char"]) -(syntax: #export (array-length array) - {#.doc (doc "Gives the length of an array." - (array-length my-array))} - (wrap (list (` ("jvm arraylength" (~ array)))))) + _ + (wrap (list (` ("jvm array new object" (~ (type$ type)) (~ g!size)))))))) (def: (type->class-name type) (-> .Type (Meta Text)) @@ -1855,6 +1855,35 @@ _ (macro.fail (format "Cannot convert to JVM type: " (type.to-text type)))))) +(syntax: #export (array-length array) + {#.doc (doc "Gives the length of an array." + (array-length my-array))} + (case array + [_ (#.Identifier array-name)] + (do macro.monad + [array-type (macro.find-type array-name) + array-jvm-type (type->class-name array-type) + #let [g!extension (code.text (case array-jvm-type + "[Z" "jvm array length boolean" + "[B" "jvm array length byte" + "[S" "jvm array length short" + "[I" "jvm array length int" + "[J" "jvm array length long" + "[F" "jvm array length float" + "[D" "jvm array length double" + "[C" "jvm array length char" + _ "jvm array length object"))]] + (wrap (list (` (.|> ((~ g!extension) (~ array)) + "jvm conversion int-to-long" + "jvm object cast" + (.: (.primitive "java.lang.Long")) + (.:coerce .Nat)))))) + + _ + (with-gensyms [g!array] + (wrap (list (` (let [(~ g!array) (~ array)] + (..array-length (~ g!array))))))))) + (syntax: #export (array-read idx array) {#.doc (doc "Loads an element from an array." (array-read 10 my-array))} @@ -1862,22 +1891,29 @@ [_ (#.Identifier array-name)] (do macro.monad [array-type (macro.find-type array-name) - array-jvm-type (type->class-name array-type)] + array-jvm-type (type->class-name array-type) + #let [g!idx (` (.|> (~ idx) + (.: .Nat) + (.:coerce (.primitive "java.lang.Long")) + "jvm object cast" + "jvm conversion long-to-int"))]] (case array-jvm-type - (^template [ ] + (^template [ ] - (wrap (list (` ( (~ array) (~ idx)))))) - (["[Z" "jvm zaload"] - ["[B" "jvm baload"] - ["[S" "jvm saload"] - ["[I" "jvm iaload"] - ["[J" "jvm jaload"] - ["[F" "jvm faload"] - ["[D" "jvm daload"] - ["[C" "jvm caload"]) + (wrap (list (` (.|> ( (~ g!idx) (~ array)) + "jvm object cast" + (.: (.primitive ))))))) + (["[Z" "jvm array read boolean" "java.lang.Boolean"] + ["[B" "jvm array read byte" "java.lang.Byte"] + ["[S" "jvm array read short" "java.lang.Short"] + ["[I" "jvm array read int" "java.lang.Integer"] + ["[J" "jvm array read long" "java.lang.Long"] + ["[F" "jvm array read float" "java.lang.Float"] + ["[D" "jvm array read double" "java.lang.Double"] + ["[C" "jvm array read char" "java.lang.Character"]) _ - (wrap (list (` ("jvm aaload" (~ array) (~ idx))))))) + (wrap (list (` ("jvm array read object" (~ g!idx) (~ array))))))) _ (with-gensyms [g!array] @@ -1891,22 +1927,30 @@ [_ (#.Identifier array-name)] (do macro.monad [array-type (macro.find-type array-name) - array-jvm-type (type->class-name array-type)] + array-jvm-type (type->class-name array-type) + #let [g!idx (` (.|> (~ idx) + (.: .Nat) + (.:coerce (.primitive "java.lang.Long")) + "jvm object cast" + "jvm conversion long-to-int"))]] (case array-jvm-type - (^template [ ] + (^template [ ] - (wrap (list (` ( (~ array) (~ idx) (~ value)))))) - (["[Z" "jvm zastore"] - ["[B" "jvm bastore"] - ["[S" "jvm sastore"] - ["[I" "jvm iastore"] - ["[J" "jvm jastore"] - ["[F" "jvm fastore"] - ["[D" "jvm dastore"] - ["[C" "jvm castore"]) + (let [g!value (` (.|> (~ value) + (.:coerce (.primitive )) + "jvm object cast"))] + (wrap (list (` ( (~ g!idx) (~ g!value) (~ array))))))) + (["[Z" "jvm array write boolean" "java.lang.Boolean"] + ["[B" "jvm array write byte" "java.lang.Byte"] + ["[S" "jvm array write short" "java.lang.Short"] + ["[I" "jvm array write int" "java.lang.Integer"] + ["[J" "jvm array write long" "java.lang.Long"] + ["[F" "jvm array write float" "java.lang.Float"] + ["[D" "jvm array write double" "java.lang.Double"] + ["[C" "jvm array write char" "java.lang.Character"]) _ - (wrap (list (` ("jvm aastore" (~ array) (~ idx) (~ value))))))) + (wrap (list (` ("jvm array write object" (~ g!idx) (~ value) (~ array))))))) _ (with-gensyms [g!array] diff --git a/stdlib/source/lux/target/jvm/type.lux b/stdlib/source/lux/target/jvm/type.lux index 98880e5a8..d8851d978 100644 --- a/stdlib/source/lux/target/jvm/type.lux +++ b/stdlib/source/lux/target/jvm/type.lux @@ -28,6 +28,7 @@ (template [ ] [(def: #export )] + [void-reflection "void"] [boolean-reflection "boolean"] [byte-reflection "byte"] [short-reflection "short"] @@ -38,14 +39,14 @@ [char-reflection "char"] ) -(def: array-prefix "[") +(def: #export array-prefix "[") (def: object-prefix "L") (def: var-prefix "T") (def: wildcard-descriptor "*") (def: lower-prefix "-") (def: upper-prefix "+") (def: object-suffix ";") -(def: object-class "java.lang.Object") +(def: #export object-class "java.lang.Object") (def: valid-var-characters/head (format "abcdefghijklmnopqrstuvwxyz" @@ -278,24 +279,24 @@ )))) (def: #export parse-signature - (-> Text (Error Type)) - (.run (<>.rec - (function (_ recur) - ($_ <>.or - ($_ <>.or - (.this ..boolean-descriptor) - (.this ..byte-descriptor) - (.this ..short-descriptor) - (.this ..int-descriptor) - (.this ..long-descriptor) - (.this ..float-descriptor) - (.this ..double-descriptor) - (.this ..char-descriptor) - ) - ..parse-generic - (<>.after (.this ..array-prefix) - recur) - ))))) + (Parser Type) + (<>.rec + (function (_ recur) + ($_ <>.or + ($_ <>.or + (.this ..boolean-descriptor) + (.this ..byte-descriptor) + (.this ..short-descriptor) + (.this ..int-descriptor) + (.this ..long-descriptor) + (.this ..float-descriptor) + (.this ..double-descriptor) + (.this ..char-descriptor) + ) + ..parse-generic + (<>.after (.this ..array-prefix) + recur) + )))) (def: #export (method args return exceptions) (-> (List Type) (Maybe Type) (List Generic) Method) diff --git a/stdlib/source/lux/tool/compiler/phase.lux b/stdlib/source/lux/tool/compiler/phase.lux index a6b080a19..6137e9fd6 100644 --- a/stdlib/source/lux/tool/compiler/phase.lux +++ b/stdlib/source/lux/tool/compiler/phase.lux @@ -1,7 +1,7 @@ (.module: [lux #* [abstract - [monad (#+ do)]] + [monad (#+ Monad do)]] [control ["." state] ["ex" exception (#+ Exception exception:)] @@ -10,7 +10,7 @@ ["s" code]]] [data ["." product] - ["." error (#+ Error) ("#;." functor)] + ["." error (#+ Error) ("#@." functor)] ["." text format]] [time @@ -23,6 +23,7 @@ (state.State' Error s o)) (def: #export monad + (All [s] (Monad (Operation s))) (state.with error.monad)) (type: #export (Phase s i o) @@ -73,7 +74,7 @@ (def: #export (lift error) (All [s a] (-> (Error a) (Operation s a))) (function (_ state) - (error;map (|>> [state]) error))) + (error@map (|>> [state]) error))) (syntax: #export (assert exception message test) (wrap (list (` (if (~ test) diff --git a/stdlib/source/lux/tool/compiler/phase/extension/analysis/jvm.lux b/stdlib/source/lux/tool/compiler/phase/extension/analysis/jvm.lux index 61d65e67f..947bbc69f 100644 --- a/stdlib/source/lux/tool/compiler/phase/extension/analysis/jvm.lux +++ b/stdlib/source/lux/tool/compiler/phase/extension/analysis/jvm.lux @@ -6,7 +6,8 @@ ["." monad (#+ do)]] [control ["p" parser - ["s" code (#+ Parser)]] + ["s" code (#+ Parser)] + ["" text]] ["." exception (#+ exception:)] pipe] [data @@ -53,6 +54,117 @@ ["_jvm_upper" upper-relationship-name upper-relationship-type] ) +## TODO: Get rid of this template block and use the definition in +## lux/host.jvm.lux ASAP +(template [ ] + [(def: #export .Type (#.Primitive #.Nil))] + + ## Boxes + [Boolean "java.lang.Boolean"] + [Byte "java.lang.Byte"] + [Short "java.lang.Short"] + [Integer "java.lang.Integer"] + [Long "java.lang.Long"] + [Float "java.lang.Float"] + [Double "java.lang.Double"] + [Character "java.lang.Character"] + [String "java.lang.String"] + + ## Primitives + [boolean jvm.boolean-reflection] + [byte jvm.byte-reflection] + [short jvm.short-reflection] + [int jvm.int-reflection] + [long jvm.long-reflection] + [float jvm.float-reflection] + [double jvm.double-reflection] + [char jvm.char-reflection] + ) + +(type: Mapping + (Dictionary Var .Type)) + +(def: fresh-mapping Mapping (dictionary.new text.hash)) + +(exception: #export (unknown-jvm-type-var {var Var}) + (exception.report + ["Var" (%t var)])) + +(def: (generic-type mapping generic) + (-> Mapping Generic (Check .Type)) + (case generic + (#jvm.Var var) + (case (dictionary.get var mapping) + #.None + (check.throw ..unknown-jvm-type-var var) + + (#.Some type) + (check@wrap type)) + + (#jvm.Wildcard wildcard) + (case wildcard + #.None + (do check.monad + [[id type] check.existential] + (wrap type)) + + (#.Some [bound limit]) + (do check.monad + [limitT (generic-type mapping limit)] + (case bound + #jvm.Lower + (wrap (lower-relationship-type limitT)) + + #jvm.Upper + (wrap (upper-relationship-type limitT))))) + + (#jvm.Class name parameters) + (do check.monad + [parametersT+ (monad.map @ (generic-type mapping) parameters)] + (wrap (#.Primitive name parametersT+))))) + +(def: (class-type mapping [name parameters]) + (-> Mapping Class (Check .Type)) + (do check.monad + [parametersT+ (monad.map @ (generic-type mapping) parameters)] + (wrap (#.Primitive name parametersT+)))) + +(def: (jvm-type mapping type) + (-> Mapping Type (Check .Type)) + (case type + (#jvm.Primitive primitive) + (check@wrap (case primitive + #jvm.Boolean ..boolean + #jvm.Byte ..byte + #jvm.Short ..short + #jvm.Int ..int + #jvm.Long ..long + #jvm.Float ..float + #jvm.Double ..double + #jvm.Char ..char)) + + (#jvm.Generic generic) + (generic-type mapping generic) + + (#jvm.Array type) + (case type + (#jvm.Primitive primitive) + (check@wrap (#.Primitive (jvm.descriptor (jvm.array 1 type)) (list))) + + _ + (do check.monad + [elementT (jvm-type mapping type)] + (wrap (.type (Array elementT))))))) + +(def: (return-type mapping type) + (-> Mapping Return (Check .Type)) + (case type + #.None + (check@wrap Any) + + (#.Some type) + (jvm-type mapping type))) + (def: (custom [syntax handler]) (All [s] (-> [(Parser s) @@ -161,33 +273,6 @@ [cannot-correspond-type-with-a-class] ) -## TODO: Get rid of this template block and use the definition in -## lux/host.jvm.lux ASAP -(template [ ] - [(def: #export .Type (#.Primitive #.Nil))] - - ## Boxes - [Boolean "java.lang.Boolean"] - [Byte "java.lang.Byte"] - [Short "java.lang.Short"] - [Integer "java.lang.Integer"] - [Long "java.lang.Long"] - [Float "java.lang.Float"] - [Double "java.lang.Double"] - [Character "java.lang.Character"] - [String "java.lang.String"] - - ## Primitives - [boolean "boolean"] - [byte "byte"] - [short "short"] - [int "int"] - [long "long"] - [float "float"] - [double "double"] - [char "char"] - ) - (def: bundle::conversion Bundle (<| (///bundle.prefix "conversion") @@ -237,8 +322,8 @@ (///bundle.install "ushr" (//common.binary Integer )) )))] - [bundle::int "int" ..long] - [bundle::long "long" ..long] + [bundle::int jvm.int-reflection ..long] + [bundle::long jvm.long-reflection ..long] ) (template [ ] @@ -255,13 +340,13 @@ (///bundle.install "<" (//common.binary Bit)) )))] - [bundle::float "float" ..float] - [bundle::double "double" ..double] + [bundle::float jvm.float-reflection ..float] + [bundle::double jvm.double-reflection ..double] ) (def: bundle::char Bundle - (<| (///bundle.prefix "char") + (<| (///bundle.prefix jvm.char-reflection) (|> ///bundle.empty (///bundle.install "=" (//common.binary ..char ..char Bit)) (///bundle.install "<" (//common.binary ..char ..char Bit)) @@ -269,14 +354,14 @@ (def: #export boxes (Dictionary Text Text) - (|> (list ["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"]) + (|> (list [jvm.boolean-reflection "java.lang.Boolean"] + [jvm.byte-reflection "java.lang.Byte"] + [jvm.short-reflection "java.lang.Short"] + [jvm.int-reflection "java.lang.Integer"] + [jvm.long-reflection "java.lang.Long"] + [jvm.float-reflection "java.lang.Float"] + [jvm.double-reflection "java.lang.Double"] + [jvm.char-reflection "java.lang.Character"]) (dictionary.from-list text.hash))) (def: (array-type-info allow-primitives? arrayT) @@ -303,13 +388,27 @@ (#.Primitive class _) (if (dictionary.contains? class boxes) - (/////analysis.throw primitives-cannot-have-type-parameters class) + (/////analysis.throw ..primitives-cannot-have-type-parameters class) (////@wrap [level class])) _ (/////analysis.throw non-array arrayT)))) -(def: array::length +(def: (primitive-array-length-handler primitive-type) + (-> Type Handler) + (function (_ extension-name analyse args) + (case args + (^ (list arrayC)) + (do ////.monad + [_ (typeA.infer ..int) + arrayA (typeA.with-type (#.Primitive (jvm.descriptor (jvm.array 1 primitive-type)) (list)) + (analyse arrayC))] + (wrap (#/////analysis.Extension extension-name (list arrayA)))) + + _ + (/////analysis.throw ///.incorrect-arity [extension-name 1 (list.size args)])))) + +(def: array::length::object Handler (function (_ extension-name analyse args) (case args @@ -363,14 +462,47 @@ (/////analysis.throw ///.incorrect-arity [extension-name 1 (list.size args)])))) (def: (check-jvm objectT) - (-> .Type (Operation Text)) + (-> .Type (Operation Type)) (case objectT - (#.Primitive name _) - (////@wrap name) + (#.Primitive name #.Nil) + (case name + (^ (static jvm.boolean-reflection)) (////@wrap jvm.boolean) + (^ (static jvm.byte-reflection)) (////@wrap jvm.byte) + (^ (static jvm.short-reflection)) (////@wrap jvm.short) + (^ (static jvm.int-reflection)) (////@wrap jvm.int) + (^ (static jvm.long-reflection)) (////@wrap jvm.long) + (^ (static jvm.float-reflection)) (////@wrap jvm.float) + (^ (static jvm.double-reflection)) (////@wrap jvm.double) + (^ (static jvm.char-reflection)) (////@wrap jvm.char) + _ (if (text.starts-with? jvm.array-prefix name) + (////.lift (.run jvm.parse-signature name)) + (////@wrap (jvm.class name (list))))) + + (^ (#.Primitive (static array.type-name) + (list elementT))) + (|> elementT + check-jvm + (////@map (jvm.array 1))) + + (#.Primitive name parameters) + (do ////.monad + [parameters (monad.map @ check-jvm parameters) + parameters (monad.map @ (function (_ parameter) + (case parameter + (#jvm.Generic generic) + (wrap generic) + + _ + (/////analysis.throw ..primitives-cannot-have-type-parameters name))) + parameters)] + (////@wrap (jvm.class name parameters))) + + (#.Named name anonymous) + (check-jvm anonymous) (^template [] ( id) - (////@wrap "java.lang.Object")) + (////@wrap (jvm.class "java.lang.Object" (list)))) ([#.Var] [#.Ex]) @@ -394,16 +526,16 @@ (def: (check-object objectT) (-> .Type (Operation Text)) (do ////.monad - [name (check-jvm objectT)] - (if (dictionary.contains? name boxes) + [name (:: @ map jvm.reflection-class (check-jvm objectT))] + (if (dictionary.contains? name ..boxes) (/////analysis.throw ..primitives-are-not-objects [name]) (////@wrap name)))) (def: (check-return type) (-> .Type (Operation Text)) (if (is? .Any type) - (////@wrap "void") - (check-jvm type))) + (////@wrap jvm.void-descriptor) + (////@map jvm.signature (check-jvm type)))) (def: (read-primitive-array-handler lux-type jvm-type) (-> .Type Type Handler) @@ -495,39 +627,49 @@ Bundle (<| (///bundle.prefix "array") (|> ///bundle.empty - (///bundle.install "length" array::length) + (dictionary.merge (<| (///bundle.prefix "length") + (|> ///bundle.empty + (///bundle.install jvm.boolean-reflection (primitive-array-length-handler jvm.boolean)) + (///bundle.install jvm.byte-reflection (primitive-array-length-handler jvm.byte)) + (///bundle.install jvm.short-reflection (primitive-array-length-handler jvm.short)) + (///bundle.install jvm.int-reflection (primitive-array-length-handler jvm.int)) + (///bundle.install jvm.long-reflection (primitive-array-length-handler jvm.long)) + (///bundle.install jvm.float-reflection (primitive-array-length-handler jvm.float)) + (///bundle.install jvm.double-reflection (primitive-array-length-handler jvm.double)) + (///bundle.install jvm.char-reflection (primitive-array-length-handler jvm.char)) + (///bundle.install "object" array::length::object)))) (dictionary.merge (<| (///bundle.prefix "new") (|> ///bundle.empty - (///bundle.install "boolean" (new-primitive-array-handler jvm.boolean)) - (///bundle.install "byte" (new-primitive-array-handler jvm.byte)) - (///bundle.install "short" (new-primitive-array-handler jvm.short)) - (///bundle.install "int" (new-primitive-array-handler jvm.int)) - (///bundle.install "long" (new-primitive-array-handler jvm.long)) - (///bundle.install "float" (new-primitive-array-handler jvm.float)) - (///bundle.install "double" (new-primitive-array-handler jvm.double)) - (///bundle.install "char" (new-primitive-array-handler jvm.char)) + (///bundle.install jvm.boolean-reflection (new-primitive-array-handler jvm.boolean)) + (///bundle.install jvm.byte-reflection (new-primitive-array-handler jvm.byte)) + (///bundle.install jvm.short-reflection (new-primitive-array-handler jvm.short)) + (///bundle.install jvm.int-reflection (new-primitive-array-handler jvm.int)) + (///bundle.install jvm.long-reflection (new-primitive-array-handler jvm.long)) + (///bundle.install jvm.float-reflection (new-primitive-array-handler jvm.float)) + (///bundle.install jvm.double-reflection (new-primitive-array-handler jvm.double)) + (///bundle.install jvm.char-reflection (new-primitive-array-handler jvm.char)) (///bundle.install "object" array::new::object)))) (dictionary.merge (<| (///bundle.prefix "read") (|> ///bundle.empty - (///bundle.install "boolean" (read-primitive-array-handler ..boolean jvm.boolean)) - (///bundle.install "byte" (read-primitive-array-handler ..byte jvm.byte)) - (///bundle.install "short" (read-primitive-array-handler ..short jvm.short)) - (///bundle.install "int" (read-primitive-array-handler ..int jvm.int)) - (///bundle.install "long" (read-primitive-array-handler ..long jvm.long)) - (///bundle.install "float" (read-primitive-array-handler ..float jvm.float)) - (///bundle.install "double" (read-primitive-array-handler ..double jvm.double)) - (///bundle.install "char" (read-primitive-array-handler ..char jvm.char)) + (///bundle.install jvm.boolean-reflection (read-primitive-array-handler ..boolean jvm.boolean)) + (///bundle.install jvm.byte-reflection (read-primitive-array-handler ..byte jvm.byte)) + (///bundle.install jvm.short-reflection (read-primitive-array-handler ..short jvm.short)) + (///bundle.install jvm.int-reflection (read-primitive-array-handler ..int jvm.int)) + (///bundle.install jvm.long-reflection (read-primitive-array-handler ..long jvm.long)) + (///bundle.install jvm.float-reflection (read-primitive-array-handler ..float jvm.float)) + (///bundle.install jvm.double-reflection (read-primitive-array-handler ..double jvm.double)) + (///bundle.install jvm.char-reflection (read-primitive-array-handler ..char jvm.char)) (///bundle.install "object" array::read::object)))) (dictionary.merge (<| (///bundle.prefix "write") (|> ///bundle.empty - (///bundle.install "boolean" (write-primitive-array-handler ..boolean jvm.boolean)) - (///bundle.install "byte" (write-primitive-array-handler ..byte jvm.byte)) - (///bundle.install "short" (write-primitive-array-handler ..short jvm.short)) - (///bundle.install "int" (write-primitive-array-handler ..int jvm.int)) - (///bundle.install "long" (write-primitive-array-handler ..long jvm.long)) - (///bundle.install "float" (write-primitive-array-handler ..float jvm.float)) - (///bundle.install "double" (write-primitive-array-handler ..double jvm.double)) - (///bundle.install "char" (write-primitive-array-handler ..char jvm.char)) + (///bundle.install jvm.boolean-reflection (write-primitive-array-handler ..boolean jvm.boolean)) + (///bundle.install jvm.byte-reflection (write-primitive-array-handler ..byte jvm.byte)) + (///bundle.install jvm.short-reflection (write-primitive-array-handler ..short jvm.short)) + (///bundle.install jvm.int-reflection (write-primitive-array-handler ..int jvm.int)) + (///bundle.install jvm.long-reflection (write-primitive-array-handler ..long jvm.long)) + (///bundle.install jvm.float-reflection (write-primitive-array-handler ..float jvm.float)) + (///bundle.install jvm.double-reflection (write-primitive-array-handler ..double jvm.double)) + (///bundle.install jvm.char-reflection (write-primitive-array-handler ..char jvm.char)) (///bundle.install "object" array::write::object)))) ))) @@ -727,11 +869,6 @@ ## else (/////analysis.throw cannot-convert-to-a-class jvm-type))) -(type: Mapping - (Dictionary Var .Type)) - -(def: fresh-mapping Mapping (dictionary.new text.hash)) - (def: (java-type-to-lux-type mapping java-type) (-> Mapping java/lang/reflect/Type (Operation .Type)) (<| (case (host.check TypeVariable java-type) @@ -760,17 +897,25 @@ (#.Some java-type) (let [java-type (:coerce (java/lang/Class java/lang/Object) java-type) class-name (java/lang/Class::getName java-type)] - (////@wrap (case (array.size (java/lang/Class::getTypeParameters java-type)) - 0 - (case class-name - "void" - Any - - _ - (#.Primitive class-name (list))) - - arity - (|> (list.indices arity) + (case (array.size (java/lang/Class::getTypeParameters java-type)) + 0 + (case class-name + (^ (static jvm.void-reflection)) + (////@wrap Any) + + _ + (if (text.starts-with? jvm.array-prefix class-name) + (case (.run jvm.parse-signature (jvm.binary-name class-name)) + (#error.Success jtype) + (typeA.with-env + (jvm-type fresh-mapping jtype)) + + (#error.Failure error) + (/////analysis.fail error)) + (////@wrap (#.Primitive class-name (list))))) + + arity + (////@wrap (|> (list.indices arity) list.reverse (list@map (|>> (n/* 2) inc #.Parameter)) (#.Primitive class-name) @@ -832,8 +977,11 @@ (dictionary.from-list text.hash))) )) + (#.Named name anonymousT) + (correspond-type-params class anonymousT) + _ - (/////analysis.throw non-jvm-type type))) + (/////analysis.throw ..non-jvm-type type))) (def: (class-candiate-parents from-name fromT to-name to-class) (-> Text .Type Text (java/lang/Class java/lang/Object) (Operation (List [[Text .Type] Bit]))) @@ -861,7 +1009,7 @@ (monad.map ////.monad (function (_ superT) (do ////.monad - [super-name (check-jvm superT) + [super-name (:: @ map jvm.reflection-class (check-jvm superT)) super-class (load-class super-name)] (wrap [[super-name superT] (java/lang/Class::isAssignableFrom super-class to-class)]))) @@ -877,24 +1025,24 @@ (^ (list fromC)) (do ////.monad [toT (///.lift macro.expected-type) - to-name (check-jvm toT) + to-name (:: @ map jvm.reflection-class (check-jvm toT)) [fromT fromA] (typeA.with-inference (analyse fromC)) - from-name (check-jvm fromT) + from-name (:: @ map jvm.reflection-class (check-jvm fromT)) can-cast? (: (Operation Bit) (case [from-name to-name] (^template [ ] - (^or [ ] - [ ]) + (^or (^ [(static ) ]) + (^ [ (static )])) (wrap #1)) - (["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"]) + ([jvm.boolean-reflection "java.lang.Boolean"] + [jvm.byte-reflection "java.lang.Byte"] + [jvm.short-reflection "java.lang.Short"] + [jvm.int-reflection "java.lang.Integer"] + [jvm.long-reflection "java.lang.Long"] + [jvm.float-reflection "java.lang.Float"] + [jvm.double-reflection "java.lang.Double"] + [jvm.char-reflection "java.lang.Character"]) _ (do @ @@ -1131,7 +1279,7 @@ (def: reflection-arguments (-> (List Text) (Operation (List Text))) - (|>> (monad.map error.monad jvm.parse-signature) + (|>> (monad.map error.monad (.run jvm.parse-signature)) (:: error.monad map (list@map jvm.reflection-class)) ////.lift)) @@ -1403,12 +1551,19 @@ _ (////.assert non-interface class-name (Modifier::isInterface (java/lang/Class::getModifiers class))) [methodT exceptionsT] (method-candidate class-name method #Interface argsT) - [outputT argsA] (inferenceA.general analyse methodT (list& objectC (list@map product.right argsTC))) + [outputT allA] (inferenceA.general analyse methodT (list& objectC (list@map product.right argsTC))) + #let [[objectA argsA] (case allA + (#.Cons objectA argsA) + [objectA argsA] + + _ + (undefined))] outputJC (check-return outputT)] (wrap (#/////analysis.Extension extension-name (list& (/////analysis.text class-name) (/////analysis.text method) (/////analysis.text outputJC) + objectA (decorate-inputs argsT argsA))))))])) (def: invoke::constructor @@ -1470,96 +1625,17 @@ (Parser Class) (s.form (p.and s.text (p.some ..generic)))) -(exception: #export (unknown-jvm-type-var {var Var}) - (exception.report - ["Var" (%t var)])) - -(def: (generic-type mapping generic) - (-> Mapping Generic (Check .Type)) - (case generic - (#jvm.Var var) - (case (dictionary.get var mapping) - #.None - (check.throw unknown-jvm-type-var var) - - (#.Some type) - (check@wrap type)) - - (#jvm.Wildcard wildcard) - (case wildcard - #.None - (do check.monad - [[id type] check.existential] - (wrap type)) - - (#.Some [bound limit]) - (do check.monad - [limitT (generic-type mapping limit)] - (case bound - #jvm.Lower - (wrap (lower-relationship-type limitT)) - - #jvm.Upper - (wrap (upper-relationship-type limitT))))) - - (#jvm.Class name parameters) - (do check.monad - [parametersT+ (monad.map @ (generic-type mapping) parameters)] - (wrap (#.Primitive name parametersT+))))) - -(def: (class-type mapping [name parameters]) - (-> Mapping Class (Check .Type)) - (do check.monad - [parametersT+ (monad.map @ (generic-type mapping) parameters)] - (wrap (#.Primitive name parametersT+)))) - -(def: (jvm-type mapping type) - (-> Mapping Type (Check .Type)) - (case type - (#jvm.Primitive primitive) - (check@wrap (case primitive - #jvm.Boolean ..boolean - #jvm.Byte ..byte - #jvm.Short ..short - #jvm.Int ..int - #jvm.Long ..long - #jvm.Float ..float - #jvm.Double ..double - #jvm.Char ..char)) - - (#jvm.Generic generic) - (generic-type mapping generic) - - (#jvm.Array type) - (case type - (#jvm.Primitive primitive) - (check@wrap (#.Primitive (jvm.descriptor (jvm.array 1 type)) (list))) - - _ - (do check.monad - [elementT (jvm-type mapping type)] - (wrap (.type (Array elementT))))))) - -(def: (return-type mapping type) - (-> Mapping Return (Check .Type)) - (case type - #.None - (check@wrap Any) - - (#.Some type) - (jvm-type mapping type))) - (def: primitive (Parser Primitive) ($_ p.or - (s.identifier! ["" "boolean"]) - (s.identifier! ["" "byte"]) - (s.identifier! ["" "short"]) - (s.identifier! ["" "int"]) - (s.identifier! ["" "long"]) - (s.identifier! ["" "float"]) - (s.identifier! ["" "double"]) - (s.identifier! ["" "char"]) + (s.identifier! ["" jvm.boolean-reflection]) + (s.identifier! ["" jvm.byte-reflection]) + (s.identifier! ["" jvm.short-reflection]) + (s.identifier! ["" jvm.int-reflection]) + (s.identifier! ["" jvm.long-reflection]) + (s.identifier! ["" jvm.float-reflection]) + (s.identifier! ["" jvm.double-reflection]) + (s.identifier! ["" jvm.char-reflection]) )) (def: type @@ -1595,7 +1671,7 @@ (def: return (Parser Return) - (p.or (s.identifier! ["" "void"]) + (p.or (s.identifier! ["" jvm.void-reflection]) ..type)) (type: #export (Overriden-Method a) @@ -1677,14 +1753,14 @@ (case type (#jvm.Primitive primitive) (case primitive - #jvm.Boolean (/////analysis.constant ["" "boolean"]) - #jvm.Byte (/////analysis.constant ["" "byte"]) - #jvm.Short (/////analysis.constant ["" "short"]) - #jvm.Int (/////analysis.constant ["" "int"]) - #jvm.Long (/////analysis.constant ["" "long"]) - #jvm.Float (/////analysis.constant ["" "float"]) - #jvm.Double (/////analysis.constant ["" "double"]) - #jvm.Char (/////analysis.constant ["" "char"])) + #jvm.Boolean (/////analysis.constant ["" jvm.boolean-reflection]) + #jvm.Byte (/////analysis.constant ["" jvm.byte-reflection]) + #jvm.Short (/////analysis.constant ["" jvm.short-reflection]) + #jvm.Int (/////analysis.constant ["" jvm.int-reflection]) + #jvm.Long (/////analysis.constant ["" jvm.long-reflection]) + #jvm.Float (/////analysis.constant ["" jvm.float-reflection]) + #jvm.Double (/////analysis.constant ["" jvm.double-reflection]) + #jvm.Char (/////analysis.constant ["" jvm.char-reflection])) (#jvm.Generic generic) (generic-analysis generic) @@ -1696,7 +1772,7 @@ (-> Return Analysis) (case return #.None - (/////analysis.constant ["" "void"]) + (/////analysis.constant ["" jvm.void-descriptor]) (#.Some type) (type-analysis type))) -- cgit v1.2.3