... This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. ... If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. (.require [library [lux (.except) [program (.only program)] ["[0]" ffi (.only import)] ["[0]" debug] [abstract ["[0]" monad (.only do)]] [control ["[0]" pipe] ["[0]" maybe] ["[0]" try (.only Try) (.use "[1]#[0]" monad)] ["[0]" exception (.only Exception)] ["[0]" io (.only IO io)] ["[0]" function] [concurrency ["[0]" async (.only Async)]]] [data ["[0]" text (.use "[1]#[0]" hash) ["%" \\format (.only format)] [encoding ["[0]" utf8]]] [collection ["[0]" array (.only Array)] ["[0]" list (.use "[1]#[0]" functor)]]] [math [number ["n" nat] ["[0]" i64]]] [meta ["[0]" static] ["[0]" code] [macro ["^" pattern] ["[0]" template]] ["[0]" compiler [reference [variable (.only Register)]] ["@" target (.only) ["_" python]] [language [lux [program (.only Program)] [translation (.only Host)] ["[0]" synthesis] [analysis [macro (.only Expander)]] ["[0]" phase (.only Operation Phase) (.use "[1]#[0]" monad) ["[0]" extension (.only Extender Handler) ["[0]" analysis ["[1]" python]] ["[0]" translation ["[1]" python]]] [translation ["[0]" reference] ["[0]" python (.only) ["[0]" runtime] ["[1]/[0]" reference]]]]]] [default ["[0]" platform (.only Platform)]] [meta ["[0]" context] ["[0]" cli] [archive (.only Archive) ["[0]" unit]] ["[0]" packager ["[1]" script]]]]] ["[0]" world ["[0]" file] ["[1]/[0]" environment]]]] [program ["/" compositor]]) (with_expansions [ (these (import java/lang/String "[1]::[0]") (import (java/lang/Class a) "[1]::[0]" ("static" forName [java/lang/String] (java/lang/Class java/lang/Object)) (getName [] java/lang/String)) (import java/lang/Object "[1]::[0]" (new []) (toString [] java/lang/String) (getClass [] (java/lang/Class java/lang/Object))) (import org/python/core/PyNone "[1]::[0]") (import org/python/core/PyInteger "[1]::[0]") (import org/python/core/PyTuple "[1]::[0]") (import org/python/core/PyList "[1]::[0]") (import org/python/core/PyBoolean "[1]::[0]" (new [boolean])) (import org/python/core/PyLong "[1]::[0]" (new [long])) (import org/python/core/PyFloat "[1]::[0]" (new [double])) (import org/python/core/PyString "[1]::[0]" (new [java/lang/String])) (import org/python/core/PyObject "[1]::[0]" (asInt [] java/lang/Integer) (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 "[1]::[0]" (__call__ [[org/python/core/PyObject]] "try" org/python/core/PyObject)) (import org/python/core/ThreadState "[1]::[0]") (import org/python/core/PyArray "[1]::[0]" (new [(java/lang/Class [? < java/lang/Object]) java/lang/Object]) (getArray [] java/lang/Object)) (import org/python/util/PythonInterpreter "[1]::[0]" (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__ ffi.of_int .nat)] (loop (again [idx 0 output (as (Array Any) (array.empty size))]) (if (n.< size idx) (when (org/python/core/PyObject::__getitem__ (ffi.as_int (.int idx)) host_object) {try.#Success value} (when (read value) {try.#Success lux_value} (again (++ idx) (array.has! idx lux_value output)) failure failure) failure failure) {try.#Success output})))) (exception.def (unknown_kind_of_object object) (Exception java/lang/Object) (exception.report (list ["Object" (ffi.of_string (java/lang/Object::toString object))]))) (def (read_variant read host_object) (-> Translator Translator) (when [(org/python/core/PyObject::__getitem__ (ffi.as_int +0) host_object) (org/python/core/PyObject::__getitem__ (ffi.as_int +1) host_object) (org/python/core/PyObject::__getitem__ (ffi.as_int +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 (is Any (when (ffi.as 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)]))) (ffi.interface LuxValue (value [] java/lang/Object)) (import LuxValue "[1]::[0]" (value [] java/lang/Object)) (def (read host_object) Translator (`` (<| (,, (with_template [ ] [(when (ffi.as (as host_object)) {.#Some host_object} {try.#Success (`` (|> host_object (,, (template.spliced ))))} _)] [LuxValue [LuxValue::value]] [org/python/core/PyNone [(pipe.new [] [])]] [org/python/core/PyBoolean [org/python/core/PyObject::__nonzero__]] ... [org/python/core/PyInteger [(ffi.is org/python/core/PyObject) org/python/core/PyObject::asInt]] [org/python/core/PyInteger [(ffi.is org/python/core/PyObject) (.jvm_member_invoke_virtual# [] "org.python.core.PyObject" "asInt" []) .jvm_object_cast# (is (Nominal "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] [(|>)]] )) (,, (with_template [ ] [(when (ffi.as 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}))) (def (function/? arity) (-> Nat Code) (` (.-> (,* (list.repeated arity (` .Any))) .Any))) (def (inputs/? arity) (-> Nat (List Text)) (|> (list.indices arity) (list#each (|>> %.nat (format "input/"))))) (def (pseudo_function to_host it) (-> (-> Any org/python/core/PyObject) Any org/python/core/PyObject) (<| (as org/python/core/PyObject) (ffi.object [] org/python/core/PyObject [LuxValue] [] ... Methods (LuxValue [] (value self []) java/lang/Object (as java/lang/Object it)) (org/python/core/PyObject [] (__call__ self [inputs [org/python/core/PyObject] keywords [java/lang/String]]) org/python/core/PyObject (try.trusted (do [! try.monad] [inputs (monad.each ! ..read (array.list {.#None} inputs))] (in (loop (again [it it inputs inputs]) (`` (`` (when inputs (list) (as org/python/core/PyObject self) (,, (with_template [] [(list (,, (static.literals code.local (inputs/? )))) (to_host ((as (,, (static.literal function.identity (function/? ))) it) (,, (static.literals code.local (inputs/? )))))] [1] [2] [3] [4] [5] [6] [7] [8])) (list.partial (,, (static.literals code.local (inputs/? 8))) input/+) (again ((as (,, (static.literal function.identity (function/? 8))) it) (,, (static.literals code.local (inputs/? 8)))) input/+)))))))))))) (def object_class (java/lang/Class java/lang/Object) (java/lang/Object::getClass (java/lang/Object::new))) (import library/lux/Function "[1]::[0]") (def (to_host|array to_host it) (-> (-> Any org/python/core/PyObject) Any org/python/core/PyObject) (as org/python/core/PyObject (ffi.object [] org/python/core/PyArray [LuxValue] [(java/lang/Class java/lang/Object) ..object_class java/lang/Object (as java/lang/Object it)] ... Methods (LuxValue [] (value self []) java/lang/Object (as java/lang/Object it)) (org/python/core/PyArray [] (pyget self [index' int]) org/python/core/PyObject (when (|> it (as (Array Any)) (array.item (|> index' ffi.int_to_long (as Nat)))) {.#None} (ffi.super [index'] self) {.#Some it} (<| (when (ffi.as [java/lang/Object] (as java/lang/Object it)) {.#Some it} (to_host it) {.#None}) (when (ffi.as library/lux/Function (as java/lang/Object it)) {.#Some it} (pseudo_function to_host it) {.#None}) (ffi.super [index'] self)))) ))) (def (to_host it) (-> Any org/python/core/PyObject) (`` (<| (,, (with_template [ ] [(when (ffi.as (as java/lang/Object it)) {.#Some it} (as org/python/core/PyObject ( [it])) {.#None})] [java/lang/Boolean org/python/core/PyBoolean::new] [java/lang/Long org/python/core/PyLong::new] [java/lang/Double org/python/core/PyFloat::new] [java/lang/String org/python/core/PyString::new] [library/lux/Function (pseudo_function to_host)] [[java/lang/Object] (to_host|array to_host)] )) (as org/python/core/PyObject it)))) )] (for @.old (these ) @.jvm (these ) @.python (these))) (with_expansions [ (these (def (call_macro inputs lux macro) (-> (List Code) Lux org/python/core/PyFunction (Try (Try [Lux (List Code)]))) (|> macro (org/python/core/PyFunction::__call__ (|> (ffi.array org/python/core/PyObject 2) (ffi.write! 0 (..to_host inputs)) (ffi.write! 1 (..to_host lux)))) (try#each ..read) try#conjoint as_expected)) (def python_function! (-> Any (Maybe org/python/core/PyFunction)) (|>> (as java/lang/Object) (ffi.as org/python/core/PyFunction))) (exception.def (cannot_apply_a_non_function object) (Exception java/lang/Object) (exception.report (list ["Object" (ffi.of_string (java/lang/Object::toString object))] ["Class" (ffi.of_string (java/lang/Class::getName (java/lang/Object::getClass object)))]))) (def (expander macro inputs lux) Expander (when (python_function! macro) {.#Some macro} (when (..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 (these ) @.jvm (these ) @.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! (is (-> unit.ID [(Maybe unit.ID) (_.Expression Any)] (Try Any)) (function (evaluate! context [_ input]) (do try.monad [output (org/python/util/PythonInterpreter::eval (ffi.as_string (_.code input)) interpreter)] (..read output)))) execute! (is (-> (_.Statement Any) (Try Any)) (function (execute! input) (when (org/python/util/PythonInterpreter::exec (ffi.as_string (_.code input)) interpreter) {try.#Failure error} (if (text.contains? "maximum recursion depth exceeded" error) (execute! input) {try.#Failure error}) output output)))] (is (Host (_.Expression Any) (_.Statement Any)) (implementation (def evaluate evaluate!) (def execute execute!) (def (define context custom [@def 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 [@def @global])] (in [global value definition])))) (def (ingest context content) (|> content (of 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 [{.#None} (_.var (reference.artifact context))]))))))))] (for @.old @.jvm @.python (these (import (dict [] ffi.Dict)) (import (eval [ffi.String ffi.Dict] "try" Any)) (def host (IO (Host (_.Expression Any) (_.Statement Any))) (io (is (Host (_.Expression Any) (_.Statement Any)) (let [globals (..dict []) evaluate! (is (-> unit.ID (_.Expression Any) (Try Any)) (function (evaluate! context input) (..eval [(_.code input) globals]))) execute! (is (-> (_.Statement Any) (Try Any)) (function (execute! input) (ffi.try (.python_exec# (_.code input) globals)))) define! (is (-> unit.ID (_.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 (of 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))))))))))))) (def phase_wrapper phase.Wrapper (..pseudo_function ..to_host)) (with_expansions [ (these (def extender Extender ... TODO: Stop relying on coercions ASAP. (<| (as Extender) (function (_ handler)) (as Handler) (function (_ phase)) (as Phase) (function (_ archive parameters)) (as Operation) (function (_ state)) (as Try) try.trusted (as Try) (do try.monad [handler (try.of_maybe (..python_function! handler)) output (org/python/core/PyFunction::__call__ (|> (ffi.array org/python/core/PyObject 4) (ffi.write! 0 (as org/python/core/PyObject (phase_wrapper phase))) (ffi.write! 1 (..to_host archive)) (ffi.write! 2 (..to_host parameters)) (ffi.write! 3 (..to_host state))) handler)] (..read output)))))] (for @.old (these ) @.jvm (these ) @.python (def extender Extender (|>> as_expected)))) (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.expression platform.#runtime runtime.translate platform.#phase_wrapper ..phase_wrapper platform.#write (|>> _.code (of utf8.codec encoded))]))) (def (lux_program context program) (Program (_.Expression Any) (_.Statement Any)) (all _.then (_.import "sys") (_.when (_.= (_.string "__main__") (_.var "__name__")) (_.statement (_.apply (list (|> (_.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) program))))) (def (declare_success! _) (-> Any (Async Any)) (async.future (of world/environment.default exit +0))) (def (scope body) (-> (_.Statement Any) (_.Statement Any)) (let [@program (_.var "lux_program") ; _.statement $sys (_.__import__/1 (_.unicode "sys")) ... $threading (_.__import__/1 (_.unicode "threading")) current_limit (_.do "getrecursionlimit" (list) $sys) old_limit current_limit new_limit (_.bit_shl (_.int +2) old_limit)] (<| (_.comment "-*- coding: utf-8 -*-") (all _.then (; (_.do "setrecursionlimit" (list new_limit) $sys)) ... (; (_.do "stack_size" (list current_limit) $threading)) (_.def @program (list) body) (; (_.apply (list) @program)) )))) (def (lux_compiler it) (-> Any platform.Custom) (undefined)) (def _ (program [service cli.service] (let [extension ".py"] (exec (do async.monad [_ (/.compiler ..lux_compiler (context.python (cli.target service)) ..expander analysis.bundle ..platform translation.bundle extension.empty ..lux_program (reference.constant python/reference.system) ..extender service [(packager.package (is (_.Statement Any) (_.manual "")) _.code _.then ..scope) (format "program" extension)])] (..declare_success! [])) (io.io [])))))