(.module: [lux (#- Definition) [abstract [monad (#+ do)]] [control pipe ["ex" exception (#+ exception:)] ["." io (#+ IO io)] [concurrency ["." atom (#+ Atom atom)]]] [data ["." product] ["." error (#+ Error)] ["." text ("#/." hash) format] [collection ["." array] [list ("#/." functor)] ["." dictionary (#+ Dictionary)]]] ["." host (#+ import: do-to object) [jvm ["." loader (#+ Library)]]] [world [binary (#+ Binary)]] [tool [compiler ["." name]]]] [/// [host ["." jvm (#+ Inst Definition Host State) ["." type] ["." def] ["." inst]]]] ) (import: org/objectweb/asm/Label) (import: java/lang/reflect/Field (get [#? Object] #try #? Object)) (import: (java/lang/Class a) (getField [String] #try Field)) (import: java/lang/Object (getClass [] (Class Object))) (import: java/lang/ClassLoader) (type: #export ByteCode Binary) (def: #export value-field Text "_value") (def: #export $Object jvm.Type (type.class "java.lang.Object" (list))) (exception: #export (cannot-load {class Text} {error Text}) (ex.report ["Class" class] ["Error" error])) (exception: #export (invalid-field {class Text} {field Text} {error Text}) (ex.report ["Class" class] ["Field" field] ["Error" error])) (exception: #export (invalid-value {class Text}) (ex.report ["Class" class])) (def: (class-value class-name class) (-> Text (Class Object) (Error Any)) (case (Class::getField ..value-field class) (#error.Success field) (case (Field::get #.None field) (#error.Success ?value) (case ?value (#.Some value) (#error.Success value) #.None (ex.throw invalid-value class-name)) (#error.Failure error) (ex.throw cannot-load [class-name error])) (#error.Failure error) (ex.throw invalid-field [class-name ..value-field error]))) (def: class-path-separator ".") (def: (evaluate! library loader eval-class valueI) (-> Library ClassLoader Text Inst (Error [Any Definition])) (let [bytecode-name (text.replace-all class-path-separator .module-separator eval-class) bytecode (def.class #jvm.V1_6 #jvm.Public jvm.noneC bytecode-name (list) ["java.lang.Object" (list)] (list) (|>> (def.field #jvm.Public ($_ jvm.++F jvm.finalF jvm.staticF) ..value-field ..$Object) (def.method #jvm.Public ($_ jvm.++M jvm.staticM jvm.strictM) "" (type.method (list) #.None (list)) (|>> valueI (inst.PUTSTATIC bytecode-name ..value-field ..$Object) inst.RETURN))))] (io.run (do (error.with io.monad) [_ (loader.store eval-class bytecode library) class (loader.load eval-class loader) value (:: io.monad wrap (class-value eval-class class))] (wrap [value [eval-class bytecode]]))))) (def: (execute! library loader temp-label [class-name class-bytecode]) (-> Library ClassLoader Text Definition (Error Any)) (io.run (do (error.with io.monad) [existing-class? (|> (atom.read library) (:: io.monad map (dictionary.contains? class-name)) (error.lift io.monad) (: (IO (Error Bit)))) _ (if existing-class? (wrap []) (loader.store class-name class-bytecode library))] (loader.load class-name loader)))) (def: (define! library loader [module name] valueI) (-> Library ClassLoader Name Inst (Error [Text Any Definition])) (let [class-name (format (text.replace-all .module-separator class-path-separator module) class-path-separator (name.normalize name) "___" (%n (text/hash name)))] (do error.monad [[value definition] (evaluate! library loader class-name valueI)] (wrap [class-name value definition])))) (def: #export host (IO Host) (io (let [library (loader.new-library []) loader (loader.memory library)] (: Host (structure (def: (evaluate! temp-label valueI) (let [eval-class (|> temp-label name.normalize (text.replace-all " " "$"))] (:: error.monad map product.left (..evaluate! library loader eval-class valueI)))) (def: execute! (..execute! library loader)) (def: define! (..define! library loader))))))) (def: #export runtime-class "LuxRuntime") (def: #export function-class "LuxFunction") (def: #export runnable-class "LuxRunnable") (def: #export $Variant jvm.Type (type.array 1 ..$Object)) (def: #export $Tuple jvm.Type (type.array 1 ..$Object)) (def: #export $Function jvm.Type (type.class ..function-class (list)))