(.module: [lux (#- Type primitive int char) [abstract ["." monad (#+ do)]] [control ["." exception (#+ exception:)] ["." function] ["<>" parser ("#@." monad) ["" text] ["" synthesis (#+ Parser)]]] [data ["." product] ["." maybe] ["." error] [number ["." nat]] ["." text format] [collection ["." list ("#@." monad)] ["." dictionary (#+ Dictionary)] ["." set]]] [target ["." jvm #_ ["#" type (#+ Primitive Bound Generic Class Type Method Var Typed Argument Return) ["." box] ["." reflection]]]] [tool [compiler [analysis (#+ Environment)] ["." reference (#+ Variable)] ["." synthesis (#+ Synthesis Path %synthesis)] ["." phase ("#@." monad) ["." generation [extension (#+ Nullary Unary Binary nullary unary binary)]] [analysis [".A" reference]] ["." extension ["." bundle] [analysis ["/" jvm]]]]]] [host (#+ import:)]] [luxc [lang [host ["$" jvm (#+ Label Inst Def Handler Bundle Operation Phase) ["_" inst] ["_." def]]]]] ["." // #_ [common (#+ custom)] ["/#" // #_ ["#." reference] ["#." function]]]) (exception: #export invalid-syntax-for-argument-generation) (template [ ] [(def: Inst )] [L2S (|>> _.L2I _.I2S)] [L2B (|>> _.L2I _.I2B)] [L2C (|>> _.L2I _.I2C)] ) (template [ ] [(def: ( inputI) (Unary Inst) (if (is? _.NOP ) inputI (|>> inputI )))] [conversion::double-to-float #jvm.Double _.D2F #jvm.Float] [conversion::double-to-int #jvm.Double _.D2I #jvm.Int] [conversion::double-to-long #jvm.Double _.D2L #jvm.Long] [conversion::float-to-double #jvm.Float _.F2D #jvm.Double] [conversion::float-to-int #jvm.Float _.F2I #jvm.Int] [conversion::float-to-long #jvm.Float _.F2L #jvm.Long] [conversion::int-to-byte #jvm.Int _.I2B #jvm.Byte] [conversion::int-to-char #jvm.Int _.I2C #jvm.Char] [conversion::int-to-double #jvm.Int _.I2D #jvm.Double] [conversion::int-to-float #jvm.Int _.I2F #jvm.Float] [conversion::int-to-long #jvm.Int _.I2L #jvm.Long] [conversion::int-to-short #jvm.Int _.I2S #jvm.Short] [conversion::long-to-double #jvm.Long _.L2D #jvm.Double] [conversion::long-to-float #jvm.Long _.L2F #jvm.Float] [conversion::long-to-int #jvm.Long _.L2I #jvm.Int] [conversion::long-to-short #jvm.Long L2S #jvm.Short] [conversion::long-to-byte #jvm.Long L2B #jvm.Byte] [conversion::long-to-char #jvm.Long L2C #jvm.Char] [conversion::char-to-byte #jvm.Char _.I2B #jvm.Byte] [conversion::char-to-short #jvm.Char _.I2S #jvm.Short] [conversion::char-to-int #jvm.Char _.NOP #jvm.Int] [conversion::char-to-long #jvm.Char _.I2L #jvm.Long] [conversion::byte-to-long #jvm.Byte _.I2L #jvm.Long] [conversion::short-to-long #jvm.Short _.I2L #jvm.Long] ) (def: conversion Bundle (<| (bundle.prefix "conversion") (|> (: Bundle bundle.empty) (bundle.install "double-to-float" (unary conversion::double-to-float)) (bundle.install "double-to-int" (unary conversion::double-to-int)) (bundle.install "double-to-long" (unary conversion::double-to-long)) (bundle.install "float-to-double" (unary conversion::float-to-double)) (bundle.install "float-to-int" (unary conversion::float-to-int)) (bundle.install "float-to-long" (unary conversion::float-to-long)) (bundle.install "int-to-byte" (unary conversion::int-to-byte)) (bundle.install "int-to-char" (unary conversion::int-to-char)) (bundle.install "int-to-double" (unary conversion::int-to-double)) (bundle.install "int-to-float" (unary conversion::int-to-float)) (bundle.install "int-to-long" (unary conversion::int-to-long)) (bundle.install "int-to-short" (unary conversion::int-to-short)) (bundle.install "long-to-double" (unary conversion::long-to-double)) (bundle.install "long-to-float" (unary conversion::long-to-float)) (bundle.install "long-to-int" (unary conversion::long-to-int)) (bundle.install "long-to-short" (unary conversion::long-to-short)) (bundle.install "long-to-byte" (unary conversion::long-to-byte)) (bundle.install "long-to-char" (unary conversion::long-to-char)) (bundle.install "char-to-byte" (unary conversion::char-to-byte)) (bundle.install "char-to-short" (unary conversion::char-to-short)) (bundle.install "char-to-int" (unary conversion::char-to-int)) (bundle.install "char-to-long" (unary conversion::char-to-long)) (bundle.install "byte-to-long" (unary conversion::byte-to-long)) (bundle.install "short-to-long" (unary conversion::short-to-long)) ))) (template [ ] [(def: ( [xI yI]) (Binary Inst) (|>> xI yI ))] [int::+ _.IADD] [int::- _.ISUB] [int::* _.IMUL] [int::/ _.IDIV] [int::% _.IREM] [int::and _.IAND] [int::or _.IOR] [int::xor _.IXOR] [int::shl _.ISHL] [int::shr _.ISHR] [int::ushr _.IUSHR] [long::+ _.LADD] [long::- _.LSUB] [long::* _.LMUL] [long::/ _.LDIV] [long::% _.LREM] [long::and _.LAND] [long::or _.LOR] [long::xor _.LXOR] [long::shl _.LSHL] [long::shr _.LSHR] [long::ushr _.LUSHR] [float::+ _.FADD] [float::- _.FSUB] [float::* _.FMUL] [float::/ _.FDIV] [float::% _.FREM] [double::+ _.DADD] [double::- _.DSUB] [double::* _.DMUL] [double::/ _.DDIV] [double::% _.DREM] ) (def: boolean-class (jvm.class box.boolean (list))) (def: falseI (_.GETSTATIC "java.lang.Boolean" "FALSE" boolean-class)) (def: trueI (_.GETSTATIC "java.lang.Boolean" "TRUE" boolean-class)) (template [ ] [(def: ( [xI yI]) (Binary Inst) (<| _.with-label (function (_ @then)) _.with-label (function (_ @end)) (|>> xI yI ( @then) falseI (_.GOTO @end) (_.label @then) trueI (_.label @end))))] [int::= _.IF_ICMPEQ] [int::< _.IF_ICMPLT] [char::= _.IF_ICMPEQ] [char::< _.IF_ICMPLT] ) (template [ ] [(def: ( [xI yI]) (Binary Inst) (<| _.with-label (function (_ @then)) _.with-label (function (_ @end)) (|>> xI yI (_.int ) (_.IF_ICMPEQ @then) falseI (_.GOTO @end) (_.label @then) trueI (_.label @end))))] [long::= _.LCMP +0] [long::< _.LCMP -1] [float::= _.FCMPG +0] [float::< _.FCMPG -1] [double::= _.DCMPG +0] [double::< _.DCMPG -1] ) (def: int Bundle (<| (bundle.prefix reflection.int) (|> (: Bundle bundle.empty) (bundle.install "+" (binary int::+)) (bundle.install "-" (binary int::-)) (bundle.install "*" (binary int::*)) (bundle.install "/" (binary int::/)) (bundle.install "%" (binary int::%)) (bundle.install "=" (binary int::=)) (bundle.install "<" (binary int::<)) (bundle.install "and" (binary int::and)) (bundle.install "or" (binary int::or)) (bundle.install "xor" (binary int::xor)) (bundle.install "shl" (binary int::shl)) (bundle.install "shr" (binary int::shr)) (bundle.install "ushr" (binary int::ushr)) ))) (def: long Bundle (<| (bundle.prefix reflection.long) (|> (: Bundle bundle.empty) (bundle.install "+" (binary long::+)) (bundle.install "-" (binary long::-)) (bundle.install "*" (binary long::*)) (bundle.install "/" (binary long::/)) (bundle.install "%" (binary long::%)) (bundle.install "=" (binary long::=)) (bundle.install "<" (binary long::<)) (bundle.install "and" (binary long::and)) (bundle.install "or" (binary long::or)) (bundle.install "xor" (binary long::xor)) (bundle.install "shl" (binary long::shl)) (bundle.install "shr" (binary long::shr)) (bundle.install "ushr" (binary long::ushr)) ))) (def: float Bundle (<| (bundle.prefix reflection.float) (|> (: Bundle bundle.empty) (bundle.install "+" (binary float::+)) (bundle.install "-" (binary float::-)) (bundle.install "*" (binary float::*)) (bundle.install "/" (binary float::/)) (bundle.install "%" (binary float::%)) (bundle.install "=" (binary float::=)) (bundle.install "<" (binary float::<)) ))) (def: double Bundle (<| (bundle.prefix reflection.double) (|> (: Bundle bundle.empty) (bundle.install "+" (binary double::+)) (bundle.install "-" (binary double::-)) (bundle.install "*" (binary double::*)) (bundle.install "/" (binary double::/)) (bundle.install "%" (binary double::%)) (bundle.install "=" (binary double::=)) (bundle.install "<" (binary double::<)) ))) (def: char Bundle (<| (bundle.prefix reflection.char) (|> (: Bundle bundle.empty) (bundle.install "=" (binary char::=)) (bundle.install "<" (binary char::<)) ))) (def: (array-java-type nesting elem-class) (-> Nat Text Type) (jvm.array nesting (case elem-class (^ (static reflection.boolean)) jvm.boolean (^ (static reflection.byte)) jvm.byte (^ (static reflection.short)) jvm.short (^ (static reflection.int)) jvm.int (^ (static reflection.long)) jvm.long (^ (static reflection.float)) jvm.float (^ (static reflection.double)) jvm.double (^ (static reflection.char)) jvm.char _ (jvm.class elem-class (list))))) (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) (synthesis.text elem-class) arrayS)) (do phase.monad [arrayI (generate arrayS)] (wrap (|>> arrayI (_.CHECKCAST (jvm.descriptor (array-java-type (.nat nesting) elem-class))) _.ARRAYLENGTH))) _ (phase.throw extension.invalid-syntax [extension-name %synthesis inputs]))) (def: (new-primitive-array-handler jvm-primitive) (-> Type Handler) (function (_ extension-name generate inputs) (case inputs (^ (list lengthS)) (do phase.monad [lengthI (generate lengthS)] (wrap (|>> lengthI (_.array jvm-primitive)))) _ (phase.throw extension.invalid-syntax [extension-name %synthesis inputs])))) (def: (array::new::object extension-name generate inputs) Handler (case inputs (^ (list (synthesis.i64 nesting) (synthesis.text elem-class) lengthS)) (do phase.monad [lengthI (generate lengthS)] (wrap (|>> lengthI (_.array (array-java-type (.nat nesting) elem-class))))) _ (phase.throw extension.invalid-syntax [extension-name %synthesis inputs]))) (def: (read-primitive-array-handler jvm-primitive loadI) (-> Type Inst Handler) (function (_ extension-name generate inputs) (case inputs (^ (list idxS arrayS)) (do phase.monad [arrayI (generate arrayS) idxI (generate idxS)] (wrap (|>> arrayI (_.CHECKCAST (jvm.descriptor (jvm.array 1 jvm-primitive))) idxI loadI))) _ (phase.throw extension.invalid-syntax [extension-name %synthesis inputs])))) (def: (array::read::object extension-name generate inputs) Handler (case inputs (^ (list (synthesis.i64 nesting) (synthesis.text elem-class) idxS arrayS)) (do phase.monad [arrayI (generate arrayS) idxI (generate idxS)] (wrap (|>> arrayI (_.CHECKCAST (jvm.descriptor (array-java-type (.nat nesting) elem-class))) idxI _.AALOAD))) _ (phase.throw extension.invalid-syntax [extension-name %synthesis inputs]))) (def: (write-primitive-array-handler jvm-primitive storeI) (-> Type Inst Handler) (function (_ extension-name generate inputs) (case inputs (^ (list idxS valueS arrayS)) (do phase.monad [arrayI (generate arrayS) idxI (generate idxS) valueI (generate valueS)] (wrap (|>> arrayI (_.CHECKCAST (jvm.descriptor (jvm.array 1 jvm-primitive))) _.DUP idxI valueI storeI))) _ (phase.throw extension.invalid-syntax [extension-name %synthesis inputs])))) (def: (array::write::object extension-name generate inputs) Handler (case inputs (^ (list (synthesis.i64 nesting) (synthesis.text elem-class) idxS valueS arrayS)) (do phase.monad [arrayI (generate arrayS) idxI (generate idxS) valueI (generate valueS)] (wrap (|>> arrayI (_.CHECKCAST (jvm.descriptor (array-java-type (.nat nesting) elem-class))) _.DUP idxI valueI _.AASTORE))) _ (phase.throw extension.invalid-syntax [extension-name %synthesis inputs]))) (def: array Bundle (<| (bundle.prefix "array") (|> bundle.empty (dictionary.merge (<| (bundle.prefix "length") (|> bundle.empty (bundle.install reflection.boolean (primitive-array-length-handler jvm.boolean)) (bundle.install reflection.byte (primitive-array-length-handler jvm.byte)) (bundle.install reflection.short (primitive-array-length-handler jvm.short)) (bundle.install reflection.int (primitive-array-length-handler jvm.int)) (bundle.install reflection.long (primitive-array-length-handler jvm.long)) (bundle.install reflection.float (primitive-array-length-handler jvm.float)) (bundle.install reflection.double (primitive-array-length-handler jvm.double)) (bundle.install reflection.char (primitive-array-length-handler jvm.char)) (bundle.install "object" array::length::object)))) (dictionary.merge (<| (bundle.prefix "new") (|> bundle.empty (bundle.install reflection.boolean (new-primitive-array-handler jvm.boolean)) (bundle.install reflection.byte (new-primitive-array-handler jvm.byte)) (bundle.install reflection.short (new-primitive-array-handler jvm.short)) (bundle.install reflection.int (new-primitive-array-handler jvm.int)) (bundle.install reflection.long (new-primitive-array-handler jvm.long)) (bundle.install reflection.float (new-primitive-array-handler jvm.float)) (bundle.install reflection.double (new-primitive-array-handler jvm.double)) (bundle.install reflection.char (new-primitive-array-handler jvm.char)) (bundle.install "object" array::new::object)))) (dictionary.merge (<| (bundle.prefix "read") (|> bundle.empty (bundle.install reflection.boolean (read-primitive-array-handler jvm.boolean _.BALOAD)) (bundle.install reflection.byte (read-primitive-array-handler jvm.byte _.BALOAD)) (bundle.install reflection.short (read-primitive-array-handler jvm.short _.SALOAD)) (bundle.install reflection.int (read-primitive-array-handler jvm.int _.IALOAD)) (bundle.install reflection.long (read-primitive-array-handler jvm.long _.LALOAD)) (bundle.install reflection.float (read-primitive-array-handler jvm.float _.FALOAD)) (bundle.install reflection.double (read-primitive-array-handler jvm.double _.DALOAD)) (bundle.install reflection.char (read-primitive-array-handler jvm.char _.CALOAD)) (bundle.install "object" array::read::object)))) (dictionary.merge (<| (bundle.prefix "write") (|> bundle.empty (bundle.install reflection.boolean (write-primitive-array-handler jvm.boolean _.BASTORE)) (bundle.install reflection.byte (write-primitive-array-handler jvm.byte _.BASTORE)) (bundle.install reflection.short (write-primitive-array-handler jvm.short _.SASTORE)) (bundle.install reflection.int (write-primitive-array-handler jvm.int _.IASTORE)) (bundle.install reflection.long (write-primitive-array-handler jvm.long _.LASTORE)) (bundle.install reflection.float (write-primitive-array-handler jvm.float _.FASTORE)) (bundle.install reflection.double (write-primitive-array-handler jvm.double _.DASTORE)) (bundle.install reflection.char (write-primitive-array-handler jvm.char _.CASTORE)) (bundle.install "object" array::write::object)))) ))) (def: (object::null _) (Nullary Inst) _.NULL) (def: (object::null? objectI) (Unary Inst) (<| _.with-label (function (_ @then)) _.with-label (function (_ @end)) (|>> objectI (_.IFNULL @then) falseI (_.GOTO @end) (_.label @then) trueI (_.label @end)))) (def: (object::synchronized [monitorI exprI]) (Binary Inst) (|>> monitorI _.DUP _.MONITORENTER exprI _.SWAP _.MONITOREXIT)) (def: (object::throw exceptionI) (Unary Inst) (|>> exceptionI _.ATHROW)) (def: (object::class extension-name generate inputs) Handler (case inputs (^ (list (synthesis.text class))) (do phase.monad [] (wrap (|>> (_.string class) (_.INVOKESTATIC "java.lang.Class" "forName" (jvm.method (list (jvm.class "java.lang.String" (list))) (#.Some (jvm.class "java.lang.Class" (list))) (list)) false)))) _ (phase.throw extension.invalid-syntax [extension-name %synthesis inputs]))) (def: object::instance? Handler (..custom [($_ <>.and .text .any) (function (_ extension-name generate [class objectS]) (do phase.monad [objectI (generate objectS)] (wrap (|>> objectI (_.INSTANCEOF class) (_.wrap #jvm.Boolean)))))])) (def: (object::cast extension-name generate inputs) Handler (case inputs (^ (list (synthesis.text from) (synthesis.text to) valueS)) (do phase.monad [valueI (generate valueS)] (case [from to] ## Wrap (^template [ ] (^ [(static ) (static )]) (wrap (|>> valueI (_.wrap ))) (^ [(static ) (static )]) (wrap (|>> valueI (_.unwrap )))) ([reflection.boolean box.boolean #jvm.Boolean] [reflection.byte box.byte #jvm.Byte] [reflection.short box.short #jvm.Short] [reflection.int box.int #jvm.Int] [reflection.long box.long #jvm.Long] [reflection.float box.float #jvm.Float] [reflection.double box.double #jvm.Double] [reflection.char box.char #jvm.Char]) _ (wrap valueI))) _ (phase.throw extension.invalid-syntax [extension-name %synthesis inputs]))) (def: object Bundle (<| (bundle.prefix "object") (|> (: Bundle bundle.empty) (bundle.install "null" (nullary object::null)) (bundle.install "null?" (unary object::null?)) (bundle.install "synchronized" (binary object::synchronized)) (bundle.install "throw" (unary object::throw)) (bundle.install "class" object::class) (bundle.install "instance?" object::instance?) (bundle.install "cast" object::cast) ))) (def: primitives (Dictionary Text Primitive) (|> (list [reflection.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]) (dictionary.from-list text.hash))) (def: (static::get extension-name generate inputs) Handler (case inputs (^ (list (synthesis.text class) (synthesis.text field) (synthesis.text unboxed))) (do phase.monad [] (case (dictionary.get unboxed primitives) (#.Some primitive) (wrap (_.GETSTATIC class field (#jvm.Primitive primitive))) #.None (wrap (_.GETSTATIC class field (jvm.class unboxed (list)))))) _ (phase.throw extension.invalid-syntax [extension-name %synthesis inputs]))) (def: (static::put extension-name generate inputs) Handler (case inputs (^ (list (synthesis.text class) (synthesis.text field) (synthesis.text unboxed) valueS)) (do phase.monad [valueI (generate valueS)] (case (dictionary.get unboxed primitives) (#.Some primitive) (wrap (|>> valueI (_.PUTSTATIC class field (#jvm.Primitive primitive)) (_.string synthesis.unit))) #.None (wrap (|>> valueI (_.CHECKCAST class) (_.PUTSTATIC class field (jvm.class class (list))) (_.string synthesis.unit))))) _ (phase.throw extension.invalid-syntax [extension-name %synthesis inputs]))) (def: (virtual::get extension-name generate inputs) Handler (case inputs (^ (list (synthesis.text class) (synthesis.text field) (synthesis.text unboxed) objectS)) (do phase.monad [objectI (generate objectS)] (case (dictionary.get unboxed primitives) (#.Some primitive) (wrap (|>> objectI (_.CHECKCAST class) (_.GETFIELD class field (#jvm.Primitive primitive)))) #.None (wrap (|>> objectI (_.CHECKCAST class) (_.GETFIELD class field (jvm.class unboxed (list))))))) _ (phase.throw extension.invalid-syntax [extension-name %synthesis inputs]))) (def: (virtual::put extension-name generate inputs) Handler (case inputs (^ (list (synthesis.text class) (synthesis.text field) (synthesis.text unboxed) valueS objectS)) (do phase.monad [valueI (generate valueS) objectI (generate objectS)] (case (dictionary.get unboxed primitives) (#.Some primitive) (wrap (|>> objectI (_.CHECKCAST class) _.DUP valueI (_.PUTFIELD class field (#jvm.Primitive primitive)))) #.None (wrap (|>> objectI (_.CHECKCAST class) _.DUP valueI (_.CHECKCAST unboxed) (_.PUTFIELD class field (jvm.class unboxed (list))))))) _ (phase.throw extension.invalid-syntax [extension-name %synthesis inputs]))) (def: (generate-arg generate argS) (-> (-> Synthesis (Operation Inst)) Synthesis (Operation [Type Inst])) (case argS (^ (synthesis.tuple (list (synthesis.text argD) argS))) (do phase.monad [argT (phase.lift (.run jvm.parse-signature argD)) argI (generate argS)] (wrap [argT argI])) _ (phase.throw invalid-syntax-for-argument-generation []))) (def: (method-return-type description) (-> Text (Operation Return)) (case description (^ (static jvm.void-descriptor)) (phase@wrap #.None) _ (|> description (.run jvm.parse-signature) phase.lift (phase@map (|>> #.Some))))) (def: (prepare-argI [type argI]) (-> [Type Inst] Inst) (case (jvm.class-name type) (#.Some class-name) (|>> argI (_.CHECKCAST class-name)) #.None argI)) (def: (prepare-returnI return) (-> Return Inst) (case return (#.Some _) function.identity #.None (_.string synthesis.unit))) (def: invoke::static Handler (..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) (prepare-returnI returnT)))))])) (template [ ] [(def: Handler (..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)) ) (prepare-returnI returnT)))))]))] [invoke::virtual _.INVOKEVIRTUAL false] [invoke::special _.INVOKESPECIAL false] [invoke::interface _.INVOKEINTERFACE true] ) (def: (invoke::constructor extension-name generate inputs) Handler (case inputs (^ (list& (synthesis.text class) argsS)) (do phase.monad [argsTI (monad.map @ (generate-arg generate) argsS)] (wrap (|>> (_.NEW class) _.DUP (_.fuse (list@map ..prepare-argI argsTI)) (_.INVOKESPECIAL class "" (jvm.method (list@map product.left argsTI) #.None (list)) false)))) _ (phase.throw extension.invalid-syntax [extension-name %synthesis inputs]))) (def: member Bundle (<| (bundle.prefix "member") (|> (: Bundle bundle.empty) (dictionary.merge (<| (bundle.prefix "static") (|> (: Bundle bundle.empty) (bundle.install "get" static::get) (bundle.install "put" static::put)))) (dictionary.merge (<| (bundle.prefix "virtual") (|> (: Bundle bundle.empty) (bundle.install "get" virtual::get) (bundle.install "put" virtual::put)))) (dictionary.merge (<| (bundle.prefix "invoke") (|> (: Bundle bundle.empty) (bundle.install "static" invoke::static) (bundle.install "virtual" invoke::virtual) (bundle.install "special" invoke::special) (bundle.install "interface" invoke::interface) (bundle.install "constructor" invoke::constructor)))) ))) (def: var (Parser Var) .text) (def: bound (Parser Bound) (<>.or (.constant! ["" ">"]) (.constant! ["" "<"]))) (def: (class' generic) (-> (Parser Generic) (Parser Class)) (.tuple (<>.and .text (<>.some generic)))) (def: generic (Parser Generic) (<>.rec (function (_ generic) (let [wildcard (<>.or (.constant! ["" "?"]) (.tuple (<>.and ..bound generic)))] ($_ <>.or ..var wildcard (class' generic)))))) (def: class (Parser Class) (class' ..generic)) (def: primitive (Parser Primitive) ($_ <>.or (.constant! ["" reflection.boolean]) (.constant! ["" reflection.byte]) (.constant! ["" reflection.short]) (.constant! ["" reflection.int]) (.constant! ["" reflection.long]) (.constant! ["" reflection.float]) (.constant! ["" reflection.double]) (.constant! ["" reflection.char]) )) (def: jvm-type (Parser Type) (<>.rec (function (_ jvm-type) ($_ <>.or ..primitive ..generic (.tuple jvm-type))))) (def: constructor-arg (Parser (Typed Synthesis)) (.tuple (<>.and ..jvm-type .any))) (def: annotation-parameter (Parser (/.Annotation-Parameter Synthesis)) (.tuple (<>.and .text .any))) (def: annotation (Parser (/.Annotation Synthesis)) (.tuple (<>.and .text (<>.some ..annotation-parameter)))) (def: argument (Parser Argument) (.tuple (<>.and .text ..jvm-type))) (def: return (Parser Return) (<>.or (.constant! ["" jvm.void-descriptor]) ..jvm-type)) (def: overriden-method-definition (Parser [Environment (/.Overriden-Method Synthesis)]) (.tuple (do <>.monad [_ (.text! /.overriden-tag) ownerT ..class name .text strict-fp? .bit annotations (.tuple (<>.some ..annotation)) vars (.tuple (<>.some ..var)) self-name .text arguments (.tuple (<>.some ..argument)) returnT ..return exceptionsT (.tuple (<>.some ..class)) [environment body] (.function 1 (.tuple .any))] (wrap [environment [ownerT name strict-fp? annotations vars self-name arguments returnT exceptionsT body]])))) (def: (normalize-path normalize) (-> (-> Synthesis Synthesis) (-> Path Path)) (function (recur path) (case path (^ (synthesis.path/then bodyS)) (synthesis.path/then (normalize bodyS)) (^template [] (^ ( leftP rightP)) ( (recur leftP) (recur rightP))) ([#synthesis.Alt] [#synthesis.Seq]) (^template [] (^ ( value)) path) ([#synthesis.Pop] [#synthesis.Test] [#synthesis.Bind] [#synthesis.Access])))) (def: (normalize-method-body mapping) (-> (Dictionary Variable Variable) Synthesis Synthesis) (function (recur body) (case body (^template [] (^ ( value)) body) ([#synthesis.Primitive] [synthesis.constant]) (^ (synthesis.variant [lefts right? sub])) (synthesis.variant [lefts right? (recur sub)]) (^ (synthesis.tuple members)) (synthesis.tuple (list@map recur members)) (^ (synthesis.variable var)) (|> mapping (dictionary.get var) (maybe.default var) synthesis.variable) (^ (synthesis.branch/case [inputS pathS])) (synthesis.branch/case [(recur inputS) (normalize-path recur pathS)]) (^ (synthesis.branch/let [inputS register outputS])) (synthesis.branch/let [(recur inputS) register (recur outputS)]) (^ (synthesis.branch/if [testS thenS elseS])) (synthesis.branch/if [(recur testS) (recur thenS) (recur elseS)]) (^ (synthesis.loop/scope [offset initsS+ bodyS])) (synthesis.loop/scope [offset (list@map recur initsS+) (recur bodyS)]) (^ (synthesis.loop/recur updatesS+)) (synthesis.loop/recur (list@map recur updatesS+)) (^ (synthesis.function/abstraction [environment arity bodyS])) (synthesis.function/abstraction [(|> environment (list@map (function (_ local) (|> mapping (dictionary.get local) (maybe.default local))))) arity bodyS]) (^ (synthesis.function/apply [functionS inputsS+])) (synthesis.function/apply [(recur functionS) (list@map recur inputsS+)]) (#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 [($_ <>.and .text ..class (.tuple (<>.some ..class)) (.tuple (<>.some ..constructor-arg)) (.tuple (<>.some ..overriden-method-definition))) (function (_ extension-name generate [class-name super-class super-interfaces constructor-args overriden-methods]) (do phase.monad [#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]) [capture (#reference.Foreign id)])) (dictionary.from-list reference.hash)) normalized-methods (list@map (function (_ [environment [ownerT name strict-fp? annotations vars self-name arguments returnT exceptionsT body]]) (let [local-mapping (|> environment list.enumerate (list@map (function (_ [foreign-id capture]) [(#reference.Foreign foreign-id) (|> global-mapping (dictionary.get capture) maybe.assume)])) (dictionary.from-list reference.hash))] [ownerT name strict-fp? annotations vars self-name arguments returnT exceptionsT (normalize-method-body local-mapping body)])) overriden-methods)] method-definitions (|> normalized-methods (monad.map @ (function (_ [ownerT name strict-fp? annotations vars self-name arguments returnT exceptionsT bodyS]) (do @ [bodyG (generate bodyS)] (wrap (_def.method #$.Public (if strict-fp? ($_ $.++M $.finalM $.strictM) $.finalM) name (jvm.method (list@map product.right arguments) returnT (list@map (|>> #jvm.Class) exceptionsT)) bodyG))))) (:: @ map _def.fuse)) _ (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) method-definitions))])] (anonymous-instance class-name total-environment)))])) (def: bundle::class Bundle (<| (bundle.prefix "class") (|> (: Bundle bundle.empty) (bundle.install "anonymous" class::anonymous) ))) (def: #export bundle Bundle (<| (bundle.prefix "jvm") (|> ..conversion (dictionary.merge ..int) (dictionary.merge ..long) (dictionary.merge ..float) (dictionary.merge ..double) (dictionary.merge ..char) (dictionary.merge ..array) (dictionary.merge ..object) (dictionary.merge ..member) (dictionary.merge ..bundle::class) )))