diff options
Diffstat (limited to 'stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/python/function.lux')
-rw-r--r-- | stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/python/function.lux | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/python/function.lux b/stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/python/function.lux new file mode 100644 index 000000000..1d1021d11 --- /dev/null +++ b/stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/python/function.lux @@ -0,0 +1,117 @@ +(.require + [library + [lux (.except function) + [abstract + ["[0]" monad (.only do)]] + [data + ["[0]" product] + [text + ["%" \\format (.only format)]] + [collection + ["[0]" list (.use "[1]#[0]" functor mix)]]] + [meta + [target + ["_" python (.only SVar Expression Statement)]]]]] + ["[0]" // + [runtime (.only Operation Phase Generator Phase! Generator!)] + ["[1][0]" reference] + ["[1][0]" case] + ["[1][0]" loop] + ["/[1]" // + ["[1][0]" reference] + ["//[1]" /// + [analysis (.only Environment Abstraction Reification Analysis)] + [synthesis (.only Synthesis)] + ["[1][0]" generation] + ["//[1]" /// + [arity (.only Arity)] + ["[1][0]" phase] + [reference + [variable (.only Register Variable)]] + [meta + [archive (.only Archive) + ["[0]" artifact]] + ["[0]" cache + [dependency + ["[1]" artifact]]]]]]]]) + +(def .public (apply expression archive [functionS argsS+]) + (Generator (Reification Synthesis)) + (do [! ///////phase.monad] + [functionO (expression archive functionS) + argsO+ (monad.each ! (expression archive) argsS+)] + (in (_.apply argsO+ functionO)))) + +(def .public capture + (-> Register SVar) + (|>> (///reference.foreign //reference.system) as_expected)) + +(def (with_closure function_id @function inits function_definition) + (-> artifact.ID SVar (List (Expression Any)) (Statement Any) (Operation (Expression Any))) + (case inits + {.#End} + (do ///////phase.monad + [_ (/////generation.execute! function_definition) + _ (/////generation.save! function_id {.#None} function_definition)] + (in @function)) + + _ + (do [! ///////phase.monad] + [.let [declaration (_.def @function + (|> (list.enumeration inits) + (list#each (|>> product.left ..capture))) + (all _.then + function_definition + (_.return @function)))] + _ (/////generation.execute! declaration) + _ (/////generation.save! function_id {.#None} declaration)] + (in (_.apply inits @function))))) + +(def input + (|>> ++ //case.register)) + +(def .public (function statement expression archive [environment arity bodyS]) + (-> Phase! (Generator (Abstraction Synthesis))) + (do [! ///////phase.monad] + [dependencies (cache.dependencies archive bodyS) + [[function_module function_artifact] body!] (/////generation.with_new_context archive dependencies + (/////generation.with_anchor 1 + (statement expression archive bodyS))) + environment (monad.each ! (expression archive) environment) + .let [@curried (_.var "curried") + arityO (|> arity .int _.int) + @num_args (_.var "num_args") + @self (_.var (///reference.artifact [function_module function_artifact])) + apply_poly (.function (_ args func) + (_.apply (list (_.splat_poly args)) func)) + initialize_self! (_.set (list (//case.register 0)) @self) + initialize! (list#mix (.function (_ post pre!) + (all _.then + pre! + (_.set (list (..input post)) (_.item (|> post .int _.int) @curried)))) + initialize_self! + (list.indices arity))]] + (with_closure function_artifact @self environment + (_.def @self (list (_.poly @curried)) + (all _.then + (_.set (list @num_args) (_.len/1 @curried)) + (<| (_.if (|> @num_args (_.= arityO)) + (<| (_.then initialize!) + //loop.set_scope + body!)) + (_.if (|> @num_args (_.> arityO)) + (let [arity_inputs (_.slice (_.int +0) arityO @curried) + extra_inputs (_.slice arityO @num_args @curried)] + (_.return (|> @self + (apply_poly arity_inputs) + (apply_poly extra_inputs))))) + ... (|> @num_args (_.< arityO)) + (let [@next (_.var "next") + @missing (_.var "missing")] + (all _.then + (_.def @next (list (_.poly @missing)) + (_.return (|> @self (apply_poly (|> @curried (_.+ @missing)))))) + (_.return @next) + ))) + ))) + )) |