(.module: [library [lux #* [program (#+ program:)] ["." ffi (#+ import:)] [abstract [monad (#+ do)]] [control [pipe (#+ new>)] ["." maybe] ["." try (#+ Try)] ["." exception (#+ exception:)] ["." io (#+ IO io)] ["." function] [concurrency ["." async (#+ Async)]]] [data ["." text ("#\." hash) ["%" format (#+ format)] [encoding ["." utf8]]] [collection ["." array (#+ Array)] ["." list]]] [macro ["." template]] [math [number ["n" nat] ["." i64]]] ["." world #_ ["." file] ["#/." program]] ["@" target ["_" python]] [tool [compiler ["." phase (#+ Operation Phase)] [reference [variable (#+ Register)]] [language [lux [program (#+ Program)] [generation (#+ Context Host)] ["." synthesis] [analysis [macro (#+ Expander)]] [phase ["." extension (#+ Extender Handler) ["#/." bundle] ["." analysis #_ ["#" python]] ["." generation #_ ["#" python]]] [generation ["." reference] ["." python ["." runtime]]]]]] [default ["." platform (#+ Platform)]] [meta [archive (#+ Archive)] ["." packager #_ ["#" script]]]]]]] [program ["/" compositor ["/." cli] ["/." static]]]) (with_expansions [ (as_is (import: java/lang/String) (import: (java/lang/Class a)) (import: java/lang/Object ["#::." (new []) (toString [] java/lang/String) (getClass [] (java/lang/Class java/lang/Object))]) (import: org/python/core/PyNone) (import: org/python/core/PyBoolean) (import: org/python/core/PyInteger) (import: org/python/core/PyLong) (import: org/python/core/PyFloat) (import: org/python/core/PyTuple) (import: org/python/core/PyList) (import: org/python/core/PyString ["#::." (new [java/lang/String])]) (import: org/python/core/PyObject ["#::." ... (asInt [] int) (asLong [] long) (asDouble [] double) (asString [] java/lang/String) (__nonzero__ [] boolean) (__getitem__ [int] #try org/python/core/PyObject) (__getitem__ #as __getitem__dict [org/python/core/PyObject] #try org/python/core/PyObject) (__len__ [] int)]) (import: org/python/core/PyFunction ["#::." (__call__ [[org/python/core/PyObject]] #try org/python/core/PyObject)]) (import: org/python/core/ThreadState) (import: org/python/core/PyArray ["#::." (new [(java/lang/Class [? < java/lang/Object]) java/lang/Object]) (getArray [] java/lang/Object)]) (import: org/python/util/PythonInterpreter ["#::." (new []) (exec [java/lang/String] #try void) (eval [java/lang/String] #try PyObject)]) (type: Translator (-> org/python/core/PyObject (Try Any))) (def: (read_tuple read host_object) (-> Translator Translator) (let [size (|> host_object org/python/core/PyObject::__len__ .nat)] (loop [idx 0 output (:as (Array Any) (array.empty size))] (if (n.< size idx) (case (org/python/core/PyObject::__getitem__ (.int idx) host_object) (#try.Failure try) (#try.Failure try) (#try.Success value) (case (read value) (#try.Failure try) (#try.Failure try) (#try.Success lux_value) (recur (++ idx) (array.write! idx lux_value output)))) (#try.Success output))))) (exception: (unknown_kind_of_object {object java/lang/Object}) (exception.report ["Object" (java/lang/Object::toString object)])) (def: (read_variant read host_object) (-> Translator Translator) (case [(org/python/core/PyObject::__getitem__ +0 host_object) (org/python/core/PyObject::__getitem__ +1 host_object) (org/python/core/PyObject::__getitem__ +2 host_object)] (^or [(#try.Failure try) _ _] [_ (#try.Failure try) _] [_ _ (#try.Failure try)]) (#try.Failure try) (^multi [(#try.Success tag) (#try.Success flag) (#try.Success value)] {(read tag) (#try.Success tag)} {(read value) (#try.Success value)}) (#try.Success [tag (: Any (case (ffi.check org/python/core/PyNone (:as java/lang/Object flag)) (#.Some _) (:as Any (ffi.null)) #.None (:as Any synthesis.unit))) value]) _ (exception.except ..unknown_kind_of_object [(:as java/lang/Object host_object)]))) (def: (read host_object) Translator (`` (<| (~~ (template [ ] [(case (ffi.check (:as host_object)) (#.Some host_object) (#try.Success (`` (|> host_object (~~ (template.spliced ))))) _)] [org/python/core/PyNone [(new> [] [])]] [org/python/core/PyBoolean [org/python/core/PyObject::__nonzero__]] ... [org/python/core/PyInteger [(ffi.:as org/python/core/PyObject) org/python/core/PyObject::asInt]] [org/python/core/PyInteger [(ffi.:as org/python/core/PyObject) ("jvm member invoke virtual" [] "org.python.core.PyObject" "asInt" []) "jvm object cast" (: (primitive "java.lang.Integer"))]] [org/python/core/PyLong [org/python/core/PyObject::asLong]] [org/python/core/PyFloat [org/python/core/PyObject::asDouble]] [org/python/core/PyString [org/python/core/PyObject::asString]] [org/python/core/PyFunction []] [org/python/core/PyArray [org/python/core/PyArray::getArray]] [[java/lang/Object] [(|>)]] )) (~~ (template [ ] [(case (ffi.check host_object) (#.Some host_object) (<| (:as org/python/core/PyObject) host_object) _)] [org/python/core/PyTuple (..read_variant read)] [org/python/core/PyList (..read_tuple read)] )) ... (exception.except ..unknown_kind_of_object [(:as java/lang/Object host_object)]) (#try.Success host_object)))) (exception: (cannot_apply_a_non_function {object java/lang/Object}) (exception.report ["Non-function" (java/lang/Object::toString object)])) (def: (ensure_macro macro) (-> Macro (Maybe org/python/core/PyFunction)) (ffi.check org/python/core/PyFunction (:as java/lang/Object macro))) (def: object_class (java/lang/Class java/lang/Object) (java/lang/Object::getClass (java/lang/Object::new))) (def: to_host (-> Any org/python/core/PyObject) (|>> (:as java/lang/Object) (org/python/core/PyArray::new ..object_class) (:as org/python/core/PyObject))) (def: ensure_function (-> Any (Maybe org/python/core/PyFunction)) (|>> (:as java/lang/Object) (ffi.check org/python/core/PyFunction))) )] (for {@.old (as_is ) @.jvm (as_is ) @.python (as_is)})) (with_expansions [ (as_is (def: (call_macro inputs lux macro) (-> (List Code) Lux org/python/core/PyFunction (Try (Try [Lux (List Code)]))) (:expected (do try.monad [expansion (org/python/core/PyFunction::__call__ (|> (ffi.array org/python/core/PyObject 2) (ffi.write! 0 (..to_host inputs)) (ffi.write! 1 (..to_host lux))) macro)] (..read expansion)))) (def: (expander macro inputs lux) Expander (case (ensure_macro macro) (#.Some macro) (case (..call_macro inputs lux macro) (#try.Success output) (|> output (:as org/python/core/PyObject) ..read (:as (Try (Try [Lux (List Code)])))) (#try.Failure error) (#try.Failure error)) #.None (exception.except ..cannot_apply_a_non_function (:as java/lang/Object macro)))))] (for {@.old (as_is ) @.jvm (as_is ) @.python (def: (expander macro inputs lux) Expander (#try.Success ((:as Macro' macro) inputs lux)))})) (with_expansions [ (def: host (IO (Host (_.Expression Any) (_.Statement Any))) (io (let [interpreter (org/python/util/PythonInterpreter::new) evaluate! (: (-> Context (_.Expression Any) (Try Any)) (function (evaluate! context input) (do try.monad [output (org/python/util/PythonInterpreter::eval (_.code input) interpreter)] (..read output)))) execute! (: (-> (_.Statement Any) (Try Any)) (function (execute! input) (org/python/util/PythonInterpreter::exec (_.code input) interpreter)))] (: (Host (_.Expression Any) (_.Statement Any)) (implementation (def: evaluate! evaluate!) (def: execute! execute!) (def: (define! context custom input) (let [global (maybe.else (reference.artifact context) custom) @global (_.var global)] (do try.monad [.let [definition (_.set (list @global) input)] _ (execute! definition) value (evaluate! context @global)] (in [global value definition])))) (def: (ingest context content) (|> content (\ utf8.codec decoded) try.trusted (:as (_.Statement Any)))) (def: (re_learn context custom content) (execute! content)) (def: (re_load context custom content) (do try.monad [_ (execute! content)] (evaluate! context (_.var (reference.artifact context))))))))))] (for {@.old @.jvm @.python (as_is (import: (dict [] ffi.Dict)) (import: (eval [ffi.String ffi.Dict] #try Any)) (def: host (IO (Host (_.Expression Any) (_.Statement Any))) (io (: (Host (_.Expression Any) (_.Statement Any)) (let [globals (..dict []) evaluate! (: (-> Context (_.Expression Any) (Try Any)) (function (evaluate! context input) (..eval [(_.code input) globals]))) execute! (: (-> (_.Statement Any) (Try Any)) (function (execute! input) (ffi.try ("python exec" (_.code input) globals)))) define! (: (-> Context (_.Expression Any) (Try [Text Any (_.Statement Any)])) (function (define! context input) (let [global (reference.artifact context) @global (_.var global)] (do try.monad [.let [definition (_.set (list @global) input)] _ (execute! definition) value (evaluate! context @global)] (in [global value definition])))))] (implementation (def: evaluate! evaluate!) (def: execute! execute!) (def: define! define!) (def: (ingest context content) (|> content (\ utf8.codec decoded) try.trusted (:as (_.Statement Any)))) (def: (re_learn context content) (execute! content)) (def: (re_load context content) (do try.monad [_ (execute! content)] (evaluate! context (_.var (reference.artifact context)))))))))))})) (with_expansions [ (as_is (exception: .public (invaid_phase_application {partial_application (List Any)} {arity Nat}) (exception.report ["Partial Application" (%.nat (list.size partial_application))] ["Arity" (%.nat arity)])) (def: (host_phase partial_application phase) (All [s i o] (-> (List Any) (Phase [extension.Bundle s] i o) org/python/core/PyObject)) (<| (ffi.:as org/python/core/PyObject) (ffi.object [] org/python/core/PyObject [] [] ... Methods (org/python/core/PyObject [] (__call__ self {inputs [org/python/core/PyObject]} {keywords [java/lang/String]}) org/python/core/PyObject (try.trusted (case (array.list inputs) (^ (list)) (\ try.monad in (host_phase (list) phase)) (^ (list input/0)) (do try.monad [input/0 (..read input/0)] (case partial_application (^ (list partial/0 partial/1)) (in (..to_host ((:as (-> Any Any Any Any) phase) partial/0 partial/1 input/0))) (^ (list partial/0)) (in (host_phase (list partial/0 input/0) phase)) (^ (list)) (in (host_phase (list input/0) phase)) _ (exception.except ..invaid_phase_application [partial_application (array.size inputs)]))) (^ (list input/0 input/1)) (do try.monad [input/0 (..read input/0) input/1 (..read input/1)] (case partial_application (^ (list partial/0)) (in (..to_host ((:as (-> Any Any Any Any) phase) partial/0 input/0 input/1))) (^ (list)) (in (host_phase (list input/0 input/1) phase)) _ (exception.except ..invaid_phase_application [partial_application (array.size inputs)]))) (^ (list input/0 input/1 input/2)) (do try.monad [input/0 (..read input/0) input/1 (..read input/1) input/2 (..read input/2)] (case partial_application (^ (list)) (in (..to_host ((:as (-> Any Any Any Any) phase) input/0 input/1 input/2))) _ (exception.except ..invaid_phase_application [partial_application (array.size inputs)]))) _ (exception.except ..invaid_phase_application [partial_application (array.size inputs)]))))))) (def: (extender phase_wrapper) (-> phase.Wrapper Extender) ... TODO: Stop relying on coercions ASAP. (<| (:as Extender) (function (_ handler)) (:as Handler) (function (_ name phase)) (:as Phase) (function (_ archive parameters)) (:as Operation) (function (_ state)) (:as Try) try.trusted (:as Try) (do try.monad [handler (try.of_maybe (..ensure_function handler)) output (org/python/core/PyFunction::__call__ (|> (ffi.array org/python/core/PyObject 5) (ffi.write! 0 (:as org/python/core/PyObject (org/python/core/PyString::new name))) (ffi.write! 1 (:as org/python/core/PyObject (phase_wrapper phase))) (ffi.write! 2 (..to_host archive)) (ffi.write! 3 (..to_host parameters)) (ffi.write! 4 (..to_host state))) handler)] (..read output)))))] (for {@.old (as_is ) @.jvm (as_is ) @.python (def: (extender phase_wrapper handler) (-> phase.Wrapper Extender) (:expected handler))})) (def: (phase_wrapper archive) (-> Archive (runtime.Operation phase.Wrapper)) (do phase.monad [] (in (:as phase.Wrapper (..host_phase (list)))))) (def: platform (IO (Platform Register (_.Expression Any) (_.Statement Any))) (do io.monad [host ..host] (in {#platform.&file_system (file.async file.default) #platform.host host #platform.phase python.generate #platform.runtime runtime.generate #platform.phase_wrapper ..phase_wrapper #platform.write (|>> _.code (\ utf8.codec encoded))}))) (def: (program context program) (Program (_.Expression Any) (_.Statement Any)) ($_ _.then (_.import "sys") (_.when (_.= (_.string "__main__") (_.var "__name__")) (_.statement (_.apply/2 program (|> (_.var "sys") (_.the "argv") ... The first entry in the list will be the program.py file itself ... so, it must be removed so only the program's arguments are left. (_.slice_from (_.int +1)) runtime.lux::program_args) _.none))))) (def: (declare_success! _) (-> Any (Async Any)) (async.future (\ world/program.default exit +0))) (def: (scope body) (-> (_.Statement Any) (_.Statement Any)) (let [@program (_.var "lux_program") max_recursion (|> (_.int +10) (_.** (_.int +6))) ; _.statement] (<| (_.comment "-*- coding: utf-8 -*-") ($_ _.then (; (|> (_.__import__/1 (_.unicode "sys")) (_.do "setrecursionlimit" (list max_recursion)))) (_.def @program (list) body) (; (_.apply/* @program (list))) )))) (program: [service /cli.service] (let [extension ".py"] (exec (do async.monad [_ (/.compiler {#/static.host @.python #/static.host_module_extension extension #/static.target (/cli.target service) #/static.artifact_extension extension} ..expander analysis.bundle ..platform generation.bundle (function.constant extension/bundle.empty) ..program [Register (type (_.Expression Any)) (type (_.Statement Any))] ..extender service [(packager.package (: (_.Statement Any) (_.manual "")) _.code _.then ..scope) (format (/cli.target service) (\ file.default separator) "program" extension)])] (..declare_success! [])) (io.io []))))